我正在设计一个基于JPA / Hibernate,Spring和Wicket的新应用。不过,DAO和Service层之间的区别对我来说还不清楚。根据维基百科,DAO是
一个为某种类型的数据库或持久性机制提供抽象接口的对象,提供一些特定的操作而不公开数据库的详细信息。
我想知道DAO是否可以包含与数据访问无关的方法,但是使用查询执行起来会更容易吗?例如,“获取在一组特定机场上运营的所有航空公司的列表”?在我看来,它更像是一种服务层方法,但是我不确定在服务层中使用JPA EntityManager是否是一种良好做法的示例?
DAO应该提供对单个相关数据源的访问,并且取决于业务模型的复杂程度,DAO 将返回完整的业务对象或简单的数据对象。无论哪种方式,DAO方法都应在某种程度上紧密反映数据库。
服务可以提供更高级别的界面,不仅可以处理你的业务对象,还可以首先访问它们。如果从服务获得业务对象,则可以从不同的数据库(和不同的DAO)创建该对象,并可以使用HTTP请求中的信息修饰该对象。它可能具有某些业务逻辑,可以将多个数据对象转换为单个健壮的业务对象。
我通常会创建一个DAO,以为将要使用该数据库或一组业务相关数据的任何人都将使用它,这实际上是数据库中触发器,函数和存储过程之外的最低级代码。
对特定问题的答案:
我想知道DAO是否可以包含与数据访问无关的方法,但是使用查询执行起来会更容易吗?
在大多数情况下,你不希望在服务层中使用更复杂的业务逻辑,即从单独的查询中组装数据。但是,如果你担心处理速度,那么即使服务层破坏了模型的美观性,服务层也可能会将动作委派给DAO,这与C ++程序员可以编写汇编代码来加快某些动作的方式几乎相同。
在我看来,它更像是一种服务层方法,但是我不确定在服务层中使用JPA EntityManager是否是一种良好做法的示例?
如果要在服务中使用实体管理器,那么可以将实体管理器视为DAO,因为这就是事实。如果你需要删除一些多余的查询构建,请不要在服务类中删除,将其提取到利用实体管理器的类中,然后将其制成DAO。如果你的用例真的很简单,则可以完全跳过服务层,而在控制器中使用实体管理器或DAO,因为你要做的所有服务都是将对getAirplaneById()DAO的调用传递出去findAirplaneById()
getAirplaneById()
findAirplaneById()
更新-为澄清下面的讨论,在大多数情况下(由于注释中突出显示的各种原因)还存在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... } }