如果有人问你 MySql 怎么存取 Emoji,把这篇文章扔给他
01、前言
Emoji 在我们生活中真的是越来越常见了,几乎每次发消息的时候不带个 Emoji,总觉得少了点什么,似乎干巴巴的文字已经无法承载我们丰富的感情了。对于我们开发者来说,如何将 Emoji 存入 MySql 数据库或者取出来,就变成了一种必须掌握的技能了。
Emoji 是一种图形符号,能够很直观地反应出某种文字含义。它让我想起远古时代的象形文字。

Emoji 其实是一个日语词(えもじ),E 表示"絵",moji 表示"文字";连在一起就是"絵文字",可以更形象化地表情达意。
02、糟糕
如果我们直接将 Emoji 表情存入数据库的话,通常会出现下面这个错误。

因为数据库的字符编码一般是 utf8(支持的编码范围为 \u0000-\uFFFF),而 Emoji 所在的编码范围是 \u1F601-\u1F64F,超出 MySql 的边界了。
怎么解决这个问题呢?
03、utf8mb4
可以将 MySql 的字符集由 utf8 调整为 utf8mb4。utf8mb4 是 MySql 在 5.5.3 版本之后增加的一个编码方式,用来兼容四字节的 Unicode(包括 Emoji)。
理论上,utf8mb4 是 utf8 的超集,其中 mb4 是 most bytes 4 的意思,将字符集修改为“utf8mb4”,并不会对已有的 utf8 编码读取产生任何问题。
但通常这种方式并不是最优解,因为应用层还需要将 MySql 的连接方式作出以下调整:
jdbcUrl = jdbc:mysql://localhost/jfinal_demo?characterEncoding=utf8mb4&useSSL=false&zeroDateTimeBehavior=convertToNull
由原来的 characterEncoding=utf8 调整为 characterEncoding=utf8mb4。
04、EmojiConverter
更友好的解决方式应该将 Emoji 当做字符串存储,然后在取出来的时候再转成 Emoji,这样可以兼容所有的数据库版本。
我在 GitHub 上找到了这样的一个库——EmojiConverter,它可以很方便地将 Emoji 转换为字符串的别名,同时也支持将这个别名转换为 Emoji。
1)在 pom.xml 文件中加入 EmojiConverter
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>java-emoji-converter</artifactId>
<version>0.1.1</version>
</dependency>
2)存储 Emoji 之前调用 toHtml() 方法转换一下
EmojiConverter emojiConverter = EmojiConverter.getInstance();
String html = emojiConverter.toHtml(keywords.getContent().trim());
// JFinal 的保存方式
Record record = new Record().set("content", html)
Db.save("keywords", record);
比如说,要存储的内容当中包含了一个点赞的 Emoji。

那么通过 emojiConverter.toHtml() 转了之后的内容是什么样子呢?是一个码点:👍,debug 的时候截图如下所示。

这样的话,MySql 保存的内容就是一个普通的字符串了,编码方式仍然可以是 utf8。
3)显示 Emoji 的时候调用 toUnicode() 方法格式化一下
String unicode = emojiConverter.toUnicode(content);
outMsg.setContent(unicode);
格式化后的内容可以正常显示在微信公众号回复的文本消息中,截图如下所示。

