最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL插入emoji表情失敗問(wèn)題的解決方法

 更新時(shí)間:2017年05月04日 09:57:09   作者:Xie Zefan  
emoji表情在我們?nèi)粘i_(kāi)發(fā)中經(jīng)常會(huì)遇到,但是最近在mysql中插入emoji表情遇到了問(wèn)題,通過(guò)查找相關(guān)的資料終于解決了,所以將這次解決的過(guò)程分享出來(lái),這篇文章主要就給大家介紹了MySQL插入emoji表情失敗問(wèn)題的解決方法,需要的朋友可以參考。

前言

之前一直認(rèn)為UTF-8是萬(wàn)能的字符集問(wèn)題解決方案,直到最近遇到這個(gè)問(wèn)題。最近在做新浪微博的爬蟲(chóng), 在存庫(kù)的時(shí)候發(fā)現(xiàn)只要保持emoji表情,就回拋出以下異常:

Incorrect string value: '\xF0\x90\x8D\x83\xF0\x90...'

眾所周知UTF-8是3個(gè)字節(jié), 其中已經(jīng)包括我們?nèi)粘D芤?jiàn)過(guò)的絕大多數(shù)字體. 但3個(gè)字節(jié)遠(yuǎn)遠(yuǎn)不夠容納所有的文字, 所以便有了utf8mb4, utf8mb4是utf8的超集, 占4個(gè)字節(jié), 向下兼容utf8. 我們?nèi)粘S玫膃moji表情就是4個(gè)字節(jié)了.

所以在此我們像utf8的數(shù)據(jù)表插入數(shù)據(jù)就會(huì)報(bào)出Incorrect string value這個(gè)錯(cuò)誤.

Google一下很容易就找到了解決方案, 具體解決辦法是如下:

一、修改數(shù)據(jù)表的字符集為utf8mb4

這點(diǎn)很簡(jiǎn)單, 修改語(yǔ)句網(wǎng)上找一大堆, 不過(guò)建議重新建表, 使用 mysqldump -uusername -ppassword database_name table_name > table.sql 備份相應(yīng)數(shù)據(jù)表, 并修改其中的建表語(yǔ)句的字符集為 utf8mb4 即可, 然后 mysql -uusername -ppassword database_name < table.sql 重新導(dǎo)入sql即可完成修改字符集操作.

二、MySQL數(shù)據(jù)庫(kù)版本要5.5.3及以上

網(wǎng)絡(luò)上所有的文章都說(shuō)明要MySQL 5.5.3以上的版本才支持utf8mb4, 不過(guò)我使用的數(shù)據(jù)庫(kù)版本為5.5.18, 最終仍能解決問(wèn)題, 所以同學(xué)們不要急著找運(yùn)維哥哥升級(jí)數(shù)據(jù)庫(kù)先, 先試試能不能自己解決問(wèn)題.

三、修改數(shù)據(jù)庫(kù)配置文件/etc/my.cnf并重啟mysql服務(wù)

主要是修改數(shù)據(jù)庫(kù)的默認(rèn)字符集, 以及連接, 查詢的字符集, [Mysql支持emoji 表情符號(hào) 升級(jí)編碼為UTF8MB4][1] 這篇文章有詳細(xì)的設(shè)置方法, [深入Mysql字符集設(shè)置][2] 這篇文章有其中設(shè)置的各個(gè)字符集的作用, 大家可以科普下.

四、升級(jí)MySQL Connector到5.1.21及以上

以上所有的操作, 最關(guān)鍵的是步驟3, 修改數(shù)據(jù)庫(kù)的配置文件, 其中大概修改了

[client]
# 客戶端來(lái)源數(shù)據(jù)的默認(rèn)字符集
default-character-set = utf8mb4
[mysqld]
# 服務(wù)端默認(rèn)字符集
character-set-server=utf8mb4
# 連接層默認(rèn)字符集
collation-server=utf8mb4_unicode_ci
[mysql]
# 數(shù)據(jù)庫(kù)默認(rèn)字符集
default-character-set = utf8mb4

這些配置指定了數(shù)據(jù)從客戶端到服務(wù)端所經(jīng)過(guò)的一條條管道使用的字符集, 其中每一個(gè)管道出現(xiàn)問(wèn)題都可能會(huì)導(dǎo)致插入失敗或者亂碼.

