Hibernate二级缓存:
Hibernate一级缓存是session对象的缓存,当session关闭时,一级缓存丢失
一级缓存只用于一次业务操作内的缓存
一次缓存默认开启,无法关闭
Hibernate二级缓存是sessionFactory的缓存,当sessionFactory关闭时,二级缓存丢失
二级缓存可以用于多次业务操作的缓存
二级缓存默认关闭,如果需要开启,需引入第三方缓存工具 eg:EhCache
二级缓存:
分为内置缓存和外置缓存:
内置缓存:Hibernate自带的,不可卸载
通常在Hibernate的初始化阶段,Hibernate会把映射元数据和预定义的SQL语句放置在sessionFactory的缓存中
默认只读
外置缓存:通常说的二级缓存也就是外置缓存
默认情况下,sessionFactory不会启用缓存插件
外置缓存中的数据时数据库数据的复制
外置缓存的物理介质可以使内存或者磁盘
二级缓存使用场合:
很少被修改的数据
不是很重要的数据
不会被并发访问的数据
常量数据
二级缓存不适用场合:
经常被修改的数据
绝对不允许并发访问的数据
与其他应用共享的数据
参考链接:http://blog.csdn.net/luckyzhoustar/article/details/47748179
hibernate支持的缓存插件:
EhCache: 可作为进程范围内的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持
ehcache不支持transactional,其他三种可以支持
OpenSymphony:可作为进程范围内的缓存,存放数据的物理介质可以是内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持
SwarmCache:可作为集群范围内的缓存,但不支持Hibernate的查询缓存
JBossCache:可作为集群范围内的缓存,支持Hibernate的查询缓存
EhCache: EhCache是Hibernate的二级缓存技术之一,可以把查询出来的数据存储在内存或者磁盘,节省下次同样的查询语句再次查询数据库,大幅度减轻数据库压力 注意: 当使用Hibernate的方式修改表数据(save | update | delete),EhCache会自动把缓存中关于此表的所有缓存全部删除(以达到同步),但这对于数据经常修改的表来说,可能就失去了缓存的意义 ehcache不支持transactional,其他三种可以支持 read-only:无需修改,那么就可以对其进行只读缓存 在此策略下,如果直接修改数据库,即使能够看到前台显示效果,但是将对象修改至cache中会报error,cache不会发生作用 另:删 除记录会报错,因为不能在read-only模式的对象从cache中删除 read-write:需要更新数据,那么使用读/写缓存 比较合适 前提:数据库不可以为serializable transaction isolation level(序列化事务隔离级别) nonstrict-read-write:只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存策略
在POM中引入jar包:
<properties>
<hibernate.version>5.2.10.Final</hibernate.version>
</properties>
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>${hibernate.version}</version> </dependency>
在hibernate.cfg.xml中配置:
<!-- 开启二级缓存 --> <property name="hibernate.cache.use_second_level_cache">true</property> <!-- 引入ehcache --> <property name="hibernate.cache.region.factory_class"> org.hibernate.cache.ehcache.EhCacheRegionFactory </property> <!-- 需要缓存那个类 --> <class-cache usage="read-only" class="com.roxy.hibernate.pojo.Customer" />
Test:
//第一次查询(会查询数据库)
Session session1 = HibernateUtil.openSession(); Transaction tx1 = session1.beginTransaction(); Customer c1 = session1.get(Customer.class, 1); System.out.println(c1); tx1.commit(); session1.close();
//第二次查询(会查询数据库) Session session2 = HibernateUtil.openSession(); Transaction tx2 = session2.beginTransaction(); Customer c2 = session2.get(Customer.class, 1); System.out.println(c2); tx2.commit(); session2.close();
Console:
Hibernate: select customer0_.c_id as c_id1_0_0_, customer0_.c_name as c_name2_0_0_, customer0_.c_gender as c_gender3_0_0_, customer0_.c_age as c_age4_0_0_, customer0_.c_level as c_level5_0_0_ from t_customer customer0_ where customer0_.c_id=? com.roxy.hibernate.pojo.Customer@49aa766b com.roxy.hibernate.pojo.Customer@1e9804b9