代码之家  ›  专栏  ›  技术社区  ›  riccardo.cardin

使用JdbcTemplate将UUID插入MySQL 8表

  •  0
  • riccardo.cardin  · 技术社区  · 8 月前

    我试图在MySQL 8表中插入一行,该行的列类型为 BINARY(16) 详细来说,我使用的是Spring JdbcTemplate ,信息存储在Java中 UUID 对象。我找不到如何正确地做这件事。

    internal const val INSERT_QUOTATION = """
        INSERT INTO QUOTATION (PRODUCT_CODE, QUOTED_PRODUCT)
        VALUES (?, ?)
    """
    
    jdbcTemplate.update(INSERT_QUOTATION) { ps ->
        ps.setObject(1, UUID.fromString("9efbfa7b-1573-44ea-99f4-9607b8e45e27"))
        ps.setString(2, "{}");
    }
    

    上述代码生成以下数据库错误:

    PreparedStatementCallback; SQL [
        INSERT INTO QUOTATION (PRODUCT_CODE, QUOTED_PRODUCT)
        VALUES (?, ?)
    ]; Data truncation: Data too long for column 'PRODUCT_CODE' at row 1
    

    我该怎么做?

    2 回复  |  直到 8 月前
        1
  •  2
  •   Math    8 月前

    错误“数据截断:第1行'PRODUCT_CODE'列的数据太长”很可能是由于在PreparedStatement中设置UUID的方式造成的。

    这个 BINARY(16) 类型恰好需要16个字节的数据。当您使用 UUID.fromString("9efbfa7b-1573-44ea-99f4-9607b8e45e27") 您正在创建UUID 对象 。因此,在将其插入数据库之前,您需要确保将其正确转换为16字节数组,因为UUID对象的长度不能保证为16字节。

    以下是你可以做的:

    internal const val INSERT_QUOTATION = """
        INSERT INTO QUOTATION (PRODUCT_CODE, QUOTED_PRODUCT)
        VALUES (?, ?)
    """
    
    jdbcTemplate.update(INSERT_QUOTATION) { ps ->
        val uuid = UUID.fromString("9efbfa7b-1573-44ea-99f4-9607b8e45e27")
        val uuidBytes = ByteBuffer.allocate(16)
            .putLong(uuid.mostSignificantBits)
            .putLong(uuid.leastSignificantBits)
            .array()
        ps.setBytes(1, uuidBytes)
        ps.setString(2, "{}")
    }
    

    这种方法通常会确保UUID正确转换为MySQL中BINARY(16)列类型所需的预期16字节格式。

        2
  •  1
  •   M. Deinum    8 月前

    您正在将UUID传递给 setObject 方法这不会自动将其转换为适合的格式 BINARY(16) 这一点也应该清楚 the answer 你链接到自己。

    你可以做两件事中的一件。

    1. 使用 UUID_TO_BIN MySQL中的函数,并将UUID作为字符串传递给查询,MySQL将进行转换。
    2. 转换 UUID a byte[] 通过从中提取有效位并将其设置为 byte[] 具有 setBytes .
    internal const val INSERT_QUOTATION = """
        INSERT INTO QUOTATION (PRODUCT_CODE, QUOTED_PRODUCT)
        VALUES (UUID_TO_BIN(?, true), ?)
    """
    
    jdbcTemplate.update(INSERT_QUOTATION, "9efbfa7b-1573-44ea-99f4-9607b8e45e27", "{}");
    

    这将插入它作为 二进制(16) 对于 SELECT 您需要使用 BIN_TO_UUID 函数再次将其转换为UUID。

    internal const val INSERT_QUOTATION = """
        INSERT INTO QUOTATION (PRODUCT_CODE, QUOTED_PRODUCT)
        VALUES (?, ?)
    """
    
    val uuid = UUID.fromString("9efbfa7b-1573-44ea-99f4-9607b8e45e27");
    val uuidInBytes = ByteBuffer.allocate(16)
            .putLong(uuid.mostSignificantBits)
            .putLong(uuid.leastSignificantBits)
            .array();
    jdbcTemplate.update(INSERT_QUOTATION, uuidInBytes, "{}");
    

    两者都应该奏效。