11.1 Hibernate_二级缓存(2)

查询缓存

对于经常实用的查询语句,如果启用了查询缓存,当第一次执行查询语句时,Hibernate会把查询结果存放在查询缓存中,以后再次执行该查询语句时,只需从缓存中获得查询结果,从而提高查询性能

查询缓存使用如下场合:
  • 应用程序运行时经常使用查询语句
  • 很少对与查询语句检索到的数据进行插入,删除和更新操作
启用查询缓存的步骤
  1. 配置二级缓存,因为查询缓存依赖于二级缓存
  2. 在hibernate配置文件中启用查询缓存:<property name="cache.use_query_cache">true</property>
  3. 对于希望启用查询缓存的查询语句,调用Query的setCacheable()方法
<!--
查询缓存:默认情况下,设置的缓存对HQL 及 QBC 查询是无效的,但可以通过以下方式使其是有效地
第一步:在hibernate 配置文件中声明开启查询缓存
<property name="cache.use_query_cache">true</property>
第二步:调用Query或Criteria 的setCacheable(true)方法
第三步:配置二级缓存(查询缓依赖二级缓存)
-- >

@Test
public void testQueryCache(){
	Query query =session.createQuery("FROM Employee");
	query.setCacheable(true);
		
	List<Employee> emps=query.list();
	System.out.println(emps.size());
	
	Criteria criteria= session.queryCriteria(Employee.class);
	criteria.setCacheable(true);
}

时间戳缓存区域

时间戳缓存区域存放了对于查询结果相关的表进行插入,更新或删除操作的时间戳。hibernate通过时间戳缓存区域来判断被缓存的查询结果是否过期,其运行过程如下:
  • T1时刻执行查询操作,把查询结果存放在QueryCache区域,记录该区域的时间为T1
  • T2时刻对查询结果相关的表进行更新操作,Hibernate把T2时刻存放在UpdateTimestampCache区域
  • T3时刻执行查询结果前,先比较QueryCache区域的时间戳和UpdateTimestampCache区域的时间戳,若T2>T1,那么就丢弃原先存放在QueryCache区域的查询结果,重新到数据库中查询数据,再把结果存方法到QueryCache区域;若T2 < T1,直接从QueryCache中获得查询结果
@Test
public void testTimestampCache(){
	Query query =session.creatQuery("FROM Employess");
		
	List<Employee> emps=query.list();
	System.out.println(emps.size());

	Employee employee=(Employee) session.get(Employee.class,100);
	employee.setSalary(30000);

	emps=query.list();
	System.out.println(emps.size());
}

//打印结果:会打印select语句,update语句,select语句三条sql语句

Query接口的iterator()方法

Query接口的iterator()方法
  • 同list()一样也能执行查询操作
  • list()方法执行的SQL语句包含实体类对应的数据表的所有字段
  • iterator()方法执行的SQL语句中仅包含实体类对应的数据表的ID字段
  • 当遍历访问结果集时,该方法先到Session缓存及二级缓存中查看是否存在特定OID的对象,如果存在,就直接返回该对象,如果不存在该对象就通过相应的SQL Select语句到数据库中加载特定的实体对象
大多数情况下,应考虑使用list()方法执行查询操作
iterator()方法仅在满足以下条件的场合,可以 稍微提高查询性能
  • 要查询的数据表中包含大量字段
  • 启用二级缓存,且二级缓存中可能包含了待查询的对象
@Test
public void testQueryIterator(){
	Department dept=(Department) session.get(Department.class,80);
	System.out.println(dept.getName());
	System.out.println(dept.getEmps().size());
	
	Query query =session.createQuery("FROM Employee e WHERE e.dept.id=80");
//	List<Employee> emps=query.list();
//	System.out.println(emps.size());

	Iterator<Employee> emp2=query.iterate();
	while(emp2.hasNext()){
		System.out.println(emp2.next().getName());
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值