但很多時(shí)候, 線上的數(shù)據(jù)庫(kù)是不能隨便修改數(shù)據(jù)庫(kù)文件的, 所以我們的運(yùn)維同學(xué)很果斷的回絕了我修改數(shù)據(jù)庫(kù)配置文件的請(qǐng)求(T_T)

所以就只能用代碼解決了, 一開(kāi)始是準(zhǔn)備從JDBC連接時(shí)候就指定使用的字符集處下手.

jdbc:mysql://localhost:3306/ding?characterEncoding=UTF-8

主要把UTF-8修改為utf8mb4對(duì)于的Java Style Charset字符串應(yīng)該就能解決問(wèn)題吧?

不過(guò)很遺憾的是, Java JDBC并不存在utf8mb4對(duì)于的字符集. 使用UTF-8的時(shí)候可以兼容urf8mb4并自動(dòng)轉(zhuǎn)換字符集.

For example, to use 4-byte UTF-8 character sets with Connector/J, configure the MySQL server with character_set_server=utf8mb4, and leave characterEncoding out of the Connector/J connection string. Connector/J will then autodetect the UTF-8 setting. – [MySQL:Using Character Sets and Unicode][3]

后來(lái)科普了一下, 在每一次查詢請(qǐng)求的時(shí)候, 可以顯式的指定使用的字符集, 使用 set names utf8mb4 可以指定本次鏈接的字符集為utf8mb4, 但這個(gè)設(shè)置在每次連接被釋放后都會(huì)失效.

目前的解決辦法是, 在需要插入utf8mb4的時(shí)候, 顯示地調(diào)用執(zhí)行set names utf8mb4, 如:

jdbcTemplate.execute("set names utf8mb4");
jdbcTempalte.execute("...");

需要注意的是, 我們?cè)谑褂靡幌翺RM框架的時(shí)候, 因?yàn)樾阅軆?yōu)化原因, 框架會(huì)延遲提交, 除非事務(wù)結(jié)束或者用戶主動(dòng)調(diào)用強(qiáng)制提交, 負(fù)責(zé)執(zhí)行的set names utf8mb4仍然不會(huì)生效.

在這里我使用的是myBatis, 以MessageDao為例

// MessageDao
public interface MessageDao {
 @Update("set names utf8mb4")
 public void setCharsetToUtf8mb4();
 @Insert("insert into tb_message ......")
 public void insert(Message msg);
}
// test code
SqlSession sqlSession = sqlSessioFactory.openSession();
messageDao = sqlSession.getMapper(MessageDao.class);
messageDao.setCharsetToUtf8mb4();
// 強(qiáng)制提交
sqlSession.commit();
messageDao.insert(message);

至此, 問(wèn)題便解決了..

哎, 如果世事能那么順利就好了, 在項(xiàng)目中, mybatis是實(shí)例是交由Spring去管理的, 也就是說(shuō)我拿不到sqlSession, 也就是強(qiáng)制提交不了. 并且因?yàn)镾pring事務(wù)框架的限制, 他并不允許用戶顯式調(diào)用強(qiáng)制提交. 目前還在糾結(jié)這個(gè)問(wèn)題.

