有一个项目需要存储ios的表情(emoji表情)

这种表情虽然是utf8编码,但是一个字符需要占用4个字节,而MySQL utf8编码只能存放3字节的字符。

在MySQL 5.6中,可以设置编码为utf8mb4,这个字符集是utf8的超集。

实验环境

MySQL 5.6.14

JDBC 5.1.31

测试表 create table test( content varchar(50) )engine=innodb,charset=utf8mb4;

测试程序:

import java.io.IOException;

import java.net.URLDecoder;

import java.net.URLEncoder;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

/**

* Servlet implementation class CharsetTest

*/

@WebServlet("/CharsetTest")

public class CharsetTest extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String str = request.getParameter("content");

str = URLDecoder.decode(str, "utf8");

System.out.println(URLEncoder.encode(str, "utf8"));

try {

save(str);

} catch (Exception e) {

e.printStackTrace();

}

}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

doGet(request, response);

}

private static void save(String content) throws Exception {

/**

* create table test( content varchar(50) )engine=innodb,charset=utf8mb4

*/

Class.forName("com.mysql.jdbc.Driver");

Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/xx", "xx", "xx");

connection.setAutoCommit(true);

//通过查询运行设置字符集的命令

//connection.prepareStatement("set names utf8mb4").executeQuery();

PreparedStatement cmd = connection.prepareStatement("insert into test values(?)");

cmd.setString(1, content);

cmd.executeUpdate();

cmd.close();

connection.close();

}

}

测试链接:

两次编码后的ios表情:

http://127.0.0.1:8080/Web/CharsetTest?content=%25F0%259F%2598%2584

两次编码后的中文:http://127.0.0.1:8080/Web/CharsetTest?content=%25E4%25B8%25AD%25E6%2596%2587

关于两次编码参见:http://www.linuxidc.com/Linux/2014-07/104232.htm

首先,修改mysql的配置文件

character_set_server=utf8mb4

然后重启数据库和中间件.

点击两个测试的链接,查看数据库,发现数据成功插入。

这个过程理论上是不需要重启数据库的。但是实际测试中发现,如果不重启数据库,则插入会报错。

如果运气好,直接修改character_set_server参数,重启数据库,一切正常,就OK了。

运气不好(比如我),就很悲剧了。

我在生产库上修改了配置,并且重启了数据库。

居然发现ios的表情插入数据库都是乱码(全是问号 ????)

更悲剧的是,过了几分钟突然发现线上新插入的数据都是乱码(也都是问号)。

幸亏发现的早,还原了数据库的配置,否则运行几天之后发现,估计就得收拾小包袱走人了。

后来排查到这个问题是JDBC驱动造成的,线上JDBC驱动的版本是mysql-connector-java-5.1.6-bin

如果MySQL服务器设置为utf8mb4 高版本的JDBC驱动没有关系,但是低版本的驱动插入之后,就是下面这个样子。

所有输入的非英文字符都是乱码了。

因为JDBC驱动并不支持utf8mb4字符集,所以不能设置JDBC URL的characterEncoding

不过还有三种方式可以设置字符集1.不显式设置字符集,继承服务器的配置

2.在执行SQL之前,运行set names 的查询 (Query方式)

3.设置MySQL init_connect参数

经过测试各种因素的结果如下所示:

JDBC版本

普通中文

苹果表情

服务器utf8编码

5.1.6

正常

插入报错

5.1.6 Query

正常

正常

5.1.6 init_connect

正常

插入报错

5.1.31

正常

插入报错

5.1.31 Query

正常

正常

5.1.31 init_connect

正常

插入报错

服务器utf8mb4编码

5.1.6

乱码

乱码

5.1.6 Query

乱码

乱码

5.1.6 init_connect

乱码

乱码

5.1.31

正常

正常

5.1.31 Query

正常

正常

5.1.31 init_connect

正常

正常

总结:

1.修改了character_set_server参数,需要重启数据库

2.使用高版本的JDBC

相关标签:

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

