Hibernate有很多值得学习的地方,这里我们主要介绍Hibernate属性延迟加载,包括介绍CGLIB是Apache的一个开源工程等方面。
延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。下面我们就介绍Hibernate属性延迟加载。
Hibernate属性延迟加载
在Hibernate3中,引入了一种新的特性——Hibernate属性延迟加载,这个机制又为获取高性能查询提供了有力的工具。在前面我们讲大数据对象读取时,在User对象中有一个resume字段,该字段是一个 java.sql.Clob类型,包含了用户的简历信息,当我们加载该对象时,我们不得不每一次都要加载这个字段,而不论我们是否真的需要它,而且这种大数据对象的读取本身会带来很大的性能开销。在Hibernate2中,我们只有通过我们前面讲过的面性能的粒度细分,来分解User类,来解决这个问题(请参照那一节的论述),但是在Hibernate3中,我们可以通过Hibernate属性延迟加载机制,来使我们获得只有当我们真正需要操作这个字段时,才去读取这个字段数据的能力,为此我们必须如下配置我们的实体类:
- <hibernate-mapping>
- <class name=”com.neusoft.entity.User” table=”user”
- ……
- <property name=”resume”type=”java.sql.Clob”column=”resume” lazy=’true’/>
- </class>
- </hibernate-mapping>
通过对<property>元素的lazy属性设置true来开启Hibernate属性延迟加载,在Hibernate3中为了实现属性的延迟加载,使用了类增强器来对实体类的Class文件进行强化处理,通过增强器的增强,将CGLIB的回调机制逻辑,加入实体类,这里我们可以看出属性的延迟加载,还是通过CGLIB来实现的。CGLIB是Apache的一个开源工程,这个类库可以操纵java类的字节码,根据字节码来动态构造符合要求的类对象。根据上面的配置我们运行下面的代码:
- String sql=”from User user where user.name=’zx’ ”;
- Query query=session.createQuery(sql)
- List list=query.list();
- for(int i=0;i<list.size();i++){
- User user=(User)list.get(i);
- System.out.println(user.getName());
- System.out.println(user.getResume());
- }
当执行到第二行时,会生成类似如下的SQL语句:
- Select id,age,name from user where name=’zx’;
这时Hibernate会检索User实体中所有非延迟加载属性对应的字段数据,当执行到第七行时,会生成类似如下的SQL语句:
- Select resume from user where id=’1’;
这时会发起对resume字段数据真正的读取操作
【编辑推荐】