我有一个 scala 案例类
case class MyRecord(
id: String,
dimensions: List[String], // postgres text[]
dimensionCodes: List[Long] // postgres integer[]
)
和 Jooq 查询
JooqBuilder
.default(conn)
.select(
field("id", classOf[String]),
field("dimensions", classOf[List[String]]),
field("dimensionCodes", classOf[List[Long]]),
)
.from(table(MY_TABLE))
.fetchInto(classOf[MyRecord])
.asScala
.toList
Ofc,它不起作用,因为 jooq 无法将数组映射到 scala List。 我正在积极使用
org.jooq.Converter
,这是非常酷且灵活的东西。我不明白如何为 Postgres 数组制作它
UPD 我尝试过的:
class JooqArrayConverterOld extends Converter[PgArray, List[Long]]
无法编译。更深入地研究代码,似乎 jooq 让用户变得更容易。数据库类型应为
Array[Object]
我想我已经找到了正确的方法。
class JooqStringArrayConverter extends Converter[Array[Object], List[String]]
private val jooqStringArrayConverter = org.jooq.impl.SQLDataType.OTHER.getArrayDataType.asConvertedDataType(
new JooqStringArrayConverter()
)
效果很好
field("dimensions", jooqStringArrayConverter)
所以这个案子结束了。
还在挣扎List[Long]
class JooqLongArrayConverter extends Converter[Array[Object], List[Long]] {
override def from(databaseObject: Array[Object]): List[Long] =
Option(databaseObject)
.map(_.asInstanceOf[Array[Int]]) // Exception!
.map(_.toList.map(_.toLong))
.getOrElse(List.empty)
override def to(userValue: List[Long]): Array[Object] =
???
override def fromType(): Class[Array[Object]] = classOf[Array[Object]]
override def toType: Class[List[Long]] = classOf[List[Long]]
}
投掷
Error while reading field: dimensionCodes, at JDBC index: 10
...
Cause: java.lang.ClassCastException: class [Ljava.lang.Integer; cannot be cast to class [I ([Ljava.lang.Integer; and [I are in module java.base of loader 'bootstrap')
我又猜想痛苦的java原语。希望我们将来能摆脱它们。
Scala 类型
Array[Int]
对应于 JVM 上的 int[]
(编码为 [I
)。您希望它是 java.lang.Integer[]
,所以请使用 Array[java.lang.Integer]
来代替。