Hibernate 学习之路(四):详解 hibernate 映射文件(二)和组件映射关系

本文介绍了Hibernate中如何处理Java和数据库的时间类型对应关系,并详细解释了如何在映射文件中配置不同类型的时间字段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hibernate如何处理 java 和数据库的时间类型对应关系?
  • 首先我们需要知道在java中,代表时间和日期的类型主要是:java.util.Date 和 java.util.Calendar
    1. 在jdbc的API中,提供了三个java.util.Date 的子类,分别是:java.sql.Date,java.sql.Time,java.sql.Timestamp,这三个类分别对应了标准SQL类型中的DATE,TIME和TIMESTAMP 类型
    2. 在标准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 映射文件中的组件关系如何实现?
什么是域模型?什么是关系型数据模型?它们之间有什么区别?
  • 域模型:由代码组成,通过细化持久化类的粒度可以提高代码的可重用性,简化编程
    1. 个人理解:域模型在不同的面向对象型编程语言中都是存在的,以java为例,我们所有的操作都是依赖于对象,或者说是javaBean,我们在设计一个类的时候,其实就是在建立一个域模型,每个类尽可能设计的简洁和细化,可以很大程度上方便后续开发和维护
  • 关系型数据模型:在关系型数据库中,应该尽可能的减少表的数量,简化表之间的参照关系,提高数据的访问速度
  • 举例:当我们java代码里有两个类,而需要在数据库显示在一张表上的时候,应该怎么做呢?
    1. 设计一个员工类Emp,再设计一个工资类Salary,其中Salary类需要依赖于Emp类(这两个类存在关联关系),但是我们在数据库中只设计一张表
    2. hibernate 把持久化类的属性分为两种:
      1. 值(value)类型:没有OID,不能被单独持久化,生命周期依赖于所属的持久化类的对象的生命周期(例如Salary类)
      2. 实体(entity)类型:有OID,可以被单独持久化,有独立的生命周期(例如Emp类)
      3. 所以我们虽然设计了两个类,实际上只有一张数据库表,也只有一个对象映射文件,在这个映射文件中,使用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());
    }

最后插入数据库图:
mark

获取源代码请点击我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值