技术干货收藏

19、hibernate二级缓存(hibernate笔记)

2016-05-30  本文已影响342人  yjaal

一、简介

二、配置和使用

hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
    <!-- 下面这些字符串在.property配置文件中都能查到 -->
        <property name="hibernate.connection.url">
            <![CDATA[jdbc:mysql://localhost:3305/hibernate_cache_level_2?useUnicode=true&characterEncoding=utf8]]>
        </property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">walp1314</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        
        <!-- 开启二级缓存 -->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        
        <!-- 指定缓存产品提供商 -->
        <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
        
        <mapping resource="cn/itcast/hibernate/Student.hbm.xml"/>
        <mapping resource="cn/itcast/hibernate/Classes.hbm.xml"/>
        <!-- 指定哪些实体使用二级缓存 -->
        <class-cache class="cn.itcast.hibernate.Student" usage="read-only"/>
    </session-factory>
</hibernate-configuration>

说明:

相关实体:
Student.java

private int id;
private String name;
private Classes classes;

Classes.java

private int id;
private String name;
private Set students;

配置:
Classes.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.hibernate">
    <class name="Classes" table="_classes">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <set name="students" inverse="true" cascade="all">
            <key column="classesid"/>
            <one-to-many class="Student"/>
        </set>
    </class>
</hibernate-mapping>

Student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="cn.itcast.hibernate.Student" table="_student">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <many-to-one name="classes" column="classesid"/>
    </class>
</hibernate-mapping>

ehcache.xml

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

    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

    <cache name="sampleCache1"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />

    <cache name="sampleCache2"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        />

</ehcache>

测试:
CacheLevel2Test.java

package cn.itcast.hibernate;
import org.hibernate.CacheMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import junit.framework.TestCase;
public class CacheLevel2Test extends TestCase {
    /**
     * 开启两个session,分别调用load
     */
    public void testCache1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            Student student = (Student)session.load(Student.class, 1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //不会发出sql,因为开启了二级缓存,session是共享二级缓存的
            Student student = (Student)session.load(Student.class, 1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }   
    }   
    
    /**
     * 开启两个session,分别调用get
     */
    public void testCache2() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            Student student = (Student)session.get(Student.class, 1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //不会发出sql,因为开启了二级缓存,session是共享二级缓存的
            Student student = (Student)session.get(Student.class, 1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }   
    /**
     * 开启两个session,分别调用load,在使用SessionFactory清除二级缓存
     */
    public void testCache3() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            Student student = (Student)session.load(Student.class, 1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        //管理二级缓存
        SessionFactory factory = HibernateUtils.getSessionFactory();
        //factory.evict(Student.class);
        factory.evict(Student.class, 1);
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //会发出查询sql,因为二级缓存中的数据被清除了
            Student student = (Student)session.load(Student.class, 1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }
}

说明:从上面三个测试中可以发现load、get方法都是共享二级缓存的。注意第三个测试例子中的使用SessionFactory清理缓存,可以指定只清除某一个对象。

一级缓存和二级缓存的交互:

/**
     * 一级缓存和二级缓存的交互
     */
    public void testCache4() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //仅从二级缓存中读数据,而不向二级缓存中写数据
            session.setCacheMode(CacheMode.GET);
            Student student = (Student)session.load(Student.class, 1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //发出sql语句,因为session设置了CacheMode为GET,所以二级缓存中没有数据
            Student student = (Student)session.load(Student.class, 1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //只向二级缓存写数据,而不从二级缓存读数据
            session.setCacheMode(CacheMode.PUT);
            
            //会发出查询sql,因为session将CacheMode设置成了PUT
            Student student = (Student)session.load(Student.class, 1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
    }   
上一篇 下一篇

猜你喜欢

热点阅读