记SQL插入emoji成功,但是程序插入失败问题
创始人
2024-03-24 10:29:11
0

在执行单测时,碰到了以下熟悉的问题

org.springframework.jdbc.UncategorizedSQLException: 
### Error updating database.  Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x8B' for column 'name' at row 1
### The error may involve com.***.insert-Inline
### The error occurred while setting parameters
### SQL: insert into **********************
### Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x1B' for column 'name' at row 1
; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect string value: '\xF0\x9F\x92\x8B' for column 'name' at row 1; nested exception is java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x8B' for column 'name' at row 1at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:89)at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)at com.sun.proxy.$Proxy81.insert(Unknown Source)at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278)at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:58)at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)at com.sun.proxy.$Proxy92.insertUser(Unknown Source)

乍一看就是emoji入库失败,应该是表的字符集设置有问题。于是打开sql工作台执行

show variables like '%character%';

执行结果

mysql> show variables like "%character%";
+--------------------------+----------------------------------------+
| Variable_name            | Value                                  |
+--------------------------+----------------------------------------+
| character_set_client     | utf8mb4                                |
| character_set_connection | utf8mb4                                |
| character_set_database   | latin1                                 |
| character_set_filesystem | binary                                 |
| character_set_results    | utf8mb4                                |
| character_set_server     | utf8                                   |
| character_set_system     | utf8                                   |
| character_sets_dir       | /usr/soft/mysql-5.6.31***** |
+--------------------------+----------------------------------------+
8 rows in set

看似没有问题,字符集是utf8mb4,在使用sql试试,发现执行成功。

把代码中报错的sql复制出来,到控制台上执行,还是成功。

 这就很奇怪了,难道jdbc有什么问题?这个数据库之前就有保存emoji保存的业务,去线上库捞一下数据库配置。

mysql> show variables like "%character%";
+--------------------------+----------------------------------------+
| Variable_name            | Value                                  |
+--------------------------+----------------------------------------+
| character_set_client     | utf8mb4                                |
| character_set_connection | utf8mb4                                |
| character_set_database   | latin1                                 |
| character_set_filesystem | binary                                 |
| character_set_results    | utf8mb4                                |
| character_set_server     | utf8mb4                                   |
| character_set_system     | utf8                                   |
| character_sets_dir       | /usr/soft/mysql-5.6.31***** |
+--------------------------+----------------------------------------+
8 rows in set

发现只有character_set_server配置有所不同,难不成这个配置还能影响字符集类型?

这个character_set_server的作用是什么呢?

查阅文章可知,character_set_server与jdbc连接有关系。

官方对 JDBC 驱动的说明如下:

JDBC client与Mysqlserver默认是自动进行检测的。如果服务器端指定了character_set_server变量, 则 JDBC 驱动会自动使用该字符集(在不指定 JDBC URL 参数characterEncoding和connectionCollation的情况下)。 可以通过characterEncoding (该参数值是使用 Java 风格的形式指定. 例如 UTF-8 )来进行手工指定, 而不是自动检测。 为了在 MySQL JDBC 驱动版本 5.1.46 及之前的版本中使用 utf8mb4, 则服务器端必须配置character_set_server=utf8mb4, 否则JDBC URL参数characterEncoding=UTF-8 表示的是 MySQL 的 utf8, 而不是 utf8mb4

联系dba修改数据库参数character_set_server,但是并没有重启数据库,dba表示库比较多,暂时不需要重启,是动态生效的(实际并不是😂)。

在dba要求下重启应用n次之后,终于答应我重启数据库服务。

 直接成功,完结撒花。

最后还是看一下这个不生效的情况。。

Mysql JDBC 客户端 (Mysql Connector-j) 在不同的版本中对字符集的支持有一定差异。版本的分界线在 5.1.46 和 5.1.47 。

测试过程中,在重启 Server 情况下字符集都可以生效,而不重启 Server 的情况下只有 5.1.47 在客户端设置了字符集情况下才生效。具体情况如下表:

 官方文档中提到, Server 端的 character_set_server=utf8mb4 设置完成后,客户端如果没有配置“ characterEncoding ”会使用服务端配置的 utf8mb4 字符集。

估计是之前测试库迁移,没有按照生产配置搞,害,没用的知识又增加了

相关内容

热门资讯

将引入私人投资,加州撤回起诉美... 央视记者当地时间12月27日获悉,美国加利福尼亚州已正式撤回此前针对美联邦政府的诉讼,不再挑战联邦政...
增强市场主体获得感 以制度和规... “放得活”与“管得好”,既是一项重要的经济政策要求,也是一种治理智慧。在经济转型升级的关键阶段,把握...
东营集中巡查!抓获违法犯罪人员... 根据上级统一部署 连日来 东营市公安局东营分局 结合岁末年初社会治安特点 对全区治安复杂区域、人员密...
每周股票复盘:金煤科技(600... 截至2025年12月26日收盘,金煤科技(600844)报收于2.94元,较上周的3.0元下跌2.0...
每周股票复盘:武进不锈(603... 截至2025年12月26日收盘,武进不锈(603878)报收于9.94元,较上周的10.14元下跌1...
每周股票复盘:华依科技(688... 截至2025年12月26日收盘,华依科技(688071)报收于33.81元,较上周的32.34元上涨...
每周股票复盘:文灿股份(603... 截至2025年12月26日收盘,文灿股份(603348)报收于19.23元,较上周的19.5元下跌1...
每周股票复盘:中邮科技(688... 截至2025年12月26日收盘,中邮科技(688648)报收于58.51元,较上周的58.49元上涨...
每周股票复盘:蓝科高新(601... 截至2025年12月26日收盘,蓝科高新(601798)报收于8.99元,较上周的8.98元上涨0....
每周股票复盘:红豆股份(600... 截至2025年12月26日收盘,红豆股份(600400)报收于2.42元,较上周的2.5元下跌3.2...