Hibernate二级缓存机制-类级别的get()、load()、query.list()

类级别的二级缓存只适用于getload获取数据,对query接口可以将数据放置到类级别的二级缓存中(前提是对应的类设置了二级缓存),但是不能使用query接口的list方法从缓存中获取数据;

前提:session不是线程安全,并未绑定在ThreadLocal中。Dept已经配置了二级缓存

	@Test
	public void test2(){
		Query query = session.createQuery("from Dept where deptno = 10");
		query.list();
		transaction.commit();
		session.close();
		
		session = HibernateUtils.openSession();
		transaction = session.beginTransaction();
		List list = query.list();
		System.out.println(list);
		
	}

结果会报错:org.hibernate.SessionException: Session is closed!

	@Test
	public void test2(){
		Query query = session.createQuery("from Dept where deptno = 10");
		query.list();
		transaction.commit();
		session.close();
		
		session = HibernateUtils.openSession();
		transaction = session.beginTransaction();
		Dept dept = (Dept) session.get(Dept.class, 10);
		System.out.println(dept);
	}

结果:
Hibernate:
    select
        dept0_.DEPTNO as DEPTNO1_0_,
        dept0_.DNAME as DNAME2_0_,
        dept0_.LOC as LOC3_0_
    from
        DEPT dept0_
    where
        dept0_.DEPTNO=10
Dept [deptno=10, dname=ACCOUNTING, loc=NEW YORK]

没有报错,只发出一条sql语句。说明get()、load()方法可以获取二级缓存中的数据,但是query.list()不可以,而因为Dept设置了二级缓存,所以数据可以放到二级缓存中。


关于query.list()返回的List集合,从笔者的测试结果中作出以下推测:

在使用默认设置的情况下,每次调用query.list()都会发出sql语句去查询数据库中的记录而不会检查缓存中是否有相应的记录。如果设置了查询缓存,query.list()就可以查询缓存中的记录,没有结果才去查询数据库中的记录。虽然可以查询缓存,但是也只能查询session中的缓存,即只能查询一级缓存。

	@Test
	public void testQueryCache(){
		Query query = session.createQuery("from Dept");
		query.setCacheable(true);
		List list = query.list();
		System.out.println(list.size());
		transaction.commit();
		session.close();
		
		session = HibernateUtils.openSession();
		transaction = session.beginTransaction();
		Dept dept2  = (Dept) session.get(Dept.class, 10);
		System.out.println(dept2);
		query = session.createQuery("from Dept");
		list = query.list();
		System.out.println(list.size());
	}

得到的结果是:

Hibernate:
    select
        dept0_.DEPTNO as DEPTNO1_0_,
        dept0_.DNAME as DNAME2_0_,
        dept0_.LOC as LOC3_0_
    from
        DEPT dept0_
4
Dept [deptno=10, dname=ACCOUNTING, loc=NEW YORK]
Hibernate:
    select
        dept0_.DEPTNO as DEPTNO1_0_,
        dept0_.DNAME as DNAME2_0_,
        dept0_.LOC as LOC3_0_
    from
        DEPT dept0_
4

由此可以看出,就算二级缓存中有数据,但是只要使用query.list(),都需要先用session来创建Query对象然后再查询一级缓存中的数据,就算二级缓存中有相应的数据也查询不到。



设置查询缓存

在hibernate.cfg.xml文件中添加

<property name="cache.use_query_cache">true</property>

然后在使用query.list()之前设置:

query.setCacheable(true);



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值