存储库和服务层之间的区别

Posted

技术标签:

【中文标题】存储库和服务层之间的区别【英文标题】:Difference between Repository and Service layer 【发布时间】:2014-05-22 16:51:43 【问题描述】:

我查看了一些相关问题,但我仍然没有看到存储库和服务层之间有太大区别。所以给出的例子我想它应该是这样的,如果不是,请告诉我为什么?

public interface ProductRepository extends CrudRepository<Product, Long>

    public List<Product> findByName(String name);
    public List<Product> findByPrice(Double price);


public interface ProductService 

    public List<Product> findAll();
    public Product findById(Long id);
    public Product save(Product product);
    public void delete(Product product);
    public List<Product> findByName(String name);
    public List<Product> findByPrice(Double price);

ProductService 的实现将使用 ProductRepository 来实现这些方法。正如我从http://docs.spring.io/spring-data/jpa/docs/1.3.0.RELEASE/reference/html/jpa.repositories.html 了解到的,来自存储库的方法查询是自动生成的。在我的示例中,方法在存储库和服务中重复,所以请说明需要更改什么/为什么需要更改?

【问题讨论】:

【参考方案1】:

简单地说,我将举一个实际的例子.. 例如,如果您有 2 个数据源,一个来自本地数据库,另一个来自 Web api。 所以,存储库应该为你管理它,询问本地数据(你存在吗?从它的服务中获取它,如果不是服务,请从 api 获取数据......

所以我们将有 2 个服务(水 streams)将数据获取到 pool(存储库)。

【讨论】:

【参考方案2】:

在这种情况下,您似乎正在使用 Spring Data,其中存储库充当 DAO(它们定义了可用的数据库操作,并且这些方法的实现由框架生成)。服务层应该位于存储库之上,即它通过存储库访问数据。

其他答案并未指出您可能不需要服务层:如果您的实现看起来很简单(仅将实体传递给控制器​​而不进行任何处理),那么服务层可能是不必要的抽象级别你的申请。你应该只在有某种目的时才创建一个服务层。

【讨论】:

【参考方案3】:

您的所有业务逻辑都应该在服务层中。

对数据库(任何存储)的任何访问都应转到存储库层。

让我们举个例子。您必须保存一个实体(人)。但在保存 Person 之前,您要确保 Person 的 FirstName 不存在。

所以验证部分应该去业务层。

在服务层

PersonRepository repository; 
public Person save(Person p)
   Person p = findByName(p.getName();
   if (p != null)
          return some customException();
   
   return repository.save(p); 


public Person findByName(String name)
     return repository.findByName(name);

在您的存储库层中,只需专注于数据库操作。

您可以在存储库层中自行完成此操作。假设您已经在您的存储库中实现了这一点,那么您的保存方法总是在保存之前检查(有时您可能不需要这样做)。

【讨论】:

根据您的回复,我想我可以应用此架构:View&lt;--&gt;Controller( create instance of Model class)&lt;--&gt;Service&lt;---&gt;Repository . 是的。流程是正确的 view,Controller,Service,Repository 。在控制器中创建模型类并一直共享相同的实例到存储库取决于模型类的使用方式。如果模型没有缓存在任何地方(会话/存储库层),那就太好了。 不是每个“业务逻辑”都提供服务【参考方案4】:

存储库是一种数据访问模式,其中数据传输对象被传递到管理 CRUD 操作的存储库对象中。这种模式在您的数据访问机制可能发生显着变化的情况下很有用——例如。您希望在一个实现中使用不同的数据存储,例如 Oracle,在另一个实现中使用 SQL Server 甚至 HADOOP。

服务层是 SaaS 架构中常用的业务逻辑模式。使用服务层允许一个或多个表示实现通过通用接口访问您的业务逻辑。例如,如果您希望您的网站具有 API,您可以使用服务层来实现网站和 API 都会使用的通用后端功能。

前者应该主要关注数据访问,而后者应该关注业务逻辑。既不是强制性的,也不是必须伴随另一个。在简单的应用程序中,两种模式都可以由同一个类实现。

【讨论】:

所以我们只有在有很多数据库引擎的情况下才需要存储库。它具有ORM API的作用。【参考方案5】:

存储层为您提供了对数据访问的额外抽象级别。存储库层公开了基本的 CRUD 操作。

服务层暴露业务逻辑,使用存储库。

您可以在此处阅读更详细的答案: https://***.com/a/5049454/1446006

【讨论】:

【参考方案6】:

据我所知,存储库用于直接访问数据库。这是直接调用存储过程或任何数据存储机制的地方。

服务层是数据的 API。您通常会听到一些逻辑级别,或者在服务和存储库之间的另一个抽象层中。

例如,网站会调用您服务中的方法。您的服务会调用您的存储库以获取该数据,然后您的服务会以某种方式对其进行转换(构建对象、根据业务规则生成动态信息等),然后将其传递回网站。

【讨论】:

那么,在我的示例中,代表层和服务层是否正确?如果我有一些方法,比如 say validate(Product p) 它应该进入服务层? 我觉得没问题。很难说,因为它们只是接口,但基于你的 repo 扩展 CrudRepo 的想法,我假设它有一些保存/更新/删除功能,这似乎是正确的。至于验证,是的,我会在服务层上完成。通常我们有一个中间业务逻辑来处理这样的事情。因此,例如,服务调用调用 repo 的业务逻辑,但这取决于项目大小。

以上是关于存储库和服务层之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

存储库和服务之间的区别?

使用 Spring 从控制器层调用存储库和服务

使用Spring从控制器层调用存储库和服务

使用 DTO 在服务层和 UI 层之间传输数据

我的 Entity Framework 存储库和服务层方法应返回哪些类型:List、IEnumerable、IQueryable?

EF6(代码优先)、MVC、Unity 和没有存储库的服务层