DAO 和服务层(JPA/休眠 + 弹簧)

2022-08-31 15:56:49

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

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

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


答案 1

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

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

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

具体问题的解答:

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

在大多数情况下,不需要,您需要在服务层中更复杂的业务逻辑,即从单独的查询中组装数据。但是,如果您担心处理速度,服务层可能会将操作委托给DAO,即使它破坏了模型的美感,就像C++程序员可以编写汇编程序代码以加速某些操作一样。

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

如果您要在服务中使用实体管理器,请将实体管理器视为您的DAO,因为这正是它。如果需要删除一些冗余的查询生成,请不要在服务类中执行此操作,将其提取到利用实体管理器的类中,并将其作为 DAO。如果你的用例真的很简单,你可以完全跳过服务层,在控制器中使用你的实体管理器或DAO,因为你的服务要做的就是将调用传递给DAO的getAirplaneById()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...
   }
}

答案 2

有一件事是肯定的:如果你在服务层上使用EntityManager,你不需要一个dao层(只有一个层应该知道实现细节)。除此之外,还有不同的看法:

  • 有人说EntityManager公开了所有需要的dao功能,因此他们在服务层中注入了EntityManager。
  • 其他人有一个由接口支持的传统dao层(因此服务层不依赖于实现细节)。

第二种方法在关注点分离方面更加优雅,它也将使从一种持久性技术切换到另一种技术变得更加容易(你只需要用新技术重新实现dao接口),但是如果你知道什么都不会改变,第一种方法就更容易了。

我想说的是,如果你有一个小项目,在服务层中使用JPA,但在大型项目中使用专用的DAO层。


推荐