Hibernate基本特性和高级特性

来源:互联网 发布:linux mysql 安装包 编辑:程序博客网 时间:2024/05/18 00:48

本篇主要总结一下Hibernate基本特性和高级特性,有不正确之处,还望一块讨论......

一、对象持久性

在 Hibernate 使用过程中,实体对象有以下三种状态:
1、 临时状态:采用 new 关键字创建的对象,该对象未与 Session 发生关联(未调用Session 的 API)。也叫临时对象。临时状态的对象会被 Java 的垃圾回收机制回收。
2、 持久状态:实体对象与 Session 发生关联(调用了 Session 的 get、 load、 save、 update等 API)。也叫持久对象。

3、 游离状态:原来是持久状态,后来脱离了 Session 的管理。如: Session 被关闭,对象将从持久状态变为游离状态,同时垃圾回收机制可以回收掉,不再占用缓存空间了。

二、持久态对象的特点
1、对象生命期持久,垃圾回收机制不能回收。
2、对象的数据可以与数据库同步(即对象中的数据发生改变,则数据库中的数据自动同步)。由 Session 对象负责管理和同步。
3、对象在 Session 的一级缓存中存放。
Session.close();有两个作用:

(1)关闭连接、释放资源

(2)使对象变为游离状态,当对象的引用不存在时,对象才被回收。没被回收时,对象中的数据还在

三、 一级缓存
1、一级缓存被称为 Session 级别的缓存:每个 Session 都有自己独立的缓存区,该缓存区随着 Session 创建而开辟(由 SessionFactory 创建),随着 Session.close()而释放。该缓存区可以存储当前 Session 关联的持久对象。
2、一级缓存的好处
Hibernate 在查询时,先去缓存当中查找,如果缓存中没有,才去数据库查询。如果利用Session 对同一个对象查询多次,第一次去数据库查,后续的会从缓存查询,从而减少了与数据库的交互次数。
3、管理一级缓存的方法
(1) session.evict()方法:将对象清除。
(2) session.clear()方法:清除所有对象。
(3) session.close()方法:清除所有对象,并关闭与数据库的连接。
不同的 session 的缓存区不能交叉访问。

四、二级缓存
二级缓存是 SessionFactory 级别的。由 SessionFactory 对象负责管理。通过 Factory 创建的 Session 都可以访问二级缓存。二级缓存默认是关闭的。如果二级缓存打开,则先去一级缓存找对象,找不到则去二级缓存,还找不到则访问数据库。一级缓存和二级缓存都是存“单个对象”的,不能存集合、数组。

1、二级缓存管理方法
(1) SessionFactory.evict(class);//清除某一类型的对象
(2) SessionFactory.evict(class,id);//清除某一个对象
(3) SessionFactory.evict(list);//清除指定的集合
2、 二级缓存的使用环境
(1)共享数据,数据量不大。
(2)该数据更新频率低。

五、查询缓存
一级和二级缓存只能缓存单个对象。对于其他类型的数据,例如一组字段或一组对象集合、数组都不能缓存。这种特殊结果,可以采用查询缓存存储。查询缓存默认是关闭的。一般使用“query.setCacheable(true);开启。
查询缓存的使用环境
1、共享数据的结果集,结果集数据量不应太大。
2、查询的结果集数据变化非常小。

六、延迟加载机制
Hibernate 在使用时,有些 API 操作是具有延迟加载机制的。延迟加载机制的特点:当通过 Hibernate 的 API 获取一个对象结果后,该对象并没有数据库数据。当通过对象的 getter 方法获取属性值时,才去数据库查询加载。

1、延迟加载的原理
在使用延迟加载操作后, Hibernate 返回的对象是 Hibernate 利用 CGLIB 技术( cglib.jar)新生成的一个类型(动态的在内存中生成)。在新类型中,将属性的 getter 方法重写。新生成的类是原实体类的子类(继承关系)。
2、具有延迟加载机制的操作
(1) session.load();//延迟加载查询, session.get();是立即加载查询
(2) query.iterator();//查询
(3)获取关联对象的属性信息

3、Session 的 get 和 load 方法的区别
(1)相同点:两者都是按“主键”做条件查询。
(2)不同点:

①get 是立刻加载; load 是延迟加载。
②get 返回的对象类型是实体类型; load 返回的是动态生成的一个代理类,该代理类是实体类的子类。
③get 未查到数据返回 null; load 未查到数据抛出 ObjectNotFoundException 异常。
当实体类使用了final 修饰符修饰时,则破坏了延迟加载机制,此时 load 效果与 get完全相同。
4、延迟加载的好处
 (1)提高了内存的使用效率。

 (2)可以使数据访问降低并发量。
5、常犯的错误
(1) 报错: LazyInitializationException: could not initialize proxy - no Session,原因:代码中使用了延迟加载操作,但是 session 在加载数据前关闭了。只要看到这个类名:LazyInitializationException 就都是 session 过早关闭,后面的描述可能不同。
(2) 报错: NonUniqueObjectException: a different object with the same identifier value wasalready associated with the session, 原因:有两个不同对象,但是主键,即 id 却相同。






1 0