zoukankan      html  css  js  c++  java
  • day37 03-Hibernate二级缓存:集合缓冲区特点

    所以说要经常检查hibernate3的核心配置文件hibernate.cfg.xml.


    Hibernate:
    select
    customer0_.cid as cid0_0_,
    customer0_.version as version0_0_,
    customer0_.cname as cname0_0_,
    customer0_.age as age0_0_
    from
    customer customer0_
    where
    customer0_.cid=?
    Hibernate:
    select
    orders0_.cno as cno0_1_,
    orders0_.oid as oid1_,
    orders0_.oid as oid1_0_,
    orders0_.addr as addr1_0_,
    orders0_.cno as cno1_0_
    from
    orders orders0_
    where
    orders0_.cno=?

    订单的数量:11

    这是咱们的默认情况,fetch="select" lazy="tue"的情况。这种情况发多条SQL语句。所以不是连接查询,而是分步单表查询。

    向下执行,查询customer2没有发SQL,因为使用了二级缓存。再向下执行查询customer2的订单也没有发SQL,跟hibernate3核心配置文件hibernate.cfg.xml中的一句话:<collection-cache usage="read-write" collection="cn.itcast.hibernate3.demo1.Customer.orders"/>有关。集合缓冲区 所以在获得客户的订单的数量的时候,就没有再去发送SQL语句了。因为它已经把我们的集合orders也给缓存了。集合缓存区用来缓存对象中的集合。我们现在用的就是对象中的集合,所以它没有发送SQL语句。

    现在要证明集合缓存区的数据是依赖于类缓存区的。尝试注释掉<collection-cache usage="read-write" collection="cn.itcast.hibernate3.demo1.Customer.orders"/>这句话。

    Hibernate:
    select
    customer0_.cid as cid0_0_,
    customer0_.version as version0_0_,
    customer0_.cname as cname0_0_,
    customer0_.age as age0_0_
    from
    customer customer0_
    where
    customer0_.cid=?
    Hibernate:
    select
    orders0_.cno as cno0_1_,
    orders0_.oid as oid1_,
    orders0_.oid as oid1_0_,
    orders0_.addr as addr1_0_,
    orders0_.cno as cno1_0_
    from
    orders orders0_
    where
    orders0_.cno=?
    订单的数量:11
    Hibernate:
    select
    orders0_.cno as cno0_1_,
    orders0_.oid as oid1_,
    orders0_.oid as oid1_0_,
    orders0_.addr as addr1_0_,
    orders0_.cno as cno1_0_
    from
    orders orders0_
    where
    orders0_.cno=?
    订单的数量:11

    取消了集合缓存区的话查询customer2不会发SQL(因为customer2使用了二级缓存)。而查询customer2的订单数量的时候就会发SQL(因为取消了集合缓存区)。如果把查询订单的类缓存区给注释掉的话,把订单的类缓存区 <class-cache usage="read-write" class="cn.itcast.hibernate3.demo1.Order"/>的这句话注释掉的话,而把集合缓存区恢复的话,把<collection-cache usage="read-write" collection="cn.itcast.hibernate3.demo1.Customer.orders"/>这句话取消注释的话,

    Hibernate:
    select
    customer0_.cid as cid0_0_,
    customer0_.version as version0_0_,
    customer0_.cname as cname0_0_,
    customer0_.age as age0_0_
    from
    customer customer0_
    where
    customer0_.cid=?
    Hibernate:
    select
    orders0_.cno as cno0_1_,
    orders0_.oid as oid1_,
    orders0_.oid as oid1_0_,
    orders0_.addr as addr1_0_,
    orders0_.cno as cno1_0_
    from
    orders orders0_
    where
    orders0_.cno=?
    订单的数量:11
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    Hibernate:
    select
    order0_.oid as oid1_0_,
    order0_.addr as addr1_0_,
    order0_.cno as cno1_0_
    from
    orders order0_
    where
    order0_.oid=?
    订单的数量:11

    不仅仅发了,而且发了很多条SQL。那样的话有多少个订单就发多少条SQL。这其实跟我们的集合缓存区的结构特性有关。


    这是刚才二级缓存的类缓存区的散装数据。


     二级缓存区分为类缓存区和集合缓存区等等。集合缓存区里面缓存的都是对象的id,而且它是需要依赖类缓存区的。类缓存区缓存的是对象的散装数据。可以通过cid引用这两个属性的值。就是一查Customer,它就会这样去做了。获得订单是我们的集合缓存区。集合缓存区缓存的都是对象的id。它会把我们所有的订单的id给缓存了。集合缓存的是我们订单的id。集合缓存区的使用需要依赖类缓存区。oid对addr有引用。类缓存区是有这些对象数据的。它就不发sql了,直接从二级缓存区获取了如果不开放/配置类缓存区,它就会根据对象的id一个个地去检索。

    下面是同时开放/配置Order类缓存区和集合缓存区的效果:

    Hibernate:
    select
    customer0_.cid as cid0_0_,
    customer0_.version as version0_0_,
    customer0_.cname as cname0_0_,
    customer0_.age as age0_0_
    from
    customer customer0_
    where
    customer0_.cid=?
    Hibernate:
    select
    orders0_.cno as cno0_1_,
    orders0_.oid as oid1_,
    orders0_.oid as oid1_0_,
    orders0_.addr as addr1_0_,
    orders0_.cno as cno1_0_
    from
    orders orders0_
    where
    orders0_.cno=?
    订单的数量:11
    订单的数量:11

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    
    <hibernate-configuration>
    <session-factory>
        <!-- 必须去配置的属性 -->
        <!-- 配置数据库连接的基本信息: -->
        <property name="hibernate.connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <property name="hibernate.connection.url">
            jdbc:mysql:///hibernate3_day03
        </property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password"></property>
        <!-- Hibernate的方言 -->
        <!-- 生成底层SQL不同的 -->
        <property name="hibernate.dialect">
            org.hibernate.dialect.MySQLDialect
        </property>
    
        <!-- 可选的属性 -->
        <!-- 显示SQL -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL -->
        <property name="hibernate.format_sql">true</property>
    
        <property name="hibernate.connection.autocommit">false</property>
        <!-- hbm:映射 to DDL: create drop alter -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- 设置事务的隔离级别 -->
        <property name="hibernate.connection.isolation">4</property>
        <!-- 设置本地Session -->
        <property name="hibernate.current_session_context_class">thread</property>
    
        <!-- C3P0连接池设定-->
        <!-- 使用c3po连接池  配置连接池提供的供应商-->
        <property name="connection.provider_class">
            org.hibernate.connection.C3P0ConnectionProvider
        </property>
        <!-- Hibernate中开启二级缓存 -->
        <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>
    
        <!--在连接池中可用的数据库连接的最少数目 -->
        <property name="c3p0.min_size">5</property>
        <!--在连接池中所有数据库连接的最大数目  -->
        <property name="c3p0.max_size">20</property>
        <!--设定数据库连接的过期时间,以秒为单位,
            如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
        <property name="c3p0.timeout">120</property>
        <!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
        <property name="c3p0.idle_test_period">3000</property>
    
        <!-- 通知Hibernate加载那些映射文件 -->
        <mapping resource="cn/itcast/hibernate3/demo1/Customer.hbm.xml" />
        <mapping resource="cn/itcast/hibernate3/demo1/Order.hbm.xml" />
    
        <!-- 配置哪些类使用二级缓存 -->
        <class-cache usage="read-write" class="cn.itcast.hibernate3.demo1.Customer"/>
        <!--查询订单的类缓存区-->
          
        <class-cache usage="read-write" class="cn.itcast.hibernate3.demo1.Order"/>
        
        <!-- 集合缓冲区 
        所以在获得客户的订单的数量的时候,就没有再去发送SQL语句了。因为它已经把我们的集合orders也给缓存了。集合缓存区用来缓存对象中的集合。
        我们现在用的就是对象中的集合,所以它没有发送SQL语句。证明集合缓存区的数据是依赖于类缓存区的。
        -->
    
        <collection-cache usage="read-write" collection="cn.itcast.hibernate3.demo1.Customer.orders"/>
    
    </session-factory>
    </hibernate-configuration>
        
        @Test
        // 二级缓存的集合缓冲区特点:
        public void demo3(){
            Session session = HibernateUtils.getCurrentSession();
            Transaction tx = session.beginTransaction();
            //现在不只查客户了,只有查客户的订单的时候你才能用到它的集合缓存区。因为只有我们的客户的订单才是它的集合嘛。Customer.hbm.xml里面的<set name="orders">
            //才是一个集合
            Customer customer = (Customer) session.get(Customer.class, 1);
            // 查询客户的订单.
            System.out.println("订单的数量:"+customer.getOrders().size());
            
            tx.commit();
            
            session = HibernateUtils.getCurrentSession();
            tx = session.beginTransaction();//重新开启一个新的事务
            
            Customer customer2 = (Customer) session.get(Customer.class, 1);
            // 查询客户的订单.
            System.out.println("订单的数量:"+customer2.getOrders().size());
            
            tx.commit();
        }
        

  • 相关阅读:
    Path Sum II
    Convert Sorted Array to Binary Search Tree
    Construct Binary Tree from Inorder and Postorder Traversal
    Construct Binary Tree from Preorder and Inorder Traversal
    Maximum Depth of Binary Tree
    Binary Tree Zigzag Level Order Traversal
    Binary Tree Level Order Traversal
    Same Tree
    Validate Binary Search Tree
    Binary Tree Inorder Traversal
  • 原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6707045.html
Copyright © 2011-2022 走看看