博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hibernate 缓存机制
阅读量:4290 次
发布时间:2019-05-27

本文共 23443 字,大约阅读时间需要 78 分钟。

hibernate缓存机制是hibernate中很重要的一个内容,因为有缓存的存在,使得效率得到了很大的提升,今天这个博客,我们就来学习一个hibernate中各种查询方式对应的缓存。

缓存分为:一级缓存、二级缓存、查询缓存。

1、一级缓存:

        又称为session缓存,生命周期相同,周期较短。也称为事务级别的缓存。

下面就用项目来演示一下,缓存问题,新建一个java项目,结构如下:

实体类Book代码:

package com.myeclipse.pojo;import java.util.Date;public class Book {		private int id;	private String author;	private String name;	private double price;	private Date pubDate;		public int getId() {		return id;	}	public void setId(int id) {		this.id = id;	}	public String getAuthor() {		return author;	}	public void setAuthor(String author) {		this.author = author;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public double getPrice() {		return price;	}	public void setPrice(double price) {		this.price = price;	}	public Date getPubDate() {		return pubDate;	}	public void setPubDate(Date pubDate) {		this.pubDate = pubDate;	}	@Override	public String toString() {		return "Book [id=" + id + ", author=" + author + ", name=" + name				+ ", price=" + price + ", pubDate=" + pubDate + "]";	}		}

Book.hbm.xml代码:

HibernateUtil代码:

package com.robert.util;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.cfg.Configuration;/** * hibernate工具类 */public class HibernateUtil {	private static Configuration cfg = null;	private static SessionFactory factory = null;	private static Session session = null ;		static {		init();	}	/**	 * 初始化获得Configuration和SessionFacroty对象	 */	public static void init() {		cfg = new Configuration().configure();		factory = cfg.buildSessionFactory(new StandardServiceRegistryBuilder()				.applySettings(cfg.getProperties()).build());	}	/**	 * 获得Session对象	 * @return	 */	public static Session getSession() {		if (factory != null){			return session = factory.openSession();		}				init();		return session = factory.openSession();	}		/**	 * 关闭Session	 */	public static void closeSession() {		if(session!=null && session.isOpen())			session.close();	}}

hibernate.cfg.xml代码:

com.mysql.jdbc.Driver
jdbc:mysql:///hibernate4
root
root
org.hibernate.dialect.MySQL5Dialect
true
update

HIbernateTest测试类中,根据实体类配置文件,生成对应的数据库表的方法,

@Test	public void testCreateDB() {		Configuration cfg = new Configuration().configure();		SchemaExport se = new SchemaExport(cfg);		// 第一个参数:是否生成ddl脚本		// 第二个参数:是否执行到数据库中		se.create(true, true);	}

保存数据的方法testSave(),代码:

/**	 * 保存数据	 */	@Test	public void testSave() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		Book book = new Book();		book.setName("读者");		book.setPrice(5.6);		book.setAuthor("众人");		book.setPubDate(new Date());		Book book1 = new Book();		book1.setName("傲慢与偏见");		book1.setPrice(80.0);		book1.setAuthor("简.奥斯汀");		book1.setPubDate(new Date());		Book book2 = new Book();		book2.setName("中国历史");		book2.setPrice(30.0);		book2.setAuthor("人民出版社");		book2.setPubDate(new Date());		Book book3 = new Book();		book3.setName("翩眇之旅");		book3.setPrice(70.0);		book3.setAuthor("萧鼎");		book3.setPubDate(new Date());		Book book4 = new Book();		book4.setName("蓝血人");		book4.setPrice(60.0);		book4.setAuthor("卫斯理");		book4.setPubDate(new Date());		Book book5 = new Book();		book5.setName("我的大学");		book5.setPrice(60.5);		book5.setAuthor("高尔基");		book5.setPubDate(new Date());		session.save(book);		session.save(book1);		session.save(book2);		session.save(book3);		session.save(book4);		session.save(book5);		tx.commit();		HibernateUtil.closeSession();	}

接下来就是测试各种查询的缓存问题

1)get方法,

