Hibernate---延迟加载和OpenSessionInView
2009-02-02 21:29
453 查看
Hibernate与延迟加载: Hibernate对象关系映射提供延迟的与非延迟的对象初始化。非延迟加载在读取一个对象的时候会将与这个对象所有相关的其他对象一起读取出来。这有时会导致成百的(如果不是成千的话) select 语句在读取对象的时候执行。这个问题有时出现在使用双向关系的时候,经常会导致整个数据库都在初始化的阶段被读出来了。当然,你可以不厌其烦地检查每一个对象与其他对象的关系,并把那些最昂贵的删除,但是到最后,我们可能会因此失去了本想在 ORM 工具中获得的便利。
一个明显的解决方法是使用 Hibernate 提供的延迟加载机制。这种初始化策略只在一个对象调用它的一对多或多对多关系时才将关系对象读取出来。这个过程对开发者来说是透明的,而且只进行了很少的数据库操作请求,因此会得到比较明显的性能提升。这项技术的一个缺陷是延迟加载技术要求一个 Hibernate 会话要在对象使用的时候一直开着。这会成为通过使用 DAO 模式将持久层抽象出来时的一个主要问题。为了将持久化机制完全地抽象出来,所有的数据库逻辑,包括打开或关闭会话,都不能在应用层出现。最常见的是,一些实现了简单接口的 DAO 实现类将数据库逻辑完全封装起来了。一种快速但是笨拙的解决方法是放弃 DAO 模式,将数据库连接逻辑加到应用层中来。这可能对一些小的应用程序有效,但是在大的系统中,这是一个严重的设计缺陷,妨碍了系统的可扩展性。
在 Web 层进行延迟加载 幸运的是, Spring 框架为 Hibernate 延迟加载与 DAO 模式的整合提供了一种方便的解决方法。对那些不熟悉 Spring 与 Hibernate 集成使用的人,我不会在这里讨论过多的细节,但是我建议你去了解 Hibernate 与 Spring 集成的数据访问。以一个 Web 应用为例, Spring 提供了 OpenSessionInViewFilter 和 OpenSessionInViewInterceptor 。我们可以随意选择一个类来实现相同的功能。两种方法唯一的不同就在于 interceptor 在 Spring 容器中运行并被配置在 web 应用的上下文中,而 Filter 在 Spring 之前运行并被配置在 web.xml 中。不管用哪个,他们都在请求将当前会话与当前(数据库)线程绑定时打开 Hibernate 会话。一旦已绑定到线程,这个打开了的 Hibernate 会话可以在 DAO 实现类中透明地使用。这个会话会为延迟加载数据库中值对象的视图保持打开状态。一旦这个逻辑视图完成了, Hibernate 会话会在 Filter 的 doFilter 方法或者 Interceptor 的 postHandle 方法中被关闭。下面是每个组件的配置示例:
Interceptor的配置:
<beans>
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>
<property name="mappings">
...
</bean>
...
<bean name="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
</beans>
Filter的配置
<web-app>
...
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</filter-class>
</filter>
...
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*. spring </url-pattern>
</filter-mapping>
...
</web-app>
一个明显的解决方法是使用 Hibernate 提供的延迟加载机制。这种初始化策略只在一个对象调用它的一对多或多对多关系时才将关系对象读取出来。这个过程对开发者来说是透明的,而且只进行了很少的数据库操作请求,因此会得到比较明显的性能提升。这项技术的一个缺陷是延迟加载技术要求一个 Hibernate 会话要在对象使用的时候一直开着。这会成为通过使用 DAO 模式将持久层抽象出来时的一个主要问题。为了将持久化机制完全地抽象出来,所有的数据库逻辑,包括打开或关闭会话,都不能在应用层出现。最常见的是,一些实现了简单接口的 DAO 实现类将数据库逻辑完全封装起来了。一种快速但是笨拙的解决方法是放弃 DAO 模式,将数据库连接逻辑加到应用层中来。这可能对一些小的应用程序有效,但是在大的系统中,这是一个严重的设计缺陷,妨碍了系统的可扩展性。
在 Web 层进行延迟加载 幸运的是, Spring 框架为 Hibernate 延迟加载与 DAO 模式的整合提供了一种方便的解决方法。对那些不熟悉 Spring 与 Hibernate 集成使用的人,我不会在这里讨论过多的细节,但是我建议你去了解 Hibernate 与 Spring 集成的数据访问。以一个 Web 应用为例, Spring 提供了 OpenSessionInViewFilter 和 OpenSessionInViewInterceptor 。我们可以随意选择一个类来实现相同的功能。两种方法唯一的不同就在于 interceptor 在 Spring 容器中运行并被配置在 web 应用的上下文中,而 Filter 在 Spring 之前运行并被配置在 web.xml 中。不管用哪个,他们都在请求将当前会话与当前(数据库)线程绑定时打开 Hibernate 会话。一旦已绑定到线程,这个打开了的 Hibernate 会话可以在 DAO 实现类中透明地使用。这个会话会为延迟加载数据库中值对象的视图保持打开状态。一旦这个逻辑视图完成了, Hibernate 会话会在 Filter 的 doFilter 方法或者 Interceptor 的 postHandle 方法中被关闭。下面是每个组件的配置示例:
Interceptor的配置:
<beans>
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>
<property name="mappings">
...
</bean>
...
<bean name="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
</beans>
Filter的配置
<web-app>
...
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</filter-class>
</filter>
...
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*. spring </url-pattern>
</filter-mapping>
...
</web-app>
相关文章推荐
- Hibernate延迟加载 或 no session or session was closed 问题的解决(OpenSessionInViewFilter使用)
- Hibernate延迟加载与opensessioninviewFilter
- Hibernate延迟加载与opensessioninviewFilter
- hibernate延迟加载与OpenSessionInViewFilter
- 使用struts2 的jsonplugin插件与opensessioninview和hibernate延迟加载时遇到的问题
- [转]Hibernate延迟加载与opensessioninviewFilter
- Hibernate延迟加载与opensessioninviewFilter
- Spring使用OpenSessionInViewFilter解决Hibernate的lazy延时加载问题
- 配置Spring的OpenSessionInViewFilter过滤器,以解决Hibernate的懒加载异常(LazyInitializationException)
- 异常描述:hibernate懒加载中,用OpenSessionInViewFilter解决之后,同时对一个collection创建两个session访问导致异常(Illegal attempt to associate a collection with two open sessions)
- Spring使用OpenSessionInViewFilter解决Hibernate的lazy延时加载问题
- 【Spring】OpenSessionInViewFilter解决Hibernate懒加载异常
- OpenSessionInViewFilter解决Hibernate延时加载问题
- OpenSessionInViewFilter 配置解决延迟加载
- OpenSessionInViewFilter解决数据库操作表(一对多)延迟加载时session关闭的异常
- Spring使用OpenSessionInViewFilter解决Hibernate的lazy延时加载问题
- 使用OpenSessionInViewFilter方案解决hibernate懒加载的异常
- hibernate4 添加懒加载后设置openSessionInViewFilter
- Spring使用OpenSessionInViewFilter解决Hibernate的lazy延时加载问题
- Hibernate网页加载数据关闭 OpenSessionInViewFilter