Java EE架构 - 使用像JPA 2这样的ORM时,仍然建议使用DAO吗?

Bri*_*asa 47 java architecture dao java-ee jpa-2.0

如果我使用像JPA2这样的ORM - 我的实体映射到我的数据库,我还应该使用DAO吗?这似乎是一个更多的开销.

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

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

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

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

    public EmployeeJpaDAO implements EmployeeDAO {
        interface method implementations here
        ....
        private method that transform my Employee entity into my Employee domain object
    }
    
    Run Code Online (Sandbox Code Playgroud)

现在,每次我需要执行新的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();
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

感谢您的任何建议和/或建议!我真的很想知道有些人对此提出了什么建议.

Pas*_*ent 48

如果我使用像JPA2这样的ORM - 我的实体映射到我的数据库,我还应该使用DAO吗?这似乎是一个更多的开销.

它是.显然,Java EE不鼓励在使用JPA时使用DAO模式(JPA已经提供了域存储模式的标准化实现,并且在DAO背后屏蔽它没有多大价值).在这种情况下,我发现DAO是抗DRY的.

所以对于简单的情况(实际上,大多数情况),我很高兴跳过DAO,我没有问题.对于更复杂的情况(例如,当使用存储过程,平面文件时),我会使用它.换句话说,它取决于已经JPA杀死了DAO?.另请参阅以下相关问题:

相关问题

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

Noooo,您当然不希望将DAO实现为会话Bean:

  • 您不希望创建与表一样多(池化)的会话Bean(大量浪费资源)
  • 你不想在任何地方链接会话豆,不要重现过去的错误,这是一个不能很好地扩展的已知不良做法.

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

您可以使用DAO的内存实现来对服务层进行单元测试.

如果你真的想做单元测试,模拟DAO/EntityManager,没有区别.如果要进行集成测试,可以将JPA配置为使用内存数据库.所以最后,我只是不买这个论点.

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

老实说,我没有看到依赖DAO与实体经理之间存在很大差异,我不知道DAO如何将事情分开"更好".再说一遍,我不买这个论点.

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

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

我没有看到太多的中间立场,并且强烈暗示,如果我觉得不需要,我不会使用DAO.正如我所说,嘲笑EntityManager你是否真的需要对业务逻辑进行单元测试.它适用于我,我很乐意编写更少的代码.

更多资源


mag*_*nes 5

作为记录。

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

如果项目正在使用测试单元,那么 DAO 有助于正确测试它(模型、数据库测试等)。

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

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

JPA 带来了存储库层,但它不是我们的存储库层。同样的原理,假设我们封装了一个获取某个进程的利润的逻辑。也许封装只是简单地乘以 0.1,但它仍然值得封装。

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