Hibernate中缓存机制

本文深入探讨Hibernate中的一级缓存和二级缓存机制,包括它们的工作原理、配置方法及应用场景。通过具体示例展示了不同查询方法如何利用缓存提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Session的缓存(一级缓存):
当使用session操作对象(保存或更新),
session会将该对象放到缓存中
当使用非list()方法进行查询,session首先到缓存中
查找,如果没有,则发送查询语句到数据库中查找

SessionFactory的缓存(二级缓存,优先级比一级缓存高):
缓存中数据的生命周期与SessionFactory相同
即使session关闭,数据依然存在缓存中

使用二级缓存:
在hibernate.cfg.xml中配置
* 打开二级缓存的开关
<property name="hibernate.cache.use_second_level_cache">
true
</property>
* 使用的缓存的类
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
选择缓存处理的开发商,依赖第三方技术(OsCache,EhCache)
* 搭建EhCache的环境
拷贝hibernate3.5/project/etc/ehcache.xml到src下
hibernate3.5/lib/optional/ehcache/ehcache-1.5.0.jar

* 配置选择使用二级缓存的对象
<class-cache usage="read-only" class="com.tarena.demo.po.User"/>

具体案例:

package com.tarena.test;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.junit.Test;

import com.tarena.demo.po.User1;
import com.tarena.demo.util.HibernateUtils;



/**
 *测试Session的缓存 
 *
 */
public class TestSessionCache {
	
	/**
	 * get方法会将该对象放到缓存中
	 * session首先到缓存中查找对象,如果没有找到,再到数据库中查找(发送select语句)
	 */
	@Test
	public void test01(){
		Session session = HibernateUtils.getSession();
		User1 user1 = (User1)session.get(User1.class, 6);
		System.out.println(user1.getUserName());
		
		System.out.println("---------------");
		
		User1 user2 = (User1)session.get(User1.class, 6);
		System.out.println(user2.getUserName());
		
		HibernateUtils.close(session);
		
		/**
		 * 运行结果:Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
					李四
					---------------
					李四
		 */
	}
	
	/**
	 * 测试list()
	 * 发送一条SQL语句
	 * 该方法没有到缓存中查找数据的功能
	 */
	@Test
	public void test02(){
		Session session = HibernateUtils.getSession();
		String hql = "from User1";
		Query query = session.createQuery(hql);
		List<User1> list = query.list();
		for (User1 user1 : list) {
			System.out.println(user1.getUserName()+"**"+user1.getUserPassword());
		}
		
		System.out.println("-----------------");
		
		list = query.list();
		for (User1 user1 : list) {
			System.out.println(user1.getUserName()+"**"+user1.getUserPassword());
		}
		
		HibernateUtils.close(session);
		
		/**
 * 运行结果:
 * Hibernate: select user1x0_.uid as uid0_, user1x0_.userName as userName0_, user1x0_.userPassword as userPass3_0_ from t_user user1x0_
诸葛亮**111
诸葛亮**111
诸葛亮**111
张三**123456
李四**123456
李四**123456
李四**123456
李四**123456
李四**123456
李四**123456
张三1**123456
-----------------
Hibernate: select user1x0_.uid as uid0_, user1x0_.userName as userName0_, user1x0_.userPassword as userPass3_0_ from t_user user1x0_
诸葛亮**111
诸葛亮**111
诸葛亮**111
张三**123456
李四**123456
李四**123456
李四**123456
李四**123456
李四**123456
李四**123456
张三1**123456
 */	}
	
