为什么在使用数据库时,您更喜欢 Java 8 Stream API 而不是直接休眠/sql 查询

2022-09-01 19:39:27

最近,我在几个项目中看到很多代码使用流来过滤对象,例如:

library.stream()
          .map(book -> book.getAuthor())
          .filter(author -> author.getAge() >= 50)
          .map(Author::getSurname)
          .map(String::toUpperCase)
          .distinct()
          .limit(15)
          .collect(toList()));

使用它而不是直接向返回已筛选结果的数据库进行HQL / SQL查询是否有任何好处?

难道第二个哄哆不是快得多吗?


答案 1

如果数据最初来自数据库,则最好在数据库中进行筛选,而不是获取所有内容并在本地进行筛选。

首先,数据库管理系统擅长过滤,这是其主要工作的一部分,因此它们为此进行了优化。还可以通过使用索引来加快筛选速度。

其次,在进行本地过滤时,获取和传输许多记录并将数据解构到对象中只是为了丢弃大量记录,这是对带宽和计算资源的浪费。


答案 2

乍一看:可以使流并行运行;只需将代码更改为使用 .(免责声明:当然,这取决于特定的上下文,如果只是改变流类型会导致正确的结果;但是,是的,它可以很容易)。parallelStream()

然后:流“邀请”以使用 lambda 表达式。而这些反过来又导致使用invoke_dynamic字节码指令;有时与编写此类代码的“老派”相比,有时会获得性能优势。(并澄清误解:invoke_dynamic是lambdas的属性,而不是流!

这些是现在更喜欢“流”解决方案的原因(从一般角度来看)。

除此之外:这真的取决于...让我们看一下您的示例输入。这看起来像是处理普通的Java POJO,它已经驻留在内存中,在某种集合中。直接在内存中处理此类对象肯定比去一些进程外数据库在那里工作更快!

但是,当然:当上述调用时,就像会做“深入研究”并实际与底层数据库交谈一样;那么“在单个查询中执行整个操作”可能会为您提供更好的性能。book.getAuthor()


推荐