hibernate 中的lazy属性祥解.txt
在探讨Hibernate框架中的`lazy`属性时,我们深入解析了其功能、应用场景以及与之相关的潜在问题,尤其关注于如何有效利用此特性以优化数据库性能和应用响应速度。 ### Hibernate框架简介 Hibernate是一个开放源码的对象关系映射(ORM)框架,它允许Java应用程序将关系型数据库的数据映射为面向对象的实体,简化了数据持久化层的开发工作。通过Hibernate,开发者可以使用面向对象的方式进行数据操作,而无需直接编写SQL语句,大大提高了开发效率和代码的可维护性。 ### `lazy`属性详解 `lazy`属性是Hibernate中用于控制数据加载策略的一个关键参数,主要用于延迟加载关联对象。当一个对象被加载时,与其关联的对象不一定立即加载到内存中,而是等到真正需要使用时才加载,这就是懒加载(Lazy Loading)的基本思想。这一策略对于提高系统性能和减少内存占用具有重要意义。 #### Lazy Loading的工作原理 在Hibernate中,当设置关联属性的`fetch`或`lazy`属性为`true`时,表示该关联属性采用懒加载方式。这意味着,在获取主对象时,Hibernate不会立即加载与其关联的子对象。例如,在用户(User)与帖子(Post)之间的多对多关联中,如果用户对象的`posts`属性被标记为`lazy=true`,那么在加载用户信息时,只会加载用户的`name`、`password`、`phone`等基本信息,而不会加载与之关联的所有帖子。 #### 使用场景 1. **性能优化**:在大数据量的应用场景下,懒加载可以显著减少初始加载时间,因为不是所有数据都会一次性加载到内存中。 2. **节省资源**:对于那些并非每次访问都需要加载的关联数据,使用懒加载可以避免不必要的数据加载,从而节省内存资源。 3. **按需加载**:只有当确实需要访问关联数据时,才会触发加载动作,这使得数据加载更加灵活和高效。 #### 潜在问题及解决策略 尽管懒加载带来了很多好处,但它也有一定的局限性和潜在的问题。例如,如果在关闭了Session后尝试访问懒加载的属性,将会抛出异常,因为此时Hibernate已经无法重新建立数据库连接来加载数据。为了解决这个问题,可以采取以下几种策略: 1. **在关闭Session之前初始化关联对象**:在关闭Session前,可以显式调用`Hibernate.initialize()`方法来初始化关联对象,确保数据已经加载到内存中。 2. **使用OpenSessionInView模式**:这是一种常用的设计模式,用于确保在整个HTTP请求处理过程中,Session始终保持打开状态,从而支持懒加载的正常工作。具体实现上,可以在Servlet Filter中创建并管理Session的生命周期,确保Session在请求开始时打开,在请求结束时关闭。 ### 实例分析 考虑一个包含Person与Address之间一对多关系的场景,其中Person实体拥有一个`Set<Address>`类型的`address`属性。在`Person.hbm.xml`配置文件中,我们可以看到`address`属性被设置为`lazy="true"`,表示在加载Person实体时,其关联的Address集合不会立即加载。 ```xml <set name="address" table="address" lazy="true" cascade="none" sort="unsorted" > ``` 在代码示例中,首先通过HibernateUtil获取当前Session,并通过DAO层方法查询指定ID的Person实体。接着,尝试访问Person实体的`address`属性。如果在关闭Session之后进行访问,由于Session已关闭,将导致异常抛出。为了避免这种情况,可以在访问关联对象前检查Session是否仍然打开,或者使用OpenSessionInView模式来管理Session的生命周期。 ### 结论 `lazy`属性是Hibernate框架中一个非常重要的特性,它通过延迟加载关联对象来优化数据加载过程,从而提升应用性能和资源利用率。然而,正确理解和合理使用`lazy`属性对于避免潜在的异常和性能瓶颈至关重要。通过本篇深度解析,希望读者能够掌握`lazy`属性的核心概念及其在实际开发中的应用技巧。
延迟加载, 也就是用到的时候才去加载.这样可以提高一些性能.
Hibernate的lazy loading 采用了一个HibernateSession来管理session,它的逻辑是每进行一次数据库操作,就开新的session,操作完成后立即关闭该session。这样做的好处是可以严格关闭session,避免菜鸟级的错误,但是hibernate.org并不推荐这么做。因为这不适合lazy loading,也不适合跨方法的事务。
比如在我们的应用中,user->post形成一对多的映射,User中有一个包含post的List。
在User中,有多个属性:name,password,phone等,还有一个List类型的posts。当我们对posts使用lazy laoding的时候,hibernate会在获得User对象的时候,仅仅返回name,password,phone等基本属性,当你访问posts的时候,它才会从数据库中提取posts需要的数据,这就是所谓lazy laoding。但是在我们的系统中,session是被立即关闭的,也就是在读取了name,password,phone等基本属性后,session已经close了,再进行lazy loaiding就会有异常。
解决办法是在close session之前,调用Hibernate.initialize(user.getPosts()),告诉系统,user.getPosts()是需要lazy laoding的。但是这样做会破坏HibernateSession类的封装.
后来采用所谓的OpenSessionInView模式,把session的周期交给servlet filter来管理,每当有request进来,就打开一个session,response结束之后再关闭它,这样可以让session存在于整个请求周期中。
本文主要针对一对多情况下读取父类的子集合时,hibernate 的lazy属性在其中的影响进行总结。(以下代码运行在jdk1.5,jboss eclipse ide 1.5,hibernate 3.1环境下)
假设有:父类 Person (含有Set类型属性Address),
子类 Address(碰巧集合的名字和子类的名字都是Address,不要混淆了)
Person.hbm.xml 主要片段:
<id
name="idx"
column="idx"
type="long"
>
<generator class="identity">
</generator>
</id>
<property
name="age"
type="int"
update="true"
insert="true"
column="age"
/>
<property
name="name"
type="java.lang.String"
- 粉丝: 8
- 资源: 13
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助