测试代码如下:

/**	 * get方法使用了一级缓存,用get查数据时,首先检查缓存中是否有该数据,	 * 如果有,直接从缓存中获取数据;如果没有,再去数据库查数据,然后将数据放入缓存中	 */	@Test	public void testGet() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		Book book = (Book) session.get(Book.class, 1);		// 发出sql语句,取数据		System.out.println(book.getName());		System.out.println("-----------------------------------------");		book = (Book) session.get(Book.class, 1);		System.out.println(book.getName());		tx.commit();		HibernateUtil.closeSession();	}

控制台打印的sql语句如下:

Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?读者-----------------------------------------读者

由上面可以看出:

get方法使用了一级缓存,用get查数据时,首先检查缓存中是否有该数据,

如果有,直接从缓存中获取数据;如果没有,再去数据库查数据,然后将数据放入缓存中

2)load方法,

测试代码如下:

/**	 * load方法使用了一级缓存,用load查数据时,首先检查缓存中是否有该数据,	 * 如果有,直接从缓存中获取数据;如果没有,再去数据库查数据,然后将数据放入缓存中. load还支持lazy。	 */	@Test	public void testLoad() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		Book book = (Book) session.load(Book.class, 1);		// 发出sql语句,取数据		System.out.println(book.getName());		System.out.println("-----------------------------------------");		book = (Book) session.load(Book.class, 1);		System.out.println(book.getName());		tx.commit();		HibernateUtil.closeSession();	}

控制台打印的sql语句如下:

Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?读者-----------------------------------------读者

总结:

* load方法使用了一级缓存,用load查数据时,首先检查缓存中是否有该数据,

* 如果有,直接从缓存中获取数据;如果没有,再去数据库查数据,然后将数据放入缓存中. load还支持lazy。

3)先get,后load,

测试代码:

/**	 * 先用get,再用load,load同样从一级缓存中查数据,如果有数据,就不去数据库查语句了。	 */	@Test	public void testGetLoad() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		Book book = (Book) session.get(Book.class, 1);		// 发出sql语句,取数据		System.out.println(book.getName());		System.out.println("-----------------------------------------");		book = (Book) session.load(Book.class, 1);		// 如果这里使用了session.close()方法,关闭session,那么session就没有缓存的数据了,就会重新发出sql语句,去数据库查数据。		System.out.println(book.getName());		tx.commit();		HibernateUtil.closeSession();	}

控制台打印的sql语句如下:

Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?读者-----------------------------------------读者

总结:

先用get,再用load,load同样从一级缓存中查数据,如果有数据,就不去数据库查语句了。

4)list方法,

测试代码如下:

/**	 * list 查数据不去缓存中查数据,但是list查出来的 ‘实体对象’ 数据,会放入缓存中。	 */	@Test	public void testList() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		List
list = session.createQuery("from Book").list(); // 发出sql语句,取数据 System.out.println("条数:" + list.size()); System.out.println("-----------------------------------------"); list = session.createQuery("from Book").list(); System.out.println("条数:" + list.size()); tx.commit(); HibernateUtil.closeSession(); }

控制台打印的sql语句如下:

Hibernate:     select        book0_.id as id1_0_,        book0_.author as author2_0_,        book0_.book_name as book_nam3_0_,        book0_.price as price4_0_,        book0_.pubDate as pubDate5_0_     from        t_book book0_条数:6-----------------------------------------Hibernate:     select        book0_.id as id1_0_,        book0_.author as author2_0_,        book0_.book_name as book_nam3_0_,        book0_.price as price4_0_,        book0_.pubDate as pubDate5_0_     from        t_book book0_条数:6
总结:

list 查数据不去缓存中查数据,但是list查出来的 ‘实体对象’ 数据,会放入缓存中。

5)先list,再get,

测试代码:

