java.sql.sqlexception:不正确的字符串值:'\xf0\x9f\x91\xbd\xf0\x9f…'

rjee0c15  于 2021-06-24  发布在  Mysql
关注(0)|答案(11)|浏览(487)

我有以下字符串值:“walmart obama??”
我正在使用mysql和java。
我收到以下异常:`java.sql.sqlexception:不正确的字符串值:'\xf0\x9f\x91\xbd\xf0\x9f…'
下面是我要插入的变量:

var1 varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL`

我试图插入“walmart obama??”的java代码是一个preparedstatement。所以我用的是 setString() 方法。
看起来问题出在值的编码上??。我怎样才能解决这个问题?以前我使用的是derby sql和值??结果是两个sqaures(我认为这是空字符的表示)
非常感谢您的帮助!

eblbsuwk

eblbsuwk1#

执行

show VARIABLES like "%char%”;

如果不是utf8mb4,则查找字符集服务器。
把它放在你的my.cnf里,就像

vim /etc/my.cnf

添加一行

character_set_server = utf8mb4

最后重启mysql

0dxa2lsx

0dxa2lsx2#

我猜mysql不相信这是有效的utf8文本。我在一个具有相同列定义的测试表上尝试了insert(mysql客户端连接也是utf8),尽管它进行了insert,但我使用mysql cli客户端和jdbc检索到的数据并没有正确地检索到值。为了确保utf8工作正常,我插入了一个“ö" 而不是奥巴马的“o”:

johan@maiden:~$ mysql -vvv test < insert.sql 
--------------
insert into utf8_test values(_utf8 "walmart öbama ??")
--------------

Query OK, 1 row affected, 1 warning (0.12 sec)

johan@maiden:~$ file insert.sql 
insert.sql: UTF-8 Unicode text

要测试的小型java应用程序:

package test.sql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class Test
{

    public static void main(String[] args)
    {
        System.out.println("test string=" + "walmart öbama ??");
        String url = "jdbc:mysql://hostname/test?useUnicode=true&characterEncoding=UTF-8";
        try
        {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            Connection c = DriverManager.getConnection(url, "username", "password");
            PreparedStatement p = c.prepareStatement("select * from utf8_test");
            p.execute();
            ResultSet rs = p.getResultSet();
            while (!rs.isLast())
            {
                rs.next();
                String retrieved = rs.getString(1);
                System.out.println("retrieved=\"" + retrieved + "\"");

            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

}

输出:

johan@appel:~/workspaces/java/javatest/bin$ java test.sql.Test
test string=walmart öbama ??
retrieved="walmart öbama "

另外,我也尝试过对jdbc连接进行相同的插入,它抛出了与您得到的相同的异常。我相信这是一个mysql错误。可能已经有关于这种情况的错误报告了。。

0yg35tkg

0yg35tkg3#

这个设置useoldutf8behavior=true对我来说很好。它没有给出错误的字符串错误,但是它转换了特殊字符,比如ã 并保存在数据库中。
为了避免这种情况,我从jdbc参数中删除了这个属性,而是将列的数据类型转换为blob。这工作做得很好。

ao218c7q

ao218c7q4#

我也遇到了同样的问题,在仔细检查了所有字符集并发现它们都是正确的之后,我意识到我的类中有缺陷的属性被注解为@column而不是@joincolumn(javax.presistence;冬眠)它把一切都打破了。

c2e8gylq

c2e8gylq5#

追加行 useUnicode=true&amp;characterEncoding=UTF-8 到您的jdbc url。
在您的情况下,数据不是使用 UTF-8 编码。

eagi6jfj

eagi6jfj6#

我如何解决我的问题。
我有

?useUnicode=true&amp;characterEncoding=UTF-8

在我的hibernatejdbc连接url中,我将数据库中的字符串数据类型改为longtext,以前是varchar。

nr7wwzry

nr7wwzry7#

你所拥有的是 EXTRATERRESTRIAL ALIEN (U+1F47D) 以及 BROKEN HEART (U+1F494) 不在基本的多语言平面上。它们甚至不能在java中表示为一个字符, "??".length() == 4 . 它们绝对不是空字符,如果您不使用支持它们的字体,您将看到正方形。
mysql的 utf8 只支持基本的多语种平面,需要使用 utf8mb4 取而代之的是:
对于补充字符,utf8根本不能存储字符,而utf8mb4需要四个字节来存储字符。由于utf8根本无法存储字符,因此在utf8列中没有任何补充字符,并且在从较旧版本的mysql升级utf8数据时不必担心转换字符或丢失数据。
因此,为了支持这些字符,您的mysql需要是5.5+,并且您需要使用 utf8mb4 到处都是。连接编码需要 utf8mb4 ,字符集需要 utf8mb4 拼贴需要 utf8mb4 . 对于java来说,它仍然只是 "utf-8" ,但mysql需要区别对待。
我不知道您使用的是什么驱动程序,但设置连接字符集的一种与驱动程序无关的方法是发送查询:

SET NAMES 'utf8mb4'

就在接通之后。
另请参见连接器/j:
14.14:如何使用带连接器/j的4字节utf8、utf8mb4?
要将4字节utf8与connector/j一起使用,请使用字符\u set \u server=utf8mb4配置mysql服务器。只要连接字符串中没有设置characterencoding,connector/j就会使用该设置。这相当于自动检测字符集。
同时调整列和数据库:

var1 varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL

同样,您的mysql版本需要相对更新以支持utf8mb4。

qv7cva1a

qv7cva1a8#

奇怪的是,我发现 &characterEncoding=UTF-8JDBC url 用类似的问题帮我解决了问题。
根据我的财产,

jdbc_url=jdbc:mysql://localhost:3306/dbName?useUnicode=true

我认为这支持@esailija上面所说的,也就是说,我的mysql,它确实是5.5,正在找出自己最喜欢的utf-8编码风格。
(注意,我还指定了 InputStream 我在读as的书 UTF-8 在java代码中,这可能不会有什么坏处)。。。

hm2xizp9

hm2xizp99#

我也遇到了同样的问题,通过为每一列设置utf8\u general\u ci的排序规则来解决这个问题。

vs3odd8k

vs3odd8k10#

此外,数据类型可以使用varchar或text的blob安装。

c8ib6hqw

c8ib6hqw11#

总之,要保存需要4个字节的符号,需要更新字符集和排序规则 utf8mb4 :
数据库表/列: alter table <some_table> convert to character set utf8mb4 collate utf8mb4_unicode_ci 数据库服务器连接(请参阅)
在我的#2开发环境中,我更喜欢在启动服务器时在命令行上设置参数: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci 顺便说一句,注意接头/j的行为 SET NAMES 'utf8mb4' :
不要使用connector/j发出查询集名称,因为驱动程序不会检测到字符集已更改,并且将继续使用在初始连接设置期间检测到的字符集。
并避免设置 characterEncoding 参数,因为它将覆盖配置的服务器编码:
要覆盖客户端上自动检测到的编码,请在用于连接到服务器的url中使用characterencoding属性。

相关问题