SpringMvc+Hibernate+Mysql保存表情字符(昵称)到数据库报错的问题?

本文介绍了一款H5游戏在使用微信授权登录时遇到的问题:部分用户的微信昵称含有特殊表情字符,导致这些信息无法正常保存到MySQL数据库。文章详细分析了问题原因,并提供了逐步的解决方案,最终通过调整代码实现正确存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

  一个中小型H5游戏

 

描述

  游戏通过微信授权登入, 获取到用户昵称并将用户信息保存至Mysql数据库, 当遇到有些用户微信昵称中带有表情(特殊字符)时, 保存至数据库出错!

 

核心错误:

Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\xA4\xB4\xF0\x9F...' for column 'nick_name' at row 7
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3536)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3468)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1957)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2107)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2086)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2371)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2289)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2274)
	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2595)
	... 77 more

  

问题剖析:

  查阅线上资料后了解到, "特殊表情字符为4个字节,而 utf8 字符集只支持1-3个字节的字符, 将数据库相关字符集改为utf8mb4即可解决问题, 前提是Mysql版本需要5.5以上, 否则不支持该字符集"

 

修复实践:

  第一步: 修改 用户表 > 昵称字段 字符集改为 utf8mb4... 经测试仍无法保存, 报相同错误

  第二步: 在以上基础上 修改 用户表 字符集为 utf8mb4...经测试仍旧无法保存, 报相同错误

  第三步: 在以上基础上 修改 数据库 字符集为 utf8mb4...经测试仍旧无法保存, 报相同错误

  第四步: 在以上基础上 修改Mysql配置文件 my.ini , 修改内容包括: 1. default-character-set=utf8mb4  2. character-set-server=utf8mb4  总之把utf8都改成了 utf8mb4, 重启Mysql服务...经测试该状态下使用Mybatis可以顺利将表情字符存入数据库, 但是使用Hibernate仍旧无法保存, 报相同错误

  第五步: 修改项目持久层代码BaseDaoImpl.java, 在插入和修改记录前加入一段代码...经测试, 成功将表情字符存入Mysql

 

相关代码:

    "getSession().connection().prepareStatement("set names utf8mb4").execute();"

  

    public T save(T entity) {
        Assert.notNull(entity);
        try {
            getSession().connection().prepareStatement("set names utf8mb4").execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        getSession().save(entity);
        return entity;
    }

    public Object update(Object entity) {
        Assert.notNull(entity);
        try {
            getSession().connection().prepareStatement("set names utf8mb4").execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        getSession().update(entity);
        //getSession().flush();
        return entity;
    }

    public Object saveOrUpdate(Object entity) {
        Assert.notNull(entity);
        try {
            getSession().connection().prepareStatement("set names utf8mb4").execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        getSession().saveOrUpdate(entity);
        return entity;
    }

    

  

转载于:https://www.cnblogs.com/imyjy/p/7803108.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值