java.sql.SQLException:字符串值不正确:'\ xF0\x9F\x91\xBD\xF0\x9F ......'

Cod*_*lus 99 java mysql encoding sqlexception character-encoding

我有以下字符串值:"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`
Run Code Online (Sandbox Code Playgroud)

我试图插入"walmart obama"的Java代码是一个preparedStatement.所以我正在使用这种setString()方法.

看起来问题是值的编码.我怎样才能解决这个问题?以前我使用的是Derby SQL,而且最终只有两个sqaures(我认为这是null字符的表示)

非常感谢所有帮助!

Esa*_*ija 134

你拥有的是什么EXTRATERRESTRIAL ALIEN (U+1F47D),BROKEN HEART (U+1F494)哪些不在基本的多语言平面中.它们甚至不能在java中表示为一个char "".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'
Run Code Online (Sandbox Code Playgroud)

在建立连接后.

另见Connector/J:

14.14:如何使用带有Connector/J的4字节UTF8,utf8mb4?

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

同样调整列和数据库:

var1 varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL
Run Code Online (Sandbox Code Playgroud)

同样,你的MySQL版本需要相对最新的utf8mb4支持.

  • 如果您只想删除 BMP 外部的字符,而不是处理更改数据库的混乱,请参见此处:http://stackoverflow.com/questions/4035562/java-regex-match-characters-outside -基本多语言平面 (2认同)
  • 我有同样的问题,按照上面的步骤,但直到更改C:\ ProgramData\MySQL\MySQL Server 5.7\my.ini中的字符集-server = utf8mb4后才得到解决 (2认同)

ril*_*aby 15

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

  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发出查询集名称,因为驱动程序不会检测到字符集已更改,并将继续使用在初始连接设置期间检测到的字符集.

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

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


jsh*_*jsh 14

奇怪的是,我发现&characterEncoding=UTF-8JDBC url类似的问题中删除了对我的伎俩.

根据我的属性,

jdbc_url=jdbc:mysql://localhost:3306/dbName?useUnicode=true
Run Code Online (Sandbox Code Playgroud)

我认为这支持@Esailija上面所说的,即我的MySQL,确实是5.5,正在弄清楚它自己最喜欢的UTF-8编码风格.

(注意,我也指定InputStream我正在读取UTF-8java代码,这可能不会受到伤害)...


Ind*_*bel 6

我是如何解决我的问题的.

我有

?useUnicode=true&amp;characterEncoding=UTF-8
Run Code Online (Sandbox Code Playgroud)

在我的hibernate jdbc连接url中,我将字符串数据类型更改为数据库中的longtext,之前是varchar.


JHS*_*JHS 4

将该行附加useUnicode=true&amp;characterEncoding=UTF-8到您的 jdbc url。

在您的情况下,数据未使用UTF-8编码发送。