mysql 如何使用KotlinJOOQ和SimpleFlatMapper将Integer列转换为自定义类型?

bzzcjhmw  于 2023-05-16  发布在  Mysql
关注(0)|答案(1)|浏览(120)

我有一个Kotlin项目,使用JOOQ连接MySQL数据库。我有一个带有int int_columnmy_table表,我想将它转换为在MyTableJooqEntity文件中声明的MyCustomType类。使用build.gradle文件中指定的JOOQ forcedTypes完成配置。但是我收到了一个ClassCastException。我能做错什么?
现在我将展示一些实现细节。我有以下MySQL表:

CREATE TABLE `my_table`
(
    `id`         int PRIMARY KEY AUTO_INCREMENT  not null,
    `int_column` int                             not null
);

然后我有这个JOOQ实体Map:

@Entity
@Table(name = "my_table")
data class MyTableJooqEntity(@Id
                             @Column(name = "id")
                             var Id: Int = -1,

                             @Column(name = "int_column")
                             var intColumn: MyCustomType)

我有这个build.gradle forcedTypes配置:

forcedType {
    userType = "co.mycompany.MyCustomType"
    converter = "new co.mycompany.converters.IntegerToMyCustomTypeConverter()"
    includeExpression = "mydatabase.my_table.int_column"
}

和自定义转换器:

package co.mycompany.converters

import co.mycompany.MyCustomType
import org.jooq.Converter

class IntegerToMyCustomTypeConverter : Converter<Integer, MyCustomType> {
    override fun from(databaseObject: Integer?): MyCustomType? {
        return MyCustomType.of(databaseObject)
    }

    override fun fromType(): Class<Integer> =
        Integer::class.java

    override fun to(userObject: MyCustomType?): Integer? {
        return userObject.toBigDecimal().toInt() as Integer 
       // I need to do some transformations before
       // convert it finally to java.lang.Integer 
       // (or Kotlin Int, but neither is working)
    }

    override fun toType(): Class<MyCustomType> =
        MyCustomType::class.java
}

然后当我在我的JooqDao上运行一个select:

fun selectById(Id: Int): MyTableJooqEntity? =
   withContext {
     val query = it.select(*table.fields())
                .from(table)
                .where(table.ID.eq(Id))
     return query.fetchOneInto(MyTableJooqEntity::class.java)
   }

我终于收到这个错误,无论我怎么尝试,我都无法将int转换为任何自定义类型:

java.lang.IllegalArgumentException: argument type mismatch
      at co.mycompany.MyCustomTest.testConvert(MyCustomTest.kt:100)
  Caused by: java.lang.ClassCastException: Cannot cast java.lang.Integer to co.mycompany.MyCustomType
      at co.mycompany.MyCustomTest.testConvert(MyCustomTest.kt:100)
14ifxucb

14ifxucb1#

解决方案是将MyCustomType的getter添加到JdbcMapperFactory。在这种情况下,forcedType指定是不够的。

fun getJdbcMapperFactory(): JdbcMapperFactory =
        JdbcMapperFactory
            .newInstance()
            .addGetterForType(MyCustomType::class.java) { rs, i -> MyCustomType.of(rs.getInt(i)) }

相关问题