当前位置: 移动技术网 > IT编程>开发语言>Java > java中hibernate二级缓存详解

java中hibernate二级缓存详解

2019年07月22日  | 移动技术网IT编程  | 我要评论

hibernate的二级缓存

一、缓存概述

缓存(cache): 计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存

hibernate中提供了两个级别的缓存

第一级别的缓存是 session 级别的缓存,它是属于事务范围的缓存。这一级别的缓存由 hibernate 管理的,一般情况下无需进行干预

第二级别的缓存是 sessionfactory 级别的缓存,它是属于进程范围的缓存

hibernate 的缓存可以分为两类:

内置缓存: hibernate 自带的, 不可卸载. 通常在 hibernate 的初始化阶段, hibernate 会把映射元数据和预定义的 sql 语句放到 sessionfactory 的缓存中, 映射元数据是映射文件中数据的复制, 而预定义 sql 语句时 hibernate 根据映射元数据推到出来的. 该内置缓存是只读的.

外置缓存(二级缓存): 一个可配置的缓存插件. 在默认情况下, sessionfactory 不会启用这个缓存插件. 外置缓存中的数据是数据库数据的复制, 外置缓存的物理介质可以是内存或硬盘

二、理解二级缓存的并发访问策略

三、配置进程范围内的二级缓存(配置ehcache缓存)

1 拷贝ehcache-1.5.0.jar到当前工程的lib目录下

依赖 backport-util-concurrent 和 commons-logging

2 开启二级缓存

<property name="hibernate.cache.use_second_level_cache">true</property>

3 要指定缓存的供应商

 <property name="hibernate.cache.provider_class">
    org.hibernate.cache.ehcacheprovider</property>

4 指定使用二级缓存的类

方法一 在使用类的*.hbm.xml配置

选择需要使用二级缓存的持久化类, 设置它的二级缓存的并发访问策略, <class> 元素的 cache 子元素表明 hibernate 会缓存对象的简单属性, 但不会缓存集合属性, 若希望缓存集合属性中的元素, 必须在 <set> 元素中加入 <cache> 子元素

方法二  在hibernate.cfg.xml文件中配置(建议)

  <!-- 指定使用二级缓存的类 放在maping下面 -->
  <!-- 配置类级别的二级缓存 -->
  <class-cache class="com.sihai.c3p0.customer" usage="read-write"/>
  <class-cache class="com.sihai.c3p0.order" usage="read-write"/>
 
  <!-- 配置集合级别的二级缓存 -->
  <collection-cache collection="com.sihai.c3p0.customer.orders" 
         usage="read-write"/>

5  配置ehcache默认的配置文件ehcache.xml(名字固定)(放在类路径下)

<ehcache xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:nonamespaceschemalocation="../config/ehcache.xsd"> 
 
 <diskstore path="c:/ehcache"/> 
 <defaultcache 
   maxelementsinmemory="5" 
   eternal="false" 
   timetoidleseconds="120" 
   timetoliveseconds="120" 
   overflowtodisk="true" 
   maxelementsondisk="10000000" 
   diskpersistent="false" 
   diskexpirythreadintervalseconds="120" 
   memorystoreevictionpolicy="lru" 
   /> 
</ehcache> 

四、 测试

package com.sihai.hibernate3.test; 
 
import java.util.iterator; 
import java.util.list; 
 
import org.hibernate.query; 
import org.hibernate.session; 
import org.hibernate.transaction; 
import org.junit.test; 
 
import com.sihai.hibernate3.demo1.customer; 
import com.sihai.hibernate3.demo1.order; 
import com.sihai.utils.hibernateutils; 
 
public class hibernatetest6 { 
  
 @test 
 // 查询缓存的测试 
 public void demo9(){ 
  session session = hibernateutils.getcurrentsession(); 
  transaction tx = session.begintransaction(); 
   
  query query = session.createquery("select c.cname from customer c"); 
  // 使用查询缓存: 
  query.setcacheable(true); 
  query.list(); 
   
  tx.commit(); 
   
  session = hibernateutils.getcurrentsession(); 
  tx = session.begintransaction(); 
   
  query = session.createquery("select c.cname from customer c"); 
  query.setcacheable(true); 
  query.list(); 
   
  tx.commit(); 
 } 
  
 @suppresswarnings("unused") 
 @test 
 // 更新时间戳 
 public void demo8(){ 
  session session = hibernateutils.getcurrentsession(); 
  transaction tx = session.begintransaction(); 
   
  customer customer = (customer) session.get(customer.class, 2); 
  session.createquery("update customer set cname = '奶茶' where cid = 2").executeupdate(); 
   
  tx.commit(); 
   
  session = hibernateutils.getcurrentsession(); 
  tx = session.begintransaction(); 
   
  customer customer2 = (customer) session.get(customer.class, 2); 
   
  tx.commit(); 
 } 
  
