我正在进行表A和表B的左连接,并尝试将结果提取到自定义POJO中,该POJO具有表A和表B中的字段,如下所示:
List<MyCustomPojo> res = create.select()
.from(TABLE_A)
.leftJoin(TABLE_B)
.on(TABLE_A.MY_CODE.eq(TABLE_B.MY_CODE))
.fetchInto(MyCustomPojo.class);
除了 myCode 这两个表连接的字段外,它适用于所有字段。对我来说, myCode 的值是从右表中获取的,表B,对于表A中没有表B中相应条目的所有记录,这些值为NULL。我想要知道jooQ如何决定映射到POJO的字段以及是否记录了这种行为。
我的目标是将表A和表B中的所有字段提取到自定义POJO中,以便从左表中选取 myCode 。我很感激你就正确的方法提出建议。
答案 0 :(得分:5)
ResultQuery.fetchInto(Class)
(以及大多数其他into(Class)
方法)的默认行为在DefaultRecordMapper
中指定。它可以通过Configuration
中的providing a custom RecordMapperProvider
覆盖全局。
在您的特定情况下,DefaultRecordMapper
将按字段顺序映射记录中的所有值。如果有一个列出现两次,它将被映射两次,这意味着第二个值将保留在结果对象中。有两种简单的解决方法:
List<MyCustomPojo> res = create
.select(TABLE_A.fields())
.select(/* all fields in TABLE_B except the ones you don't want */)
.from(TABLE_A)
.leftJoin(TABLE_B)
.on(TABLE_A.MY_CODE.eq(TABLE_B.MY_CODE))
.fetchInto(MyCustomPojo.class);
RIGHT JOIN
:也许有点像黑客攻击,但这会迅速扭转SELECT
声明中的表顺序。
List<MyCustomPojo> res = create
.select()
.from(TABLE_B)
.rightJoin(TABLE_A)
.on(TABLE_A.MY_CODE.eq(TABLE_B.MY_CODE))
.fetchInto(MyCustomPojo.class);
最后是RIGHT JOIN
的用例:)
请注意,这是唯一可以防止“意外”共享同一名称的其他列的错误值的解决方案。
另一个黑客,但它会解决您遇到的问题:
List<MyCustomPojo> res = create
.select(TABLE_A.fields())
.select(TABLE_B.fields())
.select(TABLE_A.MY_CODE)
.from(TABLE_A)
.leftJoin(TABLE_B)
.on(TABLE_A.MY_CODE.eq(TABLE_B.MY_CODE))
.fetchInto(MyCustomPojo.class);