Hibernate的缓存机制

落日映苍穹つ 2022-08-08 15:48 252阅读 0赞

Hibernate的缓存

为什么使用缓存?

  1. **hibernate提供了两种缓存来提升程序的性能**
  1. 一级缓存
  2. 二级缓存(类缓存,集合缓存,查询缓存)

说到缓存,让我们先来理解下Hibernate的生命周期

  • 瞬时状态:此状态的对象存储于JVM内存中,与数据库的数据无关。
    eg: 下面的user1对象就是瞬时状态
    `Session session=HibernateSessionFactory.getSession();

    User user = new User(1, “812135023”, “一缕阳光”, ‘男’, 21, true, “本科”);`

  • 持久状态:此状态的对象由hibernate的框架管理,数据库存在与hibernate内存中,数据可由hibernate持久化(保存)到数据库中。
    eg:下面的user对象经过save方法就是持久化状态
    session.save(user); //此操作会导致数据持久化到数据库中
  • 游离(脱管)状态:如果处于持久化的对象,其会话Session关闭后,此对象就会转变成游离(脱管)状态。
    eg:经过close方法此时的user的对象处于游离(脱管)状态。
    session.close();
    Hibernate实体对象状态间的转换示意图
    20150918224608515

一级缓存
一级缓存的使用周期相当短暂,其实,当我们采用save或get方法等等,我们已经把对象user加入到了一级缓存,当我们执行session.close();方法后,user对象,也会从一级缓存中清除出去。
eg:

  1. Session session=HibernateSessionFactory.getSession();
  2. User user = new User(1, "812135023", "一缕阳光", '男', 21, true, "本科");
  3. session.save(user);//执行后,对象user已经加入到一级缓存
  4. session.close(); //执行后,user会从一级缓存中清除出去

一级缓存的管理
hibernate提供了clear和evict,contains等3个方法来管理一级缓存。

  1. session.evict(user);//从一级缓存中清除单个指定对象
  2. session.clear();//清除一级缓存内的所有对象
  3. boolean flag=session.contains(user);//检测一级缓存内是否存在某个对象

一级缓存代码演示

  1. Session session=HibernateSessionFactory.getSession();
  2. User user=(User)session.get(User.class,20);
  3. User user2=(User)session.get(User.class,20);
  4. session.close;

**配置hibernate配置文件show_sql属性为true后。如果看到一条执行语句,证明测试成功

①执行的时候,会先查看一级缓存内部是否有要查询的20号对象,如果没有,发送sql语句到数据库查询,然后把此结果对象返回,并且存储于一级缓存中。

当执行②号语句时,因为①语句已经把数据对象放入一级缓存内,所有hibernate会直接从一级缓存内读取数据,从而提升程序性能。


二级缓存(外置缓存)
hibernate要查询的数据在一级缓存中,没找到,如果配置了二级缓存了。就会在二级缓存内继续查询。如果2级缓存中没有就会发送sql语句查询数据库。
因为二级缓存产品有好几种。

本文介绍如果使用hibernate自带的ehcache缓存
步骤:

  1. 2级缓存的jar包
  2. Hibernate配置文件中设置开启二级缓存
  3. 二级缓存本身的配置文件
  4. 配置实体类对二级缓存的配置

1.jar包,因为hibernate自带的,所以嘛,jar包hibernate里面就有
就是ehcache-1.2.3.jar。
以及struts自带的commons-logging-1.0.4.jar
2.Hibernate配置文件中设置开启二级缓存

  1. <!-- 配置是否开启2级缓存 -->
  2. <property name="cache.use_second_level_cache">true</property>
  3. <!-- 配置2级缓存产品的Hibernate接口类 -->
  4. <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>````

3.在src下创建ehcache.xml文件(文件名必须是ehcache(不然要改配置才能-name属性划分区域给User对象,默认区域

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <ehcache>
  3. <cache maxElementsInMemory="10000" eternal="false" name="User" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
  4. <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
  5. </ehcache>

在实体类的配置文件中配置二级缓存区域属性

  1. <class name="User" table="User" schema="SCOTT">
  2. <!-- 配置2级缓存,存储的区域以及是否支持读和取 -->
  3. <cache usage="read-only" region="User"/>
  4. <id name="id" type="java.lang.Byte">
  5. <column name="id" precision="2" scale="0" />
  6. <generator class="assigned"></generator>
  7. </id>
  8. .....
  9. </class>
  10. 这样就配置好了二级缓存类 。配置集合缓存只需要在此基础上, 在User.hbm.xml中的se标签内配置以下 属性
  11. <set name="users" inverse="true" lazy="false">
  12. <cache usage="read-only" region="User"/>
  13. ...省略其它配置
  14. </set>

如何能看出来呢,当我们面对1对多的关系对象时候。调用对象的集合类型。此时。查到的数据就会存储到二级缓存中。

  1. Set<Emp> emps=d.getEmps();//此时数据从数据库取出,放入二级缓存区域

至此集合缓存使用介绍结束。
最后一点,查询缓存

步骤

  1. 首先已经配置了2 级缓存
  2. 告诉hibernate配置的查询缓存
    3 .使用query.setCacheable(true);方法

使用查询缓存,的前提是,我们要先配置二级缓存。然后在hibernate的配置文件下配置以下属性

  1. <property name="cache.use_query_cache">true</property>
  2. 使用quer.settCacheable(true);方法,将不自动放 缓存的数据对象,放入到二级缓存区域。
  3. /** * 配置查询缓存 * 1.首先已经配置了2级缓存 * 2.告诉hibernate配置的查询缓存 * <property name="cache.use_query_cache">true</property> * * 3.使用query.setCacheable(true);方法 * * */
  4. Session session=HibernateSessionFactory.getSession();
  5. String hql="from Emp e";
  6. Query query=session.createQuery(hql);
  7. /** * 第一次执行这一句话: * true:表明要使用查询缓存-sql语句查到的数据要放入2级缓存区 * * false:表明不要使用查询缓存-sql语句查到的数据仅仅当时使用-不放入缓存区域 * */
  8. query.setCacheable(true);//通过这一句将查询到的数据加入缓存
  9. List<Emp> emps=query.list();
  10. HibernateSessionFactory.closeSession();
  11. session=HibernateSessionFactory.getSession();
  12. query = session.createQuery(hql);
  13. /** * 第二次执行这一句话: * true:表明要使用查询缓存-先看缓存区域是否已经存在此数据,如果没有-就执行sql语句查询,然后放入缓存区 * * false:表明不要使用查询缓存-直接执行sql语句到数据库去查询数据 * */
  14. query.setCacheable(false);
  15. emps = query.list();
  16. HibernateSessionFactory.closeSession();
  17. //看到一行sql语句表明执行成功
  18. 查询缓存的代码演示和介绍到此结束,如果对本文有所异议,欢迎指导。

发表评论

表情:
评论列表 (有 0 条评论,252人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Hibernate 缓存机制

    一、why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库。 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性

    相关 hibernate缓存机制

    ![复制代码][copycode.gif] 您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态。

    相关 Hibernate 缓存机制

    一、why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库。 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性

    相关 Hibernate缓存机制

    一、why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库。 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性

    相关 hibernate 缓存机制

    hibernate缓存机制是hibernate中很重要的一个内容,因为有缓存的存在,使得效率得到了很大的提升,今天这个博客,我们就来学习一个hibernate中各种查询方式对应

    相关 Hibernate缓存机制

    一、why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库。 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性

    相关 Hibernate 缓存机制(转)

    一、why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库。 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性