【问题标题】:DAO and Service layer in Spring: session managementSpring中的DAO和Service层:会话管理
【发布时间】:2010-04-02 12:27:36
【问题描述】:

我对 DAO 和服务层互连原理的理解正确吗? DAO 执行基础对象的提取,例如从 db 中提取 id。

服务层使用 DAO 对象,并且可以在一个函数中调用多于一种 DAO 方法。 所以,服务层必须:

  1. 实例化一个 DAO 实现对象

  2. 根据需要调用尽可能多的 DAO 方法

如果一个 Dao 实现了一个接口,那么一个 DAO 接口是否必须有一个方法setSessionFactory()

如何在 Spring 中进行声明式标记:

  1. DAO 对象

  2. 服务层方法和类作为一个整体

这样它就可以提供所需的东西?

【问题讨论】:

    标签: java hibernate spring


    【解决方案1】:

    我很惊讶没有其他人特别提到这一点,但是像 setSessionFactory() 这样的特定于实现的细节应该出现在您的 DAO 接口中。通过向您的 DAO 接口添加一个特定于 Hibernate 的类,您可以将您的 DAO 直接绑定到 Hibernate。

    使用接口和依赖注入的目的是允许您更改层(您的 DAO)的实现细节(例如,您使用什么 ORM 解决方案,或者您的数据来自 Web 服务还是数据库)不影响其他层。

    如果您将setSessionFactory 添加到您的 DAO 接口,那么使用此 DAO 的所有其他层都会意识到并与通过 Hibernate 完成数据访问这一事实相关联。这与您试图通过使用接口和依赖注入来实现的目标完全相反。

    【讨论】:

    • +1 我暗示了这一点,但你这么说很好。我的 DAO 通常最终看起来像这样 class UserHibernateDAO extends HibernateDAO implements UserDAO 其中HibernateDAO 是一个抽象类。然后,如果我需要FileDAO,我可以换掉样板。
    • 同意这是暗示的,但我认为重要的是要大声疾呼。我将“特别”一词编辑为“没有人提到这个”,我意识到这只是暗示:)
    • 哦,没有伤害。我同意明确地说很重要;-)
    【解决方案2】:

    对于我的项目,我编写了一个基类,它有一个 setSessionFactory() 方法,我的所有 DAO 都扩展了该方法。然后我将我的 DAO 与 Spring 连接起来,以便它将 SessionFactory 注入每个 DAO。

    Hibernate 有一个SessionFactory.getCurrentSession(),因此如果您将SessionFactory 注入您的DAO 并使用该方法,那么Session 的范围将根据您的事务管理机制来定义。

    这意味着如果你有这样的方法:

    @Transactional
    public void doSomething(){
        dao1.makeCall();
        dao2.makeOtherCall();
    }
    

    您在构造时注入到每个 DAO 中的 SessionFactory 将使用相同的 Session。但仅限于该交易的范围。

    【讨论】:

    • @Jer DAO 方法 [在您的情况下为 dao1] 是否也必须具有 @Transactional 属性?
    • 没有。 DAO 将使用SessionFactory.getCurrentSession() 检索范围为当前事务的Session
    • @Jer 在你的情况下 dao1, dao2 是服务层对象的属性吗?你如何注射它们?
    • 是的,他们是。您可以通过在 Spring 配置 XML 文件中创建一个 spring <bean> 元素来注入它们。
    • @EugeneP - 通常你用@Transactional annotation标记你的服务类和服务方法。如果您在序列化对象时遇到延迟初始化异常,请查看 OpenSessionInViewFilter 以使事务对整个 Web 请求保持打开状态。 static.springsource.org/spring/docs/3.0.x/api/org/…
    【解决方案3】:
    • 将事务和会话管理留给 spring(通过内置事务管理器)。
    • 在您的 DAO 中使用 sessionFactory.getCurrentSession() tp 访问会话
    • SessionFactory 注入DAO。
    • singleton 范围内有DAO
    • 使用声明性事务(使用<aop@Transactional
    • DAO 通过常规依赖注入注入到服务对象中。服务类以同样的方式注入到需要的地方。

    【讨论】:

    • @Bozho 服务层 - 它如何提取 DAO 对象?也使用 ApplicationContext?
    • 另外,关于单例,这是同一个问题。如果它是从 Spring 获得的,那么它将是单例的,如果不是,那么解释你的意思。
    • @Eugene- Spring 构造的对象在默认情况下是单例的(大多数情况下),但 SessionFactory.getCurrentSession() 方法只返回一个 new Session 第一次在交易范围。否则它将继续返回相同的Session,直到事务结束,无论哪个类获得了Session
    猜你喜欢
    • 1970-01-01
    • 2016-05-06
    • 2023-03-07
    • 2012-11-22
    • 2014-12-24
    • 2015-06-23
    • 2020-06-06
    • 2016-11-28
    • 1970-01-01
    相关资源
    最近更新 更多