首页 / 软件开发 / JAVA / Hibernate和Spring的延迟加载和DAO模式
Hibernate和Spring的延迟加载和DAO模式2011-01-01Hibernate和延迟加载Hibernate对象关系映射提供了两种对象初始化模式:延迟加载和非延迟加载。非延迟加载在加载时获取对象本身以及它关联的所有对象。这可能导致在获取一个实例时,执行成百上千的select语句。当使用双向关联时,这个问题被放大,常常出现初始化请求时,整个数据库都被载入。显然检查每个对象的关系,并手工删除他们会费点事,但最终我们可能会因此丢失使用ORM工具的优势。一个明细的解决方式是使用hibernate提供的延迟载入机制。这种初始化策略在类成员被访问时只载入它的一个对象的一对多和多对多关系。对开发人员来说,这种方式是透明的,并且只有最少数量的请求发生,这样就获得了最佳的性能。这种技术的一个缺点是延迟载入要求当对象还在使用中时,Hibernate的Session必须保持打开状态。当尝试通过DAO模式抽象持久层时,这会引起一个重要问题。为了充分地抽象持久层,所有的数据库逻辑,包括打开、关闭Session都不能在应用层出现。最常见的是,这些逻辑隐藏在DAO的实现类中。快速和差一些的方案是:避免采用DAO模式,在应用层中包含数据连接的逻辑。这在小应用中是可行的,但在大系统中,这会是一个设计缺陷,它损害了应用的扩展性。在Web层使用延迟加载幸运的是,Spring框架已经提供了一个DAO模式结合Hibernate延迟加载的Web方案。对于任何不熟悉Spring框架结合Hibernate人来说,我在这里不会深入细节,但是我希望你去阅读“结合Spring框架的Hibernate数据库访问”章节。这个案例是一个Web应用,Spring提供了OpenSessionInViewerFilter和OpenSessionInViewInterceptor。使用它们中的任一个都能获得同样的功能。这两者唯一不同的是interceptor在Spring容器中运行,并且在web应用的上下文中配置;fitler在Spring前运行,并且在web.xml中配置。不管使用哪一个,他们都会在请求绑定到Session的当前线程期间打开Hibernate Session。一旦绑定到线程,打开的Hibernate Session能被DAO的实现类透明地使用。Session会持续打开允许延加载访问数据库。一旦View逻辑完成,hibernate session会被关闭,无论是在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>