Hibernate 延迟加载剖析与代理模式应用

#Hibernate 延迟加载剖析与代理模式应用
Link: http://www.ibm.com/developerworks/cn/java/j-lo-hibernatelazy/index.html
简介: Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术。这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录。通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销。Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性、关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性、关联实体,这就是代理模式应用带来的优势。
……
<set name=”addresses” table=”person_address” lazy=”true”>
<!– 指定关联的外键列 –>
<key column=”person_id”/>
<composite-element class=”Address”>
<!– 映射普通属性 detail –>
<property name=”detail”/>
<!– 映射普通属性 zip –>
<property name=”zip”/>
</composite-element>
</set>
……
熟悉 Hibernate 集合属性读者应该记得:Hibernate 要求声明集合属性只能用 Set、List、Map、SortedSet、SortedMap 等接口,而不能用 HashSet、ArrayList、HashMap、TreeSet、TreeMap 等实现类,其原因就是因为 Hibernate 需要对集合属性进行延迟加载,而 Hibernate 的延迟加载是依靠 PersistentSet、PersistentList、PersistentMap、PersistentSortedMap、PersistentSortedSet 来完成的——也就是说,Hibernate 底层需要使用自己的集合实现类来完成延迟加载,因此它要求开发者必须用集合接口、而不是集合实现类来声明集合属性。
Hibernate 对集合属性默认采用延迟加载,在某些特殊的情况下,为 <set…/>、<list…/>、<map…/> 等元素设置 lazy=”false”属性来取消延迟加载。
……
Hibernate 的延迟加载(lazy load)本质上就是代理模式的应用,我们在过去的岁月里就经常通过代理模式来降低系统的内存开销、提升应用的运行性能。Hibernate 充分利用了代理模式的这种优势,并结合了 Javassist 或 CGLIB 来动态地生成代理对象,这更加增加了代理模式的灵活性,Hibernate 给这种用法一个新名称:延迟加载。无论怎样,充分分析、了解这些开源框架的实现可以更好的感受经典设计模式的优势所在。

#懒加载
在Web应用程序中,系统的瓶颈常在于系统的响应速度。如果系统响应速度过慢,用户就会出现埋怨情绪,系统的价值也因此会大打折扣。因此,提高系统响应速度,是非常重要的。
Web应用程序做的最多就是和后台数据库交互,而查询数据库是种非常耗时的过程。当数据库里记录过多时,查询优化更显得尤为重要。为了解决这种问题,有人提出了缓存的概念。缓存就是将用户频繁使用的数据放在内存中以便快速访问。在用户执行一次查询操作后,查询的记录会放在缓存中。当用户再次查询时,系统会首先从缓存中读取,如果缓存中没有,再查询数据库。缓存技术在一定程度上提升了系统性能,但是当数据量过大时,缓存就不太合适了。因为内存容量有限,把过多的数据放在内存中,会影响电脑性能。而另一种技术,懒加载可以解决这种问题。
懒加载(Load On Demand)是一种独特而又强大的数据获取方法,它能够在用户滚动页面的时候自动获取更多的数据,而新得到的数据不会影响原有数据的显示,同时最大程度上减少服务器端的资源耗用。
考虑这样一个例子:海尔电器是一个非常大的组织机构,它下有1万多个组织单元。由于组织单元的复杂性,组织单元间也存在着上下级关系。现在的问题是:用户想加入海尔电器的某个组织单元,他该怎么选择到这个组织单元呢?
很容易想到的一个解决方法是:查询数据库,把海尔电器的所有组织单元放到一个下拉列表中,让用户选择即可。这样的确是解决问题了,但是,测试发现,浏览器在显示组织单元数据时就直接假死了。看来,这样做性能太差,可以不采纳。
另一个解决方法就是利用懒加载技术。由于组织单元间存在着上下级关系,那么组织单元的排列就可以当作一棵树来处理。在显示数据时只显示父节点,点击父节点时,就能显示父节点下的子节点。
用户要选择某个组织单元,只需点击该组织单元的父亲节点就能找到该组织单元。
可以看出,懒加载提高了系统响应时间,提升了系统性能,非常具有利用价值。

猜你喜欢

转载自tsmood.iteye.com/blog/1935118