我有一段代码,例如:
ctx.select()
.from()
...
.fetchInto(MyAwesomeClass.class)
MyAwesomeClass
有一个自定义类型的字段(我们称之为 MyLong
),它可以与 Long
相互转换。目前,jOOQ 无法在 Long
和 MyLong
之间进行转换:
org.jooq.exception.DataTypeException: Cannot convert from 1 (class java.lang.Long) to class foo.bar.MyLong
我想在 jOOQ DSL 配置中注册一个转换器,以将 Long
转换为 MyLong
。我有转换器,但我很难将其纳入 DSL 配置。有一个选项可以为配置提供 ConverterProvider,我这样做了 - 但它似乎不起作用。
ConverterProvider 代码片段是这样的:
new DefaultConfiguration()
.set(
new ConverterProvider() {
@Override
public <T, U> Converter<T, U> provide(Class<T> tType, Class<U> uType) {
if (tType == Long.class && uType == MyLong.class) {
return (Converter<T, U>) Converter.of(Long.class, MyLong.class, MyLong::of, MyLong::toLong);
} else {
throw new UnsupportedOperationException();
}
}
});
我知道这个 API 被标记为实验性的,但是是否有其他方法可以实现我想要的效果,而无需在代码生成端声明强制绑定(bind)或其他构造?
最佳答案
ConverterProvider
SPI
ConverterProvider
jOOQ 3.6 中添加了 SPI,但这一添加没有记录在案,SPI 也没有完全实现。相关的被拒绝的问题是:https://github.com/jOOQ/jOOQ/issues/3896
由于Configuration
中的向后兼容性问题,SPI类型尚未被删除。 API(在使用 Spring 配置时尤其相关)。
从 jOOQ 3.11 开始的当前解决方案
这个 SPI 确实可以解决你的问题。在实现类似的 SPI 之前,您需要注册您的自定义 Converter
带有属于投影一部分的字段的类型/SELECT
条款。这可以通过两种方式完成:
使用代码生成器
您可以使用
<forcedTypes/>
configuration轻松注册您自己的自定义数据类型和相关转换器。在您的代码生成器中。这样,每当您选择转换的列时,jOOQ 都会生成您自己的自定义类型MyLong
而不是数据库/JDBC 类型Long
使用临时转换类型
如果您不使用代码生成器,您可以创建自己的数据类型,如下所示:
DataType<MyLong> MY_LONG_TYPE = SQLDataType.BIGINT.asConvertedDataType(new MyLongConverter()); Field<MyLong> MY_LONG_FIELD = field(name("MY_TABLE", "MY_LONG_FIELD"), MY_LONG_TYPE);
您现在可以在任何查询中使用此列引用来获取
MyLong
值:ctx.select(MY_LONG_FIELD) .from(...) .fetchInto(MyAwesomeClass.class);
关于java - 在 jOOQ 中注册全局转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51962511/