本文共 2516 字,大约阅读时间需要 8 分钟。
又称为session缓存,它和session生命周期相同,周期非常短.是事务级别的缓存:
还是以Book和Category这两个表为例,我们用代码观察一个缓存的存在:
假设现在我要去查询id=1的Book信息:
Listlist =(List) session.createQuery("from Book").list(); System.out.println(list.get(0).getName()); Book book = (Book)session.get(Book.class, 1); System.out.println(book.getName());
我这里先查询了所有的Book,打印出了index=0,即id=1的那本书的书名,接着用get方法再次获取了id=1的Book,我们看一下控制台的打印信息:
通过打印信息我们能发现一个现象,当第二次我们使用get(..)方法去查询时,我们如愿得到了书名,但却没有select语句,说明了什么问题?说明了使用get()方法获取id=1的Book时,hibernate并没有去访问数据库,而是在某一个地方就得到了这个id=1的Book的信息,不难发现,我们第一次使用createQuery()时,其实已经得到了这条Book的信息,而hibernate将这些信息放到了一个缓存里,当执行查询语句时,hibernate没有着急的立即访问数据库去查询,而是先到这个缓存里去找找有没有他所要查询的数据,如果有的话,那就皆大欢喜了,不需要访问数据库,提高了效率,而这个缓存.就是我们所说的一级缓存,也叫session缓存.
同时我们也能知道,get方法使用了一级缓存,用get查询数据时,首先检查缓存中是否有该数据,如果有,直接从缓存中获取该数据直接返回,如果没有,再去访问数据库查找.load也支持一级缓存,但是同时load同时也支持延迟加载.要注意.
接下继续测试代码:
Listlist =(List) session.createQuery("from Book").list();System.out.println(list.get(0).getName()); list =(List) session.createQuery("from Book").list(); System.out.println(list.get(0).getName())
在代码中,我们执行了两次session.createQuery(),如果只打印一条sql语句,说明list查询也支持一级缓存,打印结果是这样:
很不幸,控制台打印出了两条sql语句,这就说明了:
list查询不支持一级缓存,但list查询会把返回的结果保存到session缓存,同理uniqueResult()查询也是如此.
接下来继续测试:
Listlist =(List) session.createQuery("from Book").list(); System.out.println(list.get(0).getName()); Iterator iter = session.createQuery("from Book").iterate(); while(iter.hasNext()){ System.out.println(iter.next().getName()); }
这里我们第一次使用list查询得到所有Book信息,然后用iterate查询,得到一个包含所有Book的迭代器集合,那么他会不会支持一级缓存,这是控制台打印的信息:
乍一看,第二次查询的时候依然打出了sql语句,看来iterate查询是不会先去session中查找的了,但是仔细观察第一条sql语句,可以发现,它仅仅查询了Book的id,但依然打印出了每本书的书名.说明了,iterate依然是在缓存中查询的数据,所以,iterate是支持一级缓存的,同样它执行的查询,也会把返回结果保存到session缓存中.
` 现在再来看一下管理session的几个方法.
下面用代码演示一下evict,和clear方法:
Book book =(Book) session.get(Book.class,1); System.out.println(book.getName()); session.evict(book); //b表示干掉session中保存的所有对象,当然也包括Book对象 //session.clear() book =(Book) session.get(Book.class,1); System.out.println(book.getName());
按照我们的设想,由于执行第二次查询之前,我们通过session.evict(book)方法,干掉了book对象,再次查询时会去访问数据库,来看一下控制台打印结果是不是这样的:
果然如此,跟我们料想的一样.
转载地址:http://oqtbx.baihongyu.com/