【问题标题】:Java EE Architecture - Are DAO's still recommended when using an ORM like JPA 2?Java EE 架构 - 使用 JPA 2 之类的 ORM 时,是否仍然推荐使用 DAO?
【发布时间】:2011-04-18 15:06:52
【问题描述】:

如果我使用 JPA2 之类的 ORM - 我的实体映射到我的数据库,我还应该使用 DAO 吗?这似乎需要更多的开销。

例如,我需要维护三个额外的包:

  1. 一个指定我的域对象(它几乎映射我的实体对象):

    public class Employee {
        private String firstName;
        private String lastName;
        ...
        // Getters and setters
    }
    
  2. 一个包含指定我的 DAO 方法的接口

    public interface EmployeeDAO {
        public void addEmployee(Employee employee);
        public Employee getEmployeeById(long id);
        ...
    }
    
  3. 一个包含实现我的 DAO 的会话 bean

    public EmployeeJpaDAO implements EmployeeDAO {
        interface method implementations here
        ....
        private method that transform my Employee entity into my Employee domain object
    }
    

现在每次我需要执行新的 CRUD 操作时都会添加很多额外的包袱。

但是,我从 DAO 中看到的好处是:

  1. 您可以在内存中实现 DAO,以便对服务层进行单元测试。这意味着您无需访问数据库即可测试业务逻辑,并且您可以放心,您的对象将始终包含相同的属性值

  2. 将业务逻辑与数据库访问逻辑分离

不涉及实现 DAO 的选项是仅在服务层中使用实体对象和 EntityManager:

@Stateless
public class EmployeeEjb {
    @PersistenceContext(unitName = "employee")
    private EntityManager manager;

    public Employee getEmployeeById(long id) {
        return manager.createNamedQuery(Employee.GetEmployeeById).getResultList();
    }
    ...
}

这里没有中间立场吗?有没有人遇到过一个架构或实现了一个架构,它满足了我上面提到的 DAO 层的一些好处(最重要的是业务逻辑的单元可测试性),但不涉及实现 DAO 层所涉及的所有开销?

感谢任何建议和/或建议!我真的很想看看有些人对此有何看法。

