我在PostgreSQL中有以下结构:
TableA has many TableB has many TableC
这三个表(简化)如下:
create table TableA (
idA int,
nameA varchar(100));
create table TableB (
idA int,
idB int,
nameB varchar(100));
create table TableC (
idA int,
idB int,
idC int,
nameC varchar(100));
我需要在PostgreSQL上运行jOOQ,选择TableA
,但它也应该从TableB
和TableC
加载任何相关的行。有没有办法运行单个jOOQ语句来加载这棵树?我知道我可以使用连接
s来执行此操作,但我正在尝试避免Java中的任何循环。
从jOOQ 3.15开始,可以使用标准的SQL多集运算符嵌套集合,该运算符使用SQL/XML或SQL/JSON进行模拟
var result =
ctx.select(
TABLE_A.ID_A, TABLE_A.NAME_A,
multiset(
select(
TABLE_B.ID_B, TABLE_B.NAME_B,
multiset(
select(TABLE_C.ID_C, TABLE_C.NAME_C)
.from(TABLE_C)
.where(TABLE_C.ID_B.eq(TABLE_B.ID_B))
.and(TABLE_C.ID_A.eq(TABLE_B.ID_A))
).as("c")
)
.from(TABLE_B)
.where(TABLE_B.ID_A.eq(TABLE_A.ID_A))
).as("b")
)
.from(TABLE_A)
.fetch();
结果的类型推断为:
Result<Record3<
Integer, // TABLE_A.ID_A
String, // TABLE_A.NAME_A
Result<Record3<
Integer, // TABLE_B.ID_B
String, // TABLE_B.NAME_B
Result<Record2<
Integer, // TABLE_C.ID_C
String // TABLE_C.NAME_C
>>
>>
>> result = ...
如果您希望将其映射到一些自定义DTO数据结构中,例如。
record TableC(int idC, String nameC) {}
record TableB(int idB, String nameB, List<TableC> c) {}
record TableA(int idA, String nameA, List<TableB> b) {}
您可以使用jOOQ 3.15的新ad-hoc转换功能轻松做到这一点:
List<TableA> result =
ctx.select(
TABLE_A.ID_A, TABLE_A.NAME_A,
multiset(
select(
TABLE_B.ID_B, TABLE_B.NAME_B,
multiset(
select(TABLE_C.ID_C, TABLE_C.NAME_C)
.from(TABLE_C)
.where(TABLE_C.ID_B.eq(TABLE_B.ID_B))
.and(TABLE_C.ID_A.eq(TABLE_B.ID_A))
).as("c").convertFrom(r -> r.map(Records.mapping(TableC::new)))
)
.from(TABLE_B)
.where(TABLE_B.ID_A.eq(TABLE_A.ID_A))
).as("b").convertFrom(r -> r.map(Records.mapping(TableB::new)))
)
.from(TABLE_A)
.fetch(Records.mapping(TableA::new));
所有映射都是类型安全、编译时检查和无反射的
您可以使用jOOQ 3.14的SQL/XML或SQL/JSON支持来实现这一点,请参阅此处的博客文章
如果类路径上有Gson或Jackson,它们可用于将XML或JSON结构映射回Java类层次结构。手册中关于ConverterProvider
的页面给出了一个示例
本质上:
ctx.select(
jsonObject(
key("idA").value(TABLE_A.ID_A),
key("nameA").value(TABLE_A.NAME_A),
key("b").value(
select(jsonArrayAgg(jsonObject(
key("idB").value(TABLE_B.ID_B),
key("nameB").value(TABLE_B.NAME_B),
key("c").value(
select(jsonArrayAgg(jsonObject(
key("idC").value(TABLE_C.ID_C),
key("nameC").value(TABLE_C.NAME_C)
)))
.from(TABLE_C)
.where(TABLE_C.ID_B.eq(TABLE_B.ID_B))
)
)))
.from(TABLE_B)
.where(TABLE_B.ID_A.eq(TABLE_A.ID_A))
)
)
)
.from(TABLE_A)
.fetch();
另请参阅此处的相关问题:
请注意,JSON\u ARRAYAGG()将空集聚合为空集,而不是空集。如果这是一个问题,请使用COALESCE()
在我的Java项目中,我是usinq、JOOQ,我希望更新JSONB值。但我的建造失败了。 我写了一段代码: 我收到了下一条信息: 我犯错的地方?
数据库是PostgreSQL 10,JOOQ版本是3.10.8。 是我在JOOQ上做错了什么,还是这是一个问题,可能已经在一些新版本中修复了?
如果我用ctx.insertinto来做这个...很好用。我最初使用的是Jooq3.14.0,但升级到最新的3.14.4对此没有帮助。生成的Keys类一定有问题,因为在初始化Keys类之前一切都正常工作。是Postgresql表结构出了问题,还是代码生成出了问题? 完整回购如下:https://github.com/eriran/criminal-api/tree/security-tumpt
我知道jOOQ将在不支持它的系统(如PostgreSQL)上模拟SQLMERGE。 我有一个带有串行(自动增量)id列和字符串uri列的表。我想在我的数据库中使用数字ID而不是URI,所以我必须确保在ID查找表中有一个URI。因此,按照jOOQ手册中的示例,我认为这将起作用: 这给了我一个这样的语句: 但是日志说jOOQ继续并尝试用绑定值执行查询。但是该表从未更新。所以我猜jOOQ没有在Postg
问题内容: 我是PostgresSQL的新手,我正尝试加载以下格式的数据: 记录超过1万,某些列可能包含NULL数据。当我尝试这样做时: 我收到以下错误:ERROR:最后一个预期的列SQL状态之后的多余数据:22P04 我已经检查了列,它们还可以。这意味着不会遗漏任何列。 希望有人能帮忙。提前谢谢。 问题答案: 应该是 对我有用
回到Jooq2.5,看起来可以通过FactoryOperations类设置PostgreSQL搜索路径,但Jooq3.5中没有该类。显然,FactoryOperations分为DSL和DSLContext,但我似乎找不到use(Schema)方法的结尾。如何在较新版本的jOOQ中设置PostgreSQL搜索路径?