DAO和服务层(JPA/Hibernate + Spring)

Joh*_*nak 62 java architecture spring dao jpa

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

一个对象,它为某种类型的数据库或持久性机制提供抽象接口,提供一些特定的操作而不暴露数据库的细节.

我想知道DAO是否可以包含对数据访问没有太多帮助的方法,但使用查询更容易执行?例如"获取在某些机场运营的所有航空公司的清单"?听起来我更多的是服务层方法,但我不确定在服务层中使用JPA EntityManager是否是良好实践的一个例子?

wal*_*mon 52

DAO应该提供对单个相关数据源的访问,并且根据业务模型的复杂程度,将返回完全成熟的Business对象或简单的Data对象.无论哪种方式,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...
   }
}
Run Code Online (Sandbox Code Playgroud)

  • "两个都有DAO的集合并在服务层使用EntityManager会没问题吗?" - 这是什么意思?通过在服务层中使用JPA,您已经失去了拥有DAO接口的目的,这些接口抽象了持久性技术的选择 - 当然这是您拥有DAO层的目标.如果这个抽象不是一个目标,那么你真的不需要跳过假装有一个单独的层的箍. (7认同)

Sea*_*oyd 14

有一点是肯定的:如果在服务层上使用EntityManager,则不需要dao层(只有一层应该知道实现细节).除此之外,还有不同的意见:

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

第二种方法在关注点分离时更加优雅,它也可以更容易地从一种持久性技术切换到另一种持久性技术(你只需要用新技术重新实现dao接口),但如果你知道什么都没有会改变,第一个更容易.

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


Onu*_*nur 5

文章由亚当边可能是有用的.