	/**
	 * 测试iterate()
	 * 会发出N+1条SQL语句
	 * 首先会发出查询所有记录id的SQL语句
	 * 然后根据id查询所有记录
	 * 
	 * 该方法具备到缓存中查找数据的功能
	 * 首先会发出查询所有记录id的SQL语句
	 * 在缓存找根据id查找对象
	 */
	@Test
	public void test03(){
		Session session = HibernateUtils.getSession();
		String hql = "from User1";
		Query query = session.createQuery(hql);
		Iterator<User1> it = query.iterate();
		while(it.hasNext()){
			User1 user = it.next();
			System.out.println(user.getUserName()+":"+user.getUserPassword());
		}
		session.clear();
		
		System.out.println("----------------");
		
		it = query.iterate();
		while(it.hasNext()){
			User1 user = it.next();
			System.out.println(user.getUserName()+":"+user.getUserPassword());
		}
		HibernateUtils.close(session);
		/**
		 * 运行结果:
		 *  Hibernate: select user1x0_.uid as col_0_0_ from t_user user1x0_
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			诸葛亮:111
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			诸葛亮:111
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			诸葛亮:111
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			张三:123456
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			李四:123456
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			李四:123456
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			李四:123456
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			李四:123456
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			李四:123456
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			李四:123456
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			张三1:123456
			----------------
			Hibernate: select user1x0_.uid as col_0_0_ from t_user user1x0_
			诸葛亮:111
			诸葛亮:111
			诸葛亮:111
			张三:123456
			李四:123456
			李四:123456
			李四:123456
			李四:123456
			李四:123456
			李四:123456
			张三1:123456

		 */
	}
	/**
	 * 测试其他方法对缓存的使用
	 * save()方法,saveOrUpdate方法,update方法,get()方法,load()方法,iterate()方法
	 * 数据量比较庞大的时候不用hibernate,因为save()的时候,会往缓存中放
	 * 缓存可能会出现溢出。
	 */
	@Test
	public void test04(){
		Session session = HibernateUtils.getSession();
		
		for(int i=1;i<=10;i++){
			User1 user = new User1();
			
			user.setUserName("www");
			user.setUserPassword("tarena");
			session.save(user);
			session.beginTransaction().commit();
//			if(i%5 == 0){
//				session.clear();   如果数据太多,可以采取这种方式清除session中的缓存数据
//			}
		}
			
		
		User1 user2 = (User1)session.load(User1.class, 60);//不到数据库中去查询
		System.out.println(user2);
		
		HibernateUtils.close(session);
		/**
		 * 运行结果:
		 *  Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			Hibernate: insert into t_user (userName, userPassword) values (?, ?)
			com.tarena.demo.po.User1@fa39d7
		 * 
		 */
	}
	
	/**
	 * 测试2级缓存
	 */
	@Test
	public void test05(){
		Session session = HibernateUtils.getSession();
		User1 user1 = (User1)session.load(User1.class, 6);
		System.out.println(user1.getUserName());
		HibernateUtils.close(session);
		
		System.out.println("----------");
		session = HibernateUtils.getSession();
		User1 user2 = (User1)session.load(User1.class, 6);
		System.out.println(user1.getUserName());
		HibernateUtils.close(session);
		
		/**
		 * 运行结果:
		 *  Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			李四
			----------
			李四
		 */
		
	}
	/**
	 * 测试懒加载
	 * 使用对象才到数据库查询,不使用,hibernate会返回一个代理对象。
	 * 如果将User1类改为final类,即不可以继承子类。则不会生成代理对象
	 * load  iterate()方法支持懒加载
	 */
	@Test
	public void test06(){
		Session session = HibernateUtils.getSession();
		User1 user1 = (User1)session.load(User1.class, 6);
		System.out.println(user1.getClass().getName());
		System.out.println("-------------------------");
		
		HibernateUtils.close(session);
		/**
		 * 运行结果:
		 * 	com.tarena.demo.po.User1_$$_javassist_0
			-------------------------

		 */
	}
	
	/**
	 * 测试iterate()方法支持懒加载
	 */
	@Test
	public void test07(){
		Session session = HibernateUtils.getSession();
		Iterator<User1> it = session.createQuery("from User1").iterate();
		System.out.println("-------------------------");
		while(it.hasNext()){
			System.out.println(it.next().getUserName());
		}
		System.out.println("-----------以下是list()方法-------------");
		List<User1> users = session.createQuery("from User1").list();
		System.out.println("----------------------------------------");
		HibernateUtils.close(session);
		
		/**
		 * 运行结果:
		 *  Hibernate: select user1x0_.uid as col_0_0_ from t_user user1x0_
			-------------------------
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			诸葛亮
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			诸葛亮
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			诸葛亮
			Hibernate: select user1x0_.uid as uid0_0_, user1x0_.userName as userName0_0_, user1x0_.userPassword as userPass3_0_0_ from t_user user1x0_ where user1x0_.uid=?
			-----------以下是list()方法-------------
			Hibernate: select user1x0_.uid as uid0_, user1x0_.userName as userName0_, user1x0_.userPassword as userPass3_0_ from t_user user1x0_
			----------------------------------------
			
		 */
	}
	
	
	
	
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值