Hibernate中性能优化之缓存

来源:互联网 发布:c语言,a 什么意思 编辑:程序博客网 时间:2024/05/02 04:16

引言      

         在Hibernate中,提到性能优化,很自然地我们就想到了缓存。缓存是什么,都有哪些呢?接下来就分享一下。

 一级缓存

      一级缓存生命周期很短和session的生命周期一致,一级缓存也叫session级的缓存或事务级缓存。


       哪些方法支持一级缓存:load/get/iterate查询实体对象。 

       以load方法举例,查询出的数据都会存入session中。如果后面用到,则可以直接从缓存中取。      

<span style="font-size:18px;">student =(Student)session.load(Student.class, new Integer(1));</span>
       get/iterator方法同理,代码如下

<span style="font-size:18px;">student =(Student)session.get(Student.class, new Integer(1)); </span>
<span style="font-size:18px;">//它会发出查询id的语句,但不会发出根据id查询学生的语句iter =session.createQuery("from Student s where s.id<5").iterate();</span>
<span style="font-size:18px;">//iterate查询普通属性,一级缓存不会缓存,所以发出查询语句//一级缓存是缓存实体对象的iter =session.createQuery("select s.name from Student s where s.id<5").iterate();</span>

       从以上还可以看出,一级缓存是缓存实体对象的。

       如果我们大批量处理数据,会造成缓存溢出问题,那么此时我们就应该在处理一定的数据后就清理一次缓存,代码如下

<span style="font-size:18px;">for(int i=0;i<100;i++){Student student = new Student();student.setName("张三"+i);session.save(student);//每20条更新一次if(i%20 ==0){session.flush();//清除缓存的内容session.clear();}}</span>


 二级缓存

       如果在两个session中load查询,会发出查询语句,session之间不能共享一级缓存数据,因为他会伴随着session的消亡而消亡。那么此时为了解决这个问题,二级缓存诞生了。下面我们就来具体了解一下。

        二级缓存也称为进程级的缓存或SessionFactory级的缓存,二级缓存可以被所有的session共享。二级缓存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二级缓存。  

       

       举个例子,在两个session中执行load方法,会发出两个sql语句,但是用了二级缓存,则第一个发出sql语句后,第二个就会从缓存中读取。

      

       了解一下使用二级缓存需要引入的jar包。

       cglib.jar,支持lazy生成代理

       encache.jar,Hibernate一般用此类jar包比较多

       Jboss-cache.jar和Oschache.jar

      
       我们来了解一下二级缓存的配置和使用

       首先将ehcache.xml文件拷贝到src下

       在hibernate.cfg.xml文件中加入缓存产品提供商

<span style="font-size:18px;"><property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property></span>

       启用二级缓存,这也是它的默认配置

<span style="font-size:18px;"><property name="hibernate.cache.use_second_level_cache">true</property></span>

        指定哪些实体类使用二级缓存,可以在映射文件中采用<cache>标签指定或在hibernate.cfg.xml文件中统一指定。注意使用的策略,通常采用read-only和read-write。

        在映射文件中指定:

<span style="font-size:18px;"><cache usage="read-only"/></span>
         在hibernate.cfg.xml文件中统一指定

<span style="font-size:18px;"><!-- 指定Student使用二级缓存 --><class-cache class="com.tgb.hibernate.Student" usage="read-only"/></span>

          缓存原则:通常读远远大于写的数据进行缓存

          注意:二级缓存是缓存实体对象的,了解一级缓存和二级缓存的交互,注意大批量数据更新时,如果配置了二级缓存建议禁用一级缓存和二级缓存的交互。

 查询缓存

查询缓存缓存什么?

          查询缓存是缓存普通属性结果集的,对实体对象的结果集会缓存id,查询缓存的生命周期,当关联的表发生修改,查询缓存的生命周期结束。

了解一下配置

         修改hibernatge.cfg.xml文件,来开启查询缓存,默认是false是不启用的

<span style="font-size:18px;"><property name="hibernate.cache.use_query_cache">true</property></span>

必须在程序启用

<span style="font-size:18px;">query.setCacheable(true)</span>

具体代码体现

     1、不论是在一个还是在两个session中查询,那么在执行第二次查询的时候不会再发出sql语句,而是从session中获取

<span style="font-size:18px;">List names =session.createQuery("select s.name from Student s").setCacheable(true).list();</span>
      2、用迭代器的话会发出查询语句,query.iterate()查询普通属性它不会使用查询缓存,查询缓存只对query.list()起作用

     

<span style="font-size:18px;">Iterator iter =session.createQuery("select s.name from Student s").setCacheable(true).iterate();</span>

     3、会发出n条查询语句,因为开启了查询缓存,关闭了二级缓存,那么查询缓存就会缓存实体对象的id,第二次执行query.list(),将查询缓存中的id依次取出,分别到一级缓存和二级缓存中查询相应的实体对象,如果存在就使用缓存中的实体对象,否则根据id发出查询学生的语句(如果开启二级缓存,就不会发出n条查询语句了)

<span style="font-size:18px;">List students =session.createQuery("select s from Student s").setCacheable(true).list();</span>
      

小结

  原来缓存还有这么多的用法,之前对session的使用只是限于一级的层面。学无止境,多学习,多总结。



       

        


0 0
原创粉丝点击