8

在我的数据库中,我收到错误

com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column

我使用 Java 和 MySQL 5。我知道 4 字节 Unicode 在 Java 中是合法的,但在 MySQL 5 中是非法的,我认为它可能会导致我的问题,我想检查我的数据类型,所以这是我的问题:如何我检查我的 UTF-8 数据是 3 字节还是 4 字节 Unicode?

4

3 回答 3

17

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;
}
于 2013-02-20T13:37:08.870 回答
10

如果您不想支持 BMP 以外的内容,则可以在将其交给 MySQL 之前删除这些字符:

public static String withNonBmpStripped( String input ) {
    if( input == null ) throw new IllegalArgumentException("input");
    return input.replaceAll("[^\\u0000-\\uFFFF]", "");
}

如果你想支持 BMP 以外的东西,你需要 MySQL 5.5+ 并且你需要改变所有的东西utf8utf8mb4排序规则、字符集......)。但是您还需要我不熟悉的驱动程序中对此的支持。在 Java 中处理这些字符也很痛苦,因为它们分布在 2 上chars ,因此在许多操作中需要特殊处理。

于 2013-02-20T15:29:16.250 回答
6

我发现在 java 中去除非 BMP 字符的最佳方法如下:

inputString.replaceAll("[^\\u0000-\\uFFFF]", "\uFFFD");
于 2013-11-18T04:39:02.467 回答