JOOQ multiple select count in one connection 与 PostgreSQL
JOOQ multiple select count in one connection with PostgreSQL
我有一个 table SUBSCRIPTION
,我想 运行 多个 selectCount
用 JOOQ 在一个连接中用不同的谓词连接到数据库。
为此,我创建了一个查询列表:
List<Query> countQueries = channels.stream().map(c ->
selectCount().from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.equal(c))
).collect(toList());
最后,我使用 batch
:
启动了这个查询列表
using(configuration).batch(countQueries).execute();
我原本希望在 execute
的 return 值中得到上述查询的结果,但我得到了一个填充了 0
值的整数数组。
这是使用 JOOQ 运行 多个 selectCount
的正确方法吗?
用execute
方法return得到的整型数组是什么意思?
我在 JOOQ 博客中查看了这个 link,谈论“如何在单个查询中计算多个聚合函数”,但它只是关于 SQL 查询,没有 JOOQ 方言。
对您的假设的评论
I have expected to have the results of the above queries in the return values of execute, but I get an array of integer filled with 0 values.
batch()
API 只能用于 DML 查询(INSERT
、UPDATE
、DELETE
),就像原生 [=44] =].我的意思是,您可以 运行 批量查询,但您无法通过这种方式获取结果。
I have checked this link, in the JOOQ blog, talking about "How to Calculate Multiple Aggregate Functions in a Single Query", but It's just about SQL queries, no JOOQ dialects.
普通 SQL 查询几乎总是按字面意思翻译成 jOOQ,因此您也可以在您的案例中应用那篇文章中的技术。事实上,你应该! 运行这么多查询肯定不是个好主意。
将 linked 查询翻译成 jOOQ
那么,让我们看看如何将 link 中的简单 SQL 示例翻译成您的案例:
Record record =
ctx.select(
channels.stream()
.map(c -> count().filterWhere(CHANNEL.CODE.equal(c)).as(c))
.collect(toList())
)
.from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.in(channels)) // Not strictly necessary, but might speed up things
.fetch();
这将生成包含所有计数值的单个记录。
一如既往,这是假设以下静态导入
import static org.jooq.impl.DSL.*;
使用经典 GROUP BY
当然,您也可以在特定情况下只使用经典 GROUP BY
。这甚至可能会更快一些:
Result<?> result =
ctx.select(CHANNEL.CODE, count())
.from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.in(channels)) // This time, you need to filter
.groupBy(CHANNEL.CODE)
.fetchOne();
这现在生成一个 table,每个代码有一个计数值。或者,将其提取到 Map<String, Integer>
:
Map<String, Integer> map =
ctx.select(CHANNEL.CODE, count())
.from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.in(channels))
.groupBy(CHANNEL.CODE)
.fetchMap(CHANNEL.CODE, count());
我有一个 table SUBSCRIPTION
,我想 运行 多个 selectCount
用 JOOQ 在一个连接中用不同的谓词连接到数据库。
为此,我创建了一个查询列表:
List<Query> countQueries = channels.stream().map(c ->
selectCount().from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.equal(c))
).collect(toList());
最后,我使用 batch
:
using(configuration).batch(countQueries).execute();
我原本希望在 execute
的 return 值中得到上述查询的结果,但我得到了一个填充了 0
值的整数数组。
这是使用 JOOQ 运行 多个 selectCount
的正确方法吗?
用execute
方法return得到的整型数组是什么意思?
我在 JOOQ 博客中查看了这个 link,谈论“如何在单个查询中计算多个聚合函数”,但它只是关于 SQL 查询,没有 JOOQ 方言。
对您的假设的评论
I have expected to have the results of the above queries in the return values of execute, but I get an array of integer filled with 0 values.
batch()
API 只能用于 DML 查询(INSERT
、UPDATE
、DELETE
),就像原生 [=44] =].我的意思是,您可以 运行 批量查询,但您无法通过这种方式获取结果。
I have checked this link, in the JOOQ blog, talking about "How to Calculate Multiple Aggregate Functions in a Single Query", but It's just about SQL queries, no JOOQ dialects.
普通 SQL 查询几乎总是按字面意思翻译成 jOOQ,因此您也可以在您的案例中应用那篇文章中的技术。事实上,你应该! 运行这么多查询肯定不是个好主意。
将 linked 查询翻译成 jOOQ
那么,让我们看看如何将 link 中的简单 SQL 示例翻译成您的案例:
Record record =
ctx.select(
channels.stream()
.map(c -> count().filterWhere(CHANNEL.CODE.equal(c)).as(c))
.collect(toList())
)
.from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.in(channels)) // Not strictly necessary, but might speed up things
.fetch();
这将生成包含所有计数值的单个记录。
一如既往,这是假设以下静态导入
import static org.jooq.impl.DSL.*;
使用经典 GROUP BY
当然,您也可以在特定情况下只使用经典 GROUP BY
。这甚至可能会更快一些:
Result<?> result =
ctx.select(CHANNEL.CODE, count())
.from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.in(channels)) // This time, you need to filter
.groupBy(CHANNEL.CODE)
.fetchOne();
这现在生成一个 table,每个代码有一个计数值。或者,将其提取到 Map<String, Integer>
:
Map<String, Integer> map =
ctx.select(CHANNEL.CODE, count())
.from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.in(channels))
.groupBy(CHANNEL.CODE)
.fetchMap(CHANNEL.CODE, count());