欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mysql字符集引起的java.sql.SQLException:Incorrect?string?value:問題

 更新時間:2024年11月11日 16:37:00   作者:二掌柜,酒來!  
文章主要介紹了在MySQL數(shù)據(jù)庫中插入生僻字和emoji表情包時遇到的字符編碼問題,解釋了utf8和utf8mb4的區(qū)別,并提供了修改數(shù)據(jù)庫編碼格式和更改MySQL參數(shù)的解決方案

問題1

在執(zhí)行一次數(shù)據(jù)庫插入的時候,偶然發(fā)現(xiàn)的一個問題。數(shù)據(jù)庫在插入一些生僻字,如??、??

或者emoji 表情包的時候,會出現(xiàn)如下異常。

Cause: java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x91\x87\xE7\x9A…’ for column ‘content’ at row 1

環(huán)境

mysql-connector-java-5.1.46
mysql	5.7.27

原因:字符集編碼選擇

我們新建mysql數(shù)據(jù)庫的時候,需要指定數(shù)據(jù)庫的字符集,一般我們都是選擇utf8這個字符集。而如果我們仔細觀察的話,其實我們會發(fā)現(xiàn)還有一種utf8mb4字符集。那么這兩者有什么關(guān)聯(lián)呢。

utf8mb4 的出現(xiàn)

utf8 是 Mysql 中的一種字符集,只支持最長 三個字節(jié) 的 UTF-8字符,也就是 Unicode 中的基本多文本平面。

  • utf8 是 MySQL 中的一種字符集,最早支持的 UTF-8 編碼。
  • 它只能存儲最長三個字節(jié)的 UTF-8 字符,也就是 Unicode 中的基本多文本平面(BMP)中的字符。
  • 原始的 utf8 實現(xiàn)并沒有涵蓋所有 Unicode 字符,僅支持 BMP 中的字符,大約占所有 Unicode 字符的 90%。
  • 在 MySQL 5.7 及更早版本中,utf8 是默認字符集。

MySQL在5.5.3之后增加了這個utf8mb4的編碼,mb4就是most bytes 4的意思,專門用來兼容四字節(jié)的unicode。

好在utf8mb4是utf8的超集,除了將編碼改為utf8mb4外不需要做其他轉(zhuǎn)換。

當然,為了節(jié)省空間,一般情況下使用utf8也就夠了。

可以簡單的理解 utf8mb4 是目前最大的一個字符編碼,支持任意文字。

Mysql 中的 utf8 為什么只支持持最長三個字節(jié)的 UTF-8字符呢?

  • 我想了一下,可能是因為 Mysql 剛開始開發(fā)那會,Unicode 還沒有輔助平面這一說呢。
  • 那時候,Unicode 委員會還做著 “65535 個字符足夠全世界用了”的美夢。
  • Mysql 中的字符串長度算的是字符數(shù)而非字節(jié)數(shù),對于 CHAR 數(shù)據(jù)類型來說,需要為字符串保留足夠的長。
  • 當使用 utf8 字符集時,需要保留的長度就是 utf8 最長字符長度乘以字符串長度,所以這里理所當然的限制了 utf8 最大長度為 3,比如 CHAR(100) Mysql 會保留 300字節(jié)長度。
  • 至于后續(xù)的版本為什么不對 4 字節(jié)長度的 UTF-8 字符提供支持,我想一個是為了向后兼容性的考慮,還有就是基本多文種平面之外的字符確實很少用到。

要在 Mysql 中保存 4 字節(jié)長度的 UTF-8 字符,需要使用 utf8mb4 字符集,但只有 5.5.3 版本以后的才支持。

我覺得,為了獲取更好的兼容性,應(yīng)該總是使用 utf8mb4 而非 utf8. 對于 CHAR 類型數(shù)據(jù),utf8mb4 會多消耗一些空間,根據(jù) Mysql 官方建議,使用 VARCHAR 替代 CHAR。

解決方案

