Hibernate二级缓存

Hibernate提供的缓存

         有一级缓存、二级缓存。 目的是为了减少对数据库的访问次数,提升程序执行效率!

一级缓存:

         基于Session的缓存,缓存内容只在当前session有效,session关闭,缓存内容失效!

         特点:

                   作用范围较小! 缓存的事件短。

                   缓存效果不明显。

概述

二级缓存:

         Hibernate提供了基于应用程序级别的缓存, 可以跨多个session,即不同的session都可以访问缓存数据。 这个换存也叫二级缓存。

         Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可; 不想用,直接移除,不影响代码。

         如果用户觉得hibernate提供的框架框架不好用,自己可以换其他的缓存框架或自己实现缓存框架都可以。


二级缓存,使用步骤

1) 开启二级缓存

2)指定缓存框架

3)指定那些类加入二级缓存

4)测试

         测试二级缓存!

缓存策略

<class-cache usage="read-only"/>     放入二级缓存的对象,只读;

         <class-cache usage="nonstrict-read-write"/>  非严格的读写

         <class-cache usage="read-write"/>    读写; 放入二级缓存的对象可以读、写;

         <class-cache usage="transactional"/>   (基于事务的策略)

集合缓存

<!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->

      <collection-cache

usage="read-write" collection="cn.loaderman.b_second_cache.Dept.emps"/>

查询缓存

list() 默认情况只会放入缓存,不会从一级缓存中取!

   使用查询缓存,可以让list()查询从二级缓存中取!


Hibernate.cfg.xml

<!--****************** 【二级缓存配置】****************** -->
        <!-- a.  开启二级缓存 -->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <!-- b. 指定使用哪一个缓存框架(默认提供的) -->
        <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
        <!-- 开启查询缓存 -->
        <property name="hibernate.cache.use_query_cache">true</property>
        <!-- c. 指定哪一些类,需要加入二级缓存 -->
        <class-cache usage="read-write" class="loaderman.b_second_cache.Dept"/>
        <class-cache usage="read-only" class="loaderman.b_second_cache.Employee"/>

        <!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
        <collection-cache usage="read-write" collection="loaderman.b_second_cache.Dept.emps"/>
package loaderman.b_second_cache;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

public class App {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(Dept.class)
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
    }
    // 1. 测试二级缓存的使用
    // 没有/有用 二级缓存
    @Test
    public void testCache() {
        Session session1 = sf.openSession();
        session1.beginTransaction();
        // a. 查询一次
        Dept dept = (Dept) session1.get(Dept.class, 10);
        dept.getEmps().size();// 集合
        session1.getTransaction().commit();
        session1.close();

        System.out.println("------");

        // 第二个session
        Session session2 = sf.openSession();
        session2.beginTransaction();
        // a. 查询一次
        dept = (Dept) session2.get(Dept.class, 10);  // 二级缓存配置好; 这里不查询数据库
        dept.getEmps().size();

        session2.getTransaction().commit();
        session2.close();
    }


    @Test
    public void listCache() {
        Session session1 = sf.openSession();
        session1.beginTransaction();
        // HQL查询  【setCacheable  指定从二级缓存找,或者是放入二级缓存】
        Query q = session1.createQuery("from Dept").setCacheable(true);
        System.out.println(q.list());
        session1.getTransaction().commit();
        session1.close();


        Session session2 = sf.openSession();
        session2.beginTransaction();
        q = session2.createQuery("from Dept").setCacheable(true);
        System.out.println(q.list());  // 不查询数据库: 需要开启查询缓存
        session2.getTransaction().commit();
        session2.close();
    }
}
package loaderman.b_second_cache;

import java.util.HashSet;
import java.util.Set;

public class Dept {

    private int deptId;
    private String deptName;
    // 【一对多】 部门对应的多个员工
    private Set<Employee> emps = new HashSet<Employee>();




    public Dept(int deptId, String deptName) {
        super();
        this.deptId = deptId;
        this.deptName = deptName;
    }
    public Dept() {
        super();
    }
    public int getDeptId() {
        return deptId;
    }
    public void setDeptId(int deptId) {
        this.deptId = deptId;
    }
    public String getDeptName() {
        return deptName;
    }
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
    public Set<Employee> getEmps() {
        return emps;
    }
    public void setEmps(Set<Employee> emps) {
        this.emps = emps;
    }
    @Override
    public String toString() {
        return "Dept [deptId=" + deptId + ", deptName=" + deptName + "]";
    }




}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="loaderman.b_second_cache">
    
    <class name="Dept" table="t_dept" >
        <id name="deptId">
            <generator class="native"></generator>
        </id>    
        <property name="deptName" length="20"></property>
         <set name="emps">
              <key column="dept_id"></key>
              <one-to-many class="Employee"/>
         </set>
    </class>
    
    <!-- 存放sql语句 -->
    <query name="getAllDept">
        <![CDATA[
            from Dept d where deptId < ?
        ]]>
        
    </query>
    

</hibernate-mapping>
package loaderman.b_second_cache;



public class Employee {

    private int empId;
    private String empName;
    private double salary;
    // 【多对一】员工与部门
    private Dept dept;;


    public int getEmpId() {
        return empId;
    }
    public void setEmpId(int empId) {
        this.empId = empId;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public Dept getDept() {
        return dept;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }


}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="loaderman.b_second_cache">
    
    <class name="loaderman.b_second_cache.Employee" table="t_employee">
        <id name="empId">
            <generator class="native"></generator>
        </id>    
        <property name="empName" length="20"></property>
        <property name="salary" type="double"></property>
        
        <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
         
    </class>
    

</hibernate-mapping>
原文地址:https://www.cnblogs.com/loaderman/p/10038539.html