mysql中Incorrect string value乱码问题解决方案
mysql中Incorrect string value乱码问题解决方案
java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x9C' for column 'content' at row 1
产生这种异常的原因在于,mysql中的utf8编码最多会用3个字节存储一个字符,如果一个字符的utf8编码占用4个字节(最常见的就是emoji表情字符),那么在写入数据库时就会报错。
mysql从5.5.3版本开始,才支持4字节的utf8编码,编码名称为utf8mb4(mb4的意思是max bytes 4),这种编码方式最多用4个字节存储一个字符。
要想证明这个问题,可以执行以下sql:
select * from
information_schema.CHARACTER_SETS
where CHARACTER_SET_NAME like 'utf8%'
因此,要解决上述异常的发生,需要使用utf8mb4编码
解决完数据库编码后,如果还发生乱码问题或者在客户端执行sql没问题,但是在代码执行中依旧抱乱码错误,那么还需要解决客户端Connection连接对象使用的编码问题。
执行以下sql:
--查看mysql连接客户端的字符编码
show variables like 'char%'
可以看出客户端Connection连接对象使用的编码是utf8mb4
解决:
//调用创建的Connection对象执行以下sql:
conn.createStatement().execute("SET names 'utf8mb4'");
如果项目中使用了DataSource数据源,只需要对数据源进行相关配置即可,这里以druid为例讲解,在spring框架下配置如下:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://xxxxx" /> <property name="username" value="username" /> <property name="password" value="password" /> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="8"/> <property name="maxIdle" value="2" /> <property name="maxActive" value="150" /> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="30000"/> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="8000"/> <!-- 连接最小存活时间,最新活跃时间开始计算,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="5000"/> <property name="validationQuery" value="SELECT 'x'"/> <property name="testWhileIdle" value="true"/> <!-- 申请连接时检查连接有效性,验证不通过则会直接关闭该连接,并重新从连接池获取下一条连接 --> <property name="testOnBorrow" value="true"/> <property name="testOnReturn" value="true"/> <!-- 打开PSCache,并且指定每个连接上PSCache的大小--> <property name="poolPreparedStatements" value="false"/> <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/> <!-- 此配置用于在创建Connection对象时执行指定的初始化sql --> <property name="connectionInitSqls"> <list> <value>set names 'utf8mb4'</value> </list> </property> </bean>
springboot自行对应修改,就不贴了
配置执行完此sql语句后,通过此连接对象后续创建的Statement都会成功地执行了。
引用自mysql参考手册
SET NAMES 'charset_name'
SET NAMES显示客户端发送的SQL语句中使用什么字符集。
因此,SET NAMES 'utf8mb4'语句告诉服务器:“将来从这个客户端传来的信息采用字符集utf8mb4”。它还为服务器发送回客户端的结果指定了字符集。(例如,如果你使用一个SELECT语句,它表示列值使用了什么字符集。)
SET NAMES 'x'语句与这三个语句等价:
mysql> SET character_set_client = x;
mysql> SET character_set_results = x;
mysql> SET character_set_connection = x;

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)