我尝试在 Hibernate native 中实现这种 SQL 查询。
val list = listOf((z,1),(w,2),(y,3))
SELECT * FROM table WHERE (a, b) IN (:list)
最终获得类似的东西:
SELECT * FROM table WHERE (a, b) IN ((z,1),(w,2),(y,3))
我尝试了几种使用自定义 UserType 或 Vlad Mihalcea 的 Hibernate-Types 的实现,但我无法得到它。
Hibernate 中是否有一种方法可以将参数或参数列表转换为元组或元组列表?
编辑
我已经成功地做到了,但我并不是 100% 对此感到高兴。
为了提供更多上下文,这对(a,b)是类型(uuid,timestamp)。对于这个解决方案工作,我需要创建一个 Postgres 复杂类型:
CREATE TYPE pair_uuid_timestamp AS (
first uuid,
second timestamp
);
然后,我需要一个基于来自 hibernate-types-52 的 ImmutableType 的 PostgreSQLPairType。避免它很容易,但我已经拥有它。
class PostgreSQLPairType(
val first: UUID?,
val second: LocalDateTime?
) : ImmutableType<PostgreSQLPairType>(PostgreSQLPairType::class.java) {
constructor(): this(null, null)
override fun sqlTypes(): IntArray {
return intArrayOf(Types.OTHER)
}
@Throws(SQLException::class)
override fun get(rs: ResultSet, names: Array<String>, session: SharedSessionContractImplementor, owner: Any): PostgreSQLPairType? {
return null
}
@Throws(SQLException::class)
override fun set(st: PreparedStatement, pair: PostgreSQLPairType?, index: Int, session: SharedSessionContractImplementor) {
if (pair == null) {
st.setNull(index, Types.OTHER)
} else {
val pgObject = PGobject()
pgObject.type = "pair_uuid_timestamp"
pgObject.value = "(${pair.first},${pair.second?.toInstantStr()})"
st.setObject(index, pgObject)
}
}
}
今天,我暂时不使用它,我看不出与我的参数列表构造有任何区别,如下所示:
val list = listOf((uuid1,timestamp1),(uuid2,timestamp2),(uuid3,timestamp3))
val parameter = list.joinToString(",") { "('${it.first}', '${it.second.toInstantStr()}')" }
SELECT * FROM table WHERE (a, b) IN (:list)