Hibernate缓存学习笔记

第一次写文章,写得不好或不对的地方,请大家指出

一级缓存(在同一个Session中,缓存实体对象,生命周期与Session一致)
	查询实体
		1.执行两次load,get,第二次会从缓存里取
		2.执行两次iterate
			HQL:from Student s where s.id=1
			第一次:
				首先:select student_id from t_student where student_id=1;查询出ID列表
				然后:select * from t_student where student_id=1;根据ID查询实体
			第二次:
				select student_id from t_student where student_id=1;查询出ID列表
				不会发出SQL,因为缓存里有。
		3.先save,后load或get,不会发SQL,因为save后,它会往缓存里放一份
		
	查询普通属性
		1.执行两次iterate
			HQL:select s.name from Student s where s.id=1;
			第一次:select name from t_student where id=1;没有放入缓存
			第二次:select name from t_student where id=1;
	缓存管理
		一级缓存是无法取消,但可以管理(session.evict(object),session.clear())
		Hibernate导入数据:因为save方法,每执行一次就会往缓存里让一份,所以可以每隔小量数据,
		先session.flush(),然后session.clear(),避免内存溢出。
		如果数据量特别大,可以采用jdbc,如果jdbc也不能满足要求,可采用数据库的专门导入工具
		
二级缓存(进程级缓存,缓存实体对象,生命周期与SessionFactory一致)
	配置:1.首先到Hibernate根目录下的etc下的ehcache.xml拷贝到classpath可以搜索到的地方
		  它有个默认配置选项
		  <defaultCache
			maxElementsInMemory="10000"		//内存中可以存一万个对象
			eternal="false"					//这些对象在内存中不是永久有效的,与下面两个属性是互斥的
			timeToIdleSeconds="120"			//空闲的时间
			timeToLiveSeconds="120"			//缓存对象生命是多长(120秒)
			overflowToDisk="true"			//超过10000个对象时,是否要保存到磁盘上.保存路径为如下
			/>
			<diskStore path="java.io.tmpdir"/>  这表示操作系统的临时路径,
			在WINDOWS上为C:\WINDOWS\temp\
		  2.在Hibernate.cfg.xml中开启二级缓存将hibernate.cache.use_second_level_cache设置为true
		  3.指定缓存产品提供商
		  将hibernate.cache.provider_class设置为 org.hibernate.cache.OSCacheProvider
		  4.在映射文件中指定缓存策略
			<cache usage="read-only"/>
			也可以在配置文件中指定<class-cache class="com.shadow.Student" usage="read-only"/>
			我个喜欢配置在配置文件中,这样查看比较方便(read-only效率最高,read-write也可以)
	查询实体
		1.在两个不同的Session中,get,load,都会使用二级缓存
	一级缓存与二级缓存的交互
		session.setCacheMode(CacheMode.GET | CacheMode.PUT | Cache.NORMAL)
		
查询缓存(只有query.list()使用查询缓存,query.list()也只使用查询缓存)
	缓存普通属性结果集,对实体对象的结果集只缓存ID,如果当前关联的表发生的修改,那么查询缓存生命周期结束
	配置:启用查询缓存	将hibernate.cache.use_query_cache设置为true
		在程序中显式的查询缓存query.setCacheable(true)
		HQL:select s.name from Student s
	一.查询普通属性
		1.在同一个Session中,执行两次query.list();
			1>关闭二级缓存,关闭查询缓存,会发两次SQL
			2>关闭二级缓存,打开查询缓存,第一次会发,第二次不会发
		2.开启两个Session,分别调用query.list();
			关闭二级缓存,打开查询缓存,第一次会发,第二次不会发,查询缓存的生命周期与Session无关
		3.开启两个Session,分别调用query.iterate();
			关闭二级缓存,打开查询缓存,两次都会发,查询缓存对query.iterate()方法无效,即query.iterate()
			不使用查询缓存
	二.查询实体对象
		1.开启两个Session,分别调用query.list();
			HQL:select s from Student s
			1>关闭二级缓存,关闭查询缓存,会发两次SQL
			2>关闭二级缓存,开启查询缓存,第一次会发一条SQL:select * from t_student
			第二次会发n条SQL,都是根据Id来查询,SQL:select * from t_student where id=?
			因为开启了查询缓存,对于实体对象只会缓存实体Id
			3>开启二级缓存,开启查询缓存,第一次会发,第二次不会发
		2.在同一个Session中,执行两次query.list();
			1>关闭二级缓存,关闭查询缓存,会发两次SQL,因为query.list()只存不取

 

 

 

你可能感兴趣的:(sql,Hibernate,cache,jdbc,配置管理)