小编典典

DAO and Service layers (JPA/Hibernate + Spring)

spring

我正在设计一个基于JPA / Hibernate,Spring和Wicket的新应用。不过,DAO和Service层之间的区别对我来说还不清楚。根据维基百科,DAO是

一个为某种类型的数据库或持久性机制提供抽象接口的对象,提供一些特定的操作而不公开数据库的详细信息。

我想知道DAO是否可以包含与数据访问无关的方法,但是使用查询执行起来会更容易吗?例如,“获取在一组特定机场上运营的所有航空公司的列表”?在我看来,它更像是一种服务层方法,但是我不确定在服务层中使用JPA EntityManager是否是一种良好做法的示例?


阅读 389

收藏
2020-04-17

共1个答案

小编典典

DAO应该提供对单个相关数据源的访问,并且取决于业务模型的复杂程度,DAO 将返回完整的业务对象或简单的数据对象。无论哪种方式,DAO方法都应在某种程度上紧密反映数据库。

服务可以提供更高级别的界面,不仅可以处理你的业务对象,还可以首先访问它们。如果从服务获得业务对象,则可以从不同的数据库(和不同的DAO)创建该对象,并可以使用HTTP请求中的信息修饰该对象。它可能具有某些业务逻辑,可以将多个数据对象转换为单个健壮的业务对象。

我通常会创建一个DAO,以为将要使用该数据库或一组业务相关数据的任何人都将使用它,这实际上是数据库中触发器,函数和存储过程之外的最低级代码。

对特定问题的答案:

我想知道DAO是否可以包含与数据访问无关的方法,但是使用查询执行起来会更容易吗?

在大多数情况下,你不希望在服务层中使用更复杂的业务逻辑,即从单独的查询中组装数据。但是,如果你担心处理速度,那么即使服务层破坏了模型的美观性,服务层也可能会将动作委派给DAO,这与C ++程序员可以编写汇编代码来加快某些动作的方式几乎相同。

在我看来,它更像是一种服务层方法,但是我不确定在服务层中使用JPA EntityManager是否是一种良好做法的示例?

如果要在服务中使用实体管理器,那么可以将实体管理器视为DAO,因为这就是事实。如果你需要删除一些多余的查询构建,请不要在服务类中删除,将其提取到利用实体管理器的类中,然后将其制成DAO。如果你的用例真的很简单,则可以完全跳过服务层,而在控制器中使用实体管理器或DAO,因为你要做的所有服务都是将对getAirplaneById()DAO的调用传递出去findAirplaneById()

更新-为澄清下面的讨论,在大多数情况下(由于注释中突出显示的各种原因)还存在DAO层的情况下,在服务中使用实体管理器可能不是最佳决定。但我认为,鉴于以下情况,这将是完全合理的:

  1. 服务需要与不同的数据集进行交互
  2. 至少一组数据已经具有DAO
  3. 服务类驻留在需要一些持久性的模块中,该持久性足够简单以至于不能保证其自己的DAO
    例。
//some system that contains all our customers information
class PersonDao {
   findPersonBySSN( long ssn )
}

//some other system where we store pets
class PetDao {
   findPetsByAreaCode()
   findCatByFullName()
}

//some web portal your building has this service
class OurPortalPetLostAndFoundService {

   notifyOfLocalLostPets( Person p ) {
      Location l = ourPortalEntityManager.findSingle( PortalUser.class, p.getSSN() )
        .getOptions().getLocation();
      ... use other DAO's to get contact information and pets...
   }
}
2020-04-17