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()方法获取二级缓存中的数据

相关推荐