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();
        }
        

  • 相关阅读:
    算法两则
    windows XP 神key
    mysql空间型数据使用python executemany批量插入报错
    关于集合的相似度测量方法
    读取经纬度坐标并存储为字典格式,即key为ID,value为轨迹点
    ubuntu下安装软件时报错解决:Unmet dependencies. Try 'apt-get -f install' with no packages
    ubuntu环境下pycharm编译程序import包出错:ImportError: dynamic module does not define init function (init_caffe)
    linux Ubuntu14.04 make编译文件报错:No rule to make target `/usr/lib/libpython2.7.so', needed by `python/_pywraps2.so'. Stop.
    U盘安装Ubuntu14.04&配置远程win10远程连接
    解决:error LNK1169: 找到一个或多个多重定义的符号
  • 原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6707045.html
Copyright © 2011-2022 走看看