gpt4 book ai didi

java - 在 JPA/Hibernate 中执行只读操作的最佳实践是什么?

转载 作者:行者123 更新时间:2023-12-05 05:37:09 27 4
gpt4 key购买 nike

28.6 hibernate 手册中提到您不应该使用实体查询进行只读获取,因为它们会请求太多数据。

这是有道理的,我们已经看到复杂的领域模型会导致查询运行时间非常长,尤其是在使用 TableView 时。

手册继续指出:

For read-only transactions, you should fetch DTO projections because they allow you to select just as many columns as you need to fulfill a certain business use case.

但是 AFAIK JPA 没有提供获取这些预测的好方法,您只能使用标准构建器,我们发现它冗长、脆弱并且经常无法正常工作(实现很困难)。

确实,查看 SO 上的各种帖子表明很多人都在使用实体进行读取。所以我提出的问题如下:

  1. 正在避免在现实世界的企业应用程序中常见的只读实体查询,我觉得它不是。
  2. 如果是,人们使用什么工具来使它变得可以忍受,我想到了一个单独的查询 dsl,jOOQ?
  3. 是否有任何资源为连接到持久层的 Spring 应用程序的架构制定了最佳实践(我正在考虑可能导致问题的其他复杂问题,例如事务管理),似乎每个人似乎采取了一种特别的方法。

最佳答案

你要明白,没有绝对的答案,每个人都会根据自己的经验给你不同的建议/意见。

通常,首选的解决方案是使用 DTO 方法,但如何实现它留给开发人员练习。一些开发人员太懒惰或只是接受/应对使用实体查询可能带来的负面影响。这实际上取决于您的用例和需求。

不过我认为,您正在寻找的是类似 Blaze-Persistence Entity Views 的解决方案.

我创建了该库以允许在 JPA 模型和自定义接口(interface)或抽象类定义的模型之间轻松映射,类似于 Spring Data Projections on steroids。这个想法是您按照自己喜欢的方式定义目标结构(领域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

使用 Blaze-Persistence 实体 View 的示例用例的 DTO 模型如下所示:

@EntityView(User.class)
public interface UserDto {
@IdMapping
Long getId();
String getName();
Set<RoleDto> getRoles();

@EntityView(Role.class)
interface RoleDto {
@IdMapping
Long getId();
String getName();
}
}

查询是将实体 View 应用于查询,最简单的就是通过 id 进行查询。

UserDto a = entityViewManager.find(entityManager, UserDto.class, id);

Spring Data 集成允许您像使用 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

Page<UserDto> findAll(Pageable pageable);

最好的部分是,它只会获取实际需要的状态!

关于java - 在 JPA/Hibernate 中执行只读操作的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73177513/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com