zoukankan      html  css  js  c++  java
  • 29hibernate_query_cache

    hibernate查询缓存

    查询缓存是针对普通属性结果集的缓存
    对实体对象的结果集只缓存id

    查询缓存的生命周期(不确定),当前关联的表发生修改,那么查询缓存生命周期结束

    查询缓存的配置和使用:
        * 在hibernate.cfg.xml文件中启用查询缓存,如:
        <property name="hibernate.cache.use_query_cache">true</property>
        * 在程序中必须手动启用查询缓存,如:
        query.setCacheable(true);
        
        
            <!-- 开启二级缓存 -->
            <property name="hibernate.cache.use_second_level_cache">true</property>
            
            <!-- 指定缓存产品提供商 -->
            <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
            
            <!-- 启用查询缓存 -->
            <property name="hibernate.cache.use_query_cache">true</property>    
            
            <class-cache class="com.bjsxt.hibernate.Student" usage="read-only"/>
            
            
            
            =======================================================
            package com.bjsxt.hibernate;

    import java.io.Serializable;
    import java.util.Iterator;
    import java.util.List;

    import org.hibernate.CacheMode;
    import org.hibernate.Query;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;

    import junit.framework.TestCase;

    public class QueryCacheTest extends TestCase {

        /**
         * 开启查询缓存,关闭二级缓存
         * 
         * 开启一个session,分别调用query.list
         
    */
        public void testCache1() {
            Session session = null;
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s.name from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                
                List names = query.list(); 
                for (Iterator iter=names.iterator();iter.hasNext(); ) {
                    String name = (String)iter.next();
                    System.out.println(name);
                }
                
                System.out.println("-------------------------------------");
                query = session.createQuery("select s.name from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                
                //没有发出查询sql,因为启用了查询缓存
                names = query.list(); 
                for (Iterator iter=names.iterator();iter.hasNext(); ) {
                    String name = (String)iter.next();
                    System.out.println(name);
                }

                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
        }    
        
        /**
         * 开启查询缓存,关闭二级缓存
         * 
         * 开启两个session,分别调用query.list
         * 在两个session中,不影响查询缓存,也就是说session与查询缓存的生命周期没有关系
         
    */
        public void testCache2() {
            Session session = null;
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s.name from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                
                List names = query.list(); 
                for (Iterator iter=names.iterator();iter.hasNext(); ) {
                    String name = (String)iter.next();
                    System.out.println(name);
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
            
            System.out.println("-------------------------------------");
            
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s.name from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                
                //不会发出查询sql,因为查询缓存的生命周期和session无关
                List names = query.list(); 
                for (Iterator iter=names.iterator();iter.hasNext(); ) {
                    String name = (String)iter.next();
                    System.out.println(name);
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
        }        
        
        /**
         * 开启查询缓存,关闭二级缓存
         * 
         * 开启两个session,分别调用query.iterate
         
    */
        public void testCache3() {
            Session session = null;
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s.name from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                 
                for (Iterator iter=query.iterate();iter.hasNext(); ) {
                    String name = (String)iter.next();
                    System.out.println(name);
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
            
            System.out.println("-------------------------------------");
            
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s.name from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                 
                //查询缓存只对query.list()起作用,query.iterate不起作用,也就是query.iterate不使用
                
    //查询缓存
                for (Iterator iter=query.iterate();iter.hasNext(); ) {
                    String name = (String)iter.next();
                    System.out.println(name);
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
        }
        
        /**
         * 关闭查询缓存,关闭二级缓存
         * 
         * 开启两个session,分别调用query.list查询实体对象
         
    */
        public void testCache4() {
            Session session = null;
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                
                List students = query.list(); 
                for (Iterator iter=students.iterator();iter.hasNext(); ) {
                    Student student = (Student)iter.next();
                    System.out.println(student.getName());
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
            
            System.out.println("-------------------------------------");
            
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                //会发出查询sql,因为list默认每次都会发出查询sql
                List students = query.list(); 
                for (Iterator iter=students.iterator();iter.hasNext(); ) {
                    Student student = (Student)iter.next();
                    System.out.println(student.getName());
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
        }        

        /**
         * 开启查询缓存,关闭二级缓存
         * 
         * 开启两个session,分别调用query.list查询实体对象
         
    */
        public void testCache5() {
            Session session = null;
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                
                List students = query.list(); 
                for (Iterator iter=students.iterator();iter.hasNext(); ) {
                    Student student = (Student)iter.next();
                    System.out.println(student.getName());
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
            
            System.out.println("-------------------------------------");
            
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                
                //会发出n条查询语句,因为开启了查询缓存,关闭了二级缓存,那么查询缓存会缓存实体对象的id
                
    //所以hibernate会根据实体对象的id去查询相应的实体,如果缓存中不存在相应的
                
    //实体那么将发出根据实体id查询的sql语句,否则不会发出sql使用缓存中的数据
                List students = query.list(); 
                for (Iterator iter=students.iterator();iter.hasNext(); ) {
                    Student student = (Student)iter.next();
                    System.out.println(student.getName());
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
        }    
        
        /**
         * 开启查询缓存,开启二级缓存
         * 
         * 开启两个session,分别调用query.list查询实体对象
         
    */
        public void testCache6() {
            Session session = null;
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                
                List students = query.list(); 
                for (Iterator iter=students.iterator();iter.hasNext(); ) {
                    Student student = (Student)iter.next();
                    System.out.println(student.getName());
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
            
            System.out.println("-------------------------------------");
            
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
                
                Query query = session.createQuery("select s from Student s");
                //启用查询查询缓存
                query.setCacheable(true);
                
                //不会发出查询sql,因为开启了二级缓存和查询缓存,查询缓存缓存了实体对象的id列表
                
    //hibernate会根据实体对象的id列表到二级缓存中取得相应的数据
                List students = query.list(); 
                for (Iterator iter=students.iterator();iter.hasNext(); ) {
                    Student student = (Student)iter.next();
                    System.out.println(student.getName());
                }
                session.getTransaction().commit();
            }catch(Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }finally {
                HibernateUtils.closeSession(session);
            }
        }        
    }
            
            
            ======================================================
            ==========================查询变通属性==================
    Test1:    关闭查询缓存,关闭二级缓存,开启一个session,分别调用query.list    
    <property name="hibernate.cache.use_second_level_cache">false</property>
    <property name="hibernate.cache.use_query_cache">false</property>

    //query.setCacheable(true);
    测试结果:
    Hibernate: select student0_.name as col_0_0_ from t_student student0_
    ....
    s_999
    -------------------------------------
    Hibernate: select student0_.name as col_0_0_ from t_student student0_
    ....
    s_999

    Test2:    开启查询缓存,关闭二级缓存,开启一个session,分别调用query.list    
    <property name="hibernate.cache.use_query_cache">true</property>
    测试结果:
    Hibernate: select student0_.name as col_0_0_ from t_student student0_
    班级0的学生0
    班级0的学生1
    ....
    s_999
    -------------------------------------
    班级0的学生0
    班级0的学生1
    ...... 
    结论:查询缓存是针对普通属性结果集的缓存,它的生命周期不可控制,所以它的利用率不高

    Test2:在两个session中,不影响查询缓存,也就是说session与查询缓存的生命周期没有关系
    测试结果:
    Hibernate: select student0_.name as col_0_0_ from t_student student0_
    班级0的学生0
    班级0的学生1
    ....
    s_999
    -------------------------------------
    班级0的学生0
    班级0的学生1
    ...... 

    Test4:关闭查询缓存,关闭二级缓存, 开启两个session,分别调用query.iterate

    测试结果:
    Hibernate: select student0_.name as col_0_0_ from t_student student0_
    ....
    s_999
    -------------------------------------
    Hibernate: select student0_.name as col_0_0_ from t_student student0_
    ....
    s_999


    Test5: 开启查询缓存,关闭二级缓存, 开启两个session,分别调用query.iterate
    测试结果:
    Hibernate: select student0_.name as col_0_0_ from t_student student0_
    ....
    s_999
    -------------------------------------
    Hibernate: select student0_.name as col_0_0_ from t_student student0_
    ....
    s_999
    结论:查询缓存对iterate不起作用!
    //查询缓存只对query.list()起作用,query.iterate不起作用,也就是query.iterate不使用查询缓存

            ==========================查询实体对象==================
    Test6:关闭查询缓存,关闭二级缓存,开启两个session,分别调用query.list查询实体对象
    Hibernate: select student0_.id as id1_, student0_.name as name1_, student0_.classesid as classesid1_ from t_student student0_
    班级0的学生0
    班级0的学生1
    ... ...
    s_999
    -------------------------------------
    Hibernate: select student0_.id as id1_, student0_.name as name1_, student0_.classesid as classesid1_ from t_student student0_
    班级0的学生0
    班级0的学生1
    结论:会发出查询sql,因为list默认每次都会发出查询sql


    Test7:开启查询缓存,关闭二级缓存,开启两个session,分别调用query.list查询实体对象
    发出N条
    Hibernate select student0_.id as id1_0_, student0_.name as name1_0_, student0_.classesid as classesid1_0_ from t_student student0_ where student0_.id=?
    结论:两个session,二级缓存关闭着:
    //会发出n条查询语句,因为开启了查询缓存,关闭了二级缓存,那么查询缓存会缓存实体对象的id
    //所以hibernate会根据实体对象的id去查询相应的实体,如果缓存中不存在相应的实体,那么将发出根据实体id查询的sql语句,否则不会发出sql使用缓存中的数据

    Test8:开启查询缓存,开启二级缓存, 开启两个session,分别调用query.list查询实体对象
    Hibernate: select student0_.id as id1_, student0_.name as name1_, student0_.classesid as classesid1_ from t_student student0_
    班级0的学生0
    班级0的学生1
    ... ...
    s_999
    -------------------------------------
    班级0的学生0
    班级0的学生1
    ... ...
    s_999
    结论://不会发出查询sql,因为开启了二级缓存和查询缓存,查询缓存缓存了实体对象的id列表
                
    //hibernate会根据实体对象的id列表到二级缓存中取得相应的数据
    ========================================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 name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_cache</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</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>

    <!-- 启用查询缓存 -->
    <property name="hibernate.cache.use_query_cache">true</property>

    <mapping resource="com/bjsxt/hibernate/Classes.hbm.xml"/>
    <mapping resource="com/bjsxt/hibernate/Student.hbm.xml"/>

    <class-cache class="com.bjsxt.hibernate.Student" usage="read-only"/>
    </session-factory>
    </hibernate-configuration>
  • 相关阅读:
    ubuntu的php7与apache2的环境搭建
    git服务器搭建post-receive 钩子部署服务端代码
    node redis安装与使用
    微信小程序坑集
    微信小程序登录
    mobx react
    react-native-router-flux 下部导航
    java
    java
    java
  • 原文地址:https://www.cnblogs.com/alamps/p/2633867.html
Copyright © 2011-2022 走看看