`
wlh269
  • 浏览: 447970 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

hibernate查询缓存

阅读更多
hibernate查询缓存

查询缓存是缓存普通属性结果集的
对实体对象的结果集只缓存id

查询缓存的生命周期,当关联的表发生修改,那么查询缓存的生命周期结束

查询缓存的配置和使用:
* 在配置文件hibernate.cfg.xml中启用查询缓存,如:
<property name="hibernate.cache.use_query_cache">true</property>
* 在程序中必须手动启用查询缓存,如:
query.setCachable(true);

1、开启查询缓存,关闭二级缓存
在用一个session中执行两次query.list()查询普通属性
   --->没有发出sql,因为启用了查询缓存
2、开启查询缓存,关闭二级缓存
开启两个session,分别中执行query.list()查询普通属性
--->不会发出sql,因为查询缓存的生命周期和session无关
3、开启查询缓存,关闭二级缓存
开启两个session,分别中执行query.iterate()查询普通属性
  --->查询缓存只对query.list()起作用,对query.iterate()不起作用(query.iterate()不使用查询缓存)

4、关闭查询缓存, 关闭二级缓存,
在同一个session中执行两次query.list()查询实体对象
--->再次发出查询语句,在默认情况下list每次发出查询sql
/**
* 关闭二级缓存,关闭查询缓存
*
* 在同一个session中执行两次query.list()查询实体对象
*/
public void testCache4() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			List students = session.createQuery("from Student").list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			System.out.println("------------------------------------------------");
			
			//再次发出查询语句,在默认情况下list每次发出查询sql
			students = session.createQuery("from Student").list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}			
		


5、关闭二级缓存,开启查询缓存
在同一个session中执行两次query.list()查询实体对象
---->不回发出sql,因为是同一个session,实体对象保存到了一级缓存中,
而查询缓存中保存的是实体对象的id列表,所以第二次查询会根据id列表
到缓存中取得数据
/**
* 关闭二级缓存,开启查询缓存
*
* 在同一个session中执行两次query.list()查询实体对象
*/
public void testCache5() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			List students = session.createQuery("from Student")
								   .setCacheable(true)
								   .list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			System.out.println("------------------------------------------------");	
		
			//不回发出sql,因为是同一个session,实体对象保存到了一级缓存中,
			//而查询缓存中保存的是实体对象的id列表,所以第二次查询会根据id列表
			//到缓存中取得数据
			students = session.createQuery("from Student")
							  .setCacheable(true)
							  .list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}	


6、关闭二级缓存,关闭查询缓存
开启两个session中执行query.list()查询实体对象
--->会发出sql,因为关闭了查询缓存和二级缓存
7、关闭二级缓存,开启查询缓存----出现n问题,不是n+1问题
开启两个session中执行query.list()查询实体对象
--->会发出查询sql,二级缓存关闭了,查询缓存缓存的是实体对象的id列表,此次查询会根据id列表到缓存中获取数据,但是二级缓存缓存已经被关闭,缓存中没有数据,所以会根据id发出n条sql到数据中去查询
/**
* 关闭二级缓存,开启查询缓存
* 开启两个session中执行query.list()查询实体对象
*/
public void testCache7() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			List students = session.createQuery("from Student")
								   .setCacheable(true)
								   .list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			System.out.println("------------------------------------------------");
			
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
		
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
//会发出查询sql,二级缓存关闭了,查询缓存缓存的是实体对象的id列表,此次查询根据id列表
到缓存中获取数据,但是二级缓存缓存已经被关闭,所以会根据id发出n条sql到数据中去查询
			//
			//select student0_.id as id1_0_, student0_.name as name1_0_, 
			//student0_.classesid as classesid1_0_ 
			//from t_student student0_ where student0_.id=?
			List students = session.createQuery("from Student")
								   .setCacheable(true)
								   .list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
		
	}				


8、开启二级缓存,开启查询缓存
开启两个session中执行query.list()查询实体对象
   --->不会发出sql,因为开启二级缓存和查询缓存,查询缓存缓存的是实体对象的id列表
hibernate会根据id列表到缓存中获取数据,只有在缓存不存在的数据,才会发出sql到数据库中查询
 
/**
* 开启二级缓存,开启查询缓存
*
* 开启两个session中执行query.list()查询实体对象
*/
public void testCache8() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			List students = session.createQuery("from Student")
								   .setCacheable(true)
								   .list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			System.out.println("------------------------------------------------");
			
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
		
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			//不会发出sql,因为开启二级缓存和查询缓存,查询缓存缓存的是实体对象的id列表
			//hibernate会根据id列表到缓存中获取数据,只有在缓存不存在的数据,才会发出sql到数据库中查询
			List students = session.createQuery("from Student")
								   .setCacheable(true)
								   .list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
		
	}						
	
分享到:
评论
2 楼 浪客剑心 2011-08-23  
谢谢啦,总结得很详细。
1 楼 rothmada 2011-03-15  
收获很大

相关推荐

Global site tag (gtag.js) - Google Analytics