hibernate缓存
Hibernate缓存
缓存是计算机领域的概念,它介于应用程序和永久性数据存储源(如硬盘上的文件或者
数据库)之间,其作用是降低应用程序直接写永久性数据存储源的频率,从而提高应用
的运行性能。缓存中的数据是数据存储源中数据的复制,应用程序在运行时直接读写缓
存中的数据,只在某些特定时刻按照缓存中的数据来同步更新数据存储源。
缓存的物理解释通常是内存,而永久性数据存储源的物理介质通常是硬盘或磁盘,应用
程序读写内存的数据显然比读写硬盘的速度快。如果缓存中存放的数据量非常大,也会
用硬盘作为缓存的物理介质。
Hibernate的缓存一般分为3类
1.一级缓存:Session缓存称为一级缓存,由于Session对象的声明周期通常对应一
个数据库事务,因此它的缓存是事务范围的缓存,
2.二级缓存:SessionFactory缓存分为内存缓存和外置缓存,内置缓存是Hibernate
自带的,不可拆卸,是只读取缓存,用来存放映射元数据和预定义SQL语句。
外置缓存是一个可配置的缓存插件,默认SessionFactory不会启用这个缓存插
件。
3.查询缓存:
它是Hibernate为查询结果提供的,依赖于二级缓存。
缓存的作用范围分为3类
1.事务范围:每个事务都有自己的缓存,缓存内数据不会被多个事务并发访问。
2.进程范围:进程内的所有事务共享缓存,进程结束,缓存结束生命周期。
3.集群范围:缓存被一个或多个机器上的多个进程共享,Hibernate的二级缓存也可
以作为集群范围的缓存
hibernate的一级缓存(一级缓存区域和快照区域)
当瞬时态对象转换为持久态对象时存入一级缓存及快照区
当持久化对象数据更新时,一级缓存区和快照区进行内容对比,如果一致不
更新,如果不一致更新数据库内容
缓存的本质是一个MAP集合,缓存的管理clear()/evict(customer)/flush()/
refresh()
eg:
Sessionsession=HibernateUtils.openSession();
Transactiontx=session.beginTransaction();
Customerliudehua=(Customer)session.get(Customer.class,1);
liudehua.setCname("刘德华");
//session.refresh(liudehua);
session.flush();//执行该方法执行update语句
tx.commit();
hibernate的二级缓存
SessionFactory的外置缓存是一个可配置的插件。在默认情况下,SessionFactory不
会启用这个插件。
外置缓存的数据是数据库数据的副本,外置缓存的介质可以是内存或者硬盘。
SessionFactory的外置缓存也被称为Hibernate的二级缓存。
二级缓存是进程或集群范围内的缓存,可以被所有Session共享,其生命周期和
SessionFactory一样
二级缓存相当于一个交互地带
二级缓存的适用范围
●很少被修改的数据。
●不是很重要的数据,允许出现偶尔并发的数据。
●不会被并发访问的数据。
●参考数据。
hibernate使用二级缓存(EHCache)
3.1在工程中添加二级缓存的jar包
拷贝ehcache-1.5.0.jar到当前工程的lib目录下
依赖backport-util-concurrent和commons-logging
3.2在src下添加配置文件ehcache.xml
3.3zai核心配置文件hibernate.cfg.xml中开启二级缓存,并指定缓存的供
应商
<!--开启二级缓存-->
<propertyname="hibernate.cache.use_second_level_cache">
true
</property>
<!--指定缓存的供应商-->
<propertyname="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider</property>
3.4配置使用缓存的实体类
3.4.1方法一:在实体类.hbm.xml中的<class>下添加缓存普通属性的
策略<cacheusage="read-write"/>
如果要缓存集合属性,则在<set>下要配置
<cacheusage="read-write"/>
3.4.2方法二:直接在hibernate.cfg.xml的<mapping>下添加
<class-cacheusage="read-write"class="com.wsjy.entity.User"/>
<collection-cachecollection="com.wsjy.entity.User.orderses"
usage="read-write"/>
3.5证明二级缓存的存在
//二级缓存是sessionFactory级别的缓存
SessionFactorysf=new
Configuration().configure().buildSessionFactory();
Sessionsession=sf.openSession();
Transactiontx=session.beginTransaction();
Useru=(User)session.get(User.class,7);
System.out.println(u.getUname());
tx.commit();
session.close();
session=sf.openSession();
tx=session.beginTransaction();
Useru2=(User)session.get(User.class,7);
System.out.println(u2.getUname());
tx.commit();
session.close();
sf.close();
两个查询最终只发送一条sql语句,说明第二个查询操作没有向数据库发送请求,而是直接在二级缓存中查询
***
测试类级别的二级缓存只适用于get和load获取数据,对query接口可以
将数据放置到类级别的二级缓存中,
但是不能使用query接口的list方法从缓存中获取数据;query接口将查
询的对象放置到二级缓存的查询缓存
使用查询缓存的步骤:
在前面Hibernate的二级缓存,只有基于ID查找对象时才会用到,对于查询则毫无
作用。为此Hibernate提供了针对查询的查询缓存。查询缓存依赖于二级缓存,
1、在hibernate.cfg.xml中启用查询缓存
<!--启用查询缓存-->
<propertyname="hibernate.cache.use_query_cache">true</property>
2、调用Query的setCacheable(true)方法
然后就可以使用Query.list()方法获取二级缓存中的数据