【问题标题】:Using Postgres (and AWS Redshift) DB Link with JOOQ将 Postgres(和 AWS Redshift)数据库链接与 JOOQ 一起使用
【发布时间】:2021-06-15 10:18:38
【问题描述】:

我们正在尝试在 Postgres 和 AWS Redshift DB 之间建立一个数据库链接(这不是问题),但我们正在使用 JOOQ 来构建相同的数据库查询。

什么是有效的?如果两个表在同一个数据库中,我们可以为我们想要获取的数据编写 JOIN SQL 查询。例如,如果我们有一个查询:

SELECT somefields
FROM dblink('global_database'::text, '
SELECT
    ... some data selected...) t1(username text, location int, createdAt timestamptz)
         JOIN user_meta t2 on "userId" = t1.userId
    AND createdAt between ... some date range ...
WHERE ...'
GROUP BY ...
ORDER BY ... DESC;

现在我们正在使用 JOOQ 构建查询:

Query query = dslContext
                .select(somefields))
                .from(table(TABLE))
                .rightJoin(TABLE_TWO).on(getJoinOnCondition())
                .where(whereCondition)
                .groupBy(groupByFields)
                .orderBy(orderByFields)
                .limit((int) pageRequest.getPageSize());

JOOQ Query中如何建立DB链接?

【问题讨论】:

    标签: java postgresql jooq dblink


    【解决方案1】:

    分两步完成:

    • 分别为您的两个数据库生成代码。使用<outputSchemaToDefault>true</outputSchemaToDefault>see the manual 确保 Redshift 表没有与之关联的架构
    • 无论何时使用 dblink,当您将 Redshift 表放入 FROM 子句时,将其包装在 plain SQL template 中,否则使用生成的类,例如使用以下实用程序:
    static Table<?> dblink(String conn, Table<?> table, Field<?>... fields) {
        return table("dblink({0}, {1}) as {2}({3})",
            inline(conn),
            inline(DSL.using(POSTGRES).render(select(fields).from(table))),
            table.getUnqualifiedName(),
            list(
                Stream.of(fields)
                      .map(f -> DSL.sql("{0} {1}",
                           f.getUnqualifiedName(),
                           sql(f.getDataType().getCastTypeName())
                      ))
                      .toArray(QueryPart[]::new)
            )
        );
    }
    

    隐含通常的静态导入:

    import static org.jooq.impl.DSL.*;
    

    然后像这样使用这个实用程序:

    Query query = dslContext
                    .select(somefields))
                    .from(dblink("global_database", TABLE, TABLE.fields()))
                    .rightJoin(TABLE_TWO).on(getJoinOnCondition())
                    // You can now use TABLE as if it were a local table
                    .where(whereCondition)
                    .groupBy(groupByFields)
                    .orderBy(orderByFields)
                    .limit((int) pageRequest.getPageSize());
    

    【讨论】:

    • 不确定您在哪里分别构建了 Redshift 查询。我不明白的主要部分是.from(dblink("global_database", TABLE, TABLE.fields()))。这只是指定数据库链接名称、表引用和字段。我们将实际查询放在哪里,其中可能包含 WHERE 子句?
    • @ShubhamA.:我向您展示了dblink() 方法的定义。看看它,它都在那里。它使用plain SQL template
    猜你喜欢
    • 2017-04-19
    • 2015-12-19
    • 2019-05-29
    • 1970-01-01
    • 2017-07-13
    • 2013-06-11
    • 2021-01-12
    • 2016-06-03
    • 2015-11-09
    相关资源
    最近更新 更多