1. 程式人生 > >被折騰了一下午的java查詢mysql資料庫的中文亂碼問題

被折騰了一下午的java查詢mysql資料庫的中文亂碼問題

java 通過connector 訪問 mysql, 可是裡面返回的中文字元是亂碼

排除一:  mysql 裡面直接查詢出來的字元是中文的

排除二: connector的設定  jdbc:mysql://localhost:3306/envisionin_db?tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8

排除三: response.setContentType("text/html;charset=utf-8");

剩下的就只是 mysql的字符集設定問題了

VERSION:

mysql> select version();

+-----------+

| version() |

+-----------+

| 5.1.73    |

+-----------+

1 row in set (0.00 sec)

-----------------------------------------------------

BEFORE:

mysql> SHOW VARIABLES LIKE 'character_set_%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)


mysql> SHOW VARIABLES LIKE 'collation_%'; 
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)

AFTER:

mysql> SHOW VARIABLES LIKE 'character_set_%';

+--------------------------+----------------------------+

| Variable_name            | Value                      |

+--------------------------+----------------------------+

| character_set_client     | utf8                       |

| character_set_connection | utf8                       |

| character_set_database   | utf8                       |

| character_set_filesystem | binary                     |

| character_set_results    | utf8                       |

| character_set_server     | utf8                       |

| character_set_system     | utf8                       |

| character_sets_dir       | /usr/share/mysql/charsets/ |

+--------------------------+----------------------------+

8 rows in set (0.00 sec)

mysql> SHOW VARIABLES LIKE 'collation_%'; 

+----------------------+-----------------+

| Variable_name        | Value           |

+----------------------+-----------------+

| collation_connection | utf8_general_ci |

| collation_database   | utf8_general_ci |

| collation_server     | utf8_general_ci |

+----------------------+-----------------+

3 rows in set (0.00 sec)


最後的改動:

[[email protected] ~]# cd /etc/

[[email protected] etc]# cat my.cnf 

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

user=mysql

# Disabling symbolic-links is recommended to prevent assorted security risks

symbolic-links=0

default-character-set=utf8

default-character=utf8

[mysqld_safe]

log-error=/var/log/mysqld.log

pid-file=/var/run/mysqld/mysqld.pid

[client]

port=3306

default-character-set=utf8

default-character=utf8


下面是原理部分, 

-----------------------------------------------------------------------

轉自: http://blog.csdn.net/fdipzone/article/details/18180325

基本概念

• 字元(Character)是指人類語言中最小的表義符號。例如’A'、’B'等;

• 給定一系列字元,對每個字元賦予一個數值,用數值來代表對應的字元,這一數值就是字元的編碼(Encoding)。例如,我們給字元’A'賦予數值0,給字元’B'賦予數值1,則0就是字元’A'的編碼;

