欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hibernate中的缓存机制

程序员文章站 2022-06-20 10:42:09
...

什么是缓存

缓存是介于应用程序与物理数据源之间的空间,也就是我们常说的内存。是为了减少程序对物理数据源的访问,因为对物理数据源的访问比较的消耗资源而且访问速度比较慢。而内存是告诉缓冲区,处于缓冲区中的数据,基本上都是用户需要的数据,这样可以提高程序执行的性能

hibernate中的一级缓存

一级缓存又称session缓存,一个回话一个缓存,默认开启不可关闭,多个session之间数据不共享,单会话关闭或者session关闭时,缓存丢失

原理

当用户发送查询请求的时候,orm会从缓存中查找数据,如果有直接拿使用该数据;如果没有,那么orm会发送一条sql语句从数据库中查询,同时将查询得到的结果放在session缓存中。

缓存处理相关的问题

但对数据执行了增删改动作是,程序会自动的删除缓存中的数据,目的是为了降低数据并发的可能性,已经处于session缓存中的数据不允许执行删除动作

测试一级缓存

Student stu=(Student) session.get(Student.class, "4");
			System.out.println(stu.getStu_name());
			System.out.println("===============1=================");
			Student stu1=(Student) session.get(Student.class, "4");
			System.out.println(stu1.getStu_name());

此时只会发送一条sql语句,第一次查询的时候会将得到的对象放在session缓存中,当第二次查询的时候会直接从session缓存获取该对象,从而不用发送sql语句来查询数据库

hibernate二级缓存

hibernate中二级缓存是一个可插拔式的缓存插件,需要手动开启,同时可以选择不同的供应商,有sessionFactory管理,所有的回话都是通过sessionFactory创建,多个session之间共享sessionFactory中的缓存数据,实现了跨事务共享数据。带来了更高的访问性能,同时也会产生严重的数据并发

使用场合

  • 很少被修改的数据
  • 允许出现并发数据的场合
  • 不会出现数据并发的场合

二级缓存的使用

1.下载二级缓存依赖的包

<!- 并发处理端口的工具包->
<dependency>
	    <groupId>backport-util-concurrent</groupId>
	    <artifactId>backport-util-concurrent</artifactId>
	    <version>2.2</version>
	</dependency>
	<!-- 日志文件包-->
	<dependency>
	    <groupId>commons-logging</groupId>
	    <artifactId>commons-logging</artifactId>
	    <version>1.1.1</version>
	</dependency>
<!- 进程内缓存的框架->	
	<dependency>
	    <groupId>org.ehcache</groupId>
	    <artifactId>ehcache</artifactId>
	    <version>3.1.4</version>
	</dependency>

2.开启二级缓存和配置二级缓存供应商
hibernate.cfg.xml

<!-- 配置二级缓存 -->
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!--<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> -->
<!--二级缓存提供商• -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<!-- 制定需要二级缓存的对象 -->
<class-cache usage="read-write" class="com.it.bean.Student"/>

3.配置ehcache.xml配置文件

ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />
</ehcache>

其中的配置参数

<!-- 
    defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理
    maxElementsInMemory:设置了缓存的上限,最多存储多少个记录对象
    eternal:代表对象是否永不过期
    timeToIdleSeconds:最大的发呆时间
    timeToLiveSeconds:最大的存活时间
    overflowToDisk:是否允许对象被写入到磁盘
 -->
<defaultCache maxElementsInMemory="10000" eternal="false"
    timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" />

<!-- 
    cache:为指定名称的对象进行缓存的特殊配置
    name:指定对象的完整名
 -->
<cache name="com.zbaccp.entity.Person" maxElementsInMemory="10000" eternal="false"
    timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" />

测试二级缓存

public class TestSecondCache {
	SessionFactory sessionFactory=null;
	   Session session=null;
	   Transaction tx=null;
	   
   @Before
   public void  createSessionFactory(){
	   try {
			 //创建SessionFactory工厂
			   sessionFactory =new Configuration().configure().buildSessionFactory();
	   }catch (Exception e) {
		   e.printStackTrace();
	}
   }
   
   @Test
   public void testSecontCache(){
	  try {
		  Session session1=sessionFactory.getCurrentSession();
		  Transaction tx1=session1.beginTransaction();
		  Session session2=sessionFactory.getCurrentSession();
		  Transaction tx2=session2.beginTransaction();
		  
		  Student stu1=(Student)session1.get(Student.class, "1003");
		  System.out.println(stu1.getStu_name()+"===1====");
		  tx1.commit();
		  
		  Student stu2=(Student)session2.get(Student.class, "1003");
		  System.out.println(stu2.getStu_name()+"===2===");
	} catch (Exception e) {
		e.printStackTrace();
	}
   }
}

测试二级缓存可能出现的问题

延迟加载
延迟加载(lazy load)是(也称为懒加载)Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。
懒加载的特殊情况:
代理对象的创建需要依赖session,代理对象依赖的session已经被关闭了。

  • Load:延迟加载

当访问该对象的非主属性的时候,才会通过orm发送sql语句,进行查询。
当查找的对象不存在的时候,报错ObjectNotFoundException
体现的是资源调度
lazy=“false”:去除延迟加载

  • Get:即刻加载

当查找的对象不存在的时候,报错NullpointException

hibernate中对象的三种状态

  • 临时态(瞬时态)

Student stu=new Student(“”,””);
不和 Session 实例关联
在数据库中没有和瞬时对象关联的记录
当执行new动作的时候,对象会转化成临时态

  • 持久态:
    (1) 和 Session 实例关联(2) 在数据库中有和持久对象关联的记录
    【注意点】
    Save() 方法将瞬时对象保存到数据库,对象的临时状态将变为持久化状态。当对象在持久化状态时,它一直位于 Session 的缓存中,对它的任何操作在事务提交时都将同步到数据库,因此,对一个已经持久的对象调用 save() 或 update() 方法是没有意义的

  • 游离态(托管态):
    (1) 本质上和瞬时对象相同(2) 只是比瞬时对象多了一个数据库记录标识值 id.

三种对象之间如何相互转化

hibernate中的缓存机制