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

Java 存储库和服务层之间的区别,java,service,repository,data-access-layer,Java,Service,Repository,Data Access Layer,我浏览了一些相关的问题,但仍然没有看到存储库和服务层之间有什么区别。举个例子,我想应该是这样的,如果不是,请告诉我为什么 public interface ProductRepository extends CrudRepository<Product, Long>{ public List<Product> findByName(String name); public List<Product> findByPrice(Double pr

我浏览了一些相关的问题,但仍然没有看到存储库和服务层之间有什么区别。举个例子,我想应该是这样的,如果不是,请告诉我为什么

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);
}
公共接口ProductRepository扩展了Crudepository{
公共列表findByName(字符串名称);
公共清单定价(双倍价格);
}
公共接口产品服务{
公共列表findAll();
公共产品findById(长id);
公共产品储蓄(产品);
公共作废删除(产品);
公共列表findByName(字符串名称);
公共清单定价(双倍价格);
}

ProductService的实现将使用ProductRepository来实现这些方法。据我所知,从存储库中查询方法是自动生成的。在我的示例中,这些方法在存储库和服务中重复,因此请解释需要更改的内容/原因?

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

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


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

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

服务层公开使用存储库的业务逻辑

您可以在此处阅读更详细的答案:


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

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


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

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

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

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

因此,验证部分应该转到业务层

在服务层中

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);
}
在您的存储库层中,只需关注数据库操作


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

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


其他答案没有指出您可能不需要服务层:如果您的实现看起来很简单(只将实体传递给控制器而不进行任何处理),那么服务层可能是应用程序中不必要的抽象级别。您应该只在服务层有某种用途时创建它。

那么,在我的示例中,代表层和服务层是否正确?如果我有一些方法,比如说验证(产品p),它应该进入服务层?我觉得没问题。很难说,因为它们只是接口,但基于您的repo扩展了CrudRepo的想法,我认为它有一些保存/更新/删除功能,这似乎是正确的。至于验证,是的,我希望在服务层进行验证。通常我们有一个中间业务逻辑来处理类似的事情。例如,服务调用业务逻辑,业务逻辑调用repo,但这取决于项目大小。因此,只有在有许多数据库引擎的情况下,我们才需要存储库。它具有ORM API的角色。根据您的回答,我想我可以应用此模式:
ViewController(创建模型类的实例)servicepository。
yes。流程是正确的视图、控制器、服务和存储库。在controller中创建模型类并在存储库中共享同一实例的方法取决于模型类的使用方式。如果模型没有缓存到任何地方(会话/存储库层),那么就完全可以了