Hibernate的性能分析--懒加载、抓取策略、缓存策略

Hibernate的性能分析:

	影响性能的3个方面:懒加载、抓取策略、缓存策略

	说明:发出的sql语句越少,性能就越高。懒加载是研究什么时候发出SQL语句,抓取策略是研究怎么样发出SQL语句。
	  
懒加载:
	说明:主要研究类、集合、many-to-one在什么时候发出SQL语句并加载数据
	1,类的懒加载
		1,利用session.load方法可以产生代理对象
		2,在session.load方法执行的时候并不发出sql语句
		3,在得到其一般属性的时候发出sql语句
		4,只针对一般属性有效,针对标示符属性(id)是无效的
		5,默认情况就是懒加载
		6,session.load方法返回的是一个代理对象,要求类不能是final的,否则不能生成子类代理,就不能使用懒加载功能了。
		7,数组不能生产代理对象,故数组不能使用懒加载
	2,集合的懒加载(lazy)
		false  		当session.get时,集合就被加载出来了
		true(默认)  在get到集合的时候没有加载,只有在遍历集合的时候才加载
		extra		当对集合做count,min,max,sum等操作时,直接加载出操作结果,做其他操作时与值为true时相同。
	3,单端关联的懒加载(多对一)
		<many-to-one lazy="false/no-proxy/proxy">  no-porxy相当于true(默认)
		根据多的一端加载一的一端,就一个数据,几乎不影响性能,一般默认即可。
	注:当fetch="join" lazy="true" 时,如果不存在子查询,则此时lazy的值不起作用,即在session.get(Classes.class, 1L)时,student也查询出来了。
	
抓取策略:
	
	概念:由一个对象怎么样查询关联对象,怎么样对关联的对象发出SQL语句。
	1,主要研究对set集合的提取
	2,在Classes.hbm.xml文件中:classes和student的一对多关系:<set fetch="join/select/subselect">
		join(左外连接):如果把需求分析翻译sql语句,存在子查询,这个时候用该策略不起作用。	对于n+1问题:发出1条SQL语句
		select(默认):先查询一的一端,再查询多的一端。										对于n+1问题:发出 n+1 条SQL语句
		subselect(子查询):如果需求分析翻译成sql语句存在子查询,这个时候用该策略效率最高。	对于n+1问题:发出2条SQL语句
	注:当fetch="join" lazy="true" 时,如果不存在子查询,则此时lazy的值不起作用,即在session.get(Classes.class, 1L)时,student也查询出来了。

缓存策略:

	查询顺序:一级缓存、二级缓存、数据库

	一级缓存(session缓存):放私有数据
		1,存放在session中,生命周期就是session的生命周期
		2,一级缓存存放的数据都是私有数据:把session存放在threadlocal中,不同的线程是不能访问的,保证了数据的安全性
		3,把数据存放到一级缓存中的方式:利用session.save/update/load/get方法都可以存放在一级缓存中
		4,利用session.get/load方法可以得到一级缓存中的数据
		5,利用session.evict方法可以把一个对象从一级缓存中清空
		6,利用session.clear方法可以把session中的所有的数据清空
		7,利用session.Refresh方法把数据库中的数据同步到缓存中
		8,session.flush
			在session的缓存内部,会去检查所有的持久化对象
			   1,如果一个持久化对象没有ID值,则会发出insert语句
			   2,如果一个持久化对象有ID值,则会去对比,如果一样,则什么都不做,如果不一样,则发出update语句
			   3,检查所有的持久化对象是否有关联对象:检查关联对象的级联操作、检查关联对象的关系操作
			注:session.flush只是发出SQL语句了,并没有清空Session缓存!
		9,操作大量数据时,要防止Session中对象过多而导致内存溢出
			session.flush(); // 先刷出
			session.clear(); // 再清空
		
	二级缓存(sessionFactory缓存):放公有数据
		1,适用场合:
			1)数据不能频繁更新
			2)数据能公开,私密性不是很强
		2,存放在sessionFactory中,生命周期就是sessionFactory的生命周期
		3,hibernate本身并没有提供二级缓存的解决方案,二级缓存的实现是依赖于第三方供应商完成的
			ehcache、oscache、jbosscache、swamchache
		4,把数据存放到二级缓存中的方式:session.get方法和session.load方法都可以把数据同时存放在一级缓存和二级缓存中
		5,使用二级缓存的步骤
			1)在hibernate.cfg.xml中:
				<!-- 开启二级缓存 -->
				<property name="cache.use_second_level_cache">true</property>
				<!-- 二级缓存的提供商 -->
				<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
			2)让某一个对象拥有进入到二级缓存中的权限
				方案一:在hibernate.cfg.xml中
					<class-cache usage="read-only" class="com.jxn.hiberate.domain.Classes"/>
				方案二:在映射文件中
					<cache usage="read-only"/>
			3)使用
				session.get/session.load
		6,查询缓存:
			1,二级缓存是查询缓存的基础
			2,使用查询缓存的步骤
				1)在配置好二级缓存的基础上,在hibernate.cfg.xml文件中添加以下配置:
					<property name="cache.use_query_cache">true</property>
				2)使用
					Query query = session.createQuery("from Classes");
					
					// 允许该query访问查询缓存,classes里所有的数据要往查询缓存中存放了
					query.setCacheable(true);
					
					List<Classer> classerList = query.list();
					
					Query query2 = session.createQuery("from Classes");
					
					//允许该query2访问查询缓存
					query2.setCacheable(true);
					
					classerList = query.list();	
			3,注意:
				只有两次的SQL语句一样时(例如都是"from Classes"),查询缓存才能使用!
	
	

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值