修改 Mysql 數(shù)據(jù)中數(shù)據(jù)表的編碼格式,設(shè)置成 utf8mb4

1. 修改編碼方式

  • 修改單個字段編碼方式
alter table <表名> modify column <字段名> <字段類型> character set utf8mb4 collate utf8mb4_unicode_ci;

utf8mb4_unicode_ci 是排序方式

  • 修改表編碼方式
 ALTER TABLE <表名> CONVERT TO CHARACTER SET utf8mb4 COLLATE UTF8MB4_UNICODE_CI;

或者直接通過cavicat or sqlyog 等連接工具修改編碼方式表。有時候修改沒有效果,還是需要命令行修改。

2. 更改mysql 參數(shù)

mysql 字符集參數(shù)查看

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%'

  • character_set_client:客戶端字符集,用于指定從客戶端發(fā)送到服務(wù)器的字符集。
  • character_set_connection:連接字符集,用于指定客戶端與服務(wù)器之間的連接字符集。
  • character_set_database:數(shù)據(jù)庫字符集,用于指定創(chuàng)建新數(shù)據(jù)庫時的默認字符集。
  • character_set_results:結(jié)果字符集,用于指定從服務(wù)器返回給客戶端的結(jié)果字符集。
  • character_set_server:服務(wù)器字符集,用于指定服務(wù)器的默認字符集。
  • collation_server:服務(wù)器校對規(guī)則,用于指定服務(wù)器的默認校對規(guī)則。
  • collation_database:數(shù)據(jù)庫校對規(guī)則,用于指定創(chuàng)建新數(shù)據(jù)庫時的默認校對規(guī)則。
  • collation_connection:連接校對規(guī)則,用于指定客戶端與服務(wù)器之間的連接校對規(guī)則。
SET GLOBAL character_set_client = utf8mb4;
SET GLOBAL character_set_connection = utf8mb4;
SET GLOBAL character_set_database = utf8mb4;
SET GLOBAL character_set_results = utf8mb4;
SET GLOBAL character_set_server = utf8mb4;
SET GLOBAL collation_server = utf8mb4_unicode_ci;
SET GLOBAL collation_database = utf8mb4_unicode_ci;
SET GLOBAL collation_connection = utf8mb4_unicode_ci;

需要 重啟數(shù)據(jù)庫 生效?。?!

  • 需要注意的是,修改字符集可能會涉及到數(shù)據(jù)轉(zhuǎn)換和重新排序操作。在執(zhí)行這些操作之前,請務(wù)必備份您的數(shù)據(jù)庫,以防數(shù)據(jù)丟失或不可逆的更改發(fā)生。
  • 只改這個兩個也能成功。character_set_server,collation_server

注意

在解決這個問題的過程中,還有一些其他的冗余操作,屬于加上也能正常入口特殊字段,但不加也行。如何問題沒有解決的話,不妨一試。

1.數(shù)據(jù)庫鏈接接增加 &character_set_server=utf8mb4

Connector/J 5.1.47 及以上版本:

  • 指定 characterEncoding 參數(shù)為 UTF8/UTF-8 即可, 新版本直接映射到 utf8mb4 編碼;
  • 如果 connectionCollation 指定的排序規(guī)則不是 utf8mb4 相關(guān)的, 則 characterEncoding 參數(shù)會重寫為排序規(guī)則對應(yīng)的編碼;

Connector/J 5.1.47 以下版本:

  • 設(shè)置 MySQL 參數(shù)變量 character_set_server=utf8mb4;
  • 指定 characterEncoding 參數(shù)為 UTF8/UTF-8, jdbc 程序會進行探測是否使用 utf8mb4;

2.在 application.yaml 中添加下面屬性

initConnectionSqls=[ "SET NAMES utf8mb4"]

獲取上面的值并設(shè)置給數(shù)據(jù)源

