hibernate二级缓存

Posted on 2017-04-26 16:01  李太阳  阅读(154)  评论(0编辑  收藏  举报

Hibernate二级缓存

前言:

    hibernate中的二级缓存是属于SessionFactory级别的缓存机制,一级别的缓存是Session级别的缓存,是属于事务范围的缓存,由Hibernate管理,一般无需进行干预。第二级别的缓存是SessionFactory级别的缓存,是属于进程范围的缓存。hibernate二级缓存中的缓存对象可以被整个应用的Session对象共享,即使关闭当前Session对象,新建的Session对象仍可使用。使用Hibernate的二级缓存之后查询数据,Session对象会首先在以及缓存中查找有无缓存数据被命中。如果没有,则查找二级缓存。如果有,则直接返回所命中的数据,否则查询数据库。所以hibernate的二级缓存是优化数据库的一个手段。

  那么什么样的数据适合放在二级缓存中呢?

    1.很少被修改的数据

    2.不是很重要的数据

    3不会被并发访问的数据

    4常量数据

   那么什么样的数据不适合放在二级缓存中呢?

    1经常被修改的数据

    2绝对不允许出现并发访问的数据。如财务数据,绝对不允许出现并发

    3与其他应用共享的数据

1.     配置

1.1在hibernate.cfg.xml文件中:

                <property name="hibernateProperties">

                            <props>

                                <!-- 配置二级缓存的所需的类 -->

                                     <prop key="hibernate.cache.provider_class">

                                               org.hibernate.cache.EhCacheProvider

                                     </prop>

                                     <!-- 配置启用查询缓存-->

                                     <prop key="hibernate.cache.use_query_cache">

                                               true

                                     </prop>

                                     <!-- 开启二级缓存 -->

                                     <prop key="hibernate.cache.use_second_level_cache">

                                               true

                                     </prop>

                                     <!-- 方言 -->

                                     <prop key="hibernate.dialect">

                                               org.hibernate.dialect.MySQL5Dialect

                                     </prop>

                                     <!-- 是否开启显示sql发送 -->

                                     <prop key="hibernate.show_sql">

                                               true

                                     </prop>

         <!-- 是否自动创建|更新|验证数据库表结构 ,防止数据库表数据丢失建议为none-->

                                     <prop key="hibernate.hbm2ddl.auto">

                                               none

                                     </prop>

                            </props>

                   </property>

1.2在src目录下建立一个文件,名字叫做encache.xml(必须叫这个名字),内容为:

<?xml version="1.0" encoding="UTF-8"?>

//防止加载不到encache文件,加上xmlns, xsi:noNamespaceSchemaLocation为所在路径

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

         //当二级缓存对象超过我们设置的maxElementsInMemory数量时,才起作用么

         <diskStore path="java.io.tmpdir" />

         //全局配置

<defaultCache

maxElementsInMemory="500"

eternal="false"

            timeToIdleSeconds="300"

timeToLiveSeconds="1200"

overflowToDisk="true" />

//可对具体的类做具体的配置

<cache name="com.demo.hibernate.testDemo"

        maxElementsInMemory="10"

        eternal="false"

        timeToIdleSeconds="300"

        timeToLiveSeconds="600"

        overflowToDisk="true"/>

</ehcache>

 

2.针对具体类的配置

2.1以pojo类以注解的形式实现

@Entity

@Table(name="emp")

@Cacheable(value=true)

@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)

public class Employee {

    @Id

    @Column(name="empno")

    @GenericGenerator(name="assignedGenerator", strategy="assigned")

    @GeneratedValue(generator="assignedGenerator")

    private int id;

   

    @Column(name="ename")

    private String ename;

   

    @Column(name="job")

    private String job;

 

    @Column(name="hiredate")

    private Date hiredate;

   

    @Column(name="sal")

    private Double salary;

   

    @Column(name="comm")

private Double comm;

 

    //setter and getter(省略)

}

2.2在hibernate.cfg.xml文件中,采用<class-cache>标签

<class-cacheclass=" com.demo.hibernate.testDemo " usage="read-only"/>

 

:

hibernate应用中,设置二级缓存的并发策略有两种方法,一种是通过Hibernate的全局配置文件,另一种是为各个Entity类单独设置。

1. 通过hibernate.cache.default_cache_concurrency_strategy配置参数,设置全局的二级缓存的并发策略

hibernate.cache.default_cache_concurrency_strategy配置参数的可用值:

read-only,适合只读事务

read-write,适合读写事务

nonstrict-read-write,适合高并发的读写事务

transactional,事务序列化

2. 使用Cache标注为各个Entity类单独设置二级缓存的并发策略,或者在<class-cache>标签中修改usage属性

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)

 

3.测试

public class HibernateQBCTest {

   

    private SessionFactory sf;

   

    @Before

    public void getSessionFactory(){

        sf = OracleSessionUtils.getSessionFactory();

    }

   

    //查询所有

    @Test

    public void list(){

         Session session = sf.openSession();

         Transaction tx = session.beginTransaction();

         List<Employee> empList = session.createCriteria(Employee.class).list();

         for(Employee e : empList){

             System.out.println(e.getEname());

         }

         tx.commit();

         session.close();

        

         //以下查询不会发送SQL

         Session session1 = sf.openSession();

         Transaction tx1 = session1.beginTransaction();

         Employee e = session1.get(Employee.class, 7369);

         System.out.println(e.getEname()); 

         tx1.commit();

         session1.close();

    }

}