zoukankan      html  css  js  c++  java
  • Hibernate的二级缓存 下

    HibernateTest.java

    代码:

    /**
     *
     */
    package com.b510.examplex;

    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;


    /**
     *
     * @author XHW
     *
     * @date 2011-7-15
     *
     */
    public class HibernateTest {

     /**
      * @param args
      */
     public static void main(String[] args) {
      new HibernateTest().getGuestbooks();
     }

     public void getGuestbooks(){
      SessionFactory sessionFactory=HibernateSessionFactoryUtil.getSessionFactory();
      Session session1=sessionFactory.getCurrentSession();
      System.out.println("Session1:"+session1);
      Transaction tx=session1.beginTransaction();

    //Guestbook gb=(Guestbook)session1.load(Guestbook.class, 1);
      Guestbook gb=(Guestbook)session1.get(Guestbook.class, 1);
      System.out.println("ID : "+gb.getId()+"name:  "+gb.getName());
      tx.commit();
      
      System.out.println("----------------------------------");
      
      Session session2=sessionFactory.getCurrentSession();
      System.out.println("Session2:"+session2);
      System.out.println("session1是否等于session2  ?");
      System.out.println(session1==session2);
      session2.beginTransaction();

    //  gb=(Guestbook)session2.load(Guestbook.class, 1);      load和get方法在这里可以随便使用,不会影响运行的结果
      gb=(Guestbook)session2.get(Guestbook.class, 1);
      System.out.println("ID : "+gb.getId()+"name:  "+gb.getName());
      session2.getTransaction().commit();
     } 
    }

    运行效果:

    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
    log4j:WARN Please initialize the log4j system properly.
    Session1:SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[]])
    Hibernate:
        select
            guestbook0_.id as id0_0_,
            guestbook0_.version as version0_0_,
            guestbook0_.name as name0_0_,
            guestbook0_.email as email0_0_,
            guestbook0_.phone as phone0_0_,
            guestbook0_.title as title0_0_,
            guestbook0_.content as content0_0_,
            guestbook0_.created_time as created8_0_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 1name:  liuwei
    ----------------------------------
    Session2:SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[]])
    session1是否等于session2  ?
    false
    ID : 1name:  liuwei

    我们看到,session1和session2两个session对象是不想等的,也就是说两个session的地址不是同一个内存地址

    然而我们却看到,这里却只用了一条select语句,我们明明是查询两条记录啊!这说明HIbernate的缓存是跨session的

    也就是一个session对象被干掉了以后,他的缓存还是存在的,不因session被干掉二干掉。这样在我们读取相同的数据

    的时候就不会再却读数据库,而是直接从缓存中读取出来。

    测试代码二:

    HibernateTest.java

    代码;

    /**
     *
     */
    package com.b510.examplex;

    import java.util.List;

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


    /**
     *
     * @author XHW
     *
     * @date 2011-7-15
     *
     */
    public class HibernateTest {

     /**
      * @param args
      */
     public static void main(String[] args) {
      new HibernateTest().getGuestbooks();
     }

     public void getGuestbooks(){
      SessionFactory sessionFactory=HibernateSessionFactoryUtil.getSessionFactory();
      Session session1=sessionFactory.getCurrentSession();
      Transaction tx=session1.beginTransaction();
      Query query=session1.createQuery("from Guestbook");
      List<Guestbook> list=query.list();
      for(Guestbook gb:list){
       System.out.println("ID : "+gb.getId()+"name:  "+gb.getName());
      }
      tx.commit();
      
      System.out.println("----------------------------------");
      
      Session session2=sessionFactory.getCurrentSession();
      session2.beginTransaction();
      query=session2.createQuery("from Guestbook");
      list=query.list();
      for(Guestbook gb:list){
       System.out.println("ID : "+gb.getId()+"name:  "+gb.getName());
      }
      session2.getTransaction().commit();
     } 
    }

    运行效果:

    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
    log4j:WARN Please initialize the log4j system properly.
    Hibernate:
        select
            guestbook0_.id as id0_,
            guestbook0_.version as version0_,
            guestbook0_.name as name0_,
            guestbook0_.email as email0_,
            guestbook0_.phone as phone0_,
            guestbook0_.title as title0_,
            guestbook0_.content as content0_,
            guestbook0_.created_time as created8_0_
        from
            users.guestbook guestbook0_
    ID : 1name:  liuwei
    ID : 2name:  Hongtenzone@foxmail.com
    ID : 3name:  Hongten
    ID : 4name:  HOngten
    ID : 5name:  HOngten
    ID : 6name:  HOngten
    ID : 7name:  HOngten
    ----------------------------------
    Hibernate:
        select
            guestbook0_.id as id0_,
            guestbook0_.version as version0_,
            guestbook0_.name as name0_,
            guestbook0_.email as email0_,
            guestbook0_.phone as phone0_,
            guestbook0_.title as title0_,
            guestbook0_.content as content0_,
            guestbook0_.created_time as created8_0_
        from
            users.guestbook guestbook0_
    ID : 1name:  liuwei
    ID : 2name:  Hongtenzone@foxmail.com
    ID : 3name:  Hongten
    ID : 4name:  HOngten
    ID : 5name:  HOngten
    ID : 6name:  HOngten
    ID : 7name:  HOngten

    我们看到的结果是用两条select语句,查出了相同的结果!

    这个list对象有这么一个特点:他只是从数据库中读取数据,放到缓存中,但是据对不会到缓存中

    去索要数据。也就是说list只是贡献缓存,不会索要缓存。

    他不用二级缓存。

    测试代码三:

    HibernateTest.java

    代码:

    /**
     *
     */
    package com.b510.examplex;

    import java.util.List;

    import java.util.Iterator;

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


    /**
     *
     * @author XHW
     *
     * @date 2011-7-15
     *
     */
    public class HibernateTest {

     /**
      * @param args
      */
     public static void main(String[] args) {
      new HibernateTest().getGuestbooks();
     }

     public void getGuestbooks(){
      SessionFactory sessionFactory=HibernateSessionFactoryUtil.getSessionFactory();
      Session session1=sessionFactory.getCurrentSession();
      Transaction tx=session1.beginTransaction();
      Query query=session1.createQuery("from Guestbook");
      List<Guestbook> list=query.list();
      for(Guestbook gb:list){
       System.out.println("ID : "+gb.getId()+"name:  "+gb.getName());
      }
      tx.commit();
      
      System.out.println("----------------------------------");
      
      Session session2=sessionFactory.getCurrentSession();
      session2.beginTransaction();
      query=session2.createQuery("from Guestbook");
      Iterator it=query.iterate();
      while(it.hasNext()){
       Guestbook gb=(Guestbook)it.next();
       System.out.println("ID : "+gb.getId()+"name:  "+gb.getName());
      }
      session2.getTransaction().commit();
     } 
    }

    运行效果:

    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
    log4j:WARN Please initialize the log4j system properly.
    Hibernate:
        select
            guestbook0_.id as id0_,
            guestbook0_.version as version0_,
            guestbook0_.name as name0_,
            guestbook0_.email as email0_,
            guestbook0_.phone as phone0_,
            guestbook0_.title as title0_,
            guestbook0_.content as content0_,
            guestbook0_.created_time as created8_0_
        from
            users.guestbook guestbook0_
    ID : 1name:  liuwei
    ID : 2name:  Hongtenzone@foxmail.com
    ID : 3name:  Hongten
    ID : 4name:  HOngten
    ID : 5name:  HOngten
    ID : 6name:  HOngten
    ID : 7name:  HOngten
    ----------------------------------
    Hibernate:
        select
            guestbook0_.id as col_0_0_
        from
            users.guestbook guestbook0_
    ID : 1name:  liuwei
    ID : 2name:  Hongtenzone@foxmail.com
    ID : 3name:  Hongten
    ID : 4name:  HOngten
    ID : 5name:  HOngten
    ID : 6name:  HOngten
    ID : 7name:  HOngten

    第一条selelct语句是从数据库中读出数据然后将数据放入二级缓存中,接着进入第二个会话

    Iterator会向二级缓存索要查询的数据,他的方式是首先将要查的实体类的主键值获取到,

    这样在底层上就要使用一条selelct  id 的语句,就是我们看到的第二条selelct语句。这样就获取了

    这个持久化对象的的主键值的一个集合。从 这个主键值集合中再分别读出一个主键值,将他的其他内容

    读取出来。如上面显示的一样,先获取Id=1,然后获取id=1的其他数据,如name字段的值,然后再获取

    id=2,再获取id=2的其他数据(name),以这种方式进行下去,直到读取完数据。还要申明的是,Iterator

    都是先从二级缓存中获取数据,如果不在二级缓存中,那么要使用“n+1”方式了。

    看下面的测试代码:

    HibernateTest.java

    代码:

    /**
     *
     */
    package com.b510.examplex;

    import java.util.List;

    import java.util.Iterator;

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


    /**
     *
     * @author XHW
     *
     * @date 2011-7-15
     *
     */
    public class HibernateTest {

     /**
      * @param args
      */
     public static void main(String[] args) {
      new HibernateTest().getGuestbooks();
     }

     public void getGuestbooks(){
      SessionFactory sessionFactory=HibernateSessionFactoryUtil.getSessionFactory();
      
      /*
      Session session1=sessionFactory.getCurrentSession();
      Transaction tx=session1.beginTransaction();
      Query query=session1.createQuery("from Guestbook");
      List<Guestbook> list=query.list();
      for(Guestbook gb:list){
       System.out.println("ID : "+gb.getId()+"name:  "+gb.getName());
      }
      tx.commit();
      */
      System.out.println("----------------------------------");
      
      Session session2=sessionFactory.getCurrentSession();
      session2.beginTransaction();
      Query query=session2.createQuery("from Guestbook");
      Iterator it=query.iterate();
      while(it.hasNext()){
       Guestbook gb=(Guestbook)it.next();
       System.out.println("ID : "+gb.getId()+"name:  "+gb.getName());
      }
      session2.getTransaction().commit();
     } 
    }

    运行效果:

    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
    log4j:WARN Please initialize the log4j system properly.
    ----------------------------------
    Hibernate:
        select
            guestbook0_.id as col_0_0_
        from
            users.guestbook guestbook0_                                          “n+1”方式中 的“1”
    Hibernate:
        select
            guestbook0_.id as id0_0_,
            guestbook0_.version as version0_0_,
            guestbook0_.name as name0_0_,
            guestbook0_.email as email0_0_,
            guestbook0_.phone as phone0_0_,
            guestbook0_.title as title0_0_,
            guestbook0_.content as content0_0_,
            guestbook0_.created_time as created8_0_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 1name:  liuwei
    Hibernate:
        select
            guestbook0_.id as id0_0_,
            guestbook0_.version as version0_0_,
            guestbook0_.name as name0_0_,
            guestbook0_.email as email0_0_,
            guestbook0_.phone as phone0_0_,
            guestbook0_.title as title0_0_,
            guestbook0_.content as content0_0_,
            guestbook0_.created_time as created8_0_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 2name:  Hongtenzone@foxmail.com
    Hibernate:
        select
            guestbook0_.id as id0_0_,
            guestbook0_.version as version0_0_,
            guestbook0_.name as name0_0_,
            guestbook0_.email as email0_0_,
            guestbook0_.phone as phone0_0_,
            guestbook0_.title as title0_0_,
            guestbook0_.content as content0_0_,
            guestbook0_.created_time as created8_0_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 3name:  Hongten
    Hibernate:
        select
            guestbook0_.id as id0_0_,
            guestbook0_.version as version0_0_,
            guestbook0_.name as name0_0_,
            guestbook0_.email as email0_0_,
            guestbook0_.phone as phone0_0_,
            guestbook0_.title as title0_0_,
            guestbook0_.content as content0_0_,
            guestbook0_.created_time as created8_0_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 4name:  HOngten
    Hibernate:
        select
            guestbook0_.id as id0_0_,
            guestbook0_.version as version0_0_,
            guestbook0_.name as name0_0_,
            guestbook0_.email as email0_0_,
            guestbook0_.phone as phone0_0_,
            guestbook0_.title as title0_0_,
            guestbook0_.content as content0_0_,
            guestbook0_.created_time as created8_0_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 5name:  HOngten
    Hibernate:
        select
            guestbook0_.id as id0_0_,
            guestbook0_.version as version0_0_,
            guestbook0_.name as name0_0_,
            guestbook0_.email as email0_0_,
            guestbook0_.phone as phone0_0_,
            guestbook0_.title as title0_0_,
            guestbook0_.content as content0_0_,
            guestbook0_.created_time as created8_0_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 6name:  HOngten
    Hibernate:
        select
            guestbook0_.id as id0_0_,
            guestbook0_.version as version0_0_,
            guestbook0_.name as name0_0_,
            guestbook0_.email as email0_0_,
            guestbook0_.phone as phone0_0_,
            guestbook0_.title as title0_0_,
            guestbook0_.content as content0_0_,
            guestbook0_.created_time as created8_0_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 7name:  HOngten

    这就是“n+1”或者说“1+n”方式,也就是说,我们要查询的结果只有7条记录,但是,我们看到 的selelctyuj

    却是8条。首先从缓存中去找,没有找到,就向数据库发出请求,查询出数据。然后执行id=2的Guestbook对象,

    缓存中没有记录,有要向数据库发出请求,以这种方式进行下去。

    要注意 的是:如果二级缓存中没有任何对象或者说是数据,那么这时如果我们采用Iterator方法,就会用到“n+1”

    条selelct语句,这时还不如list的查询效率高。所以我们要用Iterator的时候的前提是二级缓存中要有数据,这样

    的查询效率要才会高。不然会出现相反的效果。

    测试代码四;

    HibernateTest.java

    代码:

    /**
     *
     */
    package com.b510.examplex;

    import java.util.List;

    import java.util.Iterator;

    import org.hibernate.Query;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;


    /**
     *
     * @author XHW
     *
     * @date 2011-7-15
     *
     */
    public class HibernateTest {

     /**
      * @param args
      */
     public static void main(String[] args) {
      new HibernateTest().getGuestbooks();
     }

     public void getGuestbooks(){
      SessionFactory sessionFactory1=new Configuration().configure().buildSessionFactory();
      
      Session session1=sessionFactory1.getCurrentSession();
      Transaction tx1=session1.beginTransaction();
      Guestbook gb=(Guestbook)session1.get(Guestbook.class, 1);
      System.out.println("ID : "+gb.getId()+"name:  "+gb.getName());
      System.out.println(sessionFactory1);
      sessionFactory1.close();
      
      System.out.println("----------------------------------");
      
      SessionFactory sessionFactory2=new Configuration().configure().buildSessionFactory();
      Session session2=sessionFactory2.getCurrentSession();
      Transaction tx2=session2.beginTransaction();
      Guestbook gb2=(Guestbook)session2.get(Guestbook.class, 1);
      System.out.println("ID : "+gb2.getId()+"name:  "+gb2.getName());
      System.out.println(sessionFactory2);
      sessionFactory2.close();
     } 
    }

    运行效果:

    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
    log4j:WARN Please initialize the log4j system properly.
    Hibernate:
        select
            guestbook0_.id as id0_0_,
            guestbook0_.version as version0_0_,
            guestbook0_.name as name0_0_,
            guestbook0_.email as email0_0_,
            guestbook0_.phone as phone0_0_,
            guestbook0_.title as title0_0_,
            guestbook0_.content as content0_0_,
            guestbook0_.created_time as created8_0_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 1name:  liuwei
    org.hibernate.impl.SessionFactoryImpl@1fcc0a2
    ----------------------------------
    Hibernate:
        select
            guestbook0_.id as id2_0_,
            guestbook0_.version as version2_0_,
            guestbook0_.name as name2_0_,
            guestbook0_.email as email2_0_,
            guestbook0_.phone as phone2_0_,
            guestbook0_.title as title2_0_,
            guestbook0_.content as content2_0_,
            guestbook0_.created_time as created8_2_0_
        from
            users.guestbook guestbook0_
        where
            guestbook0_.id=?
    ID : 1name:  liuwei
    org.hibernate.impl.SessionFactoryImpl@19b46dc

    Hibernate的二级缓存是跟SessionFactory相关的,所以当一个SessionFactory对象关闭后,二级缓存中的

    数据就会跟着这个SessionFactory对象的关闭而随之消失,当我们启动第二个SessionFactory对象的时候,这个

    这个对象的二级缓存生效。当然当这个SessionFactory对象关闭的时候,二级缓存中的数据也会消失。

    因此,我们就会看到两个select语句。

    所以:Hibernate的二级缓存又被叫做SessionFactory缓存

  • 相关阅读:
    鸡哥的限币令(有上下限的网络流/费用流问题)
    AtCoder Regular Contest 128 部分题题解
    一道题
    2021CCPC河南省赛
    10.26训练赛
    博弈论和SG函数
    10.24训练赛
    10.22训练赛
    CF #749
    atcoder ABC233
  • 原文地址:https://www.cnblogs.com/hongten/p/2108855.html
Copyright © 2011-2022 走看看