Java 使用Hibernate时使用服务和DAO获取DTO和实体的最佳实践

Java 使用Hibernate时使用服务和DAO获取DTO和实体的最佳实践,java,hibernate,service,repository,dto,Java,Hibernate,Service,Repository,Dto,**一,。服务使用:当你看到hibernate spring教程时,他们都说对于一个实体(例如我的例子中的用户),你必须有一个名为UserRepository的存储库,其中包含find、findAll、delete等方法。通常UserRepository会扩展一些基本存储库接口 然后您必须添加UserService,它将注入一个UserRepository a。我必须拥有一个由UserServiceImpl实现的UserService接口吗?在我看来,拥有这个接口没有任何价值。我可以让UserS

**一,。服务使用:当你看到hibernate spring教程时,他们都说对于一个实体(例如我的例子中的用户),你必须有一个名为UserRepository的存储库,其中包含find、findAll、delete等方法。通常UserRepository会扩展一些基本存储库接口

然后您必须添加UserService,它将注入一个UserRepository

a。我必须拥有一个由UserServiceImpl实现的UserService接口吗?在我看来,拥有这个接口没有任何价值。我可以让UserService成为一个类,并使用Spring的功能使用GCLIB而不是JDKInterfaces创建代理

b。通过从UserRepository复制每个方法并将其委托给@Autowired repository,然后添加任何其他业务方法来编写UserService是否正确

c。如果我的UserService没有任何业务方法,它只是将所有内容委托给UserRepository,我可以跳过UserService直接从REST层访问UserRepository吗

d。假设我还有一个地址实体。用户在保存时需要一个地址(这是一个one2one必填项)。UserService是否可以将UserRepository和AddressRepository都注入其中,在其中建立关系,然后对每个存储库调用save?(不想使用级联持久化,我想知道如果没有它,我该怎么办,因为在某些情况下,您不能使用级联)

2.DTO用法:当您想要读取数据时,您可以通过JPQL(或标准,我更喜欢JPQL)直接获取实体或DTO

a。在我看来,我总是使用DTO而不是实体获取。这是因为,我认为SQL很简单,如果我不得不考虑实体合并、分离、附加等,我会错过SQL的全部简单性,ORM在性能和复杂性方面成为敌人。因此,我在读取数据时总是使用DTO,在修改数据时总是使用实体。你觉得怎么样

b。我想返回用户实体中的所有列。有一个UserDTo可以吗?或者我太夸张了,应该只返回一个用户实体?我在这方面的支持率是50%-50%

c。我想从用户返回部分列。在这里,我代表75%的DTO和25%的实体。你觉得怎么样

d。我想返回一些User列和Address列。这里我100%支持DTO(尽管我可以加入FetchAddress)。你觉得怎么样


亲切的问候,

我会一一回答:

1.a)是的,这是有道理的。服务层是事务边界,在这里您可以通过课程粒度接口向外部世界公开业务逻辑

不,不是。UserService定义业务方法,而不是数据访问方法

1.c)我仍然会保留这项服务

1.d)当然是。您不需要通过实体名称调用服务。根据他们所表达的业务逻辑关注点来命名

2.a)我的规则很简单:当您计划修改实体和只读投影的DTO时

2.b)与2.a相同

2.c)与2.a.相同。如果以后需要修改提取的数据,请使用子实体


2.d)与2.a.相同。如果需要修改数据,请使用实体或子实体。否则,DTO将用于只读投影。

回答得很好!我想在2a规则中加入一个例外。有时,不能从服务层之外修改属性,例如。G类似于更新时间戳属性。在这种情况下,您应该使用具有可更新属性的DTO。有时,您将拥有另一组用于创建的属性。然后,您甚至应该为create.True使用另一种类型的DTO。服务层负责只返回允许修改的子实体版本,因此隐藏不应更新的属性。