dataSource.setConnectionInitSqls(sqlLists);
  • connectionInitSqls 是一個用于配置數(shù)據(jù)庫連接池的屬性,它允許您指定在每個數(shù)據(jù)庫連接建立時要執(zhí)行的初始化 SQL 語句。
  • 這些 SQL 語句可以用于在連接建立后執(zhí)行一些特定的操作,例如設(shè)置會話變量、執(zhí)行特定的查詢或配置連接的特性。
  • 在許多數(shù)據(jù)庫連接池實現(xiàn)中,包括一些開源的連接池庫和應(yīng)用服務(wù)器,都支持 connectionInitSqls 屬性來定義連接初始化 SQL。
  • 通過配置這個屬性,您可以確保每個連接在使用之前都會執(zhí)行指定的 SQL 語句。

3.使用最新的 MySQL 連接器。

mysql:mysql-connector-java:8.0.27
jdbc:mysql://192.168.10.10:3306/db_name?characterEncoding=utf8

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • mysql 8.0.21免安裝版配置方法圖文教程

    mysql 8.0.21免安裝版配置方法圖文教程

    這篇文章主要為大家詳細介紹了mysql 8.0.21免安裝版配置教程,文中安裝步驟介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • innodb引擎redo文件維護方法

    innodb引擎redo文件維護方法

    下面小編就為大家?guī)硪黄猧nnodb引擎redo文件維護方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • MySql閃退和服務(wù)無法啟動的解決方法

    MySql閃退和服務(wù)無法啟動的解決方法

    今天小編就為大家分享一篇關(guān)于MySql閃退和服務(wù)無法啟動的解決方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • MySQL快速對比數(shù)據(jù)技巧

    MySQL快速對比數(shù)據(jù)技巧

    這篇文章主要介紹了MySQL快速對比數(shù)據(jù)的方法以及技巧分享,如果對此有興趣,一起跟著小編學(xué)習(xí)下吧。
    2018-02-02
  • 全面分析MySQL?ERROR?1045出現(xiàn)的原因及解決

    全面分析MySQL?ERROR?1045出現(xiàn)的原因及解決

    這篇文章主要介紹了全面分析MySQL?ERROR?1045出現(xiàn)的原因及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • MySQL優(yōu)化GROUP BY(松散索引掃描與緊湊索引掃描)

    MySQL優(yōu)化GROUP BY(松散索引掃描與緊湊索引掃描)

    這篇文章主要介紹了MySQL優(yōu)化GROUP BY(松散索引掃描與緊湊索引掃描),需要的朋友可以參考下
    2016-05-05
  • 線上MySQL的自增id用盡怎么辦

    線上MySQL的自增id用盡怎么辦

    MySQL的自增id都定義了初始值,然后不斷加步長。雖然自然數(shù)沒有上限,但定義了表示這個數(shù)的字節(jié)長度,那自增id用完,會怎么樣?本文就來介紹一下
    2021-08-08
  • MySQL啟動連接的命令以及與PHP程序連接的基本語法

    MySQL啟動連接的命令以及與PHP程序連接的基本語法

    這篇文章主要介紹了MySQL啟動連接的命令以及與PHP程序連接的基本語法,簡單講述了PHP中調(diào)用MySQL的方法,需要的朋友可以參考下
    2015-11-11
  • mysql表格id清零的三種方法

    mysql表格id清零的三種方法

    本文主要介紹了mysql表格id清零的三種方法,主要包括TRUNCATE TABLE語句,ALTER TABLE語句和DELETE語句,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • MySQL+Redis緩存+Gearman共同構(gòu)建數(shù)據(jù)庫緩存的方法

    MySQL+Redis緩存+Gearman共同構(gòu)建數(shù)據(jù)庫緩存的方法

    這篇文章主要介紹了MySQL+Redis緩存+Gearman共同構(gòu)建數(shù)據(jù)庫緩存,部署后在MySQL端進行創(chuàng)建一個用戶給與遠程登錄權(quán)限,使得Redis作為緩存可以用來同步數(shù)據(jù)使用,需要的朋友可以參考下
    2022-10-10

最新評論