Hibernate总结(六)--Hibernate二级缓存

转载:http://blog.csdn.net/wjw0130/article/details/47450863

首先感谢博主,参考博主自己写的测试代码

我们知道hibernate的一级缓存是将数据缓存到了session中从而减少与数据库的交互。那么二级缓存呢?

一、应用场合

比如,在12306购票时,需要选择出发地与目的地,如果每点一次都与数据库交互一次,这就很不合适,这些地点数据在相当长的一段时间内是不会发生变化的(山东省在相当长的时间内还叫山东省),所以应该缓存起来,没必要每次都与数据库交互,而且该类数据安全性也不是很高。

适合二级缓存的数据:

在现代软件开发中,确实存在一类数据没有什么私有性,为公开的数据,数据基本上不发生变化,该数据保密性不是很强,但又会经常被用到(比如火车票上的出发地与目的地数据)。

注意:如果一个数据一直在改变,不适合用缓存。

流式数据:数据时时刻刻在变的数据,比如手机应用获取手机所在地,后台的推送系统,发出一些信息,比如短信会提示你某天夜间流量超过多少,建议购买夜间流量。而这类数据适合使用strom来处理 。

二、生命周期

二级缓存为sessionFactory级别的缓存,其生命周期和sessionFactory是一致的,Hibernate启动后就有了.

二级缓存在Hibernate中的位置


所以Hibernate内部并没有实现二级缓存,而是应用第三方插件来实现二级缓存的。

三、二级缓存的设置

利用的是ehcache实现的二级缓存

1.添加ehcache所需的jar包

2.在hibernate的配置文件中进行配置


四、二级缓存的操作

哪些方法可以把对象放入到二级缓存中?

get方法,list方法可以把一个或者一些对象放入到二级缓存中

哪些方法可以把对象从二级缓存中提取出来?

get方法,iterator方法可以提取

注意:用的时候一定要小心使用各方法,取数据时,如果把list用成iterate会造成效率的及其降低

五、二级缓存的存储策略


read-only:对象只要加载到二级缓存以后,就只能读取,不能修改。

read-write:对二级缓存中的对象能够进行读和写的操作

注意:一般都设置为read-only

缓存得到磁盘

如果一个系统的权限特别大,这就不适合长时间的放入到二级缓存中,会导致占用内存逐渐变大,查询效率逐渐降低,这种情况可以二级缓存移到磁盘上,但是在现代开发如果需要缓存较多,一般都是使用分布式缓存。


测试:

	
//首先配置二级缓存 按上述步骤

        /**
	 * session.get方法不仅要把数据放入到一级缓存,而且要放入到二级缓存
	 *   该方法在提取数据的时候,先从一缓存中查找,再从二级缓存中查找,如果找不到,则查询数据库
	 */
	@Test
	public void testGet(){
		Session session = sessionFactory.openSession();
		Classes classes = (Classes)session.get(Classes.class, 1L);
		System.out.println(sessionFactory.getStatistics()
				.getEntityLoadCount());
		session.close();
	}
	
	/**
	 * session.save方法不操作二级缓存
	 */
	@Test
	public void testSave(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Classes classes = new Classes();
		classes.setName("a");
		session.save(classes);
		System.out.println(sessionFactory.getStatistics()
				.getEntityLoadCount());  //输出0
		transaction.commit();
		session.close();
	}
	
	/**
	 * session.update不操作二级缓存
	 */
	@Test
	public void testUpdate(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Classes classes = new Classes();
		classes.setCid(3L);
		classes.setName("afds");
		session.update(classes);
		System.out.println(sessionFactory.getStatistics().getEntityInsertCount());
		transaction.commit();
		session.close();
	}
	
	/**
	 * 利用查询让对象进入到二级缓存中
	 */
	@Test
	public void testQuery() throws Exception{
		/**
		 * list方法可以让hql语句指定的对象进入了二级缓存中,但是list方法不利用二级缓存查询数据
		 */
		Session session = sessionFactory.openSession();
		List<Classes> classes = session.createQuery("from Classes").list(); //hql:hibernate query language
		System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
		session.close();
		
		Thread.sleep(1000L);
		
		/**
		 * iterate方法的查询策略:
		 *    1、先查找该表中所有的id的值
		 *    2、再根据id值从二级缓存中查找对象,如果有,则利用二级缓存,如果没有则根据id查询该表中的所有的属性的值
		 */
		session = sessionFactory.openSession();
		Iterator<Classes> iterator = session.createQuery("from Classes").iterate();
		while(iterator.hasNext()){
			Classes classes2 = iterator.next();
			System.out.println(classes2.getName());
		}
		session.close();
	}
	
	/**
	 * 集合的二级缓存
	 */
	@Test
	public void testCollection_SecondLevel(){
		Session session = sessionFactory.openSession();
		Classes classes = (Classes)session.get(Classes.class, 1L);
		Set<Student> students = classes.getStudents();
		for (Student student : students) {
			System.out.println(student.getName());
		}
		//输出的值为1,说明有一个集合进入了二级缓存中
		System.out.println(sessionFactory.getStatistics().getCollectionLoadCount());
		session.close();
	}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值