在使用Hibernate时,经常会遇到实体对象延迟加载问题。
延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。下面我们就分别介绍这些种类的延迟加载的细节。
Hibernate实现实体对象延迟加载:
如果想Hibernate实现实体对象延迟加载,必须要在实体的映射配置文件中进行相应的配置,如下所示:
1 |
< hibernate-mapping >
|
2 |
< class name=”com.neusoft.entity.User” table=”user” lazy=”true”>
|
3 |
…… |
4 |
</ class >
|
5 |
</ hibernate-mapping >
|
通过将class的lazy属性设置为true,来开启实体的延迟加载特性。如果我们运行下面的代码:
1 |
User user=(User)session.load(User. class ,” 1 ”);
|
2 |
System.out.println(user.getName()); |
当运行到第一条时,Hibernate并没有发起对数据的查询,如果我们此时通过一些调试工具(比如JBuilder2005的Debug工具),观察此时user对象的内存快照,我们会惊奇的发现,此时返回的可能是 User$EnhancerByCGLIB$$bede8986类型的对象,而且其属性为null,这是怎么回事?session.load()方法,会返回实体对象的代理类对象,这里所返回的对象类型就是User对象的代理类对象。在Hibernate中通过使用CGLIB,来实现动态构造一个目标对象的代理类对象,并且在代理类对象中包含目标对象的所有属性和方法,而且所有属性均被赋值为null。通过调试器显示的内存快照,我们可以看出此时真正的User对象,是包含在代理对象的CGLIB$CALBACK_0.target属性中,当代码运行到第二条时,此时调用user.getName()方法,这时通过CGLIB赋予的回调机制,实际上调用 CGLIB$CALBACK_0.getName()方法,当调用该方法时,Hibernate会首先检查CGLIB$CALBACK_0.target属性是否为null,如果不为空,则调用目标对象的getName方法,如果为空,则会发起数据库查询,生成类似这样的SQL语句:select * from user where id='@id';来查询数据,并构造目标对象,并且将它赋值到 CGLIB$CALBACK_0.target属性中。
这样,通过一个中间代理对象,Hibernate实现实体对象延迟加载,只有当用户真正发起获得实体对象属性的动作时,才真正会发起数据库查询操作。所以实体的延迟加载是用通过中间代理类完成的,所以只有session.load()方法才会利用实体延迟加载,因为只有session.load()方法才会返回实体类的代理类对象。
相关推荐
主要介绍了Java的Hibernate框架中的缓存和延迟加载机制,Hibernate是注明的Java下SSH三大web开发框架之一,需要的朋友可以参考下
1. **延迟加载(Lazy Loading)**:Hibernate支持实体对象和集合的延迟加载,只有在真正需要时才加载数据,减少内存占用,提升性能。 2. **缓存机制**: - **一级缓存**:内部缓存,即Session级别的缓存,每个Session...
第一,`find()`方法会将所有查询结果加载到内存中,如果数据量大,可能会消耗大量内存。第二,提交事务时,Hibernate会为每个对象生成一个单独的`UPDATE`语句,这会导致大量的数据库访问,严重影响性能。 为了解决...
通过`session.createQuery("from TItem")`,Hibernate会自动找出所有继承自`TItem`的子类实例,并将它们从数据库中加载出来。这是由于`polymorphism=implicit`的设置,使得Hibernate能够在不指定具体子类的情况下,...
Servlet生命周期包括加载、实例化、初始化、服务、销毁几个阶段。 - JSP:JSP是Servlet的简化版本,它允许开发者在HTML页面中直接插入Java代码,以实现动态内容的生成。JSP页面在服务器端被转换为Servlet,然后像...
3. **ORM框架**:如Hibernate,使用反射来映射数据库记录到Java对象。 4. **测试工具**:JUnit等测试框架使用反射来调用私有方法进行测试。 5. **动态代理**:Java的`java.lang.reflect.Proxy`类允许创建动态代理类...
"浅析Java 反射机制的用途和缺点" Java 反射机制是一种强大的技术,可以让应用程序做一些几乎不可能做到的事情。它可以让程序在运行时检测或修改程序行为,是 Java 语言中一个相对高级的特性。开发者可以使用反射...
在Spring、Hibernate等Java框架中,反射机制被广泛应用于配置加载、依赖注入、AOP(面向切面编程)等方面,极大地提高了代码的可维护性和灵活性。 总的来说,Java反射机制是Java语言的精髓之一,它使得Java具备了...
1. **动态创建对象**:通过`Class.forName()`方法,我们可以根据类名字符串动态加载类,并使用`Class`对象的`newInstance()`方法创建该类的实例,即使在编写代码时不知道具体的类名。 2. **访问私有成员**:反射...
- **页面的国际化**:通过在JSP页面中使用`<s:text>`标签引用资源文件中的键值,实现文本的动态加载。 - **Action的国际化**:在Action中使用`getText()`方法获取资源文件中的文本,以实现动态的语言切换。 -...