java.sql.SQLException:错误的string值:'\ xF0 \ x9F \ x91 \ xBD \ xF0 \ x9F …'

我有以下string值:“沃尔玛奥巴马👽💔”

我正在使用MySQL和Java。

我得到以下exception:`java.sql.SQLException:不正确的string值:'\ xF0 \ x9F \ x91 \ xBD \ xF0 \ x9F …'

这是我想要插入的variables:

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

我试图插入“沃尔玛奥巴马👽💔”的Java代码是一个preparedStatement。 所以我使用setString()方法。

看起来问题是值的编码。 我该如何解决这个问题? 以前我使用的是Derby SQL,值刚好是两个sqaure(我认为这是空字符的表示)

所有的帮助非常感谢!

你有什么是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 ,拼接需要为utf8mb4 。 对于java来说,它仍然只是"utf-8" ,但是MySQL需要一个区别。

我不知道你正在使用什么驱动程序,但是驱动程序不可知的方式来设置连接字符集是发送查询:

 SET NAMES 'utf8mb4' 

进行连接后。

另请参阅连接器/ J :

23.3.15.15:如何在连接器/ J上使用4字节的UTF8,utf8mb4?

要使用带有Connector / J的4字节UTF8,请使用character_set_server = utf8mb4configurationMySQL服务器。 只要连接string中没有设置characterEncoding ,Connector / J就会使用该设置。 这相当于字符集的自动检测。

调整您的列和数据库以及:

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

再一次,你的MySQL版本需要相对最新的utf8mb4支持。

总而言之,要保存需要4个字节的符号,您需要更新utf8mb4的characher-set和collat​​ion:

  1. 数据库表/列: alter table <some_table> convert to character set utf8mb4 collate utf8mb4_unicode_ci
  2. 数据库服务器连接( 参见 )

在我的#2开发环境中,我更喜欢在启动服务器时在命令行上设置参数: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci


顺便说一句,注意连接器/ J行为与SET NAMES 'utf8mb4'

请勿使用Connector / J发出查询集名称,因为驱动程序不会检测到字符集已更改,并且将继续使用在初始连接设置期间检测到的字符集。

并且避免在连接url中设置characterEncoding参数,因为它将覆盖configuration的服务器编码:

要覆盖客户端自动检测到的编码,请使用用于连接到服务器的URL中的characterEncoding属性。

奇怪的是,我发现从JDBC url中删除&characterEncoding = UTF-8对我来说也有类似的问题。

从我的属性,

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

我认为这支持@Esailija上面所说的,也就是说,我的MySQL确实是5.5,正在计算出它自己最喜欢的UTF-8编码。

(注意,我还指定了我正在读取的InputStream,作为UTF-8在Java代码,可能不会伤害)…

我如何解决我的问题。

我有

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

在我的hibernate jdbc连接url中,我将string数据types更改为数据库中的longtext,这是varchar之前的版本。

useUnicode=true&amp;characterEncoding=UTF-8行附加到您的jdbcurl。

在你的情况下,数据不是使用UTF-8编码发送的。

我猜MySQL不相信这是有效的UTF8文本。 我尝试了与列定义相同的testing表插入(mysql客户端连接也是UTF8),虽然它插入,我用MySQL CLI客户端以及JDBC检索到的数据没有正确检索值。 为了确保UTF8确实工作正常,我为obama插入了一个“ö”而不是“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应用程序testing:

 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连接相同的插入,并且抛出了相同的exception。 我相信这是一个MySQL的错误。 也许有关于这种情况的错误报告已经..

我遇到了同样的问题,并通过将Collat​​ion设置为每列的utf8_general_ci来解决此问题。

我遇到了同样的问题,经过认真对待所有的字符集,发现他们都是正确的,我意识到,我在我的课被错误的属性被注释为@Column而不是@JoinColumn(javax.presistence;hibernate)和它把一切都打破了。