繁体   English   中英

在MVC体系结构的控制器中打开休眠会话是个好主意吗?

[英]Is it a good idea to open a hibernate session in controller in MVC architecture?

我有一个非常复杂的域实体。 我想对所有关联进行延迟加载。 所以场景是这样的:

1.获取我的业务逻辑实例。

2.从业务中获取对象。

3.问o给我其他相关对象。

4.准备视图。

为了摆脱在延迟加载其他对象时关闭会话的休眠异常,我想到了在控制器中打开和关闭整个会话的想法。 这是个好主意吗? 有更好的解决方案吗?

谢谢

鉴于会议是一种不良做法

这是通常用于解决此问题的层的建议:

控制者

  • 控制器仅关心处理Web请求,将其解释为服务将要处理的对象以及将服务结果作为Web响应返回。 我通常在每个控制器方法中只有一个事务服务方法调用,更喜欢在一个事务中将一个控制器操作的所有数据访问都保留下来。

服务

  • 服务层只关心从控制器接收数据,从中获取执行操作所需的数据(从数据层),并返回有意义的结果。 该服务应完全加载控制器所需的所有延迟加载的实体。 这里的服务方法是事务性的,不会出现延迟加载问题,您可以组合多个DAO的结果。 这样,DAO无需彼此了解

资料存取

  • 数据访问层仅与持久性(CRUD)有关,它允许通过过滤,排序等方式访问数据。

Spring有一个opensessioninviewfilter和一个opensessininviewinterceptor ,它们应该为您处理此功能。

作为一种设计模式,openinig会话的观点非常糟糕。 我认为SpringMVC的设置会导致您打开会话并解决您的问题。

但是,如果您的应用程序比宠物商店复杂,我建议不要使用此模式。 我建议将数据检索和业务逻辑向下移动一层,并在控制器中仅保留与UI相关的代码。 认真思考关系并对其设置急切和懒惰的设置应该有效。 不进行分析而将所有内容设置为惰性不是一个好主意。 每个请求最终将进行数百次SQL调用。

我建议将L2缓存(例如EHCache)插入Hibernate。 配置和使用非常简单。

您确实可以做到,这是使用Spring和Hibernate时的常见模式。 通过将下面的代码放入web.xml中,可以非常轻松地启用它

<filter>
    <filter-name>lazyLoadingFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>lazyLoadingFilter</filter-name>
    <url-pattern>/mvc/*</url-pattern>
</filter-mapping>

一旦设置好位置,该调用中在休眠状态下进行的每个调用都将使用相同的会话:

@Autowired
protected SessionFactory sessionFactory;

protected Session getSession() {

    return SessionFactoryUtils.getSession(sessionFactory, true);
}

但是,正如Peter Gwiazda所说,您可能会或可能不想这样做,具体取决于应用程序的规模和复杂性。 听起来您的对象很复杂,所以当您在JSP中遍历实体时,让视图本质上会触发更多的SQL语句,或者任何不会带来出色性能的事情。

通常,将视图满足需求的对象转换为DTO并限制从数据库中取回的数据量通常是更好的模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM