java-jOOQ选择仅针对某些字段指定的映射进入POJO

我将jOOQ与普通SQL(未生成的代码)一起使用.
我正在尝试直接选择具有枚举类型的某些字段的POJO.

MyType pojo = context.select().from(table("Table"))
            .where(field("ID").equal("1")).fetchOne()
            .into(MyType.class);

在我看来,我只能为整个POJO指定一个高级映射器,如下所示:

MyType pojo = context.select().from(table("Table"))
            .where(field("ID").equal("1")).fetchOne()
            .map(new RecordMapper<Record, MyType>() {
                @Override
                public MyType map(Record record) {
                    ...
                }
            });

我找不到只为某些字段提供映射或转换器的方法.具体来说,我想告诉jooq像“正常转换所有字段,除非我的POJO中的字段是MyEnum类型,在这种情况下使用此映射(或转换器)”.

如何为某些字段而不是其他字段指定映射器?

顺便说一句,我注意到我可以在配置级别上做类似的事情,用通配符匹配数据库字段名称(如here所述),但是我认为最好由POJO中字段的类型来决定.

解决方法:

有多种方法可以解决此问题:

1.使用代码生成器

明显.我知道您没有使用它,但是也许有人会发现这个问题.在这种情况下,代码生成器将:

>自动为您生成枚举类型(如果您使用的是MySQL或PostgreSQL枚举)
>允许您使用< forcedTypes /&gt ;,您可以在其中实现自己的converters和/或bindings

2.还要对普通SQL使用显式转换器/绑定

即使您没有使用代码生成器,也可以通过指定自己的DataType来受益于自定义转换器/绑定:

// Assuming that the enum type enumerates varchar values:
SQLDataType<MyEnum> myEnumType = 
    SQLDataType.VARCHAR.asConvertedDataType(new MyEnumConverter());

现在,您可以使用DSL.field(String, DataType)在普通的SQL字段表达式中使用该类型

context.select(field("Column", myEnumType), ...)
       .from(table("Table"))

在这种情况下,由于jOOQ记录已经包含所需的数据类型,因此不再需要在记录映射器中进行显式转换.

3.使用自定义的RecordMapperProvider

如果您使用任何into(Class)方法,则默认情况下将使用DefaultRecordMapper.它知道如何通过调用EnumClass.valueOf(stringValue)将字符串转换为枚举.如果这不是理想的行为(如您的问题所提示),那么您仍然可以通过提供自己的RecordMapperProvider来覆盖默认行为.

就像您所说的那样,它也是一个“高级映射器”,但是您可以在全局范围内注册它,并在想要映射到MyType.class时随时重用它.

(4.使用转换器注册表)

jOOQ的未来版本(尚不支持jOOQ 3.9)可能支持转换器注册表,该注册表允许为任何类型的< T,U>实现默认转换.这是问题#5713.

上一篇:使用jooq / postgresql从json提取键/值对-Java


下一篇:java-具有模拟字段的JOOQ模拟结果