• 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>
  • 相关阅读:
    OCP-1Z0-053-V13.02-498题
    Oracle索引扫描算法
    dojo CsvStore简介
    Oracle预估的基数算法
    HTML多表头表格
    hql查询实例
    PGA突破pga_aggregate_target限制
    OCP-1Z0-053-V13.02-330题
    java 发送字节流图片,c++接收二进制流
    windows 7蓝屏解决办法
  • 原文地址:https://www.cnblogs.com/loaderman/p/10038539.html
Copyright © 2020-2023  润新知