【问题讨论】:

    标签: java jakarta-ee dao jpa-2.0 architecture


    【解决方案1】:

    如果我使用 JPA2 之类的 ORM - 我的实体映射到我的数据库,我还应该使用 DAO 吗?这似乎需要更多的开销。

    是的。很明显,Java EE 不鼓励在使用 JPA 时使用 DAO 模式(JPA 已经提供了 Domain Store 模式的标准化实现,并且在 DAO 后面屏蔽它没有太大价值)。在这种情况下,我发现 DAO 是反DRY

    所以对于简单案例(实际上,大多数情况),我很乐意跳过 DAO,我对此没有任何问题。对于更复杂的情况(例如使用存储过程、平面文件时),我会使用它。换句话说,这取决于Has JPA Killed the DAO? 中的总结。另请参阅以下相关问题:

    相关问题

    (...) 一个包含实现我的 DAO 的会话 bean

    不,您当然不想将 DAO 实现为会话 Bean:

    • 您不想创建与表一样多的(池化)会话 Bean(资源浪费很大)
    • 您不想到处链接 Session Bean,也不想重现过去的错误,这是一种已知的不好的做法,不能很好地扩展。

    因此,如果您真的想采用 DAO 方式并希望注入 EM,请将您的 DAO 实现为 Spring bean(在 Java EE 5 中)或 CDI 托管 bean(在 Java EE 6 中)。

    您可以在内存中实现 DAO 来对您的服务层进行单元测试。

    如果你真的想做单元测试,mock DAO/EntityManager,没有区别。如果你想做集成测试,你可以配置 JPA 使用内存数据库。所以最后,我只是不认同这个论点。

    它将业务逻辑与数据库访问逻辑分开

    老实说,我看不出依赖 DAO 与依赖实体管理器之间的区别,我看不出 DAO 如何“更好地”分离事物。再说一次,我不认同这个论点。

    根据我的经验,更改底层持久性解决方案是一个非常特殊的事件,我不会为不太可能发生的事情引入 DAO(YAGNIKISS)。

    这里没有中间立场吗?有没有人遇到过一个架构或实现了一个架构,它满足了我上面提到的 DAO 层的一些好处(最重要的是业务逻辑的单元可测试性),但不涉及实现 DAO 层所涉及的所有开销?

    我看不到太多中间立场,正如强烈暗示的那样,如果我觉得没有必要,我不会使用 DAO。正如我所说,如果您想真正对业务逻辑进行单元测试,请模拟 EntityManager。它对我有用,我很乐意编写更少的代码。

    更多资源

    【讨论】:

    • 感谢您提供信息丰富的回复。如果您想看一下,我已经问过另一个问题,即在使用没有 DAO 的 JPA 时如何对 EJB 进行单元测试。 :D stackoverflow.com/questions/3834307/…
    • 为什么将 DAO 实现为 SLSB 在可扩展性方面是一种不好的做法?哪些问题与此相关,应用程序会在多大的“规模”上出现这样的问题?我很害怕在 Java EE 环境中使用 Spring,这也重现了过去的一个大错误....
    • @Pascal 我知道你的回答已经有好几年了,但据我所见,你已经混合了 DAO 和服务。我是新手,我想知道它是如何完成的。如果这不是不便,请给我一些代码示例。我真的很想了解如何有效地实施这一点。我想学这个。我想你可能是对的。我只是想了解为什么,所以我可以投票给你的答案。您是否拥有或知道执行此操作的某些系统的 Git 示例?谢谢。
    • 哦,很高兴我的东西在几年前就被分享了,太糟糕了,我当时没有发现它,我花了很长时间想知道这是否是个好主意,因为它没有t 与您自己开发的 DAO 层的“经典”相匹配。另请注意,如果您可以将应用程序中的搜索作为不同的组件来处理,则可以进一步减少对 DAO 层的需求。但是 EntityManager alnoe 对于整个 DAO 层来说有点短,您至少可以添加 JPAListener 连同它。由于托管实体的性质,您将需要它们来拦截每次写入。
    【解决方案2】:

    记录在案。

    对于单一职责原则 (SRP),DAO 是必须具备的,它将模型和逻辑分离在一个易于移植的持久层中。

    如果一个项目正在使用测试单元,那么 DAO 有助于对其进行正确测试(样机、数据库测试等)。

    DAO 是一种服务,就像一个服务一样,我们可以将我们的流程包装在一个易于维护的精美类中。

    JPA 减少了代码行数,但仅此而已,旧规则仍然适用。

    JPA 带来了存储库层,但它不是我们的存储库层。同样的原理,假设我们封装了一个逻辑,获取某个过程的利润。可能封装只是 0.1 的乘法,但仍然值得封装。

    例如,假设我有下一个问题:出于某种奇怪的原因,我可以在数据库中插入一个新客户端?我应该从哪里开始测试? a: ClientDao 如果存在,如果不存在,那么祝你在别处找到。

    【讨论】:

    • JPA 已经将模型和逻辑与持久层分离。你想再次分离它,这很好,而且通常很有用,但这不是 DAO 模式。您只是重新定义模式来描述您的实现。您所描述的内容听起来更像是facade,一种更通用的模式。
    • 不是特别 JPA 是分层的。例如,如果我想插入一个实体客户,它不像 em.Persist(customer) 那样简单,我需要“工厂”或“注入”实体管理器,然后我需要包装在 try catch 函数中并可能是我需要创建(并关闭)交易。如果在一个简单的例子中
    • 同意,但DAO pattern 是一个特例。如果我们说 DAO 是封装数据库并公开 API 的任何东西,那不是一个有用的定义,因为它不够具体。
    猜你喜欢
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 2012-07-17
    • 2011-06-22
    • 2014-12-08
    • 1970-01-01
    相关资源
    最近更新 更多