zoukankan      html  css  js  c++  java
  • day37 04-Hibernate二级缓存:list和iterate方法比较

    get()和load()方法既可以向一级缓存区放数据,也可以向二级缓存区放数据。这是查询一个的情况。要是查询所有呢?注意,

    // 查询所有.Query接口的list()方法.
    // list()方法会向二级缓存中放数据,但是不会使用二级缓存中的数据.

    //list()方法没有使用二级缓存的数据.

    没有发生SQL,证明肯定是从一级缓存或者是二级缓存获取的数据.一级缓存没有,那肯定是从二级缓存获取的.有人说那这list()方法的效率就比较低了。一级缓存经常使用list(),但是有了二级缓存如果你想查询所有,可以用另外一个方法。

    如果没有二级缓存,不建议使用iterate()(因为效率会比较低),迭代器的方法。


    // iterate()方法可以查询所有信息.
    // iterate方法会发送N+1条SQL查询.但是会使用二级缓存的数据

      // N+1条SQL去查询.

    iterate()的效果:

    Hibernate:
    select
    customer0_.cid as col_0_0_
    from
    customer customer0_
    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=?
    Customer [cid=1, cname=小金, age=23, ver=0]
    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=?
    Customer [cid=2, cname=小明, age=32, ver=0]
    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=?
    Customer [cid=3, cname=沈明贞, age=28, ver=1]
    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=?
    Customer [cid=4, cname=张三, age=28, ver=0]
    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=?
    Customer [cid=5, cname=张三, age=28, ver=0]

    如果没有二级缓存,iterate()方法效率比较低。因为执行Iterator<Customer> iterator = session.createQuery("from Customer").iterate();调用iterate()只查询所有客户的id。当你每次迭代的时候它才会根据你每个客户的id去查询客户的信息。所以iterate()是一个N+1条SQL去查询。你有N条记录,它会发N+1条SQL去查询。第一条是查询所有的id,然后再根据id逐一检索。所以这个方法效率比较低。list()方法效率高,直接全部都查出来了。

    但是list()有了二级缓存,效率就比不上iterate()。因为iterate()可以使用二级缓存的数据。

    开放/配置二级缓存

    <!-- Hibernate中开启二级缓存 -->
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <!-- 配置二级缓存的提供商 -->
    <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>


    <!-- 配置哪些类使用二级缓存 -->
    <class-cache usage="read-write" class="cn.itcast.hibernate3.demo1.Customer"/>
    <!--查询订单的类缓存区-->

    <class-cache usage="read-write" class="cn.itcast.hibernate3.demo1.Order"/>

    之后,iterate()的效果:

    Hibernate:
    select
    customer0_.cid as col_0_0_
    from
    customer customer0_
    Customer [cid=1, cname=小金, age=23, ver=0]
    Customer [cid=2, cname=小明, age=32, ver=0]
    Customer [cid=3, cname=沈明贞, age=28, ver=1]
    Customer [cid=4, cname=张三, age=28, ver=0]
    Customer [cid=5, cname=张三, age=28, ver=0]

    还是会发送SQL语句查询所有客户的id,但是在根据客户的id检索每一条记录的时候就直接打印了,而没有再发生SQL去查询。所以iterate()是可以使用二级缓存的。


     结论:

    在查询所有的时候,如果有二级缓存,使用iterate(),如果没有二级缓存,使用list(). 


        @SuppressWarnings("unchecked")
        @Test
        // iterate()方法可以查询所有信息.
        // iterate方法会发送N+1条SQL查询.但是会使用二级缓存的数据
        public void demo5(){
            Session session = HibernateUtils.getCurrentSession();
            Transaction tx = session.beginTransaction();
            
            // N+1条SQL去查询.
            Iterator<Customer> iterator = session.createQuery("from Customer").iterate();
            while(iterator.hasNext()){
                Customer customer = iterator.next();
                System.out.println(customer);
            }
            
            tx.commit();
            
            session = HibernateUtils.getCurrentSession();
            tx = session.beginTransaction();
            
            iterator = session.createQuery("from Customer").iterate();
            while(iterator.hasNext()){
                Customer customer = iterator.next();
                System.out.println(customer);
            }
            
            tx.commit();
        }
        
        @SuppressWarnings("unchecked")
        @Test
        // 查询所有.Query接口的list()方法.
        // list()方法会向二级缓存中放数据,但是不会使用二级缓存中的数据.
        public void demo4(){
            Session session = HibernateUtils.getCurrentSession();
            Transaction tx = session.beginTransaction();
            
            // 查询所有客户:
            // list方法会向二级缓存中放入数据的.
            List<Customer> list = session.createQuery("from Customer").list();
            for (Customer customer : list) {
                System.out.println(customer.getCname());
            }
            tx.commit();
            
            session = HibernateUtils.getCurrentSession();
            tx = session.beginTransaction();
            
             Customer customer = (Customer) session.get(Customer.class, 1);// 没有发生SQL ,从二级缓存获取的数据.
             //list()方法没有使用二级缓存的数据.
    /*        list = session.createQuery("from Customer").list();
            for (Customer customer : list) {
                System.out.println(customer.getCname());
            }*/
            
            tx.commit();
        }
  • 相关阅读:
    获取连接无线路由客户机信息命令
    HTB进行流量控制方法
    exec函数族用法
    java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    struts2从请求取值的三种方式
    用jsp写的网页 怎么在传递参数时包含中文?
    Struts2使用DoubleSelect实现二级级联下拉框省份城市
    MySQL里主键与外键的关系
    查看struts2源码
    WIN7系统下,用笔记本发送WIFI信号让手机无线上网!
  • 原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6708443.html
Copyright © 2011-2022 走看看