为什么接口预测比使用Hibernate的Spring Data JPA中的构造函数预测和实体预测慢得多?

前端之家收集整理的这篇文章主要介绍了为什么接口预测比使用Hibernate的Spring Data JPA中的构造函数预测和实体预测慢得多?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我一直在想我应该使用哪种投影,所以我做了一点测试,其中包括5种类型的投影(基于文档:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections):

1.实体投射

这只是Spring Data存储库提供的标准findAll().没什么好看的.

服务:

List

实体:

@Entity
@Table(name = "SAMPLE_ENTITIES")
public class SampleEntity {
    @Id
    private Long id;
    private String name;
    private String city;
    private Integer age;
}

2.构造函数投影

服务:

List

库:

@Query("select new path.to.dto.NameOnlyDTO(e.name) from SampleEntity e")
List

数据传输对象:

@NoArgsConstructor
@AllArgsConstructor
public class NameOnlyDTO {
    private String name;
}

3.界面投影

服务:

List

库:

List

接口:

public interface NameOnly {
    String getName();
}

4.元组投影

服务:

List

库:

@Query("select e.name as name from SampleEntity e")
List

5.动态投影

服务:

List

库:

数据传输对象:

public class DynamicProjectionDTO {

    private String name;

    public DynamicProjectionDTO(String name) {
        this.name = name;
    }
}

一些额外的信息:

该项目是使用gradle spring boot插件(版本2.0.4)构建的,它使用了引擎盖下的Spring 5.0.8.数据库:内存中的H2.

结果:

Entity projections took 161.61 ms on average out of 100 iterations.
Constructor projections took 24.84 ms on average out of 100 iterations.
Interface projections took 252.26 ms on average out of 100 iterations.
Tuple projections took 21.41 ms on average out of 100 iterations.
Dynamic projections took 23.62 ms on average out of 100 iterations.
-----------------------------------------------------------------------
One iteration retrieved (from DB) and projected 100 000 objects.
-----------------------------------------------------------------------

笔记:

检索实体需要一些时间是可以理解的. Hibernate跟踪这些对象的更改,延迟加载等.

构造函数投影非常快,对DTO方面没有限制,但需要在@Query注释中创建手动对象.

接口预测结果非常缓慢.看问题.

元组预测是最快的,但不是最方便的.他们需要JPQL中的别名,并且必须通过调用.get(“name”)而不是.getName()来检索数据.

动态投影看起来很酷很快,但必须只有一个构造函数.不多也不少.否则Spring Data会抛出异常,因为它不知道使用哪一个(它需要构造函数参数来确定从DB检索哪些数据).

题:

为什么界面预测比检索实体需要更长的时间?返回的每个界面投影实际上都是代理.创建该代理是否如此昂贵?如果是这样,它是否会破坏预测的主要目的(因为它们意味着比实体更快)?其他投影看起来很棒.我真的很喜欢这方面的一些见解.谢谢.

编辑:
这是测试存储库:https://github.com/aurora-software-ks/spring-boot-projections-test,以防您想自己运行它.它很容易设置.自述文件包含您需要知道的所有内容.

最佳答案
我在旧版Spring Data中遇到了类似的行为,这是我对它的看法:https://blog.arnoldgalovics.com/how-much-projections-can-help/

我与Oliver Gierke(Spring Data主管)进行了一次谈话,并且他做了一些改进(这就是为什么你得到了如此“好”的结果:-))但是基本上总是需要抽象而不是手动编码.

这是其他一切的权衡.一方面,您获得灵活性,更容易开发,更少维护(希望如此),另一方面,您可以获得完全控制,有点丑陋的查询模型.

猜你在找的Spring相关文章