我使用JOOQ查询多对多关系,需要将一个条目的多个结果映射到单个对象中。为此,我使用唯一标识符将结果分组,并从每个分组的结果中提取所需的数据。对于多对多数据,我得到所有可用值,对于正常数据,我只使用第一个条目的数据:
Map<String, Result<Record2<String, String>> groupedResults = create.select(LOC.NAME, GROUP.GROUP_)
.from(LOC)
.leftOuterJoin(LOC2GROUP)
.on(Tables.LOC2GROUP.LOC_ID.eq(LOC.LOC_ID))
.leftOuterJoin(GROUP)
.on(LOC2GROUP.GROUP_ID.eq(GROUP.GROUP_ID))
.fetch().intoGroups(LOC.NAME);
Collection<Loc> ret = new ArrayList<Loc>();
for (Result<Record2<String, String>> result : groupedResults.values()) {
Loc loc = new Loc(result.getValue(0, LOCATION.NAME), result.getValues(Tables.GROUP.GROUP_));
ret.add(loc);
}
现在,我虽然每个条目可以有多个组,但它不需要有任何组,以下将是一个有效的条目,无需设置任何组:
|name |group |
|simple|{null}|
奇怪的是,我注意到Result.get值()
在这种情况下返回一个包含null
的List,而不是一个空列表。
这是有意的吗?如果是,还有比在获取后删除空条目更好的解决方法吗?
您正在查询中使用外部连接。这意味着您的结果集可能确实包含LOC表中的值,但不包含组表中的相应值。以下是查询的一些有效示例输出:
+------+--------+
| name | group |
+------+--------+
| a | x |
| a | y |
| b | x |
| c | {null} | <-- there's a value in LOC, but no corresponding value in GROUP
+------+--------+
现在,当您在该结果上调用jOOQ的intoGroups()时,jOOQ只看到3个组:a
、b
和c
,这将为您提供以下映射(使用JSON作为伪符号):
{
"a" : [ { "name" : "a", "group" : "x" },
{ "name" : "a", "group" : "y" } ],
"b" : [ { "name" : "b", "group" : "x" } ],
"c" : [ { "name" : "c", "group" : null } ]
}
仅仅因为其中一列中碰巧有一个值,并不意味着这个值在分组时应该有任何语义。这一列(组)是您感兴趣的唯一列,这一事实并没有改变分组结果是记录而不是单个值的事实。
我希望这有道理?
jOOQ目前不支持返回您真正寻找的数据结构的方法:
{
"a" : [ "x", "y" ],
"b" : [ "x" ],
"c" : [ ]
}
但自己编写这样一个实用方法应该相当容易。。。
或者,如果您使用的是PostgreSQL或HSQLDB,您可以使用
array_agg()
代替:
Result<Record2<String, String[]>> result =
create.select(LOC.NAME, arrayAgg(GROUP.GROUP_))
.from(LOC)
.leftOuterJoin(LOC2GROUP)
.on(Tables.LOC2GROUP.LOC_ID.eq(LOC.LOC_ID))
.leftOuterJoin(GROUP)
.on(LOC2GROUP.GROUP_ID.eq(GROUP.GROUP_ID))
.groupBy(LOC.NAME)
.fetch();
DSL。arrayAgg()
将是jOOQ 3.5的一部分,但您可以自己创建该jOOQ函数:
@Support({SQLDialect.POSTGRES})
protected static <T> Field<T[]> arrayAgg(Field<T> field) {
return DSL.field("array_agg({0})", field.getDataType().getArrayDataType(), field);
}
使用此选项: 返回null:/(也尝试了getIdentity()) 在调用getPrimaryKey之前,我执行所有查询: 本文的输出为:create table filetest(id integer主键自动递增非null,Meno varchar(21)null,Priezvisko varchar(24)null,Vek int null); 所以这里有“id”主键……不要理解。 还尝试了
我如何用JOOQ表示以下PostgreSQL语法? Jooq的函数需要类型作为其参数,但是函数返回类型?
问题内容: 是否可以将此代码转换为Java 8可选单行表达式? 即如果某个对象不为空,我需要调用一个对象方法并返回其结果,否则返回0。 不适合,因为它返回相同类型的对象,但是我需要方法调用的结果或一些默认值。 问题答案: 几种形式: 其中,最后一个不使用Optional(因此不能严格回答您的问题!)更易于阅读,运行时开销也较小,因此应优先使用。 可以说,如果您反转选项,它甚至更简单: …尽管您可能
是否可以将此代码转换为Java8可选的单行表达式? i、 如果某个对象不是null,我需要调用一个对象方法并返回其结果,否则返回0<代码>可选。不可数()。orElse()不适合,因为它返回相同类型的对象,但我需要方法调用的结果或一些默认值。
将从非null元素返回最小值。 我想编写一个查询,将NULL视为可能的最小值。 我见过使用特殊值的日期技巧,如下所示:https://stackoverflow.com/a/32240382/7810882 但是,如果列的类型是并且没有可以映射到的特殊值怎么办?
Firebase查询返回此查询的值 该项由model类捕获 但是,返回null