避免在某些情况下,关联关系给我们带来无谓的开销,Hibernate引入了延迟加载的概念;
Hibernate3中的延迟记载可以针对:
- 实体对象
- 集合(Collection)
- 属性的延迟加载
通过Load方法,可以返回目标实体对象的代理;
1,针对实体对象的延迟加载:
在class标签里添加lazy="true",属性:
<class name="TUser" table="t_user" lazy="true">
如果将lazy="false"时,当程序运行:
TUser user = (TUser) session.load(TUser.class, new Integer(1));
时,会发出SQL,从数据库中取出所对应的记录,并构造了一个完整的TUser对象;
如果将lazy="true"后,程序执行到:
TUser user = (TUser) session.load(TUser.class, new Integer(1));
时,并没有任何SQL语句发出,此时对象里的属性也为空,当程序执行到:
System.out.println("user Name:"+users.getName());
时,可以用Eclipse的Debug看到对象的属性仍然为空,但是看日志输出,会发现已经发出SQL,并也取到了其想要的name名字;
延迟加载和非延迟加载的差异在于Hibernate的代理机制,Hibernate引入了CGLib作为代理机制的实现,也就是我们在DeBug下可以看到TUser$EnhancerByCGLIB$$bede8986类型对象的原因;
CGLIB可以在运行期生成 java Class,这里的代理机制,其基本原理就是通过由CGLIB构造一个包含目标对象所有属性和方法的动态对象(相当于动态构造目标对象的一个子类)返回,并以之作为中介,为目标对象提供更多的特性;
这时,真正的TUser对象,位于代理类的CGLIB$CALLBACK_0.target属性中,当我们调用getName()方法时,实际上调用的是CGLIB$CALLBACK_0.getName()方法,当调用了CGLIB$CALLBACK_0.getName()后,首先会检查 CGLIB$CALLBACK_0.target中是否存在目标对象;如果存在,则调用目标对象的getName方法返回,如果目标对象为空,则发起数据库查询指令,读取记录,构建目标对象并将其设入CGLIB$CALLBACK_0.target。这样,通过一个中间代理,实现数据延迟加载功能,只有当用户真正的调用实体类的取值方法,Hibernate才会去数据库中取值;
2,类型集合的延迟加载
假如我们有个TUser实体对象,这个对象里面有Set<Book> books;属性;在我们获取TUser基本信息的时候,不必要将books一起查出来,这样的话可以给<set />标签添加lazy属性;
<set name="books" cascade="all" lazy="true">
这样的话,只有我们实际中真正的用到book了,才会去数据库里查询!
3,属性延迟加载
现将其属性设置:
<property name="name" lazy="true"/>
配置了lazy属性之外,还要借助类增强器对二进制Class文件进行强化处理(buildtime bytecode instrumentation)。通过ANT调用Hibernate类增强器对TUser.class文件进行强化处理。脚本如下:
<project name="HibernateSample" default="instrument" basedir=".">
<property name="lib.dir" value="./lib"/>
<property name="classes.dir" value="./bin"/>
<path id="lib.class.path">
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
<target name="instrument">
<taskdef name="instrument"
classname="org.hibernate.tool.instrument.InstrumentTask">
<classpath path="${classes.dir}"/>
<classpath refid="lib.class.path"/>
</taskdef>
<instrument verbose="true">
<fileset dir="${classes.dir}/com.redsaga/hibernate/db/entity">
<include name="TUser.class"/>
</fileset>
</instrument>
</target>
</project>
分享到:
相关推荐
Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术。这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录。通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销。...
图片延迟加载,可以增加用户体验,jQuery图片延迟加载插件jQuery.lazyload,使用延迟加载在可提高网页下载速度。在某些情况下,它也能帮助减轻服务器负载。
深入理解hibernate懒加载技术,正确使用懒加载
JQuery 图片延迟加载 lazyload
NULL 博文链接:https://xuwoool.iteye.com/blog/1306207
实现网页内容、图片延迟加载,没有浏览到的不显示,只有浏览器看到的才显示。
Hibernate延时加载与lazy机制.docHibernate延时加载与lazy机制.doc
Lazyload是通过延迟加载来实现按需加载,达到节省资源,加快浏览速度的目的。 网上也有不少类似的效果,这个Lazyload主要特点是: 支持使用window(窗口)或元素作为容器对象; 对静态(位置大小不变)元素做了大量...
图片延迟加载实例。在chrome network中查看效果。简单易用 无冗余代码
In this article I want to discuss the lazy loading mechanism provided by NHibernate. It is recommended for maximum flexibility to define all relations in your domain as lazy loadable. This is the ...
你必须修改 HTML 代码. 在 src 属性中设置展位符图片, demo 页面使用 1x1 像素灰色 GIF 图片.... 这里可以定义特定的 class 以获得需要延迟加载的图片对象. 通过这种方法你可以简单地控制插件绑定.
UITableView 與 Lazy Loading 結合 當cell 需要顯示照片時, 由NSURLConnect 去下載圖片.
LazyLoad 图片延迟加载效果示例 LazyLoad 图片延迟加载效果示例,这是由cloudgamer编写的一个封装插件,用它可以完成不少的效果,现在这个是图片延迟效果,也就是说,我们需要显示的图片会先加载,暂时用不上的也就...
页面延迟加载JS包 lazyload.js scrollloading.js
jquery.lazyload用JQ实现图片延迟加载,即在浏览器看到的地方才加载图片。
Hiberbate 3延迟加载(Lazy)介绍
js lazyload实现网页图片延迟加载特效
hibernate 中的lazy属性的使用
博客与文章作为例子,查询一个博客的时候并不是需要将其下面的文章都加载进来。把需要延迟加载的属性使用Lazy泛型,实例时候传入一个Fun委托。
jQuery图片延迟加载插件Lazy Load,在网页上出现大量图片的时候,一下加载全部图片需要加载比较长的时间,懒加载的目的就是减少加载时间,按需加载从而达到提升用户体验的目的。