/**	 * 先用list查,list查出来的 ‘实体对象’ 数据,放入缓存中。 然后用get查,get直接去缓存中查数据。	 */	@Test	public void testListGet() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		List
list = session.createQuery("from Book").list(); // 发出sql语句,取数据 System.out.println("条数:" + list.size()); System.out.println("-----------------------------------------"); Book book = (Book) session.get(Book.class, 2); System.out.println("书名:" + book.getName()); tx.commit(); HibernateUtil.closeSession(); }
控制台打印的sql语句:

Hibernate:     select        book0_.id as id1_0_,        book0_.author as author2_0_,        book0_.book_name as book_nam3_0_,        book0_.price as price4_0_,        book0_.pubDate as pubDate5_0_     from        t_book book0_条数:6-----------------------------------------书名:傲慢与偏见
总结:

先用list查,list查出来的 ‘实体对象’ 数据,放入缓存中。 然后用get查,get直接去缓存中查数据。

6)先list ,后uniqueResult,

测试代码:

@Test	public void testListUniqueResult() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		//这里list查询出来的不是 ‘实体对象’ ,所以这些数据不会存入缓存中		//(备注:list查询出来的,只有当是 ‘实体对象’ 时,才会被存入缓存中)		List
list = session.createQuery("select name from Book").list(); // 发出sql语句,取数据 System.out.println("条数:" + list.size()); System.out.println("-----------------------------------------"); Object bookName = session.createQuery("select name from Book where id =:id ") .setInteger("id", 2).uniqueResult(); //发出sql语句,取数据 System.out.println("书名:"+bookName); tx.commit(); HibernateUtil.closeSession(); }

控制台打印的sql语句如下:

Hibernate:     select        book0_.book_name as col_0_0_     from        t_book book0_条数:6-----------------------------------------Hibernate:     select        book0_.book_name as col_0_0_     from        t_book book0_     where        book0_.id=?书名:傲慢与偏见
总结:

  这里list查询出来的不是 ‘实体对象’ ,所以这些数据不会存入缓存中

(备注:list查询出来的,只有当是 ‘实体对象’ 时,才会被存入缓存中)

7)uniqueResult测试,

代码:

@Test	public void testUnique() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();				Book book = (Book) session.createQuery("from Book where id =:id ")				.setInteger("id", 2).uniqueResult();		//发出sql语句,取数据		System.out.println("书名:"+book.getName());				System.out.println("------------------------------------------");				book = (Book) session.createQuery("from Book where id =:id ")				.setInteger("id", 2).uniqueResult();		//发出sql语句,取数据		System.out.println("书名:"+book.getName());				tx.commit();		HibernateUtil.closeSession();			}

控制台打印的sql语句,如下:

Hibernate:     select        book0_.id as id1_0_,        book0_.author as author2_0_,        book0_.book_name as book_nam3_0_,        book0_.price as price4_0_,        book0_.pubDate as pubDate5_0_     from        t_book book0_     where        book0_.id=?书名:傲慢与偏见------------------------------------------Hibernate:     select        book0_.id as id1_0_,        book0_.author as author2_0_,        book0_.book_name as book_nam3_0_,        book0_.price as price4_0_,        book0_.pubDate as pubDate5_0_     from        t_book book0_     where        book0_.id=?书名:傲慢与偏见

总结:

uniqueResult 不会去缓存中查询数据

8)先uniqueResult,后get,

测试代码:

/**	 * unique 将 ‘实体对象’ 数据放入了 缓存中,get方法从缓存中把实体类对象取出。	 * 但是unique不会去缓存中查数据	 */	@Test	public void testUniqueGet() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();				Book book = (Book) session.createQuery("from Book where id =:id ")				.setInteger("id", 2).uniqueResult();		//发出sql语句,取数据		System.out.println("书名:"+book.getName());				System.out.println("------------------------------------------");				book = (Book) session.get(Book.class, 2) ;		System.out.println("书名:"+book.getName());				tx.commit();		HibernateUtil.closeSession();			}

控制台打印的sql语句如下:

