hibernate的延迟加载的原理

来源:互联网 发布:SQL2010怎么创建数据库 编辑:程序博客网 时间:2024/06/10 18:04
hibernate的延迟加载,就是在关联映射的时候,对于被关联的对象或集合,不当时查询数据库,而是该集合或用户被用到的时候才去查。
原理就是使用动态代理的方式,把持久化类替换成代理类(对于单个对象和集合,均有对应的代理类),在代理类中实现这样的功能,即当第一次访问被代理对象的非id字段时,查询数据库。
至于应用范围,默认情况下,hibernate对于集合都是用延迟select抓取,对返回单值的关联使用延迟代理抓取。
这样做从道理上讲是很有道理的,任何被关联的其他对象,hibernate不知道你是否有需求去用它里面的字段。如果全部一口气查出来,大部分时候是在白白浪费资源。当需要的时候才去“叫醒”数据,否则让它在数据库里“冬眠”,这是hibernate的目的所在。
缺点就是在hibernate session关闭后,用该session取到的数据,如果其中有被延迟加载的数据还未被加载过,则不能被加载了。hibernate的建议是,将加载数据的代码放在session被关闭之前。
我个人认同这样的建议(有人认为这是hibernate自打耳光):不要以为用了hibernate,就可以完全无视对何时该查数据库这样的细节的控制。在明知需要得到被关联数据的情况下,你有义务在session被关闭以前将它初始化。大部分情况下这是完全合理的。
有一种技术叫Open Session In View,针对hibernate在3层架构的webApp中,往往会在业务层做事务,然后在业务层事务提交后关闭session,导致view层显示数据时,延迟加载失败。它可以透明的将session在request来到时打开,response完全送走后关闭。用了它就不用管什么时候查数据库了,做到了在需要时就拿得到数据,不需要时不做多余的查询。但是它把封装了jdbc Connection的session的生存周期拉长了,而Connection应该最晚得到,尽早释放。被一个线程长期占着不放的话,会对效率有影响。在并发访问越多,网络连接越不稳定的时候,这种影响越明显。
0 0