我的数据库出现了错误
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column
我使用Java和MySQL 5。据我所知,4字节Unicode在Java中是合法的,但在MySQL 5中是非法的。我认为这可能会导致我的问题,并且我想检查数据类型,因此我的问题是: 如何检查UTF-8数据是3字节还是4字节Unicode?
我的数据库出现了错误
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column
我使用Java和MySQL 5。据我所知,4字节Unicode在Java中是合法的,但在MySQL 5中是非法的。我认为这可能会导致我的问题,并且我想检查数据类型,因此我的问题是: 如何检查UTF-8数据是3字节还是4字节Unicode?
UTF-8 编码将基本多文种平面(即U+0000到U+FFFF,包括在内)的所有内容编码为1-3个字节。 因此,您只需要检查您的字符串中的每个字符 是否 在BMP中。
在Java中,这意味着检查任何char
(它是一个UTF-16代码单元)是否是高代理或低代理字符,因为Java将使用代理对来编码非BMP字符:
public static boolean isEntirelyInBasicMultilingualPlane(String text) {
for (int i = 0; i < text.length(); i++) {
if (Character.isSurrogate(text.charAt(i))) {
return false;
}
}
return true;
}
如果您不想支持 BMP 之外的字符,您可以在交给 MySQL 之前删除这些字符:
public static String withNonBmpStripped( String input ) {
if( input == null ) throw new IllegalArgumentException("input");
return input.replaceAll("[^\\u0000-\\uFFFF]", "");
}
如果您想支持 BMP 以外的字符集,您需要 MySQL 5.5+ 并且您需要将所有使用的 utf8
改为 utf8mb4
(包括排序规则、字符集等)。但是,您还需要检查我不熟悉的驱动程序中是否支持该字符集。在 Java 中处理这些字符也很麻烦,因为它们分散在 2 个 chars
中,因此在许多操作中需要特殊处理。
preg_replace('/[^\x{0000}-\x{FFFF}]/u', '\x{FFFD}', $input);
。 - DOOManiac
VARCHAR
中,则没有编码错误。 - JonVARCHAR(n) CHARSET utf8
视为一个N*3
字节结构,因此这不太可能是问题所在。问题很可能是OP试图插入过多的数据。 - Christopher Schultz