一、Hibernate的缓存处理
二、什么是缓存
三、 缓存分类
四、 一级缓存
1、 一级缓存 : 即在当前事务范围内的数据缓存
- 就 Hibernate 来讲 , ( 一级缓存 ) 事务级缓存是基于 Session 的生命 周期实现的2、应用级 ( 二级 ) 缓存 : 即在某个应用中或应用中某个独立数据库访问子集中的共享缓存 , 此缓存可由多个事务共享 .
- 在 Hibernate 中 , 应用级缓存由 SessionFactory 实现
( Ehcached )3、 分布式缓存 : 即在多个应用实例 , 多个 JVM 间共享的缓存策略 ( OsCache,MEMCACHE )
1、 Session Level Cache
public class Test {
public voidget(){
Sessionsession = HibernateSessionFactory.getSession();
TUser t =(TUser)session.get("hibernate.TUser", 2);
System.out.println(t.getName());
session.close();
}
}
SQL语句:
Hibernate: select tuser0_.id as id0_0_, tuser0_.name asname0_0_, tuser0_.sex as sex0_0_ from test.t_user tuser0_ where tuser0_.id=?
说明进行了一次数据库的调用.
代码修改如下:
public class Test {
public voidget(){
Sessionsession = HibernateSessionFactory.getSession();
TUser t =(TUser)session.get("hibernate.TUser", 2);
System.out.println(t.getName());
TUser tt =(TUser)session.get("hibernate.TUser", 2);
System.out.println(tt.getName());
session.close();
}
控制台仍然只打出一条SQL语句:
Hibernate: select tuser0_.id as id0_0_, tuser0_.name asname0_0_, tuser0_.sex as sex0_0_ from test.t_user tuser0_ wheretuser0_.id=?
说明还是只进行了一次数据库的调用.
再次修改代码public class Test {
public voidget(){
Sessionsession = HibernateSessionFactory.getSession();
TUser t =(TUser)session.get("hibernate.TUser", 2);
System.out.println(t.getName());
session.close();
Sessionsession1 = HibernateSessionFactory.getSession();
TUser tt =(TUser)session1.get("hibernate.TUser", 2);
System.out.println(tt.getName());
session1.close();
}
}
控制台打印两条SQL语句:
Hibernate: select tuser0_.id as id0_0_, tuser0_.name asname0_0_, tuser0_.sex as sex0_0_ from test.t_user tuser0_ where tuser0_.id=?
Hibernate: select tuser0_.id as id0_0_, tuser0_.name asname0_0_, tuser0_.sex as sex0_0_ from test.t_user tuser0_ where tuser0_.id=?
结论:Hibernate进行查询时总是先在缓存中进行查询,如缓存中没有所需数据才进行数据库的查询.Hibernate的内部缓存是基于 Session的生命周期的, 内部缓存一般由Hibernate自动维护,不需要人为干预,当然我们也可以根据需要进行相应操作:
Session.evict(Object)(将指定对象从内部缓存清除),
Session.clear()(清空内部缓存).
如在两次查询间加入Session.clear()将会清空内部缓存,使得一个 Sesion内部的两次相同的查询要对数据库进行两次操作).
五、二级缓存
六、 缓存同步策略
1、 使用第三方缓存组件 : EHcache.Hibernate 的二级缓存2、基本信息配置文件
<propertyname="hibernate.cache.EhCacheProvider">true</property>
<property name="cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<propertyname="hibernate.cache.use_query_cache">true</property>
3、 EHcache 配置文件
<?xml version="1.0"encoding="UTF-8"?>
<ehcache>
<diskStore path="d:/cache"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="180"
timeToLiveSeconds= " 300"
diskPersistent="false"
diskExpiryThreadIntervalSeconds= "120"/>
</ehcache>
4、在 hibernate.cfg.xml 映射文件中添加缓存同步策略
<class-cache usage="read-write" />
七、 Hibernate 的延迟加载
缓存同步策略决定了数据对象在缓存中的存取规则 .Hibernate 中提供了 4 种不同的缓存同步策略
- read-only: 只读 . 对于不会发生改变的数据可使用
- nonstrict-read-write: 如果程序对并发访问下的数据 同步要求不 严格 , 且数据更新频率较低 , 采用本缓存 同步策略可获得较 好性能
- read-write: 严格的读写缓存 . 基于时间戳判定机制 , 实 现了“ read committed” 事务隔离等级 . 用于对数据同步要求的情况 , 但 不 支持分布式缓存 , 实际应用中 使用最多的缓存同步策略 .
- transactional: 事务型缓存 , 必须运行在 JTA 事务环境中 . 此缓存中 , 缓存的相关操作被添加到事务中 , 如事务失败 , 则缓冲池的数据 会一同回滚到事务的开始之前的状态 . 事务型缓存实现了 “ Repeatable read” 事务隔离等级 , 有效保证了数据的合法性 , 适应于对关键数据的缓存 ,Hibernate 内置缓存中 , 只有 JBossCache 支持事务型缓存 .
1、在有关联的持久类对象中 , 对一个对象进行的查询也会向另一个对象进行查询2、所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作3、hibernate 3.X 的 lazy( 延迟加载 ) 默认值是 true ,需要注意4、延迟加载类型
- 实体对象的延迟加载
- 集合的延迟加载
- 属性的延迟加载