Hibernate:     select        book0_.id as id1_0_,        book0_.author as author2_0_,        book0_.book_name as book_nam3_0_,        book0_.price as price4_0_,        book0_.pubDate as pubDate5_0_     from        t_book book0_     where        book0_.id=?书名:傲慢与偏见------------------------------------------书名:傲慢与偏见
总结:

* unique 将 ‘实体对象’ 数据放入了 缓存中,get方法从缓存中把实体类对象取出。

* 但是unique不会去缓存中查数据

9)先list ,在iterator,

测试代码:

/**	 * iterator使用了缓存	 */	@Test	public void testIterator() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		List
list = session.createQuery("from Book").list(); // 发出sql语句,取数据 System.out.println("条数:" + list.size()); System.out.println("-----------------------------------------"); Iterator
iter = session.createQuery("from Book").iterate(); for(;iter.hasNext();) { Book book = iter.next() ; System.out.println("书名:"+book.getName()); } tx.commit(); HibernateUtil.closeSession(); }
控制台打印的sql语句:

Hibernate:     select        book0_.id as id1_0_,        book0_.author as author2_0_,        book0_.book_name as book_nam3_0_,        book0_.price as price4_0_,        book0_.pubDate as pubDate5_0_     from        t_book book0_条数:6-----------------------------------------Hibernate:     select        book0_.id as col_0_0_     from        t_book book0_书名:读者书名:傲慢与偏见书名:中国历史书名:翩眇之旅书名:蓝血人书名:我的大学

iterator只查询了id,并没有查询实体类,

总结:

iterator使用了缓存

10)查询两次iterator,

测试代码:

/**	 * iterator 查询出来的 ‘实体对象’ 数据会放入缓存中,需要数据时,先到缓存中查询	 */	@Test	public void testIteratorTow() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();				Iterator
iter = session.createQuery("from Book").iterate(); // 发出sql语句,取数据 for(;iter.hasNext();) { Book book = iter.next() ; System.out.println("书名:"+book.getName()); } System.out.println("-----------------------------------------"); iter = session.createQuery("from Book").iterate(); for(;iter.hasNext();) { Book book = iter.next() ; System.out.println("书名:"+book.getName()); } tx.commit(); HibernateUtil.closeSession(); }

控制台打印的sql语句:

Hibernate:     select        book0_.id as col_0_0_     from        t_book book0_Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?书名:读者Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?书名:傲慢与偏见Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?书名:中国历史Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?书名:翩眇之旅Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?书名:蓝血人Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?书名:我的大学-----------------------------------------Hibernate:     select        book0_.id as col_0_0_     from        t_book book0_书名:读者书名:傲慢与偏见书名:中国历史书名:翩眇之旅书名:蓝血人书名:我的大学
总结:

iterator 查询出来的 ‘实体对象’ 数据会放入缓存中,需要数据时,先到缓存中查询

管理一级缓存:

flush:强制将数据存入数据库表中;

clear:关闭session;

evict:将对象从当前的session中清除;

一级缓存很难管理,我们不一定知道,什么时候该flush,clear,evict,如果需要实时性很强的数据,一般不用hibernate。

flush代码:

