在jooq中使用row()将结果映射到自定义seekStep类

发布于 2025-01-13 22:19:27 字数 3254 浏览 1 评论 0原文

由于我不想使用 RecordX 类(在我的例子中,我从查询返回 11 个字段),因此我创建了自定义映射器来将 SelectSeekStep 结果映射到其中。当我的字段属于连接表的一部分时,就会出现问题。例如,

@Value
public class CustomMapperSelectSeekStep {
  private final String field1;
  private final String field2;
  private final String field3;
  private final String field4;
  private final String field5;
  private final String field6;
  private final String field7;
  private final String test_id;
  private final String field9;
  private final String field10;
}

假设除了 test_id 字段之外的所有字段都是主表的一部分(我们称之为 dummy),并且该字段是 test 表的一部分,其中我们将使用左连接进行连接。

dslContext
.select(
row(DUMMY.FIELD1,
    DUMMY.FIELD2,
    DUMMY.FIELD3,
    DUMMY.FIELD4,
    DUMMY.FIELD5,
    DUMMY.FIELD6,
    DUMMY.FIELD7,
    TEST.TEST_NAME,
    DUMMY.FIELD8,
    DUMMY.FIELD9,
    DUMMY.FIELD10).mapping(CustomMapperSelectSeekStep::new))
.from(DUMMY)
.leftJoin(TEST).on(TEST.ID.eq(DUMMY.TEST_ID))
.orderBy(DUMMY.FIELD1);

我收到异常:

java.lang.IllegalArgumentException: Field ("test"."test_name") is not contained in Row 
(row (
"DUMMY"."FIELD1",
"DUMMY"."FIELD2",
"DUMMY"."FIELD3",
"DUMMY"."FIELD4",
"DUMMY"."FIELD5",
"DUMMY"."FIELD6",
"DUMMY"."FIELD7",
"DUMMY"."FIELD8",
"TEST"."TEST_NAME",
"DUMMY"."FIELD9",
"DUMMY"."FIELD10"
))  

更新:添加了整个方法调用:

dslContext.transaction(configuration -> {
DSLContext localDsl = DSL.using(configuration);
try (Cursor<Record1<CustomMapperSelectSeekStep>> records = 
selectRecords(localDsl)
    .fetchSize(1000)
    .resultSetType(ResultSet.TYPE_FORWARD_ONLY)
    .resultSetConcurrency(ResultSet.CONCUR_READ_ONLY)
    .fetchLazy()) {
        processRecords(records);
    }
});
//method
private SelectSeekStep1<Record1<CustomMapperSelectSeekStep>,Timestamp> selectRecords(DSLContext dslContext) {
return dslContext.select(
    row(DUMMY.FIELD1,
        DUMMY.FIELD2,
        DUMMY.FIELD3,
        DUMMY.FIELD4,
        DUMMY.FIELD5,
        DUMMY.FIELD6,
        DUMMY.FIELD7,
        TEST.TEST_NAME,
        DUMMY.FIELD8,
        DUMMY.FIELD9,
        DUMMY.FIELD10).mapping(CustomMapperSelectSeekStep::new))
    .from(DUMMY)
    .leftJoin(TEST).on(TEST.ID.eq(DUMMY.TEST_ID))
    .orderBy(DUMMY.FIELD1);
    }

在流程记录内,我将 Record 对象映射到所需的对象类型。

void processRecords(List<Records> records) {
record.map(recordMapper);
} 

我有自定义 recordMapper 实现,我正在执行如下逻辑:

testName = record.get(TEST.TEST_NAME, Test.class);

堆栈跟踪:

    at org.jooq.impl.Tools.indexFail(Tools.java:1769)
at org.jooq.impl.AbstractRecord.get(AbstractRecord.java:331)
at org.jooq.impl.AbstractRecord.get(AbstractRecord.java:336)
at org.test.CustomMapper.map(CustomMapper.java:42)
at org.test.CustomMapper.map(CustomMapper.java:16)
at org.jooq.impl.AbstractRecord.map(AbstractRecord.java:904)
at org.test.Processor.processRecords(Processor.java:88)
at org.test.Repository.lambda$fetchLazy$0(Repository.java:78)
at org.jooq.impl.DefaultDSLContext.lambda$transaction$5(DefaultDSLContext.java:611)
at org.jooq.impl.DefaultDSLContext.lambda$transactionResult0$3(DefaultDSLContext.java:549)

Since I don't want to use RecordX class (in my case I am returning 11 fields from query) I've created custom mapper to map SelectSeekStep result into it. The problem occurs when I have fields that are part of joined table. E.g.

@Value
public class CustomMapperSelectSeekStep {
  private final String field1;
  private final String field2;
  private final String field3;
  private final String field4;
  private final String field5;
  private final String field6;
  private final String field7;
  private final String test_id;
  private final String field9;
  private final String field10;
}

Let's say that all fields except test_id fields are part of main table (let's call it dummy) and that field is part of test table which we will connect with left join.

