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

JOOQ:结果。getValues()返回条目为null的列表

亢正德
2023-03-14

我使用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,而不是一个空列表。

这是有意的吗?如果是,还有比在获取后删除空条目更好的解决方法吗?

共有1个答案

司马念
2023-03-14

您正在查询中使用外部连接。这意味着您的结果集可能确实包含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个组:abc,这将为您提供以下映射(使用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