/**	 * 批量保存数据	 */	@Test	public void testSaveBache() {				Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();				for(int i=0;i<10000;i++) {			Book book = new Book();			book.setName("测试_"+i);			book.setPrice(5.6);			book.setAuthor("作者_"+i);			book.setPubDate(new Date());			if (i%100==0) {				//防止数据量过大,导致session缓存崩溃,强制将数据从session缓存中刷入数据库,清空session中存的数据				session.flush() ;			}			session.save(book);		}		tx.commit();		HibernateUtil.closeSession();			}

evict代码:

@Test	public void testEvict() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		Book book = (Book) session.get(Book.class, 1) ;		//发出sql语句		System.out.println(book.getName());				//将book对象从session缓存中清除		session.evict(book);		System.out.println("----------------------------");				book = (Book) session.get(Book.class, 1) ;		//缓存中没有了book实体对象数据,需要重新发出sql语句查询		System.out.println(book.getName());				tx.commit();		HibernateUtil.closeSession();			}

控制台打印的sql语句

Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?读者----------------------------Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?读者
clear将缓存清空,代码:

@Test	public void testClear() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();				Book book = (Book) session.get(Book.class, 1) ;		//发出sql语句		System.out.println(book.getName());				//清空缓存		session.clear() ;				System.out.println("----------------------------");				book = (Book) session.get(Book.class, 1) ;		//缓存中没有了book实体对象数据,需要重新发出sql语句查询		System.out.println(book.getName());				tx.commit();		HibernateUtil.closeSession();			}
控制台打印的sql语句:

Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?读者----------------------------Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?读者

2、二级缓存

sessionFactory:进程级别的缓存,支持集群。

二级缓存使用个步骤:

1)、先在hibernate.cfg.xml中开启二级缓存(默认是开启)

代码如下:

true
如图:

2)、配置二级缓存提供商cache.provider_class

org.hibernate.cache.EhCacheProvider
来源于下图:

3)、导入ehcache.jar包

找到hibernate文件地址hibernate-release-4.3.11.Final\lib\optional\ehcache,里面有对应的jar包,如图:

将这三个jar包拷贝到项目中,

因为有slf4j-api-1.6.1.jar包,所以需要将slf4j的实现包也导入项目,实现包下载地址《》,

导入后的jar包如下

4)、将ehcache的配置文件放入src下

ehcache配置文件的地址是 hibernate-release-4.3.11.Final\project\etc

如图:

项目中的位置如图:

ehcache.xml中部分属性的含义如图:

5)、在*.hbm.xml或在hibernate.cfg.xml中指定二级缓存策略

  1)该项目中在Book.hbm.xml中增加配置,如图

     2)在hibernate.cfg.xml中指定,如图:

6)、测试

测试代码如下:

/**	 * 二级缓存	 */	@Test	public void testGet_secondCache() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();				Book book = (Book) session.get(Book.class, 1);		// 发出sql语句,取数据		System.out.println(book.getName());		HibernateUtil.closeSession();		System.out.println("-----------------------------------------");		session = HibernateUtil.getSession();		book = (Book) session.get(Book.class, 1);		System.out.println(book.getName());				tx.commit();		HibernateUtil.closeSession();			}
运行junit4报错了,错误如下:

调整hibernate.cfg.xml中的配置顺序,调整之后如图:

再次运行junit4,仍然报错,如下:

去查找文档,文档地址:hibernate-release-4.3.11.Final\documentation\manual\en-US\html

打开index.html,找到The Second Level Cache,如图:

发现文档中的EHCache是这样的:

EHCache org.hibernate.cache.ehcache.EhCacheRegionFactory

而我们在hibernate.cfg.xml中配置的是这样的

org.hibernate.cache.EhCacheProvider

补充:现在配置的这个EHCache是hibernate3中的配置方式,在hibernate4中已经变了。

将这个属性值,重新修改为

org.hibernate.cache.ehcache.EhCacheRegionFactory

同时注意在错误提示中property名称也不是cache.provider_class了,而是错误提示中的,如图:

修改后,如图:

我们重新来看一下测试代码:

/**	 * 二级缓存	 */	@Test	public void testGet_secondCache() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();				Book book = (Book) session.get(Book.class, 1);		// 发出sql语句,取数据		System.out.println(book.getName());		//关闭session		HibernateUtil.closeSession();		System.out.println("-----------------------------------------");		//重新获得session		session = HibernateUtil.getSession();		book = (Book) session.get(Book.class, 1);		System.out.println(book.getName());				tx.commit();		HibernateUtil.closeSession();			}

运行后,控制台打印sql语句如下:

Hibernate:     select        book0_.id as id1_0_0_,        book0_.author as author2_0_0_,        book0_.book_name as book_nam3_0_0_,        book0_.price as price4_0_0_,        book0_.pubDate as pubDate5_0_0_     from        t_book book0_     where        book0_.id=?读者-----------------------------------------读者
虽然我们关闭了session,又重新获得了一个session,但是获取第二个数据时,并没有去数据库查询数据,说明二级缓存起作用了。

