Java EE架构 – 在使用像JPA 2这样的ORM时,DAO仍然是推荐的吗?

如果我使用的是像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,以便对您的服务层进行unit testing。 这意味着你不需要访问数据库来testing业务逻辑,你可以放心,你的对象将始终包含相同的属性值

  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层的某些好处的架构(最重要的是业务逻辑的单元可testing性),但是不涉及实现DAO层所涉及的所有开销?

感谢您的任何build议和/或build议! 我真的很好奇,看到有人提出这个问题。

如果我使用的是像JPA2那样的ORM – 我的实体映射到了我的数据库,那么我还应该使用DAO吗? 这似乎是更多的开销。

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

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

相关问题

  • 我发现JPA,或类似的,不鼓励DAO模式
  • EJB简单而好的模式
  • 什么是一个好的策略,隔离可以在线和离线使用的应用程序层?
  • 使用JSF,JPA和DAO。 没有spring?
  • 什么是jpa2 / eclipselink适当的DAO结构?

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

Noooo,你当然不希望实现一个会话Bean的DAO:

  • 你不想创build像表一样多的(共用的)会话Bean(大量的资源浪费)
  • 你不想把Session Beans链接到任何地方,也不会重现过去的错误,这是一个已知的不好的做法,不能很好地扩展。

所以,如果你真的想要使用DAO方式,并希望注入EM,可以将DAO实现为Spring bean(在Java EE 5中)或CDI managed bean(在Java EE 6中)。

您可以在内存中实现DAO,以便对您的服务层进行unit testing。

如果你真的想做单元testing,嘲笑DAO / EntityManager,没有什么区别。 如果你想做集成testing,你可以configurationJPA来使用内存数据库。 所以最后我只是不买这个说法。

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

老实说,我不认为依赖DAO和实体经理之间有很大的区别,我不明白DAO如何区分“更好”的东西。 再次,我不买这个说法。

根据我的经验,改变基础的持久性解决scheme是一个非常特殊的事情,我不打算将DAO引入很可能不会发生的事情( YAGNI , KISS )。

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

我没有看到太多的中间立场,并强烈暗示,如果我不觉得有必要,我不会使用DAO。 正如我所说,嘲笑EntityManager如果你想真正的unit testing的业务逻辑。 它适用于我,我很乐意编写更less的代码。

更多资源

  • JPA / EJB3杀死了DAO
  • DAO没有死 – 但是它们不是崩溃就是消失
  • …最后,你应该引入一个DAO如果:

作为logging。

对于单一责任原则(SRP), DAO是必须的 ,它将持久层中的模型和逻辑分开,可以轻松移植。

如果一个项目正在使用testing单元,则DAO有助于正确testing(模型,数据库testing等)。

DAO是一个服务,就像一个,我们可以把我们的过程包装在一个很容易维护的很好的类中。

JPA减less了代码行的数量,但是,不pipe怎样,旧规则仍然适用。

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

例如,假设我有下一个问题:出于某种奇怪的原因,我可以在数据库中插入一个新的客户端? 我应该在哪里开始testing? 答:ClientDao如果存在,如果不存在,那么祝你好运find其他地方。