Hibernate学习笔记(三)-集合、级联、继承的使用
1.Hibernate中集合的使用说明
(1).list集合的使用
部门实体:
![](https://img.haomeiwen.com/i9857208/7c3178304d6fb00f.png)
对应的映射文件:
![](https://img.haomeiwen.com/i9857208/a00eaea23f4c3f47.png)
当实体中使用了list集合时,因为list有排序功能,所以业务不需要排序时,使用的list的如上配置时,就会对性能有所损耗,在hibernate中提供了list的另一个配置标签<bag>,配置这个标签后,则可取消排序功能。<bag>标签必须与list一起使用。配置如下:
![](https://img.haomeiwen.com/i9857208/5d8dd0ec14e64b7f.png)
员工实体
![](https://img.haomeiwen.com/i9857208/784d1723a89c83f1.png)
对应映射文件:
![](https://img.haomeiwen.com/i9857208/08939b08d76947f0.png)
(2).使用Map集合
部门实体
![](https://img.haomeiwen.com/i9857208/e185d79dec11ea0c.png)
对应的映射文件
![](https://img.haomeiwen.com/i9857208/ffd8ff9b8866fee4.png)
2.Hibernate中级联的配置
![](https://img.haomeiwen.com/i9857208/a7b9190a2da1e67d.png)
One-to-many中配置级联:
![](https://img.haomeiwen.com/i9857208/761af3a4f0556b25.png)
One-to-One中配置级联:
![](https://img.haomeiwen.com/i9857208/6872d312556be2ec.png)
3.Hibernate中的inverse:
![](https://img.haomeiwen.com/i9857208/a3e26687638b71cd.png)
举例解释:
1.当没有使用inverse这个配置属性时,所有的关系维护必须由程序员写程序自己去维护,比如:部门和员工例子来说:
![](https://img.haomeiwen.com/i9857208/9bd8f9a3fd3c6ab3.png)
当按照上面的方法保存部门和员工时,没有配置inverse时,程序运行时,告诉部门有哪些员工,也就是对应的depart.setEmSet(emSet),执行,hibernate会发出一个update的sql来更新一下数据库,但是当执行上面的语句,告诉员工自己属于那个部门的时候,对应的语句是:em1.setDepart(depart);hibernate也会发出一个updatesql来更新数据库,这样做的话,会造成多此一举,从而造成浪费。当在one的一方配置inverse=”true”时,one的一方将不会再维护关联关系,当执行depart.setEmSet(emSet)时,hibernate将不会发sql。
可以通过控制台来看hibernate发出的sql语句:
没有配置inverse的情况:
![](https://img.haomeiwen.com/i9857208/b44a8a57a6db6541.png)
当配置之后one的一方将不在维护关联关系:
![](https://img.haomeiwen.com/i9857208/027affb4a5ff17e7.png)
Inverse一般配置在one的一方,让多的一方去维护关联关系,inverse的配置如下:
![](https://img.haomeiwen.com/i9857208/7b54319bed8c8b25.png)
Inverse属性在集合中才可以配置,并且在list中不能配置。
3.继承
1.整个继承树映射到一张表
![](https://img.haomeiwen.com/i9857208/7c988cff4bcd43fb.png)
继承实现之后的数据库表如下图:
![](https://img.haomeiwen.com/i9857208/d77c5bb3df590a7e.png)
这样做的好处是:单表操作,性能上比较有优势。
缺点:数据库表中有好多字段是空的,按严格来说,这样不规范。
Java代码和对应的映射文件:
1>.People类:
![](https://img.haomeiwen.com/i9857208/0ae8362e544dac33.png)
2>.Skiller类:
![](https://img.haomeiwen.com/i9857208/a551d288847d1a2a.png)
3>.Sales类:
![](https://img.haomeiwen.com/i9857208/54b3f3f702bf573a.png)
对应的映射文件:
说明一点:配置文件中的鉴别器如果不指定类型的话,默认是String类型,值为类的全名
![](https://img.haomeiwen.com/i9857208/b4957ec7b3616dce.png)
2.每个类映射到一张表
![](https://img.haomeiwen.com/i9857208/89f25c0e437ea4e8.jpg)
继承之后在数据库中对应的表如下:
![](https://img.haomeiwen.com/i9857208/8dbf2e7f93ed39c4.png)
![](https://img.haomeiwen.com/i9857208/9e2c84c11fa16200.png)
![](https://img.haomeiwen.com/i9857208/bc42e440d9450d14.png)
这样做的优点:表中的字段没有空的
缺点:在查询的时候,需要进行关联查询,这样的话,在效率上会有所下降。
Java代码和对应的映射文件:
实体的java代码和上面的一样没有变化;
映射文件有所变化:
![](https://img.haomeiwen.com/i9857208/45851b86ca90402f.png)
3.鉴别器与内连接(单独生成一张表)相结合
![](https://img.haomeiwen.com/i9857208/8ba56e489b9cb469.png)
对应的数据库中的表:
![](https://img.haomeiwen.com/i9857208/f69985188634d63a.png)
![](https://img.haomeiwen.com/i9857208/12105a47d47734e5.png)
Java代码和对应的映射文件
Java代码,没有变化;
。。。。。。
映射文件:
![](https://img.haomeiwen.com/i9857208/c994811ea210b31b.png)
4.每个具体类映射一张独立表
![](https://img.haomeiwen.com/i9857208/ccd95d4bf3ae321b.png)
说明一下:如果,people是抽象类将不会生成表,在映射文件中配置abstract="true"
![](https://img.haomeiwen.com/i9857208/6cf67e0b327122bd.png)
生成的数据库表:
![](https://img.haomeiwen.com/i9857208/2c64d21b70dcdefd.png)
![](https://img.haomeiwen.com/i9857208/027446a0d96457e2.png)
![](https://img.haomeiwen.com/i9857208/2fc2020db2a928ef.png)
Java代码和映射文件:
Java代码没啥变化;
映射文件:
![](https://img.haomeiwen.com/i9857208/faf8df99ccf2e276.png)
4.懒加载
![](https://img.haomeiwen.com/i9857208/56002fef3a35a12a.png)
5.缓存
![](https://img.haomeiwen.com/i9857208/97a4660f48c75f02.png)
Session关闭之后,缓存消失。(意思也是,一级缓存只能存在同一个session中)
![](https://img.haomeiwen.com/i9857208/8574eff905bf3f8e.png)
![](https://img.haomeiwen.com/i9857208/1fb30288de60edd7.png)