• 給定一系列字元並賦予對應的編碼後,所有這些字元和編碼對組成的集合就是字符集(Character Set)。例如,給定字元列表為{‘A’,'B’}時,{‘A’=>0, ‘B’=>1}就是一個字符集;

• 字元序(Collation)是指在同一字符集內字元之間的比較規則;

• 確定字元序後,才能在一個字符集上定義什麼是等價的字元,以及字元之間的大小關係;

• 每個字元序唯一對應一種字符集,但一個字符集可以對應多種字元序,其中有一個是預設字元序(Default Collation);

• MySQL中的字元序名稱遵從命名慣例:以字元序對應的字符集名稱開頭;以_ci(表示大小寫不敏感)、_cs(表示大小寫敏感)或_bin(表示按編碼值比較)結尾。例如:在字元序“utf8_general_ci”下,字元“a”和“A”是等價的;

MySQL字符集設定

• 系統變數:

– character_set_server:預設的內部操作字符集

– character_set_client:客戶端來源資料使用的字符集

– character_set_connection:連線層字符集

– character_set_results:查詢結果字符集

– character_set_database:當前選中資料庫的預設字符集

– character_set_system:系統元資料(欄位名等)字符集

– 還有以collation_開頭的同上面對應的變數,用來描述字元序。

• 用introducer指定文字字串的字符集:

– 格式為:[_charset] ‘string’ [COLLATE collation]

– 例如:

• SELECT _latin1 ‘string’;

• SELECT _utf8 ‘你好’ COLLATE utf8_general_ci;

– 由introducer修飾的文字字串在請求過程中不經過多餘的轉碼,直接轉換為內部字符集處理。

MySQL中的字符集轉換過程

1. MySQL Server收到請求時將請求資料從character_set_client轉換為character_set_connection;

2. 進行內部操作前將請求資料從character_set_connection轉換為內部操作字符集,其確定方法如下:

• 使用每個資料欄位的CHARACTER SET設定值;

• 若上述值不存在,則使用對應資料表的DEFAULT CHARACTER SET設定值(MySQL擴充套件,非SQL標準);

• 若上述值不存在,則使用對應資料庫的DEFAULT CHARACTER SET設定值;

• 若上述值不存在,則使用character_set_server設定值。

3. 將操作結果從內部操作字符集轉換為character_set_results。


常見問題解析

• 向預設字符集為utf8的資料表插入utf8編碼的資料前沒有設定連線字符集,查詢時設定連線字符集為utf8

– 插入時根據MySQL伺服器的預設設定,character_set_client、character_set_connection和character_set_results均為latin1;

– 插入操作的資料將經過latin1=>latin1=>utf8的字符集轉換過程,這一過程中每個插入的漢字都會從原始的3個位元組變成6個位元組儲存;

– 查詢時的結果將經過utf8=>utf8的字符集轉換過程,將儲存的6個位元組原封不動返回,產生亂碼……


• 向預設字符集為latin1的資料表插入utf8編碼的資料前設定了連線字符集為utf8

– 插入時根據連線字符集設定,character_set_client、character_set_connection和character_set_results均為utf8;

– 插入資料將經過utf8=>utf8=>latin1的字符集轉換,若原始資料中含有\u0000~\u00ff範圍以外的Unicode字 符,會因為無法在latin1字符集中表示而被轉換為“?”(0x3F)符號,以後查詢時不管連線字符集設定如何都無法恢復其內容了。


檢測字符集問題的一些手段

• SHOW CHARACTER SET;

• SHOW COLLATION;

• SHOW VARIABLES LIKE ‘character%’;

• SHOW VARIABLES LIKE ‘collation%’;

• SQL函式HEX、LENGTH、CHAR_LENGTH

• SQL函式CHARSET、COLLATION使用MySQL字符集時的建議

• 建立資料庫/表和進行資料庫操作時儘量顯式指出使用的字符集,而不是依賴於MySQL的預設設定,否則MySQL升級時可能帶來很大困擾;

• 資料庫和連線字符集都使用latin1時雖然大部分情況下都可以解決亂碼問題,但缺點是無法以字元為單位來進行SQL操作,一般情況下將資料庫和連線字符集都置為utf8是較好的選擇;

• 使用mysql C API時,初始化資料庫控制代碼後馬上用mysql_options設定MYSQL_SET_CHARSET_NAME屬性為utf8,這樣就不用顯式地用 SET NAMES語句指定連線字符集,且用mysql_ping重連斷開的長連線時也會把連線字符集重置為utf8;

• 對於mysql PHP API,一般頁面級的PHP程式總執行時間較短,在連線到資料庫以後顯式用SET NAMES語句設定一次連線字符集即可;

但當使用長連線時,請注意保持連線通暢並在斷開重連後用SET NAMES語句顯式重置連線字符集。

其他注意事項

• my.cnf中的default_character_set設定隻影響mysql命令連線伺服器時的連線字符集,不會對使用libmysqlclient庫的應用程式產生任何作用!

• 對欄位進行的SQL函式操作通常都是以內部操作字符集進行的,不受連線字符集設定的影響。

• SQL語句中的裸字串會受到連線字符集或introducer設定的影響,對於比較之類的操作可能產生完全不同的結果,需要小心!


相關推薦

折騰下午java查詢mysql資料庫中文亂碼問題

java 通過connector 訪問 mysql, 可是裡面返回的中文字元是亂碼 排除一:  mysql 裡面直接查詢出來的字元是中文的 排除二: connector的設定  jdbc:mysql://localhost:3306/envisionin_db?tinyIn

java 讀取mysql資料庫資料亂碼 解決

問題描述:      開發環境測試通過後,部署到測試環境發現頁面顯示的中文字元亂碼,通過簡單的測試,最後定位到java從mysql資料庫讀取的資料亂碼,導致前端頁面顯示的資料亂碼。       開發環境的mysql資料庫的所有編碼方式都為utf8,java程式碼的編碼方式為U

Navicat修改mysql資料庫中文亂碼問題

步驟1:開啟navict,連線你的mysql資料庫 第二步:新建資料庫。選擇連線,右鍵選擇新建資料庫 選擇:utf8 -- UTF-8 Unicode 再選擇:utf8_general_ci 第3步:新建表,每個欄位同樣選擇utf-

解決windows下mysql資料庫中文亂碼的問題

今天下午,在Qt中往mysql資料庫中插入資料時,中文顯示亂碼,如下圖所示: 開始以為是資料庫字元編碼的問題,[1]開始使用set character_set_database=utf8 在命令列上修改字元編碼, 但是重啟mysql之後,字元編碼並沒有修改成功。 [2]於是找到My

SpringBoot MySql資料庫中文亂碼問題排查實紀

引言: 最近用StringBoot開發了一個簡單的小程式伺服器,發現通過post請求插入的中文欄位在資料庫中是顯示“???”的形式,本來不以為意,以為是顯示的問題,誰知通過get請求獲取資料的時候返回的也是“???”,這下就開始慌了,於是開始了問題的排查。以下為排查的過程。 首先

centos中mysql資料庫中文亂碼的解決方法

預設my.cnf配置檔案中在/etc/mycnf,開啟之後在裡面加入以下命令即可: [client] default-character-set=utf8 [mysqld] character-set-server=utf8 collation-server=u

對於mysql資料庫中文亂碼問題的解決(在所有的編碼都是utf-8的情況下中文亂碼

在寫jdbc連結mysqll資料庫時,向其中插入中文資料出現亂碼。查看了所有的配置,都是utf-8編碼,my.ini配置檔案也修改好了,還出現這樣的亂碼,實屬不應該。 在各種部落格論壇查詢,都是修改資料庫的編碼的套路,其中也不乏有在連線資料庫的連結url中加編碼的,比如:“jdbc:mysql:

mysql資料庫中文亂碼的問題

在idea上面新建了一個web登入專案,瀏覽器提交表單,username“李華”存入資料庫是亂碼,只好一步步解決 1.在idea中輸出請求引數username就是亂碼,也就是“form表單提交中文的亂碼問題” 解決方法:在idea中設定request編碼格式和客戶端網頁一致(以UTF-8為例

eclipse匯入外部專案後中文顯示亂碼問題解決,SQLyog與MySql資料庫中文亂碼問題,其他亂碼問題

要解決中文亂碼問題,就是要保持不同的位置的編碼方式一致,目前我們通常使用UTF-8編碼,將不同的位置改為相同的編碼即可。 首先是在eclipse工作環境中,對不同的編碼進行更改: 右擊專案名稱,選擇properties,將其中涉及編碼的地方都改為UTF-8即可。  

Linux系統下Mysql資料庫中文亂碼問題解決

問題描述:當我們將開發好的javaWEB專案部署到linux系統上,操作資料庫的時候,會出現中文亂碼問題,比如做插入操作,發現新增到資料庫的資料中文出現論碼,下面就將解決linux下mysql中文亂碼問題! 一.開啟Linux視窗,啟動mysql。 二.連線mysql輸入

windows版本mysql資料庫中文亂碼解決方案

最近剛換電腦,本地安裝mysql資料庫,表中的中文漢字全部亂碼,配置沒有錯,最後通過給本地mysql強制設定UTF-8解決的。 首先找到本地mysql安裝目錄,然後新建一個my.ini檔案。 my.ini檔案內容為: [client] port=3306 defau

Windows中mysql資料庫中文亂碼永久解決方法

在mysql安裝目錄下新增一個my.ini檔案。內容如下:  [client]     port=3306     default-character-set=utf8     [mysqld]     port=3306     character_set_server

ASP.net連線mysql資料庫中文亂碼問題的解決方法

1. 修改mysql的配置。到mysql server的安裝目錄下找到my.ini,修改[mysql]小節中的default-character-set為utf8[mysql] default-character-set=utf8 2. 修改mysql server的字符集如

Mac下,MySQL資料庫中文亂碼的解決方法

在Mac下安裝MySQL資料庫,作為本地資料庫使用。但向資料庫中匯入資料時一直中文亂碼,試了很多方法都沒有解決。終於在熬夜奮戰了近3個小時後,把問題解決了(雖然還是不明白原因細節)。先上圖: 解決方案:匯入時,選擇GBK格式。(總的來講,有點瞎貓碰上死耗子

001-mac下Navicat連線MySQL資料庫中文亂碼問題

# Example MySQL config file for small systems.   #   # This is for a system with little memory (<= 64M) where MySQL is only used   # from time to time a

Django 連線mysql資料庫中文亂碼

版本:CentOS6.8 python3.6.4 django1.8.2 資料庫pymysql 我使用的終端是CentOS終端,CentOS桌面版安裝的pycham,windows使用Navicat連線mysql資料庫。 我遇到的情況大致這樣,

docker4:外部Navicat連結docker內容器mysql,步驟及錯誤及解決辦法...晚上才改出來錯誤,憋下午真是太難受...

OK,lets go.啟動mysql服務:$ docker exec -it forth-mysql bash選擇mysql資料庫mysql> use mysqlmysql> select user,host,authentication_string from

maven依賴引入失敗,找下午

http 分享 技術 .com src bubuko maven mave 依賴 maven依賴引入失敗,找了一下午

學習經驗分享(最近聽Java公開課)

要花 總結 tomcat8.0 避免 一個 地方 廣度 公開課 很好 最近聽了一節Java公開課,講的Tomcat8.0的,老師分享的學習方法很好, 時間和精力要用對地方 1.學習一個知識的廣度和深度,先學主要的主流的,不要學了很多不該學,沒必要學的東西 2.要花時間總結

大三筆記(困擾下午的bug,居然是路徑問題)

19號在寫測試ajax與controller互動時,一個bug困擾了我。 先貼程式碼。 index.jsp <head> <title>開發中......</title> <script type="text/javascript" src=