如果有人问你 MySql 怎么存取 Emoji,把这篇文章扔给他的更多相关文章
- 面试官问你MySQL的优化,看这篇文章就够了
作者:zhangqh segmentfault.com/a/1190000012155267 一.EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划. 下面来个简单的示例 ...
- Java设计模式(十三) 别人再问你设计模式,叫他看这篇文章
原创文章,转载请务注明出处 OOP三大基本特性 封装 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的属性和方法只让可信的类操作,对不可信的进行信息隐藏. 继承 继承是指这样一种能力,它可以使 ...
- MySql 怎么存取 Emoji
01.前言 Emoji 在我们生活中真的是越来越常见了,几乎每次发消息的时候不带个 Emoji,总觉得少了点什么,似乎干巴巴的文字已经无法承载我们丰富的感情了.对于我们开发者来说,如何将 Emoji ...
- 【漫画】以后在有面试官问你平衡(AVL)树,你就把这篇文章扔给他。
西天取经的路上,一样上演着编程的乐趣..... 1.若它的左子树不为空,则左子树上所有的节点值都小于它的根节点值. 2.若它的右子树不为空,则右子树上所有的节点值均大于它的根节点值. 3.它的左右子树 ...
- 再有人问你volatile是什么,把这篇文章也发给他
在上一篇文章中,我们围绕volatile关键字做了很多阐述,主要介绍了volatile的用法.原理以及特性.在上一篇文章中,我提到过:volatile只能保证可见性和有序性,无法保证原子性.关于这部分 ...
- 面试官再问Redis分布式锁如何续期?这篇文章甩 他一脸
一.真实案例 二.Redis分布式锁的正确姿势 据肥朝了解,很多同学在用分布式锁时,都是直接百度搜索找一个Redis分布式锁工具类就直接用了.关键是该工具类中还充斥着很多System.out.prin ...
- 再有人说synchronized是重量级锁,就把这篇文章扔给他看
synchronized作为Java程序员最常用同步工具,很多人却对它的用法和实现原理一知半解,以至于还有不少人认为synchronized是重量级锁,性能较差,尽量少用. 但不可否认的是synchr ...
- 互联网公司面试必问的mysql题目(上)
又到了招聘的旺季,被要求准备些社招.校招的题库.(如果你是应届生,尤其是东北的某大学,绝对福利哦) 介绍:MySQL是一个关系型数据库管理系统,目前属于 Oracle 旗下产品.虽然单机性能比不上or ...
- 互联网公司面试必问的mysql题目(下)
这是mysql系列的下篇,上篇文章地址我附在文末. 什么是数据库索引?索引有哪几种类型?什么是最左前缀原则?索引算法有哪些?有什么区别? 索引是对数据库表中一列或多列的值进行排序的一种结构.一个非常恰 ...
随机推荐
- Android 本地化适配:RTL(right-to-left) 适配清单
本文首发自公众号:承香墨影(ID:cxmyDev),欢迎关注. 一. 序 越来越多的公司 App,都开始淘金海外,寻找更多的机会.然而海外市场千差万别,无论是市场还是用户的使用习惯,都有诸多的不同. ...
- [C++] 头文件中不要用using namespace std
先总结下: 1. using namespce std:尽量不要(或者强硬一点,不许)在头文件中使用. 解析: 不让这么用,主要原因就是防止名字重复(即自定义变量名和std中名字重复),因为头文件会被 ...
- C# 反射基础用法
1.引用命名空间 using System.Reflection; 2.object[] parameters = { 参数 }; 调用方法的参数数组 3.Type t = Type.GetType( ...
- selenium使用总结
selenium selenium是一个支持各大浏览器的自动化测试工具,包括 Chrome,Safari,Firefox ,ie等.再构造爬虫时,如果我们加入了User-Agent,那么变伪装成了浏览 ...
- Moonraker 靶机渗透
0x01 简介 攻击Moonraker系统并且找出存在最大的威胁漏洞,通过最大威胁漏洞攻击目标靶机系统并进行提权获取系统中root目录下的flag信息. Moonraker: 1镜像下载地址: htt ...
- 体验Code::Blocks下的Windows GUI编程(32 bit and 64 bit)
0. 前言 不知道为什么,几乎所有的C++编程教程都是从命令行版(控制台应用程序)的Hello World开始的.然而,对于现在的年轻人来说,从小就用鼠标点击窗口或图标操作电脑,对于那个神秘黑色的窗口 ...
- Python 对cookies的处理——urllib2
import urllib2 import cookielib cookie = cookielib.CookieJar() opener = urllib2.build_opener(urllib2 ...
- 【网络安全】给你讲清楚什么是XSS攻击
给你讲清楚什么是XSS攻击 1. 什么是XSS攻击 跨站脚本攻击(Cross Site Scripting)本来的缩写为CSS,为了与层叠样式表(Cascading Style Sheets,CSS) ...
- Tomcat源码分析一:编译Tomcat源码
Tomcat源码分析一:编译Tomcat源码 1 内容介绍 在之前的<Servlet与Tomcat运行示例>一文中,给大家带来如何在Tomcat中部署Servlet应用的相关步骤,本文将就 ...
- execute,executeQuery,executeUpdate
Statement的execute(String query)方法用来执行任意的SQL查询,如果查询的结果是一个ResultSet,这个方法就返回true.如果结果不是ResultSet,比如inse ...