当前位置: 首页 > 知识库问答 >
问题:

jOOQ动态带子句

施锋
2023-03-14

我找不到关于如何动态构造with子句的留档。jOOQ中常见的表表达式/CTE)。我的用例是这样的:

  • 我需要嵌套动态创建的列,以便从这些动态创建的列中生成新数据
  • 例如,我正在创建一个新字段,它是完全外部联接的非空结果。此字段仅在查询执行时可用,因此我需要将其存储在WITH子句中,以便在其他查询中引用它以进行其他计算
  • 理想情况下,我可以动态地请求WITH子句类型的查询,通过将这个连接的数据集放在它自己的CTE中,以便在下游引用中使用,可以整理出这种依赖关系

我试图使用以下方法,但运气不佳:

    SelectQuery<Record> query =
        getQuery(
            dslContext,
            selectFields,
            fromClause,
            groupFields,
            conditionClause,
            orderFields,
            query.getOffset(),
            query.getLimit());

    // WORKS JUST FINE
    Supplier<Stream<Map<String, Object>>> results = () ->
        query
            .fetchStream()
            .map(Record::intoMap);

    // make a nested query here. static for now.
    // DOES NOT WORK
    Supplier<Stream<Map<String, Object>>> resultsWith =
        () ->
            DSL.with("s1")
                .as(query) // Shouldn't I be able to reference a SelectQuery here?
                .select()
                .from(table(name("s1")))
                .fetchStream()
                .map(Record::intoMap);

查询toString()看起来像这样:

select 
  table1.field1,
  coalesce( 
    table1.id, 
    table2.id) as table1.id_table2.id, 
  count(*) as table2.field1.count, 
  sum(table2.field2) as table2.field2.sum
  from table1.table1 as table1
  full outer join table2.table2 as table2
  on table1.id = table2.id
  where table1.field2 < 3000.0
  group by 
  table1.id_table2.id,
  table1.field1
  order by table1.field1 asc
  limit 100

我最起码想做的是在其他下游查询中引用上面的合并字段。理想情况下,当在jOOQ中构造一个AND子句时,我可以使用的动态引用的方式或数量完全不受限制。最后,我希望能够动态创建这样的查询,这些查询也显示了引用CTE的CTE:

-- WITH Clause usage is preferrable
with
  myFirstSelection as (
    select
      (id + 100) as newfield
    from table1.table1 n
  ),
  mySecondSelection as (
    select
      (newField + 200) as newerField
    from myFirstSelection
  )
select
* 
from mySecondSelection
;

-- Inline queries, while not ideal, would be permissible
select 
* 
from (
  select
  (newField + 200) as newerField
  from (
    select
      (id + 100) as newField
    from table1.table1 n
  ) as myFirstSelection
) as mySecondSelection
;

这可能吗?还是我仅限于静态表和静态选择?

  • 不支持“WITH”子句
  • 构建SQL:WITH子句
  • 已删除的旧CTETests存储库
  • 如何处理常用表表达式的名称等
  • 将任意SQL字符串作为CTE与DSL结合使用
  • 在Postgres中使用递归CTE
  • CTE、递归CTE和JOOQ
  • 递归CTE
  • 递归CTE

共有1个答案

萧修永
2023-03-14

这个问题原来是杰克逊反序列化在我的JSON负载中的一个属性中的问题,这个属性变成了我的查询。当一个属性被转换成查询类的一部分时,我得到了一个NullPointerExcema。关于jOOQ,这个例子运行良好。另外,这是一个测试查询,它通过引用结果集中的相对位置来求和第一个字段:

    /* Output looks like this : 
    +-----------------+
    |sum_of_everything|
    +-----------------+
    |              100|
    +-----------------+
     */

    Supplier<Stream<Map<String, Object>>> resultsWith =
        () ->
            dslContext
                .with("s1")
                .as(query)
                .select(sum(field("1", Integer.class)).as("sum_of_everything"))
                .from(table(name("s1")))
                .fetchStream()
                .map(Record::intoMap);

这个供应商可以在RESTful框架中作为响应返回,以将结果流回到请求者。

 类似资料:
  • 致: 我怎么能这么做?

  • 问题内容: 我有一个包含多个搜索条件的搜索页面 员工姓名 员工ID 入职日期 部门 等等 用户可以提供一个或多个搜索条件。我需要查询数据库以获取搜索结果。 使用纯JDBC,有两种方法可以实现此目的。 通过附加用户提供的搜索条件来准备SQL查询。 例如: 使用 例如: 此答案说明,像上面的ex 1一样,可以修改ex2,如下所示 然后仔细地(牢记参数索引)将输入设置为准备好的语句。听起来这不是一个非常

  • 任何帮助都很感激! 编辑

  • 我将springBoot与JOOQ一起使用,并希望记录生成的SQL。 我将slf4J添加到maven依赖项和log4j.xml中,就像在JOOQ文档中一样(http://www.JOOQ.org/doc/latest/manual/sql-execution/logging/)。但是当jooq执行一些查询时,我在控制台中看不到任何日志。