天天看點

如果有人問你 MySql 怎麼存取 Emoji,把這篇文章扔給他

01、前言

Emoji 在我們生活中真的是越來越常見了,幾乎每次發消息的時候不帶個 Emoji,總覺得少了點什麼,似乎幹巴巴的文字已經無法承載我們豐富的感情了。對于我們開發者來說,如何将 Emoji 存入 MySql 資料庫或者取出來,就變成了一種必須掌握的技能了。

Emoji 是一種圖形符号,能夠很直覺地反應出某種文字含義。它讓我想起遠古時代的象形文字。

如果有人問你 MySql 怎麼存取 Emoji,把這篇文章扔給他

Emoji 其實是一個日語詞(えもじ),E 表示"絵",moji 表示"文字";連在一起就是"絵文字",可以更形象化地表情達意。

02、糟糕

如果我們直接将 Emoji 表情存入資料庫的話,通常會出現下面這個錯誤。

如果有人問你 MySql 怎麼存取 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

1

由原來的 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。

如果有人問你 MySql 怎麼存取 Emoji,把這篇文章扔給他

那麼通過 emojiConverter.toHtml() 轉了之後的内容是什麼樣子呢?是一個碼點:&#128077,debug 的時候截圖如下所示。

如果有人問你 MySql 怎麼存取 Emoji,把這篇文章扔給他

這樣的話,MySql 儲存的内容就是一個普通的字元串了,編碼方式仍然可以是 utf8。

3)顯示 Emoji 的時候調用 toUnicode() 方法格式化一下

String unicode = emojiConverter.toUnicode(content);

outMsg.setContent(unicode);

格式化後的内容可以正常顯示在微信公衆号回複的文本消息中,截圖如下所示。

如果有人問你 MySql 怎麼存取 Emoji,把這篇文章扔給他