dslContext
.select(
row(DUMMY.FIELD1,
    DUMMY.FIELD2,
    DUMMY.FIELD3,
    DUMMY.FIELD4,
    DUMMY.FIELD5,
    DUMMY.FIELD6,
    DUMMY.FIELD7,
    TEST.TEST_NAME,
    DUMMY.FIELD8,
    DUMMY.FIELD9,
    DUMMY.FIELD10).mapping(CustomMapperSelectSeekStep::new))
.from(DUMMY)
.leftJoin(TEST).on(TEST.ID.eq(DUMMY.TEST_ID))
.orderBy(DUMMY.FIELD1);

Exception I am getting:

java.lang.IllegalArgumentException: Field ("test"."test_name") is not contained in Row 
(row (
"DUMMY"."FIELD1",
"DUMMY"."FIELD2",
"DUMMY"."FIELD3",
"DUMMY"."FIELD4",
"DUMMY"."FIELD5",
"DUMMY"."FIELD6",
"DUMMY"."FIELD7",
"DUMMY"."FIELD8",
"TEST"."TEST_NAME",
"DUMMY"."FIELD9",
"DUMMY"."FIELD10"
))  

UPDATE: added entire method call:

dslContext.transaction(configuration -> {
DSLContext localDsl = DSL.using(configuration);
try (Cursor<Record1<CustomMapperSelectSeekStep>> records = 
selectRecords(localDsl)
    .fetchSize(1000)
    .resultSetType(ResultSet.TYPE_FORWARD_ONLY)
    .resultSetConcurrency(ResultSet.CONCUR_READ_ONLY)
    .fetchLazy()) {
        processRecords(records);
    }
});
//method
private SelectSeekStep1<Record1<CustomMapperSelectSeekStep>,Timestamp> selectRecords(DSLContext dslContext) {
return dslContext.select(
    row(DUMMY.FIELD1,
        DUMMY.FIELD2,
        DUMMY.FIELD3,
        DUMMY.FIELD4,
        DUMMY.FIELD5,
        DUMMY.FIELD6,
        DUMMY.FIELD7,
        TEST.TEST_NAME,
        DUMMY.FIELD8,
        DUMMY.FIELD9,
        DUMMY.FIELD10).mapping(CustomMapperSelectSeekStep::new))
    .from(DUMMY)
    .leftJoin(TEST).on(TEST.ID.eq(DUMMY.TEST_ID))
    .orderBy(DUMMY.FIELD1);
    }

Inside process record I am mapping Record objects to desired object type.

void processRecords(List<Records> records) {
record.map(recordMapper);
} 

I have custom recordMapper implementation where i am doing logic like this:

testName = record.get(TEST.TEST_NAME, Test.class);

Stack trace:

    at org.jooq.impl.Tools.indexFail(Tools.java:1769)
at org.jooq.impl.AbstractRecord.get(AbstractRecord.java:331)
at org.jooq.impl.AbstractRecord.get(AbstractRecord.java:336)
at org.test.CustomMapper.map(CustomMapper.java:42)
at org.test.CustomMapper.map(CustomMapper.java:16)
at org.jooq.impl.AbstractRecord.map(AbstractRecord.java:904)
at org.test.Processor.processRecords(Processor.java:88)
at org.test.Repository.lambda$fetchLazy$0(Repository.java:78)
at org.jooq.impl.DefaultDSLContext.lambda$transaction$5(DefaultDSLContext.java:611)
at org.jooq.impl.DefaultDSLContext.lambda$transactionResult0$3(DefaultDSLContext.java:549)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

勿忘初心 2025-01-20 22:19:27

问题是您已经将记录嵌套为具有这样的类型

Cursor<Record1<CustomMapperSelectSeekStep>>

当您认为您有这样的类型时:

Cursor<Record10<T1, T2, ..., T10>>

在后一种情况下,您可以像您一样简单地提取投影列:

record.get(TEST.TEST_NAME);

但是当您有一个嵌套记录时,该列不再存在,它嵌套在匿名 Record1 类型中。不仅如此,还因为您使用了 使用 convertFrom() 的临时转换器,不再有嵌套记录,但 jOOQ 为您投影了自定义 POJO 类型 CustomMapperSelectSeekStep

因此,只需这样读取您的值:

void processRecords(List<Record1<CustomMapperSelectSeekStep>> records) {
    for (Record1<CustomMapperSelectSeekStep> record : records) {
        CustomMapperSelectSeekStep pojo : record.value1();
    }
} 

The problem is that you've nested your record to have a type like this

Cursor<Record1<CustomMapperSelectSeekStep>>

When you thought you had a type like this:

Cursor<Record10<T1, T2, ..., T10>>

In the latter case, you could simply extract the projected column like you did:

record.get(TEST.TEST_NAME);

But when you have a nested record, that column no longer exists, it's nested in an anonymous Record1<?> type. Not only that, but because you used an ad-hoc converter using convertFrom(), there's no nested record anymore, but jOOQ projected your custom POJO type CustomMapperSelectSeekStep for you.

So, just read your value like this:

void processRecords(List<Record1<CustomMapperSelectSeekStep>> records) {
    for (Record1<CustomMapperSelectSeekStep> record : records) {
        CustomMapperSelectSeekStep pojo : record.value1();
    }
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文