rku*_*dva 4 java mysql jooq java-stream
这是我想在 MySQL 中尝试的查询
SELECT A.x
FROM A
WHERE A.y = 'P'
UNION
SELECT A.x
FROM A
WHERE A.y = 'Q'
Run Code Online (Sandbox Code Playgroud)
以上是我正在尝试的原始查询的简化版本。在我的原始查询中,每个SELECT语句都涉及多个表INNER JOIN
如果我需要查询的表 'A' 的 'y' 列中可能的值数是 'n',那么我的查询将涉及对 'n'SELECT语句执行 'n-1' 联合
我知道 JOOQ 可以合并多个SELECT语句。但是有没有一个很好的方法来做这个 Java 8 风格的帖子?也许使用 Steam.collect()?
这就是我所拥有的,但想知道我是否可以做得更好
String firstValueToQuery = valuesToQuery.get(0);
Select<Record5<UUID, UUID, String, Integer, String>> selectQuery = getSelectQueryForValue(firstValueToQuery);
valuesToQuery.stream()
.skip(1)
.forEach(valueToQuery -> selectQuery.unionAll(getSelectQueryForValue(valueToQuery)));
selectQuery.fetchStream();
Run Code Online (Sandbox Code Playgroud)
这是我的实施方式 getSelectQueryForValue
private Select<Record5<UUID, UUID, String, Integer, String>> getSelectQueryForValue(String valueToQuery) {
return jooq.select(
A.P,
A.Q,
A.R,
A.S,
A.T)
.from(A)
.where(A.Y.eq(valueToQuery));
}
Run Code Online (Sandbox Code Playgroud)
PS:我知道我宁愿使用下面的“IN”子句
SELECT A.x
FROM A
WHERE A.y IN ('P','Q',...)
Run Code Online (Sandbox Code Playgroud)
但是根据我当前在数据库中的数据分布,MySQL 使用的是次优查询计划。因此使用 UNION 以便数据库通过使用正确的索引隐式地更喜欢更快的查询计划
这里的惯用方法如下(使用 JDK 9 API):
try (Stream<Record5<UUID, UUID, String, Integer, String>> stream = valuesToQuery
.stream()
.map(this::getSelectQueryForValue)
.reduce(Select::union)
.stream() // JDK 9 method
.flatMap(Select::fetchStream)) {
...
}
Run Code Online (Sandbox Code Playgroud)
它使用了有用的Optional.stream()方法,该方法是在 JDK 9 中添加的。在 JDK 8 中,您可以这样做:
valuesToQuery
.stream()
.map(this::getSelectQueryForValue)
.reduce(Select::union)
.ifPresent(s -> {
try (Stream<Record5<UUID, UUID, String, Integer, String>> stream =
s.fetchStream()) {
...
}
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
695 次 |
| 最近记录: |