今天开讲Hibernate映射机制啦,实例挺多,但不好理解,比较抽象,不懂的话多读几遍,多查查资料,共勉。
前言 Hibernate映射机制总结
第一部分 主键映射
前言:区分主键的两种方法。
但不管是什么主键,它都必须满足以下几个条件:
8.1 代理主键的映射
代理主键是自定义的、用来标识表记录的,不具有任何的业务实体意义,一般表中加入一个id字段来标识。如【实例7.1】中POJO类表示为:
对应的映射文件配置为:
标签<id>表示该部分映射的是主键,name属性指定类中对应的属性值,column属性指定对应表中的字段。
其中<generator>标签用来指定ID的生成方式,下面是详细介绍:
8.2 单个自然主键的映射
自然主键虽然不提倡使用,但使用自然主键的情况还是存在的,如UserTable表中的用户如果只限于学生,可以不单独指定代理主键id,而改用自然主键XH(学号),这样POJO类可改写为:
对应在映射文件中的主键配置为:
8.3 复合主键的映射
复合主键的映射有两种方法:单独定义主键类和不单独定义主键类,下面分别介绍:
8.3.1 单独定义主键类
单独定义主键类,即把主键的属性组成一个新的类,这个类与要映射的POJO类类似,也要生成它的get和set方法,但是该类并不作为POJO类使用,而是作为映射POJO类的一个主键属性。假设有一个成绩表,该表的结构如表8.1所示。
字 段 名 | 数据类型 | 主 键 | 自 增 | 允许为空 | 描 述 |
---|---|---|---|---|---|
XH | varchar(50) | 是 | 学号 | ||
KCH | varchar(50) | 是 | 课程号 | ||
CJ | int | 是 | 成绩 |
首先把主键封装成一个类,该类有两个要求。
然后在真正的映射POJO中使用:
POJO类编写完成后,可以编写配置文件Cj.hbm.xml,代码如下:
配置完成后,下面来看复合主键如何操作数据库数据。
保存一个对象:
修改一个对象:
8.3.2 不单独定义主键类
不单独定义主键类,就是把主键属性直接放在POJO类中,不需要单独对其进行封装,那么该POJO类就要实现java.io.Serializable接口,并重写equals()和hashCode()方法。
同样,映射文件Cj.hbm.xml也略有不同:
由于这种情况是把主键放入POJO类中,故数据的存取也不同。
保存一个对象:
修改一个对象:
第二部分 数据类型映射
在Hibernate的映射文件中,用<property>标签来说明POJO类的属性与数据库表中的哪一个字段对应,用type属性说明对应属性应该使用什么数据类型。例如,【实例7.1】的UserTable. hbm.xml中有:
上面代码中的加黑部分,用type属性来指定数据类型,这个属性是Java数据类型,在Hibernate框架的内部还有一套“Hibernate数据类型”,Hibernate就是通过它将Java类型自动转换为数据库标准的SQL类型,如图8.1所示,从而完成高质量的ORM映射。
用户也可在配置文件中直接写入设置Hibernate自身的数据类型,代码如下:
第三部分 对象关系映射
在实际应用中,存在这样一种情况:有很多种学生,如研究生、本科生等,它们都有学生的基本属性,但又有各自的特殊属性,故适合使用继承来实现这样的对象模型。
例如,学生POJO类Xs.java代码为:
可以看到,继承简化了程序的应用。现在就要考虑继承关系在数据库中建表的问题了,这种情况可以有3中方法来设计数据库:
1.每个子类一个数据表
2.每个类一个数据表
3.共享一个数据库表
一 每个子类一个数据表
设计两张数据库表,分别是yjs表(见表8.3)和bks表(见表8.4)。
建立两张表对应的POJO类。
Yjs.java代码为:
Bks.java代码为:
建立POJO类对应的映射文件。
Yjs.hbm.xml配置文件为:
二 每个类一个数据表
【实例8.1】采用“每个类一个数据表”的方式,实现继承关系映射。
表9.5 xs表
字 段 名 | 数 据 类 型 | 主 键 | 自 增 | 允 许 为 空 | 描 述 |
---|---|---|---|---|---|
id | int | 是 | 增1 | id标识 | |
xh | varchar(50) | 学号 | |||
xm | varchar(50) | 是 | 姓名 | ||
bir | datetime | 是 | 出生时间 |
在项目src下创建org.vo包,在其中建立POJO类。
Xs.java代码为:
执行程序后,会把xh、xm、bir记录插入xs表中,把本条记录的id值及researchResult记录插入到yjs表中。
执行程序后,会把xh、xm、bir记录插入xs表中,把本条记录的id值及ky记录插入到bks表中。
编写测试类,在项目src下创建org.test包,其下建立测试类InheritanceTest.java,代码如下:
运行程序,测试结果如图8.2所示。
三 共享一个数据库表
【实例8.2】采用“共享一个数据库表”的方式,实现继承关系映射。
采用这种方法,数据库中只要建立一张表即可,如表8.8所示。
POJO类的分配为,Xs.java中配置除子类各自独特属性外的所有属性,子类只配置各自的独特属性。在项目src下建org.vo.one包,用于存放新编写的POJO类。
Xs.java代码编写如下:
该种情况也只需要配置一个映射文件Xs.hbm.xml即可,其子类信息及关系也会在映射文件中体现。
数据的存取也很简单,只需操作不同的类来得到想要得到的信息。
运行该段代码后,程序会根据Yjs类设置Xs表中的xsType值为“yjs”,并把值插入到Xs表中。
运行该段代码后,程序会根据Bks类设置Xs表中的xsType值为“bks”,并把值插入到Xs表中。
运行程序,测试结果如图8.3所示。
一 一对一关联
共享主键方式:在注册某个论坛会员的时候,往往不但要填写登录账号和密码,还要填写其他的详细信息,这两部分信息通常会放在不同的表中,如表8.9和表8.10所示。
经过上面的操作,虽然MyEclipse自动生成了Login.java、Detail.java、Login.hbm.xml和Detail.hbm.xml共4个文件,但两表之间并未自动建立一对一关联,仍需要用户修改代码和配置,手动建立表之间的关联。具体的修改内容如下,在源代码中以加黑标识。
修改login表对应的POJO类Login.java,代码为。
修改detail表对应的Detail.java,代码为:
修改login表与Login类的ORM映射文件Login.hbm.xml为:
修改detail表与Detail类的ORM映射文件Detail.hbm.xml为:
4)创建测试类。
在src下创建包test,在该包下建立测试类,命名为Test.java。其代码为:
(5)运行程序,测试结果。
因为该程序为Java Application,所以可以直接运行。在完全没有操作数据库的情况下,程序就完成了对数据的插入。插入数据后,login表和detail表的内容如图8.4和图8.5所示。
唯一外键方式:唯一外键的情况很多,例如,每个人对应一个房间。其实在很多情况下,可以是几个人住在同一个房间里面,就是多对一的关系,但是如果把这个多变成唯一,也就是说让一个人住一个房间,就变成了一对一的关系了,这就是前面说的一对一的关系其实就是多对一关联关系的一种特殊情况。对应的Person表和Room表如表8.11和表8.12所示。
【实例8.4】唯一外键方式示例。
(1)在项目Hibernate_mapping的org.model包下生成表对应的POJO类对象和映射文件,然后按照如下的方法修改。
修改Person表对应的POJO类Person.java,代码为:
修改Room表对应的POJO类Room.java,代码为:
修改Person表与Person类的ORM映射文件Person.hbm.xml为:
修改Room表与Room类的ORM映射文件Room.hbm.xml为:
(2)编写测试代码。
在src下的包test的Test类中加入如下代码:
(3)运行程序,测试结果。
因为该程序为Java Application,所以可以直接运行(运行时把前面的测试代码注释掉)。在完全没有操作数据库的情况下,程序就完成了对数据的插入。插入数据后,Person表和Room表的内容如图8.6和图8.7所示。
二 多对一单向关联
【实例8.5】多对一单向关联示例。
(1)在【实例8.4】基础上修改,其对应表不变,表对应的Person类也不变,对应的Person.hbm.xml文件修改如下:
而Room表不变,对应的POJO类修改如下:
即删去了person属性及其get和set方法。
最后,在映射文件Room.hbm.xml中删去下面这一行:(因为这是单向的多对一关联,被控表无须指定主控表)
(2)编写测试代码。
在src下包test的Test类中加入如下代码:
(3)运行程序,测试结果。
直接运行Java Application程序,在完全没有操作数据库的情况下,程序就完成了对数据的插入。插入数据后,Person表和Room表的内容如图8.8和图8.9所示。
三 一对多双向关联
【实例8.6】一对多双向关联示例。
(1)在【实例8.5】基础上修改,Person表对应的POJO及其映射文件不用改变,现在来修改Room表对应的POJO类及其映射文件。对应的POJO类Room.java如下:
Room表与Room类的ORM映射文件Room.hbm.xml修改如下:
其中,cascade配置的是级联程度,它有以下几种取值。
(2)编写测试代码。
在src下的包test的Test类中加入如下代码:
(3)运行程序,测试结果。
因为该程序为Java Application,所以可以直接运行。在完全没有操作数据库的情况下,程序就完成了对数据的插入。插入数据后,Person表和Room表的内容如图8.10和图8.11所示。
由于是双向的,当然也可以从Room的一方来保存Person,在Test.java中加入如下代码:
四 多对多关联
student表与Student类的ORM映射文件Student.hbm.xml修改如下:
course表与Course类的ORM映射文件Course.hbm.xml改为:
双向关联实际用法和单向关联相同,双向关联的操作可以从任意一方操作。
第四部分 动态类的使用
前面的例子都是使用Java代码的POJO类作为对象模型,其实Hibernate还支持在XML文件中直接表示持久化数据类,这样的好处是便于开发人员对程序的维护。
至此本篇介绍Hibernate框架的映射机制文章结束,下篇我们开讲Hibernate对持久化对象的操作,敬请期待!(✿◡‿◡)
本章实例源代码GitEE地址:
https://gitee.com/jahero/bookManage.git