繁体   English   中英

JOOQ 多选计数与 PostgreSQL 一次连接

[英]JOOQ multiple select count in one connection with PostgreSQL

我有一个表SUBSCRIPTION ,我想在一个连接中运行多个用selectCount编写的selectCount与数据库的不同谓词。 为此,我创建了一个查询列表:

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的返回值中有上述查询的结果,但我得到一个填充了0值的整数数组。

这是使用 JOOQ 运行多个selectCount的正确方法吗? execute方法返回的整数数组的意义是什么?

我在 JOOQ 博客中检查了这个链接,谈论“如何在单个查询中计算多个聚合函数”,但它只是关于 SQL 查询,没有 JOOQ 方言。

对你的假设的评论

我希望在 execute 的返回值中包含上述查询的结果,但我得到了一个填充为 0 值的整数数组。

batch() API 只能用于 DML 查询( INSERTUPDATEDELETE ),就像原生 JDBC 一样。 我的意思是,您可以批量运行查询,但不能以这种方式获取结果。

我在 JOOQ 博客中检查了这个链接,谈论“如何在单个查询中计算多个聚合函数”,但它只是关于 SQL 查询,没有 JOOQ 方言。

普通 SQL 查询几乎总是从字面上转换为 jOOQ,因此您也可以在您的案例中应用该文章中的技术。 事实上,你应该! 运行这么多查询绝对不是一个好主意。

将该链接查询翻译为 jOOQ

因此,让我们看看如何将简单的 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();

现在生成一个表,每个代码有一个计数值。 或者,将其提取到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());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM