如何用Spring JdbcTemplate向MySQL 8的BINARY(16)列插入UUID
解决Spring JdbcTemplate向MySQL BINARY(16)列插入UUID的问题
你遇到的错误是因为直接通过setObject传入UUID对象时,JDBC驱动会将其转换为带横杠的字符串格式(长度36),而BINARY(16)列仅能存储16字节的数据,因此触发了数据截断错误。以下是三种可行的解决方案:
方案1:手动将UUID转换为16字节数组
编写工具函数将UUID拆解为字节数组,再通过setBytes方法传入:
internal const val INSERT_QUOTATION = """ INSERT INTO QUOTATION (PRODUCT_CODE, QUOTED_PRODUCT) VALUES (?, ?) """ // UUID转16字节数组工具方法 fun uuidToBytes(uuid: UUID): ByteArray { val buffer = ByteBuffer.allocate(16) buffer.putLong(uuid.mostSignificantBits) buffer.putLong(uuid.leastSignificantBits) return buffer.array() } // 插入逻辑 jdbcTemplate.update(INSERT_QUOTATION) { ps -> val productUuid = UUID.fromString("9efbfa7b-1573-44ea-99f4-9607b8e45e27") ps.setBytes(1, uuidToBytes(productUuid)) ps.setString(2, "{}") }
方案2:指定JDBC参数类型
利用setObject的重载方法,明确指定参数类型为Types.BINARY,让JDBC驱动自动完成UUID到二进制的转换(MySQL Connector/J 8.0+支持该特性):
internal const val INSERT_QUOTATION = """ INSERT INTO QUOTATION (PRODUCT_CODE, QUOTED_PRODUCT) VALUES (?, ?) """ jdbcTemplate.update(INSERT_QUOTATION) { ps -> val productUuid = UUID.fromString("9efbfa7b-1573-44ea-99f4-9607b8e45e27") ps.setObject(1, productUuid, java.sql.Types.BINARY) ps.setString(2, "{}") }
方案3:使用MySQL内置函数转换
在SQL语句中调用UUID_TO_BIN函数,将UUID字符串转换为二进制格式(第二个参数true表示使用无横杠的紧凑格式,更节省空间):
internal const val INSERT_QUOTATION = """ INSERT INTO QUOTATION (PRODUCT_CODE, QUOTED_PRODUCT) VALUES (UUID_TO_BIN(?, true), ?) """ jdbcTemplate.update(INSERT_QUOTATION) { ps -> val productUuid = UUID.fromString("9efbfa7b-1573-44ea-99f4-9607b8e45e27") ps.setString(1, productUuid.toString().replace("-", "")) // 传入无横杠的UUID字符串 // 也可直接传带横杠的字符串,UUID_TO_BIN会自动处理:ps.setString(1, productUuid.toString()) ps.setString(2, "{}") }
内容的提问来源于stack exchange,提问作者riccardo.cardin
相关产品推荐
相关产品推荐

