我正在设计一个基于 JPA/Hibernate、Spring 和 Wicket 的新应用程序。 DAO 和服务层之间的区别对我来说并不是那么清楚。根据维基百科,DAO 是
an object that provides an abstract interface to some type of database or persistence mechanism, providing some specific operations without exposing details of the database.
我想知道 DAO 是否可以包含实际上不需要对数据访问做太多事情但使用查询更容易执行的方法?例如“获取在特定机场运营的所有航空公司的列表”?在我看来,这更像是一种服务层方法,但我不确定在服务层中使用 JPA EntityManager 是否是一个好的实践示例?
最佳答案
DAO 应提供对单个相关数据源的访问,并且根据您的业务模型的复杂程度,将返回完整的业务对象或简单的数据对象。无论哪种方式,DAO 方法都应该更接近地反射(reflect)数据库。
服务可以提供更高级别的接口(interface),不仅可以处理您的业务对象,还可以首先访问它们。如果我从服务中获取业务对象,则该对象可能是从不同的数据库(和不同的 DAO)创建的,它可以用来自 HTTP 请求的信息进行修饰。它可能具有将多个数据对象转换为单个、健壮的业务对象的特定业务逻辑。
我通常创建一个 DAO,认为它将被任何将使用该数据库或一组业务相关数据的人使用,它实际上是数据库中除触发器、函数和存储过程之外的最低级别的代码。
具体问题的答案:
I was wondering whether a DAO could contain methods that don't really have to do much with data access, but are way easier executed using a query?
在大多数情况下不,您会希望在服务层中使用更复杂的业务逻辑,即来自不同查询的数据组合。但是,如果您关心处理速度,服务层可能会将操作委托(delegate)给 DAO,即使它破坏了模型的美感,就像 C++ 程序员可能编写汇编代码来加速某些操作一样。
It sounds to me to be more of a service-layer method, but I'm not sure if using JPA EntityManager in the service layer is an example of good practice?
如果您要在服务中使用实体管理器,请将实体管理器视为您的 DAO,因为它就是这样。如果您需要删除一些多余的查询构建,请不要在您的服务类中这样做,将其提取到使用实体管理器的类中并使其成为您的 DAO。如果您的用例非常简单,您可以完全跳过服务层并使用实体管理器或 Controller 中的 DAO,因为您的服务要做的就是将对 getAirplaneById()
的调用传递给DAO 的 findAirplaneById()
更新 - 为了澄清下面的讨论,在大多数情况下,由于评论中强调的各种原因,在服务中使用实体管理器可能不是最佳决策。但在我看来,这是完全合理的:
- 服务需要与不同的数据集交互
- 至少一组数据已经有一个 DAO
- 服务类驻留在需要一些持久性的模块中,这很简单,不保证它自己的 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...
}
}
关于java - DAO 和服务层(JPA/Hibernate + Spring),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3882108/