JDBC連接mysql亂碼異常問(wèn)題處理總結(jié)
前段時(shí)間學(xué)習(xí)JDBC,要連接mysql獲取數(shù)據(jù)。按照老師的樣例數(shù)據(jù),要存一些名字之類(lèi)的信息,用的都是英文名,我當(dāng)時(shí)就不太想用英文,就把我室友的名字存了進(jìn)去,嘿嘿,結(jié)果,出問(wèn)題了。
連接數(shù)據(jù)庫(kù)語(yǔ)句:
static final String DB_URL = "jdbc:mysql://localhost/filemanagement";
查詢(xún)語(yǔ)句:
private static final String theUserQuery = "SELECT name, password, role FROM userinfo WHERE name = ?";
我是用我的名字做的查詢(xún),NullPointerException,很明顯,沒(méi)有用我的名字查到對(duì)應(yīng)的數(shù)據(jù),而數(shù)據(jù)庫(kù)中是存在的。這是為什么呢?
百度到的答案是中文亂碼,解決方案是,修改連接數(shù)據(jù)庫(kù)語(yǔ)句為:
static final String DB_URL = "jdbc:mysql://localhost/filemanagement?useUnicode=true&characterEncoding=GBK";
重試!
可以了!但這是為什么呢?那兩個(gè)參數(shù)是什么?為什么加上之后就解決問(wèn)題了?
這兩個(gè)參數(shù)解釋如下:
兩個(gè)參數(shù)的缺省值都是false。也就是說(shuō)我們?cè)谶B接mysql的時(shí)候指定了連接使用的字符集后,一切就正常了。但我還是不太了解其中的機(jī)制,所以繼續(xù)查。
原來(lái)Mysql連接進(jìn)行查詢(xún)等操作時(shí)存在一個(gè)字符集轉(zhuǎn)換過(guò)程:
1. MySQL Server收到請(qǐng)求時(shí)將請(qǐng)求數(shù)據(jù)從character_set_client轉(zhuǎn)換為character_set_connection;
2. 進(jìn)行內(nèi)部操作前將請(qǐng)求數(shù)據(jù)從character_set_connection轉(zhuǎn)換為內(nèi)部操作字符集,其確定方法如下:
• 使用每個(gè)數(shù)據(jù)字段的CHARACTER SET設(shè)定值;
• 若上述值不存在,則使用對(duì)應(yīng)數(shù)據(jù)表的DEFAULT CHARACTER SET設(shè)定值(MySQL擴(kuò)展,非SQL標(biāo)準(zhǔn));
• 若上述值不存在,則使用對(duì)應(yīng)數(shù)據(jù)庫(kù)的DEFAULT CHARACTER SET設(shè)定值;
• 若上述值不存在,則使用character_set_server設(shè)定值。
3. 將操作結(jié)果從內(nèi)部操作字符集轉(zhuǎn)換為character_set_results。
這些character set代表什么呢?
character_set_server:默認(rèn)的內(nèi)部操作字符集
character_set_client:客戶(hù)端來(lái)源數(shù)據(jù)使用的字符集
character_set_connection:連接層字符集
character_set_results:查詢(xún)結(jié)果字符集
character_set_database:當(dāng)前選中數(shù)據(jù)庫(kù)的默認(rèn)字符集
character_set_system:系統(tǒng)元數(shù)據(jù)(字段名等)字符集
還查到了一些常見(jiàn)問(wèn)題,雖然和我的問(wèn)題不太一樣,但很有參考意義。
• 向默認(rèn)字符集為utf8的數(shù)據(jù)表插入utf8編碼的數(shù)據(jù)前沒(méi)有設(shè)置連接字符集,查詢(xún)時(shí)設(shè)置連接字符集為utf8
– 插入時(shí)根據(jù)MySQL服務(wù)器的默認(rèn)設(shè)置,character_set_client、character_set_connection和character_set_results均為latin1;
– 插入操作的數(shù)據(jù)將經(jīng)過(guò)latin1=>latin1=>utf8的字符集轉(zhuǎn)換過(guò)程,這一過(guò)程中每個(gè)插入的漢字都會(huì)從原始的3個(gè)字節(jié)變成6個(gè)字節(jié)保存;
– 查詢(xún)時(shí)的結(jié)果將經(jīng)過(guò)utf8=>utf8的字符集轉(zhuǎn)換過(guò)程,將保存的6個(gè)字節(jié)原封不動(dòng)返回,產(chǎn)生亂碼……
• 向默認(rèn)字符集為latin1的數(shù)據(jù)表插入utf8編碼的數(shù)據(jù)前設(shè)置了連接字符集為utf8
– 插入時(shí)根據(jù)連接字符集設(shè)置,character_set_client、character_set_connection和character_set_results均為utf8;
– 插入數(shù)據(jù)將經(jīng)過(guò)utf8=>utf8=>latin1的字符集轉(zhuǎn)換,若原始數(shù)據(jù)中含有\(zhòng)u0000~\u00ff范圍以外的Unicode字 符,會(huì)因?yàn)闊o(wú)法在latin1字符集中表示而被轉(zhuǎn)換為“?”(0x3F)符號(hào),以后查詢(xún)時(shí)不管連接字符集設(shè)置如何都無(wú)法恢復(fù)其內(nèi)容了。
(此部分摘自鳥(niǎo)哥的blog,稍后附上鏈接)
我數(shù)據(jù)庫(kù)的表都是設(shè)置的utf8編碼,但我第一次連接的時(shí)候沒(méi)有設(shè)置連接字符集,所以默認(rèn)為latin1,經(jīng)過(guò)了從utf8=>latin1的轉(zhuǎn)換,所以產(chǎn)生亂碼。我第二次用的GBK編碼,也沒(méi)用utf8編碼,為什么也可以了呢?其實(shí)是一個(gè)道理,中文不在latin1的編碼中可是在GBK和utf8中,所以不會(huì)出問(wèn)題。
以上就是為大家整理的關(guān)于JDBC連接mysql亂碼異常的解決辦法,如果大家還有任何不明白的地方可以在下方的留言區(qū)討論。
- JDBC連接MySQL出現(xiàn)的問(wèn)題
- mysql jdbc連接步驟及常見(jiàn)參數(shù)
- Java 通過(guò)JDBC連接Mysql數(shù)據(jù)庫(kù)
- JDBC 連接MySQL實(shí)例詳解
- JDBC連接MySQL5.7的方法
- JDBC連接MySql數(shù)據(jù)庫(kù)步驟 以及查詢(xún)、插入、刪除、更新等
- 使用JDBC連接Mysql數(shù)據(jù)庫(kù)會(huì)出現(xiàn)的問(wèn)題總結(jié)
- Java之jdbc連接mysql數(shù)據(jù)庫(kù)的方法步驟詳解
- Java的JDBC編程使用之連接Mysql數(shù)據(jù)庫(kù)
相關(guān)文章
MyBatis-Plus邏輯刪除和字段自動(dòng)填充的實(shí)現(xiàn)
本文主要介紹了MyBatis-Plus邏輯刪除和字段自動(dòng)填充的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08Java簡(jiǎn)單幾步實(shí)現(xiàn)一個(gè)二叉搜索樹(shù)
二叉樹(shù)包含了根節(jié)點(diǎn),孩子節(jié)點(diǎn),葉節(jié)點(diǎn),每一個(gè)二叉樹(shù)只有一個(gè)根節(jié)點(diǎn),每一個(gè)結(jié)點(diǎn)最多只有兩個(gè)節(jié)點(diǎn),左子樹(shù)的鍵值小于根的鍵值,右子樹(shù)的鍵值大于根的鍵值,下面這篇文章主要給大家介紹了關(guān)于如何在Java中實(shí)現(xiàn)二叉搜索樹(shù)的相關(guān)資料,需要的朋友可以參考下2023-02-02spring cloud 使用Eureka 進(jìn)行服務(wù)治理方法
這篇文章主要介紹了spring cloud 使用Eureka 進(jìn)行服務(wù)治理方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05Java中easypoi導(dǎo)入excel文件列名相同的處理方案
這篇文章主要介紹了Java中easypoi導(dǎo)入excel文件列名相同的處理方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Java實(shí)現(xiàn)隊(duì)列的三種方法集合
這篇文章主要介紹了Java實(shí)現(xiàn)隊(duì)列的三種方法集合,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09JetBrains IntelliJ IDEA 2020安裝與使用教程詳解
這篇文章主要介紹了JetBrains IntelliJ IDEA 2020安裝與使用教程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06在lambda的foreach遍歷中break退出操作(lambda foreach break)
這篇文章主要介紹了在lambda的foreach遍歷中break退出操作(lambda foreach break),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09