我正在对表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。感谢您提出正确的建议。
最佳答案
ResultQuery.fetchInto(Class)
(和大多数其他into(Class)
方法)的默认行为在DefaultRecordMapper
中指定。可以由RecordMapperProvider
中的providing a custom Configuration
全局覆盖它。
在您的特定情况下,DefaultRecordMapper
将按字段顺序映射记录中的所有值。如果有一列出现两次,它将被映射两次,这意味着第二个值将保留在结果对象中。有两种简单的解决方法:
不要选择“错误的” myCode。这确实是最可靠的解决方案
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
的用例:)注意,这是唯一可以防止“偶然”共享相同名称的其他列的错误值的解决方案。
再次添加“正确的” myCode字段。
另一个黑客,但是它可以解决您遇到的问题:
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);