Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > mysql字符集引起的java.sql.SQLException:Incorrect string value:

mysql字符集引起的java.sql.SQLException:Incorrect string value:问题

作者:二掌柜,酒来!

文章主要介绍了在MySQL数据库中插入生僻字和emoji表情包时遇到的字符编码问题,解释了utf8和utf8mb4的区别,并提供了修改数据库编码格式和更改MySQL参数的解决方案

问题1

在执行一次数据库插入的时候,偶然发现的一个问题。数据库在插入一些生僻字,如𨭉、𡌶

或者emoji 表情包的时候,会出现如下异常。

Cause: java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x91\x87\xE7\x9A…’ for column ‘content’ at row 1

环境

mysql-connector-java-5.1.46
mysql	5.7.27

原因:字符集编码选择

我们新建mysql数据库的时候,需要指定数据库的字符集,一般我们都是选择utf8这个字符集。而如果我们仔细观察的话,其实我们会发现还有一种utf8mb4字符集。那么这两者有什么关联呢。

utf8mb4 的出现

utf8 是 Mysql 中的一种字符集,只支持最长 三个字节 的 UTF-8字符,也就是 Unicode 中的基本多文本平面。

MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。

好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。

当然,为了节省空间,一般情况下使用utf8也就够了。

可以简单的理解 utf8mb4 是目前最大的一个字符编码,支持任意文字。

Mysql 中的 utf8 为什么只支持持最长三个字节的 UTF-8字符呢?

要在 Mysql 中保存 4 字节长度的 UTF-8 字符,需要使用 utf8mb4 字符集,但只有 5.5.3 版本以后的才支持。

我觉得,为了获取更好的兼容性,应该总是使用 utf8mb4 而非 utf8. 对于 CHAR 类型数据,utf8mb4 会多消耗一些空间,根据 Mysql 官方建议,使用 VARCHAR 替代 CHAR。

解决方案

修改 Mysql 数据中数据表的编码格式,设置成 utf8mb4

1. 修改编码方式

alter table <表名> modify column <字段名> <字段类型> character set utf8mb4 collate utf8mb4_unicode_ci;

utf8mb4_unicode_ci 是排序方式

 ALTER TABLE <表名> CONVERT TO CHARACTER SET utf8mb4 COLLATE UTF8MB4_UNICODE_CI;

或者直接通过cavicat or sqlyog 等连接工具修改编码方式表。有时候修改没有效果,还是需要命令行修改。

2. 更改mysql 参数

mysql 字符集参数查看

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%'

SET GLOBAL character_set_client = utf8mb4;
SET GLOBAL character_set_connection = utf8mb4;
SET GLOBAL character_set_database = utf8mb4;
SET GLOBAL character_set_results = utf8mb4;
SET GLOBAL character_set_server = utf8mb4;
SET GLOBAL collation_server = utf8mb4_unicode_ci;
SET GLOBAL collation_database = utf8mb4_unicode_ci;
SET GLOBAL collation_connection = utf8mb4_unicode_ci;

需要 重启数据库 生效!!!

注意

在解决这个问题的过程中,还有一些其他的冗余操作,属于加上也能正常入口特殊字段,但不加也行。如何问题没有解决的话,不妨一试。

1.数据库链接接增加 &character_set_server=utf8mb4

Connector/J 5.1.47 及以上版本:

Connector/J 5.1.47 以下版本:

2.在 application.yaml 中添加下面属性

initConnectionSqls=[ "SET NAMES utf8mb4"]

获取上面的值并设置给数据源

dataSource.setConnectionInitSqls(sqlLists);

3.使用最新的 MySQL 连接器。

mysql:mysql-connector-java:8.0.27
jdbc:mysql://192.168.10.10:3306/db_name?characterEncoding=utf8

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文