前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hibernate的二级缓存 下

Hibernate的二级缓存 下

作者头像
Hongten
发布2018-09-18 10:02:08
3390
发布2018-09-18 10:02:08
举报
文章被收录于专栏:HongtenHongten

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缓存

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-07-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档