mysql utf-8模式下,分为ut8mb3,utf8mb4,mb4是支持特殊字符、emoji表情的,mb3是不支持的。
报错信息:
1### Error updating database. Cause: java.sql.SQLException: Incorrect string value: '\xF0\xA8\x92\x82\xE6\x95...' for column 'fleet_contact_name' at row 1
需要排查mysql的字符、表、字段的字符:
SHOW VARIABLES LIKE 'character_set%';
可以看到database是utf8的,默认是走的utf8mb3。
继续查看表的ddl语句,确保表字段走到utf8mb4。
继续排查程序jdbc的连接设置UTF-8的编码
jdbc:mysql://localhost:3306/66kc_test_yunlian_truck?characterEncoding=UTF-8&useUnicode=true&useSSL=false&allowMultiQueries=true
如果上述都没问题,大概率是mysql-connector的版本问题,升级版本到8.0.13和以后的版本
-- maven引入
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version> <!-- 使用时请检查是否有更新的版本 -->
</dependency>
-- mysql的配置修改项目
driver-class-name: com.mysql.cj.jdbc.Driver
原因解释:
mysql-connector-java 版本在8.0.12之前的,包括8.0.12,服务端必须设置character_set_server=utf8mb4;如果不是的话,就算设置了characterEncoding=UTF-8,照样会被设置为MYSQL的 utf8字符集,也就是utf8mb3。
对于8.0.13和以后的版本,如果设置了characterEncoding=UTF-8,他会映射到MYSQL的utf8mb4字符集。
如果connectionCollation 也和characterEncoding一起设置了,但是不兼容,characterEncoding会被connectionCollation的设置覆盖掉。
由于没有Java-Style的utfmb3对应的字符集名称可以用在connection选项charaterEncoding上,唯一的设置utf8mb3的方式就是在连接选项设置utf8mb3 collation(例如utf8_general_ci),这会强制使用utf8mb3字符集,正如上文所述。
我们这次的问题就是mysql-connector的版本的原因,mysql server 5.7.37 ,client connector是5.1.39。使用mybatis-plus ,Hikari连接池的项目导致插入报错,升级connector8.0.13的版本后问题解决。但是另外一个项目使用mybatis\druid的连接池,就能够正常写入,具体原因可能是编码设置的内部机制问题。
编码解析流程:
总结:1、问题排查时一定确认好生产、测试的配置是否一致,不一致可能导致判断引导错误。
2、一个项目的报错,最好用同一个项目进行验证,不要用另外一个项目验证(另一个项目验证方便快时想省事)
3、验证时,一个变量一个变量的验证,否则也会错误引导。事情杂乱时,注意控制步骤跟时间