3、查询缓存

查询缓存是在二级缓存的基础上设置的,也就是说要使用查询缓存,我们需要先把二级缓存配置好,然后再配置查询缓存。

 1)配置查询缓存

2)编写测试代码:

/**	 * 查询缓存	 */	@Test	public void testQueryCache() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();		//setCacheable(true)表示设置查询缓存		List
list = session.createQuery("from Book ").setCacheable(true).list() ; // 发出sql语句,取数据 System.out.println(list.size()); System.out.println("-----------------------------------------"); //setCacheable(true)表示设置查询缓存 list = session.createQuery("from Book ").setCacheable(true).list() ; // 发出sql语句,取数据 System.out.println(list.size()); tx.commit(); HibernateUtil.closeSession(); }

控制台打印sql语句

Hibernate:     select        book0_.id as id1_0_,        book0_.author as author2_0_,        book0_.book_name as book_nam3_0_,        book0_.price as price4_0_,        book0_.pubDate as pubDate5_0_     from        t_book book0_[net.sf.ehcache.CacheManager@44739f3f] INFO net.sf.ehcache.util.UpdateChecker - New update(s) found: 2.4.7 [http://www.terracotta.org/confluence/display/release/Release+Notes+Ehcache+Core+2.4]. Please check http://ehcache.org for the latest version.10006-----------------------------------------10006
说明查询缓存起作用了。

将session关闭看一下时候仍然可以从二级缓存中使用查询缓存取出数据

测试代码:

/**	 * 测试关闭session的查询缓存	 */	@Test	public void testQueryCacheClose() {		Session session = HibernateUtil.getSession();		Transaction tx = session.beginTransaction();				//setCacheable(true)表示设置查询缓存		List
list = session.createQuery("from Book ").setCacheable(true).list() ; // 发出sql语句,取数据 System.out.println(list.size()); session.close() ; session = HibernateUtil.getSession() ; System.out.println("-----------------------------------------"); //setCacheable(true)表示设置查询缓存 list = session.createQuery("from Book ").setCacheable(true).list() ; // 发出sql语句,取数据 System.out.println(list.size()); tx.commit(); HibernateUtil.closeSession(); }
测试,控制台打印sql语句:

Hibernate:     select        book0_.id as id1_0_,        book0_.author as author2_0_,        book0_.book_name as book_nam3_0_,        book0_.price as price4_0_,        book0_.pubDate as pubDate5_0_     from        t_book book0_[net.sf.ehcache.CacheManager@370a5c21] INFO net.sf.ehcache.util.UpdateChecker - New update(s) found: 2.4.7 [http://www.terracotta.org/confluence/display/release/Release+Notes+Ehcache+Core+2.4]. Please check http://ehcache.org for the latest version.10006-----------------------------------------10006

说明数据确实是存在了二级缓存中,关闭session并不影响查询数据。

你可能感兴趣的文章
epoll 使用详解
查看>>
stl 中 set容器用法
查看>>
有序数组求交集
查看>>
文字常量区与栈
查看>>
非阻塞connect 编写方法
查看>>
epoll 边沿触发
查看>>
String类 默认生成的函数
查看>>
Linux 软连接与硬链接
查看>>
视音频数据处理入门:H.264视频码流解析
查看>>
视音频数据处理入门:AAC音频码流解析
查看>>
视音频数据处理入门:UDP-RTP协议解析
查看>>
视音频数据处理入门:FLV封装格式解析
查看>>
最简单的基于FFMPEG的封装格式转换器(无编解码)
查看>>
base64 编码原理
查看>>
单链表是否有环的问题
查看>>
判断两个链表是否相交并找出交点
查看>>
归并排序
查看>>
STL常见问题
查看>>
time_wait和close_wait状态
查看>>
STL中vector、list、deque和map的区别
查看>>