DAO 和服务层(JPA/Hibernate + Spring)[重复]

2024-02-05

我正在设计一个基于 JPA/Hibernate、Spring 和 Wicket 的新应用程序。但我并不清楚 DAO 层和服务层之间的区别。根据维基百科,DAO 是

提供抽象的对象 某种类型数据库的接口或 持久化机制,提供一些 具体操作不暴露 数据库的详细信息。

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


DAO 应该提供对单个related数据源,并且根据您的业务模型的复杂程度,将返回完整的业务对象或简单的数据对象。无论哪种方式,DAO 方法都应该在某种程度上密切反映数据库。

服务可以提供更高级别的接口,不仅可以处理您的业务对象,还可以首先访问它们。如果我从服务获取业务对象,该对象可能是从不同的数据库(和不同的 DAO)创建的,它可以用 HTTP 请求生成的信息进行修饰。它可能具有将多个数据对象转换为单个、健壮的业务对象的特定业务逻辑。

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

具体问题的答案:

我想知道 DAO 是否可以 包含实际上并不具有的方法 对数据访问做很多事情,但是 使用查询更容易执行?

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

在我看来,这更像是 服务层方法,但我不确定 如果在中使用 JPA EntityManager 服务层就是一个很好的例子 实践?

如果您打算在服务中使用实体管理器,那么请将实体管理器视为您的 DAO,因为它就是这样。如果您需要删除一些冗余的查询构建,请不要在服务类中执行此操作,而是将其提取到利用实体管理器的类中,并将其设为您的 DAO。如果您的用例非常简单,您可以完全跳过服务层并使用实体管理器或控制器中的 DAO,因为您的所有服务要做的就是将调用传递给getAirplaneById()到 DAO 的findAirplaneById()

更新 - 为了澄清下面的讨论,在大多数情况下,在服务中使用实体管理器可能不是最佳决策,因为评论中强调了各种原因,还存在 DAO 层。但在我看来,这是完全合理的:

  1. 该服务需要与不同的数据集进行交互
  2. 至少一组数据已经有 DAO
  3. 服务类驻留在需要一定持久性的模块中,该持久性很简单,不保证有自己的 DAO

example.

//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...
   }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DAO 和服务层(JPA/Hibernate + Spring)[重复] 的相关文章

随机推荐