hibernate缓存机制及配置

一 简介

在hibernate框架中,使用缓存来减少对数据库的访问,以此来提高响应速度。hibernate中提供了三种缓存可供使用,分别是一级缓存、二级缓存、查询缓存

其中一级缓存是session级别的缓存,缓存周期即为session的寿命。同一个session进行的对象查询,无论是诸如session.get(Class arg0, Seralizable arg1)这样通过session直接调用的方法,还是该session下的query发起的hql查询,包括list查询,被取出的对象或对象集合都会被存在该session下的一级缓存中,以map<key, value>形式存储,key为主键,value为对象。因为key值是主键,所以只有使用主键查询的方法才可以使用该一级缓存,也就是只有三个方法可以使用

session.get(Class arg0, Seralizable arg1);
session.load(Class arg0, Seralizable arg1);
query.iterate();

*注意* query.iterate()与list()方法不同的是,调用时会发出一条sql语句,只查询主键值,并不查询整个对象。在遍历时,会根据主键值先去一级缓存中查找是否有匹配的,若匹配,返回该缓 存,不匹配,则去数据库中进行查询,但此时查询是单独发出一条sql语句,只查询一个对象,查询主键匹配的数据。这意味着,若此时一级缓存没有一条匹配,则整个遍历过程会发出 N + 1 条sql语句,而在最好的情况下则只产生一条查询ID列的sql语句

因为所有查询都放入了一级缓存,大数据量查找可能导致内存溢出,hibernate提供了以下两种方法对一级缓存进行清除

session.clear();
session.evict(arg0);

二级缓存是sessionFactory级别的缓存,缓存周期即为sessionFactory的寿命。二级缓存在使用上类似于一级缓存,只是作用范围不再局限于同一个session,并且需先指定使用的类才可以使用二级缓存。

查询缓存对所有hql发出的查询都有效,前提是必须先设置才能使用,设置方法在下文。设置完后,同样的hql查询就不会在去数据库进行查询。

二 配置及使用测试

以下例程定义了一个简单的POJO类:Position.java,使用JUnit,hibernate版本为hibernate4.14final

1 一级缓存,一级缓存不用进行任何设置,hibernate原生支持:

/**
	 * 一级缓存测试,session级别,同一session下只查询一次,此处只发出一条sql语句
	 * 不需要设置即可使用
	 */
	@Test
	public void testA(){
		Session session = HibernateUtil.getSession();
		Position pos1 = (Position) session.get(Position.class, 22);
		Position pos2 = (Position) session.get(Position.class, 22);
		System.out.println(pos1);
		System.out.println(pos2);
	}

2 二级缓存

/**
	 * 二级缓存测试,sessionFactory级别,不同session下只查询一次,只输出一条sql语句
	 * 二级缓存需进行相关设置
	 * 1 引入jar包:hibernate-ehcache-4.1.4.Final.jar,ehcache-core-2.4.3.jar
	 * 2 在hibernate.cfg.xml文件中开启二级缓存,并指定二级缓存产品提供商
	 *    <property name="hibernate.cache.user_second_level_cache">true</property>
	 *    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
	 * 3 在hibernate.cfg.xml文件中或者实体类映射文件中指定实体类使用
	 *    <class-cache usage="read-only" class="com.bean.Position"/>
	 *  或者在其映射文件中
	 *    <cache usage="read-only"/>
	 * 4 之前的版本需设置ehcache.xml文件,此处省去,经测试正常
	 */
	@Test
	public void testB(){
		Session session1 = HibernateUtil.getSession();
		Session session2 = HibernateUtil.getSession();
		Position pos1 = (Position) session1.get(Position.class, 1);
		Position pos2 = (Position) session2.get(Position.class, 1);
		System.out.println(pos1);
		System.out.println(pos2);
	}

3 查询缓存

/**
	 * 查询缓存测试
	 * 1 使用前需开启二级缓存
	 * 2 在hibernate.cfg.xml文件中开启查询缓存
	 *    <property name="hibernate.cache.use_query_cache">true</property>
	 * 3 在query在query.setCacheable(true),即使用查询缓存
	 * 4 这样相同的hql语句就不会再去数据库查询
	 */
	@Test
	public void testC(){
		Session session = HibernateUtil.getSession();
		String hql = "from Position";
		List<Position> list1 = session.createQuery(hql).setCacheable(true).list();
		List<Position> list2 = session.createQuery(hql).setCacheable(true).list();
		System.out.println(list1);
		System.out.println(list2);
	}

4 iterator测试

/**
	 * 因为list()查询完后结果保存在缓存了,此处在list()后只有一条sql语句
	 */
        @Test
	public void testD(){
		Session session = HibernateUtil.getSession();
		String hql = "from Position";
		List<Position> list = session.createQuery(hql).list();
		System.out.println(list);
		Iterator<Position> iterator = session.createQuery(hql).iterate();
		System.out.println("--- iterator ");
		while(iterator.hasNext()){
			System.out.println("Iterator " + iterator.next());
		}
	}


转载于:https://my.oschina.net/idaren/blog/622443

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值