mysql utf8mb4 php_MySQL设置utf8mb4编码_MySQL相关推荐

  1. 在mysql中怎样设置值唯一_mysql怎么设置行值唯一?

    mysql可通过给行(字段)添加唯一性约束来设置行值唯一,语法格式"CREATE TABLE 表名 (字段名 数据类型 UNIQUE);"和"ALTER TABLE 表名 ...

  2. mysql密码一般设置什么格式_mysql更改密码_如何更改mysql root用户密码

    windows平台下如何修改mysql数据库密码 1.关闭正在运行的MySQL服务:net stop mysql或 在windows 任务管理器中结束 mysqld.exe 进程或在 管理工具里面的服 ...

  3. mysql外键设置不成功_MySQL数据库建立外键失败的原因总结

    在MySQL数据库创建外键时,经常会发生一些错误,这是一件很令人头疼的事.一个典型的错误就是:Can't create table... 的错误.在很多实例中,这种错误的发生都是因为mysql一直以来 ...

  4. mysql创建表设置自增_mysql 创建表并设置主键自增

    mysql 创建表并设置主键自增 mysql 创建表: mysql> create table user( -> userid int(4) primary key not null au ...

  5. mysql my.ini设置root密码_mysql 5.7设置root密码 windows

    1.找到my.ini,去掉skip-grant-tables,然后重启mysql服务,如无,可忽略 skip-grant-tables:数据库启动的时候 跳跃权限表的限制,不用验证密码,直接登录. 不 ...

  6. jdbc连接mysql数据库,设置字符集编码

    JDBC连接数据库时常会出现乱码的情况,那是因为我们的字符级与数据库的字符级不一样,我们通过定义url地址的时候定义字符级 String url = "jdbc:mysql://localh ...

  7. mysql中外键设置级联删除_MySQL中利用外键实现级联删除、更新

    MySQL中利用外键实现级联删除.更新 MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在 创建索引的时候,可以指 ...

  8. Navicat for MySQL 新建数据库设置数据库编码

    通过mysql命令修改 修改数据库的字符集 mysql>use mydb mysql>alter database mydb character set utf-8; 创建数据库指定数据库 ...

  9. tomcat设置UTF-8编码

    需要修改tomcat里的config.xml来修改,方法如下2种: 第一种: 1.在myclipse里,右键部署在tomcat里的项目,如下图所示,点击"浏览部署目录"(其他版本的 ...

最新文章

  1. Android Studio:依赖异常问题解决
  2. 50兆 svg 文件超过_中山兆驰产业园项目开工,预计竣工投产时间为…
  3. DataGridView 单元格验证
  4. Kafka淘汰倒计时!这个新一代消息中间件,腾讯、华为都用疯了?
  5. 【high-speed-downloader】百度网盘不限速下载 支持 Windows 和 Mac
  6. Python《爬虫初实践》
  7. Tomcat xxx unbound
  8. 2345电脑管家_PS教程第一节:如何正确安装PScc?安装前做好这一步电脑才不会卡顿....
  9. java类静态初始化_Java静态代码块和类初始化、实例初始化过程
  10. UEditor实战分享(二)定制
  11. python 修改文件名 修改日期_python实现批量修改文件名
  12. B站【云E办】在线办公系统 项目源码
  13. linux安装seaweedfs
  14. 蚂蚁笔记(Leanote) ubuntu安装教程
  15. Python神经网络编程 | 专场送书活动
  16. AMD Radeon GPU Injector tool | 老旧 AMD 显卡驱动工具
  17. jeecg-boot实现分布式定时任务
  18. react-native打包release版本闪退
  19. 数据中心机柜水冷系统中一次泵和二次泵哪个更好?
  20. 【技术三千问】之《modbus问题难点解析》,避坑指南!

热门文章

  1. Eclipse闪退解决方案
  2. 不会装系统?有这篇就够了!
  3. Xcode 静态库调试策略
  4. 使用spring cache和ehcache之前必须了解的
  5. 三 jQuery 选择器
  6. 033-Unit 11 Advanced Uses of the vi Editors
  7. 北京大学数学科学学院2006/9/20声明:坚持真理、追求卓越zz
  8. templateref html内容,angular4中的ElemenetRef和TemplateRef之间的区别
  9. J2EE--Mybatis基础知识题
  10. Python计算组合数生成杨辉三角形