Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA实体和DTO属于服务层还是Spring存储库层_Java_Spring_Hibernate_Jpa_Service Layer - Fatal编程技术网

Java JPA实体和DTO属于服务层还是Spring存储库层

Java JPA实体和DTO属于服务层还是Spring存储库层,java,spring,hibernate,jpa,service-layer,Java,Spring,Hibernate,Jpa,Service Layer,我想编写一个JPA应用程序,但在理解存储库和服务概念时遇到问题: 假设我们有3个实体: A、 B和C 实体A需要设置B和C:A.setB(B),A.setC(C)才能保存 同样对于read,我只想返回dto,因为它们将使我从中解脱出来,等等,对于修改数据,我将使用实体(本书中也描述了这些指导原则) 首先,用户将使用一些数据进行HTTP POST,这些数据将转换为ABCGuiObject。REST控制器将调用serviceA.save(ABCGuiObject) 持久化选项: 选项1 -该服务将创

我想编写一个JPA应用程序,但在理解存储库和服务概念时遇到问题:

假设我们有3个实体: A、 B和C

实体A需要设置B和C:A.setB(B),A.setC(C)才能保存

同样对于read,我只想返回dto,因为它们将使我从中解脱出来,等等,对于修改数据,我将使用实体(本书中也描述了这些指导原则)

首先,用户将使用一些数据进行HTTP POST,这些数据将转换为ABCGuiObject。REST控制器将调用serviceA.save(ABCGuiObject)

持久化选项:

选项1 -该服务将创建3个对象A、B、C,并将它们传递给repositoryA.save(A、B、C)。在a.setB和a.setC内进行重置

选项2 -该服务将创建3个对象A、B、C、do A.setB和A.setC,并调用repositoryA.save(A)

DTO检索

我想编写一个JPQL查询来获取一些DTO。我不想将实体转换为DTO,而是直接用JPQL检索它们

选项1 -Repositoria将直接返回DTO

选项2 -该服务将向repositoryA传递一个JPQL查询,它将具有一个返回DTO的通用查询方法

你推荐什么方法

写入数据 服务层应该构建实体
A
B
C
的图形,并相应地将它们连接起来(
A.setB
A.setC
),并将
A
B
C
传递到存储库。如果你有一对多的关联,你可以

读取数据 如果您想返回DTO,最好直接从JPA和Hibernate获取DTO。因此,您有两种选择:

  • 你可以用
  • 您可以使用特定于Hibernate的

    • 这是一件主观的事情,但我将分享我的观点。 对于持久化选项,我推荐选项2。理想情况下,存储库应该只执行“存储库”职责、服务,或者如果过于复杂,您可以委托工厂来构建实体

      对于DTO检索,我将发出查询来检索实体(因此存储库将始终返回实体),并将它们转换为DTO。有些人可能需要相同的存储库功能,他们可以选择转换为DTO,而不是使用DTO查询编写另一个JPQL

      保留选项2


      DTO对象通常加载惰性字段。如果不为不同的用例编写单独的查询/映射,这可能会损害性能。不要使用DTO,而是根据用例初始化惰性字段,以避免LazyinitializationException。此外,它还将为您节省大量从实体映射到实体的工作以进行保存。

      关于持久化,我选择选项2,但不是所有与服务相关的操作。如果您有一些简单的操作,例如addComment、enable/disable,那么最好只传递ID,让服务控制实体本身


      对于DTO,我建议您让Blaze持久性实体视图看看DTO模式的实现有多容易。这是一个很好的入门指南。

      DTO不会加载惰性字段。我认为我将在JPQL中编写手动连接,并且过滤将在数据库级别完成,因此只有相关信息才会出现。我不会使用连接获取或获取实体,然后将它们转换为DTO。是的,这取决于您如何将实体映射到DTO。使用像Dozer collection这样的映射框架将加载alwyas。这在性能方面不是最优的。Vlad但是我需要为每个实体类创建一个存储库吗?我从您那里了解到,该服务将从ABCGuiObject构建3个实体类,然后以正确的顺序或使用级联调用repositoryA.save(a)、repositoryB.save(b)和respoitoryC.save(c)。这是正确的吗?另外,对于DTO,有人说从存储库返回DTO是不合适的,可能是因为您将DTO转发到服务,然后再进行REST。您对此有何看法?Spring数据要求您为每个实体类型创建一个存储库。当然,对于DTO,您需要从存储库返回它们。否则,您将选择实体,然后将它们转换为DTO。但是,当您只需要DTO投影时,为什么要选择多个列来获取实体呢?但是服务层呢?我应该为每个实体类提供服务,还是为具有相关业务方法和调用存储库(视情况而定)的一般服务?在我看来,服务层与业务逻辑相关,而不是与分割实体的方式相关。但是,这更像是一个偏好问题,这是一个主观问题。@Vlad我很高兴我找到了这个答案。正如您提到的,存储库可以返回DTO进行检索。我应该为服务层创建另一个(类似)dto,将repo dto映射到服务dto并返回它,还是应该从repo返回dto。如果来自repo的DTO退出服务,我从控制器调用我的服务,我会直接访问我的repo层对象吗?例如,从Controller中的repo层导入?这不是紧密耦合吗?但是,当通过JPQL构造DTO更有效时,为什么要返回实体然后将它们转换为DTO呢?您知道要选择的数据和连接在数据库级别进行过滤,而不是通过Hibernate在内存中进行过滤。实体也是POJO,可以在UI层中使用。保存时无需将它们映射到DTO并返回到实体。当事务仍处于活动状态时,可以使用
      .size()
      获取惰性集合,例如在EJB方法内部。@user3030447“内存占用”参数在目前的大多数情况下都不起作用。大多数情况下,加载少量实体并将其转换为DTO实际上不是问题。即使在报告中,您也不应该加载超过几千条记录。映射到DTO为您提供了更大的灵活性