将 Postgres(和 AWS Redshift)DB Link 与 JOOQ 一起使用
Using Postgres (and AWS Redshift) DB Link with JOOQ
我们正在尝试在 Postgres 和 AWS Redshift 数据库之间建立一个数据库 link(这不是问题),但我们正在使用 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查询中建立数据库link?
分两步完成:
- 分别为您的两个数据库生成代码。使用
<outputSchemaToDefault>true</outputSchemaToDefault>
、see the manual 确保 Redshift table 没有与之关联的架构
- 每当您使用 dblink 时,将 Redshift table 放在
FROM
子句中时将其包装在 plain SQL template 中,否则使用生成的 class,使用例如以下实用程序:
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());
我们正在尝试在 Postgres 和 AWS Redshift 数据库之间建立一个数据库 link(这不是问题),但我们正在使用 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查询中建立数据库link?
分两步完成:
- 分别为您的两个数据库生成代码。使用
<outputSchemaToDefault>true</outputSchemaToDefault>
、see the manual 确保 Redshift table 没有与之关联的架构
- 每当您使用 dblink 时,将 Redshift table 放在
FROM
子句中时将其包装在 plain SQL template 中,否则使用生成的 class,使用例如以下实用程序:
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());