zoukankan      html  css  js  c++  java
  • SpringMvc+Hibernate+Mysql保存表情字符(昵称)到数据库报错的问题?

    背景:

      一个中小型H5游戏

    描述

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

    核心错误:

    Caused by: java.sql.SQLException: Incorrect string value: 'xF0x9FxA4xB4xF0x9F...' 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;
        }

        

      

  • 相关阅读:
    getchar()详解
    ACM错误提示
    关于printf()函数和浮点数
    PCB蚀刻,盐酸不好买,三氯化铁不方便,用这个吧【转】
    wps自动半角符转全角符取消笔记
    万恶的oj笔记之【111028】
    hdu1142 深搜+dp+最短路径。
    pl2303电路图。。
    sencha touch 监控 Carousel 旋转事件
    正则表达式限制文本框输入内容
  • 原文地址:https://www.cnblogs.com/imyjy/p/7803108.html
Copyright © 2011-2022 走看看