框架之Hibernate缓存

作者: vaneL | 来源:发表于2017-07-31 17:05 被阅读0次

一级缓存是session的缓存
二级缓存是sessionFactory的缓存

缓存.jpg 二级缓存.jpg 同一个session查询.jpg 两个session查询.jpg 发出3条SQL语句.jpg
<property name="hibernate.cache.use_second_level_cache">true</property>  
<!-- 设置二级缓存插件EHCache的Provider类 -->  
<property name="hibernate.cache.region.factory_class">  
              org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

<hibernate-mapping>  
    <class name="com.hibtest1.entity.User" table="user" catalog="bookshop">  
        <cache usage="read-only"/>  
        <id name="id" type="java.lang.Integer">  
            <column name="Id" />  
            <generator class="native" />  
        </id>  
        <property name="loginName" type="java.lang.String">  
            <column name="LoginName" length="50" />  
        </property>  
          
    </class>  
</hibernate-mapping>

usage属性取值:

  • read-only时表示只读型并发访问策略;
  • read-write表示读写型并发访问策略;
  • nonstrict-read-write表示非严格读写型并发访问策略

Hibernate查找对象如何应用缓存?
当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;
查不到,如果配置了二级缓存,那么从二级缓存中查;
如果都查不到,再查询数据库,把结果按照ID放入到缓存。
删除、更新、增加数据的时候,同时更新缓存

通过list()方法来获得对象,hibernate会发出一条sql语句,将所有的对象查询出来。
通过iterator()方法来获得我们对象的时候,hibernate首先会发出1条sql去查询出所有对象的 id 值,当我们如果需要查询到某个对象的具体信息的时候,hibernate此时会根据查询出来的 id 值再发sql语句去从数据库中查询对象的信息,这就是典型的 N+1 的问题

query.list()和query.iterator()方法的区别:
1.list每次都是通过一条语句直接操作数据库取出所有的数据返回(并且将对象存入hibernate缓存),在一个session中使用两次list()方法,都会发送查询语句,证明list()方法不使用缓存;
2.iterator首先通过一条语句取出所有数据的id,然后通过id在hibernate的一级缓存中查找是否存在该对象,如果存在则直接取出,如果没有则再次发出一条sql语句通过id取得对象(并且加入到缓存中),这样如果所有的id在缓存中都没有的话就会出现n+1条sql语句的问题。
3.所以两者需要合理的结合使用,最大提高性能。
4.使用list()后,数据在一级缓存中存在,再同一个session中使用iterator()的话,不会发送数据库语句,证明iterator()使用一级缓存,在一个session中使用两次list()方法,都会发送查询语句,证明list()方法不使用缓存

相关文章

网友评论

    本文标题:框架之Hibernate缓存

    本文链接:https://www.haomeiwen.com/subject/dherlxtx.html