有兩個(gè)解決思路:

  • 使用AOP, 在可能插入4字節(jié)UTF8字符的時(shí)候, 前置方法執(zhí)行set names utf8mb4, 但該方案還不能確定AOP的方法會(huì)被Spring進(jìn)行事務(wù)管理么, 并且在前置方法中,拿到的鏈接是否和接下來(lái)拿到的連接對(duì)象是同一個(gè)session.
  • 研究Spring JDBC的創(chuàng)建方法, 寫(xiě)一個(gè)hook在每次創(chuàng)建新的數(shù)據(jù)庫(kù)連接的時(shí)候, 都執(zhí)行一次set names utf8mb4, 這樣就保證每一次拿到的鏈接都是設(shè)置過(guò)字符集的.

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,待有時(shí)間再實(shí)驗(yàn)一下以上兩種方案。希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • MySQL數(shù)據(jù)庫(kù)10秒內(nèi)插入百萬(wàn)條數(shù)據(jù)的實(shí)現(xiàn)

    MySQL數(shù)據(jù)庫(kù)10秒內(nèi)插入百萬(wàn)條數(shù)據(jù)的實(shí)現(xiàn)

    假設(shè)現(xiàn)在我們要向mysql插入500萬(wàn)條數(shù)據(jù),如何實(shí)現(xiàn)高效快速的插入進(jìn)去?本文就詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-10-10
  • MySQL數(shù)據(jù)庫(kù)開(kāi)發(fā)的36條原則(小結(jié))

    MySQL數(shù)據(jù)庫(kù)開(kāi)發(fā)的36條原則(小結(jié))

    這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)開(kāi)發(fā)的36條原則(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Linux中MySQL 雙主復(fù)制的配置指南

    Linux中MySQL 雙主復(fù)制的配置指南

    在數(shù)據(jù)驅(qū)動(dòng)的時(shí)代,數(shù)據(jù)庫(kù)的高可用性和數(shù)據(jù)一致性是每個(gè)企業(yè)必須考慮的重要問(wèn)題,MySQL 雙主復(fù)制提供了一種有效的解決方案,通過(guò)配置兩臺(tái)服務(wù)器互為主從,保證數(shù)據(jù)的實(shí)時(shí)同步和高可用性
    2024-07-07
  • MySQL多表連接的入門(mén)實(shí)例教程

    MySQL多表連接的入門(mén)實(shí)例教程

    這篇文章主要給大家介紹了關(guān)于MySQL多表連接的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 淺析MySQL如何實(shí)現(xiàn)事務(wù)隔離

    淺析MySQL如何實(shí)現(xiàn)事務(wù)隔離

    使用過(guò)關(guān)系型數(shù)據(jù)庫(kù)的,應(yīng)該都事務(wù)的概念有所了解,知道事務(wù)有 ACID 四個(gè)基本屬性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability),今天我們主要來(lái)理解一下事務(wù)的隔離性
    2021-06-06
  • MySQL大量臟數(shù)據(jù)如何只保留最新的一條(最新推薦)

    MySQL大量臟數(shù)據(jù)如何只保留最新的一條(最新推薦)

    這篇文章主要介紹了MySQL大量臟數(shù)據(jù),如何只保留最新的一條,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • Windws?MySQL?8.4?LTS的安裝

    Windws?MySQL?8.4?LTS的安裝

    本文主要介紹了Windws?MySQL?8.4?LTS的安裝,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • MySQL8.0移除傳統(tǒng)的.frm文件原因及解讀

    MySQL8.0移除傳統(tǒng)的.frm文件原因及解讀

    MySQL 8.0移除傳統(tǒng)的.frm文件,采用基于InnoDB的事務(wù)型數(shù)據(jù)字典,主要解決了元數(shù)據(jù)不一致、性能優(yōu)化、架構(gòu)簡(jiǎn)化、增強(qiáng)功能支持、兼容性與升級(jí)問(wèn)題,這一變革提高了數(shù)據(jù)庫(kù)的可靠性和性能,為未來(lái)的高級(jí)功能奠定了基礎(chǔ)
    2025-03-03
  • MySQL中的REPLACE?INTO語(yǔ)法詳解

    MySQL中的REPLACE?INTO語(yǔ)法詳解

    REPLACEINTO是MySQL中的一種特殊語(yǔ)句,用于在插入數(shù)據(jù)時(shí)檢測(cè)是否存在沖突,如果目標(biāo)表中已存在與新插入行的主鍵(PRIMARYKEY)或唯一鍵(UNIQUEKEY)沖突的記錄,則會(huì)刪除舊記錄并插入新記錄
    2025-02-02
  • MySQL多表查詢的案例詳解

    MySQL多表查詢的案例詳解

    這篇文章主要介紹了MySQL多表查詢的案例說(shuō)明,包括多表查詢的分類(lèi)及umion的使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03

最新評(píng)論

鄢陵县| 定边县| 崇明县| 厦门市| 浦江县| 静乐县| 白城市| 青铜峡市| 汨罗市| 阿瓦提县| 南丰县| 叙永县| 黎川县| 霞浦县| 社旗县| 德格县| 和硕县| 资兴市| 沙河市| 光山县| 铜陵市| 合阳县| 开阳县| 右玉县| 军事| 离岛区| 孟村| 察隅县| 卢氏县| 清丰县| 桑日县| 濮阳县| 民县| 漳平市| 洞头县| 齐齐哈尔市| 筠连县| 兴国县| 聂拉木县| 衡阳县| 丰镇市|