[NHibernate]延迟加载
目录
写在前面
上篇文章介绍了多对多关系的关联查询的sql,HQL,Criteria查询的三种方式。本篇文章将介绍nhibernate中的延迟加载方式,延迟加载按个人理解也可以叫做按需要加载(Loading-on-demand)。
文档与系列文章
[NHibernate]持久化类(Persistent Classes)
[NHibernate]集合类(Collections)映射
[NHibernate]缓存(NHibernate.Caches)
[NHibernate]NHibernate.Tool.hbm2net
[NHibernate]Nhibernate如何映射sqlserver中image字段
[NHibernate]条件查询Criteria Query
延迟加载
延迟加载(Lazy Load)是(也成为懒加载)Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。可以简单理解为,只有在使用的时候,才会发出sql语句进行查询。
延迟加载的有效期是在session打开的情况下,当session关闭后,会报异常。当调用load方法加载对象时,返回代理对象,等到真正用到对象的内容时才发出sql语句。
Hibernate2实现延迟加载有2种方式:1实体对象,2集合。
Hibernate3中又引入了一种新的加载方式:3属性的延迟加载。
一般使用load的方法来实现延迟加载,在实现无限级联动使用延迟加载效率比较好。
——百度百科(java,hibernate)
上面是java中对hibernate的延迟加载的描述,说的比我好多了。
记住三点:1,为了避免无谓的性能开销。2,需要时才真正加载数据。3,使用了代理。
一个例子
一对多关系
默认延迟加载
采用懒加载的方式根据客户id得到客户信息
/// <summary>
/// 采用懒加载的方式根据客户id得到客户信息
/// </summary>
/// <param name="customerID"></param>
/// <returns></returns>
public Customer GetCustomerbyLazyLoad(Guid customerID)
{
//获得ISession实例
ISession session = NHibernateHelper.GetSession();
Customer customer = session.Get<Customer>(customerID);
return customer;
}
测试用代码,如图所示,此时数据已经加载出来了
使用SQL Profile监控生成的sql语句,截图如下
你会发现,此时只生成了查询customer的sql语句,nhibernate默认是使用延迟加载的,在前面的文章中,并没在映射文件中设置节点的lazy属性。
当展开customer的属性Orders时或者调试向下移动的时候,会执行查询,你会看到如下的sql语句
延迟加载并关闭Session
/// <summary>
/// 采用using释放session,懒加载的方式根据客户id得到客户信息
/// </summary>
/// <param name="customerID"></param>
/// <returns></returns>
public Customer GetCustomerbyLazyLoadUsing(Guid customerID)
{
//获得ISession实例
using(ISession session = NHibernateHelper.GetSession())
{
Customer customer = session.Get<Customer>(customerID);
return customer;
}
}
测试,当视图展开customer的orders属性,或者往下执行获得order集合时出错。
延迟加载,需要的时候再去加载,因为此时session已经关闭,没有去查询的通道了,结果是“此路不通”的提示。
多对多关系
默认延迟加载
这里采用多对多关系那篇文章中举的 Order和Product的例子。
/// <summary>
/// 多对多关系,延迟加载订单产品
/// </summary>
/// <returns></returns>
public Order GetOrderByLazyLoad(Guid orderId)
{
try
{
var session = NHibernateHelper.GetSession();
return session.Get<Wolfy.Shop.Domain.Entities.Order>(orderId);
}
catch (Exception)
{
throw;
}
}
进行测试,在查询的时候只有Order表的数据(这个地方,有Order数据的sql,猜测在一对多查询的时候,没有出现查询Customer的sql语句,很有可能是因为缓存的问题造成,因为经常使用Cusomer那条数据进行测试。)
展开Order的属性
当展开Order的属性,回去查询order下的所有的Product,此时生成的sql如下:
延迟加载并关闭Session
/// <summary>
/// 多对多关系,延迟加载订单产品
/// </summary>
/// <returns></returns>
public Order GetOrderByLazyLoadUsing(Guid orderId)
{
//session使用后即释放
using (var session = NHibernateHelper.GetSession())
{ return session.Get<Wolfy.Shop.Domain.Entities.Order>(orderId); }
}
测试
此时生成的sql语句
如果此时展开Products,同样会出现上面的异常
通过上面的比较一对多和多对多的默认延迟加载和关闭session后的情况类似。
N+1次select查询问题
如果Order下有很多个Product,而我们就想需要的时候才去加载其中某些Product的信息,如果采用立即加载的方式,势必产生多个sql语句,例如第一次查询得到所有的Order对象,然后根据orderid去查询得到所有的产品。
测试,多对多延迟加载订单和订单下单价大于6666的产品
protected void btnMany2Many_Click(object sender, EventArgs e)
{
Business.OrderBusiness orderBusiness = new Business.OrderBusiness();
Order order = orderBusiness.GetOrderByLazyLoad(new Guid("78A53F67-A293-48A1-BBE2-86FED77342FA"));
decimal sum = ;
foreach (var item in order.Products)
{
if (item.Price >= )
{
sum += item.Price;
}
}
Response.Write(sum.ToString());
}
生成的sql语句
延迟加载,可以解决select N+1的问题,比如你查询一个订单还有订单下的Product,势必会产生多条sql语句,先是查询order的sql语句,然后是查询product的sql语句,就会频繁的查询数据库,造成性能方面的压力,而采用延迟加载,通过上面生成的sql语句你会发现,使用left out join 将关联的表拼接起来,只生成了一条sql。
总结
本篇文章介绍了Nhibernate在延迟加载方面的内容,Nhibernate在使用过程中延迟加载方式是默认的。对延迟加载的定义,需要再慢慢的体会。
延迟加载(Lazy Load)是(也成为懒加载)Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。可以简单理解为,只有在使用的时候,才会发出sql语句进行查询。
延迟加载的有效期是在session打开的情况下,当session关闭后,会报异常。当调用load方法加载对象时,返回代理对象,等到真正用到对象的内容时才发出sql语句。
Hibernate2实现延迟加载有2种方式:1实体对象,2集合。
Hibernate3中又引入了一种新的加载方式:3属性的延迟加载。
一般使用load的方法来实现延迟加载,在实现无限级联动使用延迟加载效率比较好。
——百度百科(java,hibernate)
[NHibernate]延迟加载的更多相关文章
- NHibernate 延迟加载与立即加载 (第七篇)
NHibernate 延迟加载与立即加载 (第七篇) 一.延迟加载 延迟加载可以理解为:当需要用的时候才加载. 假设我们数据库有一个Person对象,一个Country对象,其中Person属于Cou ...
- NHibernate系列文章二十一:延迟加载
摘要 NHibernate的延迟加载机制是很重要的内容.通过关系映射将数据库表之间的关系映射成对象之间的关系,如果没有延迟加载机制,从主表的一个对象的查询将直接查询出所有与该对象关联的其他对象,如果关 ...
- 耗时两月,NHibernate系列出炉
写在前面 这篇总结本来是昨天要写的,可昨天大学班长来视察工作,多喝了点,回来就倒头就睡了,也就把这篇总结的文章拖到了今天. nhibernate系列从开始着手写,到现在前后耗费大概两个月的时间,通过总 ...
- Hibernate 延迟加载和立即加载
概念 什么是延迟加载:所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作.可以简单理解为,只有在使用的时候,才会发出sql语句进行查询,数据是分N次读取. 什么是立即加载:所谓立即加载既是 ...
- [NHibernate]立即加载
目录 写在前面 文档与系列文章 立即加载 一个例子 总结 写在前面 上篇文章介绍了nhibernate延迟加载的相关内容,简单回顾一下延迟加载,就是需要的时候再去加载,需要的时候再向数据库发出sql指 ...
- [NHibernate]视图处理
目录 写在前面 文档与系列文章 视图 一个例子 总结 写在前面 前面的文章主要讲了对物理数据表的操作,当然了Nhibernate同样可以操作视图,本文将讲nhibernate对视图操作的种种. 文档与 ...
- [NHibernate]N+1 Select查询问题分析
目录 写在前面 文档与系列文章 N+1 Select查询问题分析 总结 写在前面 在前面的文章(延迟加载,立即加载)中都提到了N+1 Select的问题,总觉得理解的很不到位,也请大家原谅,这也是为什 ...
- [NHibernate]存储过程的使用(一)
目录 写在前面 文档与系列文章 Nhibernate中使用存储过程 一个例子 总结 写在前面 上篇文章一个小插曲,分析了延迟加载是如何解决N+1 select查询问题的.这篇开始介绍在nhiberna ...
- [NHibernate]存储过程的使用(二)
目录 写在前面 文档与系列文章 创建对象 更新对象 总结 写在前面 上篇文章介绍了如何使用MyGeneration代码生成器生成存储过程,以及nhibernate中通过存储过程删除数据的内容,这篇文章 ...
随机推荐
- Object.observe将不加入到ES7
先请看 Object.observe 的 API Object.observe(obj, callback[, acceptList]) 它用来监听对象的变化,当给该对象添加属性,修改属性时都会被依次 ...
- Useful commmands in Gentoo
Safe way to upgrade: emerge --sync & eix-sync emerge -avuDN --with-bdeps y --keep-going world et ...
- 解密FFmpeg播放track mode控制
上一篇文章(http://www.cnblogs.com/yangdanny/p/4421130.html)我们解决了在FFmpeg下如何处理H264和AAC的扩展数据,根据解出的NALU长度恢复了H ...
- [WPF系列]- Style - Specify width/height as resource in WPF
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys=" ...
- java设计模式之中介者模式
中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...
- mybatis缓存
mybatis缓存http://www.cnblogs.com/QQParadise/articles/5109633.htmlhttp://www.mamicode.com/info-detail- ...
- 在IIS中实现JSP
在IIS中实现JSP IIS本身是不可以支持JSP页面的,但是随着JAVA技术的广泛应用,越来越多的网站采用JAVA技术编写程序,我们根据一些资料和自己的实践经验总结了以下两种JAVA应用服务器 ...
- Reverse Nodes in k-Group
Reverse Nodes in k-Group Given a linked list, reverse the nodes of a linked list k at a time and ret ...
- js 检测页面刷新或关闭
window.onbeforeunload=function(){ //要提交的内容 return "随意写";//必须有return ,不然只有ie有效,chrome无效 }
- cf Round 607
A.Chain Reaction(DP+二分) 题意:一排有n个灯塔,每个灯塔给出坐标xi和力量yi,每次从最右边依次点亮灯塔,每点亮一个灯塔,它左边的距离它yi范围内的灯塔将受到损坏.现在允许在最右 ...