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

标签 java spring hibernate jpa

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/

相关文章:

java - Spring Boot,通过 POST 从 InputStream 上传文件时出现 RestTemplate 异常

java - 在 Spring Framework 3.0 中同时使用 Hibernate 和 Jdbc

java - Hibernate HQL Count 和 Implicit Join 结果不同

java - 两种变体中列的多对多关系和命名

java.lang.NoClassDefFoundError : Could not initialize class org. mockito.internal.util.MockUtil

java - 访问 ArrayList 中每个数组的第一个元素并对所有元素求平均值

Java 性能运行时泛型

java - eclipse中的.sql文件,将其显示为表格?

java - getBean(Class<T> arg0) 在没有类型转换的情况下无法工作

java - Spring 中接口(interface)的依赖注入(inject)