`
dove19900520
  • 浏览: 592849 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

MySQL中存储来源于IOS微信端emoji表情字符出错的解决方案

阅读更多

上周在做微信摄影投票时,遇到这么一个情况,在微信中,如果将用户昵称修改为Emoji表情字符后,再通过hibernate向MySQL存储时,报如下错误:

 java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x94' for column 'name' at row 1      
         at com..jdbc.SQLError.createSQLException(SQLError.java:1073)       
         at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3593)      
         at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3525)      
         at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1986)       
         at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140)       
         at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2620)       
         at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1662)       
         at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1581) 

 原因是:MySQL中utf-8编码,一个字符占3个字节,但是微信Emoji表情字符,它的编码是utf8mb4编码的,一个字符占4个字节。就是因为这个原因,导致插入昵称时失败。

 
解决方案:
1、修改MySQL中对应表的昵称字段编码格式为utf8mb4;
2、放弃使用hibernate进行数据的存储或更新,改用纯jdbc的方式(hibernate的没研究过,不知道可不可以),代码片段如下:
String username = "root";
        String password = "111111";
        String className = "com.mysql.jdbc.Driver";
        String url = "jdbc:mysql://127.0.0.1:3306/vote?autoReconnect=true&useUnicode=true&characterEncoding=utf-&zeroDateTimeBehavior=convertToNull";
        Class.forName(className );
        Connection conn = DriverManager.getConnection(url , username , password );       

        public static Long save(String sql, Object[] params){
              Long ret = null;
              ResultSet rs = null;
              Connection conn = null;
              PreparedStatement cmd = null;
              try {
                   conn = getDBConnection();
                   conn.setAutoCommit(true);
                   //通过查询运行设置字符集的命令(这一句是重点)
                   conn.prepareStatement("set names utf8mb4").executeQuery();
                   cmd = conn.prepareStatement(sql);
                   if(params == null || params.length == 0){
                        return -1L;
                   }
                   for (int i = 0; i < params.length; i++) {
                        cmd.setObject(i+1, params[i]);
                   }
                   cmd.executeUpdate();
                   // 获取最后一条插入数据的自增列值
                   String sql2 = "select @@IDENTITY";
                   cmd = conn.prepareStatement(sql2);
                   rs = cmd.executeQuery();
                   if (rs.next()) {
                        ret = Long.parseLong(rs.getObject(1)+"");
                   }
              } catch (SQLException e) {
                   e.printStackTrace();
                   logger.error(e.getMessage(), e);
              } finally {
                   try {
                       if(cmd != null){
                             cmd.close();
                       }
                       if(rs != null){
                             rs.close();
                       }
                       if(conn != null){
                             conn.close();
                       }
                   } catch (SQLException e) {
                       e.printStackTrace();
               }
          }
          return ret;
     }
 完成上述修改之后,emoji表情字符就可以正常的插入到MySQL中了。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics