hibernate如何处理 java 和数据库的时间类型对应关系?
- 首先我们需要知道在java中,代表时间和日期的类型主要是:java.util.Date 和 java.util.Calendar
- 在jdbc的API中,提供了三个java.util.Date 的子类,分别是:java.sql.Date,java.sql.Time,java.sql.Timestamp,这三个类分别对应了标准SQL类型中的DATE,TIME和TIMESTAMP 类型
- 在标准SQL中,DATE 类型表示日期,TIME 类型表示时间,TIMESTAMP 类型表示时间戳(同时包含了日期和时间信息)
正是因为java.util.Date 是 java.sql.Date,java.sql.Time,java.sql.Timestamp 的父类,所以java.util.Date 可以对应标准SQL类型的 DATE,TIME,TIMESTAMP,所以我们在持久化类的Date类型时,通常设置为java.util.Date
那么如何在 hibernate 映射文件中将持久化类的java.util.Date 类型映射为数据库的DATE,TIME,TIMESTAMP?
<property name="date" type="time">
<column name="DATE" />
</property>
or
<property name="date" type="time">
<column name="DATE" />
</property>
or
<property name="date" type="time">
<column name="DATE" />
</property>
以上配置中的time,date,timestamp 既不是java类型,也不是标准SQL类型,而是hibernate的映射类型(类似于扁担,两边承载的是java类型和标准SQL类型)
hibernate 映射文件中的组件关系如何实现?
什么是域模型?什么是关系型数据模型?它们之间有什么区别?
- 域模型:由代码组成,通过细化持久化类的粒度可以提高代码的可重用性,简化编程
- 个人理解:域模型在不同的面向对象型编程语言中都是存在的,以java为例,我们所有的操作都是依赖于对象,或者说是javaBean,我们在设计一个类的时候,其实就是在建立一个域模型,每个类尽可能设计的简洁和细化,可以很大程度上方便后续开发和维护
- 关系型数据模型:在关系型数据库中,应该尽可能的减少表的数量,简化表之间的参照关系,提高数据的访问速度
- 举例:当我们java代码里有两个类,而需要在数据库显示在一张表上的时候,应该怎么做呢?
- 设计一个员工类Emp,再设计一个工资类Salary,其中Salary类需要依赖于Emp类(这两个类存在关联关系),但是我们在数据库中只设计一张表
- hibernate 把持久化类的属性分为两种:
- 值(value)类型:没有OID,不能被单独持久化,生命周期依赖于所属的持久化类的对象的生命周期(例如Salary类)
- 实体(entity)类型:有OID,可以被单独持久化,有独立的生命周期(例如Emp类)
- 所以我们虽然设计了两个类,实际上只有一张数据库表,也只有一个对象映射文件,在这个映射文件中,使用component元素来映射组成关系(表示Salary类是Emp类的一个成员属性),这在hibernate中称之为组件
代码如下:
Emp.java
public class Emp {
private int id;
private String name;
//工资类
private Salary salary;
//getter,setter和构造方法略
}
- Salary.java
public class Salary {
//月薪
private Integer monthSalary;
//年薪
private Integer yearSalary;
//对应映射文件component元素的parent节点(如果使用parent子节点,就必须在组件类即Salary类设置Emp类属性)
private Emp emp;
//getter,setter和构造方法略
}
- Emp.hbm.xml
<hibernate-mapping package="com.zc.cris.pojo.component">
<class name="Emp" table="EMPS">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<!-- 映射组成关系(Emp类的Salary成员属性) -->
<component name="salary" class="Salary">
<parent name="emp"/>
<!-- 指定组成关系的组件的属性 -->
<property name="monthSalary" column="MONTH_SAL"></property>
<property name="yearSalary" column="YEAR_SAL"></property>
</component>
</class>
</hibernate-mapping>
- hibernate.cfg.xml
<!-- 引入对象关系映射文件 -->
<mapping resource="com/zc/cris/pojo/News.hbm.xml"/>
<mapping resource="com/zc/cris/pojo/component/Emp.hbm.xml"/>
- TestHibernate2.java
/*
* 测试hibernate中的组件关系映射
*/
@Test
void testComponent() {
Emp emp = new Emp("james", new Salary(100, 10000));
this.session.save(emp);
Emp emp2 = this.session.get(Emp.class, 1);
System.out.println(emp2);
//需要格外注意的是:如果调用组件Salary的toString方法,是不能打印出Emp类属性的,否则会抛出overStackFlow异常
System.out.println(emp2.getSalary());
System.out.println(emp2.getSalary().getMonthSalary());
}
最后插入数据库图: