Java emoji持久化mysql
好久没有更新博客了,今天和大家分享一个关于emoji表情持久化问题,相信做web开发的都遇到过这样的问题,因为我们知道mysql的utf-8字符集保存不了保存不了表情字符,这是为什么呢?因为普通的字符串或者表情都是占位3个字节,所以utf8足够用了,但是移动端的表情符号占位是4个字节,普通的utf8就不够用了,为了应对无线互联网的机遇和挑战、避免 emoji 表情符号带来的问题、涉及无线相关的 MySQL 数据库建议都提前采用 utf8mb4 字符集,这必须要作为移动互联网行业的一个技术选型的要点。
好了看到上面的结果你是不是已经去修改数据库字符集了,如果你是个人项目或小项目上面的方法倒是一个解决方法,但是对于一个目前正在服务5000W用户的系统,上面的方式就有点不合适了,针对这种情况我这边总结了三种处理方式,下面分享给大家:
1、既然是由于移动端的表情符号占位是4个字节,那我们直接把数据转换后保存。
1.URLEncoder.encode(String s, String enc)
使用指定的编码机制将字符串转换为 application/x-www-form-urlencoded 格式 URLDecoder.decode(String s, String enc)
使用指定的编码机制对 application/x-www-form-urlencoded 字符串解码。
2、方法一的处理太粗躁,有没有更好的解决办法呢?使用轻量级工具emoji-java处理emoji表情字符
github地址:https://github.com/vdurmont/emoji-java
具体使用方式,大家可以进入git中自行查看。
3、有了上面两种方式,你是不是已经满足了,最为自己最推崇的emoji处理方式,下面才是重点,首先说一下上面两种方式存在的问题:第一种方式,数据经过转换,相当于加密,我们将无法直接查看到数据的原始内容,由其对于需要进行搜索的业务场景,将是一件很困难的事情;第二种方式,虽然避免了第一种方式存在的问题,但是它基于表情的对照表进行匹配转换的,也就意味着对于一些新表情,无法做到转换,这就会导致我们数据插入继续出现问题,这是它第一个问题,第二点在于它将表情转化为对应的匹配规则,说白一点就是转化为英文描述,就是这个转化,原本4个字节的表情,它可能给你转成了10个字节甚至更多。好了说了这么多下面我们看一下我最后的终极解决方法:
/**
* @Author: gaoshang
* @Description:
* @Date: 2019/7/19
*/
public class EmojiUtil { /**
* 将文本中的表情转为十六进制
* <p>
*
* @param input
* @return
*/
public static String parseFromAliases(String input) {
if (input == null) {
return input;
} return stringToUnicode(input);
} /**
* 将文本中的十六进制转为表情
* <p>
*
* @param input
* @return
*/
public static String parseToAliases(String input) {
if (input == null) {
return input;
} return unicodeToString(input);
} /**
* 字符串转unicode
*
* @param str
* @return
*/
public static String stringToUnicode(String str) {
StringBuilder sb = new StringBuilder();
StringBuilder cacheSB = new StringBuilder();
char[] c = str.toCharArray();
for (int i = 0; i < c.length; i++) {
if (!isEmojiCharacter(c[i])) {
if (cacheSB.length() > 0) {
sb.append("\\u").append(cacheSB);
cacheSB.delete(0, cacheSB.length());
} sb.append("\\u").append("[").append(Integer.toHexString(c[i])).append("]");
} else {
if (c[i] == '[' || c[i] == '\\' || c[i] == ']') {
if (cacheSB.length() > 0) {
sb.append("\\u").append(cacheSB);
cacheSB.delete(0, cacheSB.length());
}
sb.append("\\u").append(c[i]);
} else {
cacheSB.append(c[i]);
}
}
}
if (cacheSB.length() > 0) {
if (sb.length() > 0) {
sb.append("\\u");
}
sb.append(cacheSB);
}
return sb.toString();
} /**
* unicode转字符串
*
* @param unicode
* @return
*/
public static String unicodeToString(String unicode) {
StringBuilder sb = new StringBuilder();
String[] hex = unicode.split("\\\\u");
for (int i = 0; i < hex.length; i++) {
if (hex[i].indexOf("[") == 0 && hex[i].indexOf("]") == hex[i].length() - 1) {
try {
int index = Integer.parseInt(hex[i].substring(1, hex[i].length() - 1), 16);
sb.append((char) index);
} catch (NumberFormatException e) {
sb.append(hex[i]);
}
} else {
sb.append(hex[i]);
}
}
return sb.toString();
} private static boolean isEmojiCharacter(char codePoint) {
return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
|| (codePoint == 0xD)
|| ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
|| ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
|| ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
} }
好了就先这样,欢迎大家提出不同的看法,已经好的解决方案。
Java emoji持久化mysql的更多相关文章
- 《精通Hibernate:Java对象持久化技术详解》目录
图书信息:孙卫琴 电子工业出版社 第1章 Java应用分层架构及软件模型: 1.1 应用程序的分层体系结构 1.1.1 区分物理层和逻辑层 1.1.2 软件层的特征 1.1.3 软件分层的优点 1.1 ...
- java emoji表情存储解决方案
1.问题产生情况 我遇到这个问题是做微信开发的时候有些有用的头像用了微信的emoji表情,然而我的mysql数据库用的编码是utf8_general_ci,就是utf-8编码,结果也就报错误了. 2. ...
- Java 数据持久化系列之JDBC
前段时间小冰在工作中遇到了一系列关于数据持久化的问题,在排查问题时发现自己对 Java 后端的数据持久化框架的原理都不太了解,只有不断试错,因此走了很多弯路.于是下定决心,集中精力学习了持久化相关框架 ...
- Java 数据持久化系列之池化技术
在上一篇文章<Java 数据持久化系列之JDBC>中,我们了解到使用 JDBC 创建 Connection 可以执行对应的SQL,但是创建 Connection 会消耗很多资源,所以 Ja ...
- Java 数据持久化系列之 HikariCP (一)
在上一篇<Java 数据持久化系列之池化技术>中,我们了解了池化技术,并使用 Apache-common-Pool2 实现了一个简单连接池,实验对比了它和 HikariCP.Druid 等 ...
- java jdbc 连接mysql数据库 实现增删改查
好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...
- JSP 实现 之 调用java方法实现MySQL数据库备份和恢复
package cn.qm.db; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.IOEx ...
- 点评阿里JAVA手册之MySQL数据库 (建表规约、索引规约、SQL语句、ORM映射)
下载原版阿里JAVA开发手册 [阿里巴巴Java开发手册v1.2.0] 本文主要是对照阿里开发手册,注释自己在工作中运用情况. 本文内容:MySQL数据库 (建表规约.索引规约.SQL语句.ORM映 ...
- 第68节:Java中的MYSQL运用从小白到大牛
第68节:Java中的MYSQL运用从小白到大牛 前言 学习java必备要求,学会运用!!! 常见关系化数据库 BootStrap是轻量级开发响应式页面的框架,全局css组件,js插件.栅格系统是将页 ...
随机推荐
- EF Power Tool 代码生成器 反向生成
大致来说,这个工具有这样几个功能: 1) 按照现有数据库结构,生成Code First POCO class.DbContext class和相应的mapping class. 2) 以designe ...
- python中的while循环,格式化输出,运算符,编码
一.while循环 1.1语法 while 条件: 代码块(循环体) else: 当上面的条件为假的的时候,才会执行. 执行顺序:先判断条件是否为真,如果是真的,执行循环体,再次判断条件,直到条件不成 ...
- TDD(测试驱动开发)死了吗?
01.前言 很早之前,曾在网络上见到过 TDD 这 3 个大写的英文字母,它是 Test Driven Development 这三个单词的缩写,也就是“测试驱动开发”的意思——听起来很不错的一种理念 ...
- 给你的 GitHub Repository 加上 sponsor 按钮
「本文微信公众号 AndroidTraveler 首发」 背景 其实之前 GitHub 就已经说过要给开源的开发者提供赞助支持. 当你进入 GitHub 主页时,你会在右边发现一个 Tips. 点击进 ...
- docker search/pull 报错
docker报错 Get https://registry-1.docker.io/v2/: x509: certificate has expired or is not yet valid 这种错 ...
- 16 | 脑洞大开:GUI测试还能这么玩(Page Code Gen + Data Gen + Headless)?
- 使用Jenkins部署.Net Core遇到的几个坑
搞过CI/CD的同学一定吃过不少苦头,或者说遇到不少坑,但是对自动化的执着住挡不了前进的步伐,如果你缺少了运维这一块知识,那么你的流水线总是不那么完美,本文记录的是自己躺过的坑,希望对你有所帮助. 一 ...
- 【HDU - 2181】哈密顿绕行世界问题(dfs+回溯)
-->哈密顿绕行世界问题 Descriptions: 一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市. Input 前2 ...
- 微服务-springboot多环境配置(开发生产测试环境切换)
springboot根据spring.profiles.active会去寻找应该加载开发环境配置还是生产环境配置 application.properties #生产环境,开发环境,测试环境切换 pr ...
- 002-pythn基础-循环、编码
1. 循环 while 条件: 代码块(循环体) else: 当上面的条件为假. 才会执行 执行顺序: 判断条件是否为真. 如果真. 执行循环体. 然后再次判断条件....直到循环条件为假. 程序退出 ...