我将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 /> ;,您可以在其中实现自己的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.