Kotlin Exposed操作MySQL:自定义查询生成调用内置函数可行吗?
在Kotlin Exposed中实现MySQL UUID Binary(16)的查询自定义
当然可以不用完全自定义QueryBuilder,Exposed提供了多种灵活的方式来实现这类自定义查询逻辑,下面是几种实用方案:
方案1:自定义UUID Binary列类型(推荐,自动处理转换)
这种方式可以让列在插入、更新和查询时自动处理UUID与binary(16)的转换,无需每次手动编写函数调用。
import org.jetbrains.exposed.sql.* import java.util.UUID class MySqlUUIDBinaryColumn(name: String) : Column<UUID>(name, UUIDColumnType()) { override fun appendExpressionToQuery(queryBuilder: QueryBuilder) { when (queryBuilder.parent) { is UpdateBuilder<*>, is InsertBuilder -> { // 插入/更新时,将UUID转为binary(16),调用MySQL的UUID_TO_BIN函数 queryBuilder.append("UUID_TO_BIN(", this, ", 1)") } else -> { // 查询时,将binary(16)转回UUID,调用MySQL的BIN_TO_UUID函数 queryBuilder.append("BIN_TO_UUID(", this, ", 1)") } } } override fun createColumnOptions(): String { return "BINARY(16)" } } // 扩展Table类,简化该列的创建 fun Table.uuidBinary(name: String): Column<UUID> = registerColumn(name, MySqlUUIDBinaryColumn(name)) // 使用示例 object TestTable : Table("test_table") { val id = uuidBinary("id").primaryKey() val name = varchar("name", 50) } // 查询示例:自动生成带BIN_TO_UUID的条件 val targetUuid = UUID.randomUUID() val result = TestTable.select { TestTable.id eq targetUuid }.singleOrNull() // 生成的SQL:SELECT BIN_TO_UUID(test_table.id, 1), test_table.name FROM test_table WHERE BIN_TO_UUID(test_table.id, 1) = ?
方案2:扩展DSL函数,手动构建查询条件
如果不想自定义列类型,可以写一个扩展函数快速生成包含BIN_TO_UUID的查询条件:
import org.jetbrains.exposed.sql.Column import org.jetbrains.exposed.sql.Op import org.jetbrains.exposed.sql.SqlExpressionBuilder import java.util.UUID // 扩展ByteArray类型的列,支持直接与UUID比较 infix fun Column<ByteArray>.eqUuid(uuid: UUID): Op<Boolean> { return SqlExpressionBuilder.run { FunctionCall("BIN_TO_UUID", listOf(this@eqUuid, 1)) eq uuid.toString() } } // 使用示例 object TestTable : Table("test_table") { val id = binary("id", 16).primaryKey() val name = varchar("name", 50) } val targetUuid = UUID.randomUUID() val result = TestTable.select { TestTable.id eqUuid targetUuid }.singleOrNull() // 生成的SQL:SELECT test_table.id, test_table.name FROM test_table WHERE BIN_TO_UUID(test_table.id, 1) = ?
方案3:自定义BIN_TO_UUID函数类
直接定义对应MySQL内置函数的Exposed Function类,方便在查询中灵活组合使用:
import org.jetbrains.exposed.sql.* import java.util.UUID class BinToUuidFunction(column: Column<ByteArray>, flag: Int = 1) : Function<UUID>(UUIDColumnType()) { override fun toQueryBuilder(queryBuilder: QueryBuilder) { queryBuilder.append("BIN_TO_UUID(", column, ", ", flag, ")") } } // 使用示例 val targetUuid = UUID.randomUUID() val result = TestTable.select { BinToUuidFunction(TestTable.id) eq targetUuid }.singleOrNull() // 生成的SQL与方案2一致
内容的提问来源于stack exchange,提问作者lipsum
相关产品推荐
相关产品推荐