 @suppresswarnings("all") 
 @test 
 // 将内存中的数据写到硬盘 
 public void demo7(){ 
  session session = hibernateutils.getcurrentsession(); 
  transaction tx = session.begintransaction(); 
   
  list<order> list = session.createquery("from order").list(); 
   
  tx.commit(); 
 } 
  
 @test 
 // 一级缓存的更新会同步到二级缓存: 
 public void demo6(){ 
  session session = hibernateutils.getcurrentsession(); 
  transaction tx = session.begintransaction(); 
   
  customer customer = (customer) session.get(customer.class, 1); 
  customer.setcname("芙蓉"); 
   
  tx.commit(); 
   
  session = hibernateutils.getcurrentsession(); 
  tx = session.begintransaction(); 
   
  customer customer2 = (customer) session.get(customer.class, 1); 
   
  tx.commit(); 
 } 
  
 @suppresswarnings("unchecked") 
 @test 
 // iterate()方法可以查询所有信息. 
 // iterate方法会发送n+1条sql查询.但是会使用二级缓存的数据 
 public void demo5(){ 
  session session = hibernateutils.getcurrentsession(); 
  transaction tx = session.begintransaction(); 
   
  // n+1条sql去查询. 
  iterator<customer> iterator = session.createquery("from customer").iterate(); 
  while(iterator.hasnext()){ 
   customer customer = iterator.next(); 
   system.out.println(customer); 
  } 
   
  tx.commit(); 
   
  session = hibernateutils.getcurrentsession(); 
  tx = session.begintransaction(); 
   
  iterator = session.createquery("from customer").iterate(); 
  while(iterator.hasnext()){ 
   customer customer = iterator.next(); 
   system.out.println(customer); 
  } 
   
  tx.commit(); 
 } 
  
 @suppresswarnings("unchecked") 
 @test 
 // 查询所有.query接口的list()方法. 
 // list()方法会向二级缓存中放数据,但是不会使用二级缓存中的数据. 
 public void demo4(){ 
  session session = hibernateutils.getcurrentsession(); 
  transaction tx = session.begintransaction(); 
   
  // 查询所有客户: 
  // list方法会向二级缓存中放入数据的. 
  list<customer> list = session.createquery("from customer").list(); 
  for (customer customer : list) { 
   system.out.println(customer.getcname()); 
  } 
  tx.commit(); 
   
  session = hibernateutils.getcurrentsession(); 
  tx = session.begintransaction(); 
   
  // customer customer = (customer) session.get(customer.class, 1);// 没有发生sql ,从二级缓存获取的数据. 
  // list()方法没有使用二级缓存的数据. 
  list = session.createquery("from customer").list(); 
  for (customer customer : list) { 
   system.out.println(customer.getcname()); 
  } 
   
  tx.commit(); 
 } 
  
 @test 
 // 二级缓存的集合缓冲区特点: 
 public void demo3(){ 
  session session = hibernateutils.getcurrentsession(); 
  transaction tx = session.begintransaction(); 
   
  customer customer = (customer) session.get(customer.class, 1); 
  // 查询客户的订单. 
  system.out.println("订单的数量:"+customer.getorders().size()); 
   
  tx.commit(); 
   
  session = hibernateutils.getcurrentsession(); 
  tx = session.begintransaction(); 
   
  customer customer2 = (customer) session.get(customer.class, 1); 
  // 查询客户的订单. 
  system.out.println("订单的数量:"+customer2.getorders().size()); 
   
  tx.commit(); 
 } 
  
 @suppresswarnings("unused") 
 @test 
 // 配置二级缓存的情况 
 public void demo2(){ 
  session session = hibernateutils.getcurrentsession(); 
  transaction tx = session.begintransaction(); 
   
  customer customer1 = (customer) session.get(customer.class, 1);// 发送sql. 
   
  customer customer2 = (customer) session.get(customer.class, 1);// 不发送sql. 
   
  system.out.println(customer1 == customer2); 
   
  tx.commit(); 
   
  session = hibernateutils.getcurrentsession(); 
  tx = session.begintransaction(); 
   
  customer customer3 = (customer) session.get(customer.class, 1);// 不发送sql. 
  customer customer4 = (customer) session.get(customer.class, 1);// 不发送sql. 
   
  system.out.println(customer3 == customer4); 
   
  tx.commit(); 
 } 
  
  
 @suppresswarnings("unused") 
 @test 
 // 没有配置二级缓存的情况 
 public void demo1(){ 
  session session = hibernateutils.getcurrentsession(); 
  transaction tx = session.begintransaction(); 
   
  customer customer1 = (customer) session.get(customer.class, 1);// 发送sql. 
   
  customer customer2 = (customer) session.get(customer.class, 1);// 不发送sql. 
   
   
   
  tx.commit(); 
   
  session = hibernateutils.getcurrentsession(); 
  tx = session.begintransaction(); 
   
  customer customer3 = (customer) session.get(customer.class, 1);// 发送sql. 
   
   
  tx.commit(); 
 } 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网