晚上重溫dos窗口操作mysql的時候,遇到了一個巨蛋疼的問題------>中文驗證碼 -->_-->,所以找了找資料弄懂了怎麼解決亂碼問題,,小記一下。
新建一個表
create table student( id int, name varchar(20), chinese float, english float, math float );
向表中插入數據(包含中文)
insert into student (id,name,chinese,english,math) values (1,'李狗蛋',88,93.5,78);
結果如下:
報了一個Data too long for column 'name' at row 1的錯誤,,,為什麼呢?我的那麼字段是20個字符的啊,,,李狗蛋三個字肯定夠啊,,,為什麼還提示太長了呢!!!!其實呢,,這種情況下就算你只有一個漢字,也會報這個錯。。。。原因何在?----->中文亂碼問題!!!
跟servlet中亂碼產生的原因一樣,還是在與提交與接受二者之間的編碼方式不一樣。。。。
我們知道,在中文版win7下 dos命令行的默認編碼方式都是gbk的,而我們裝的mysql服務器的默認編碼方式確實utf8,,這樣,,兩個編碼方式不一樣。。。通過dos窗口向mysql服務器提交中文數據,一個以gbk編碼提交,一個以utf8解碼接收,可不就產生了亂碼了嘛。
不信我們看看mysql的默認編碼----在dos窗口輸入
show variables like 'character%';
查看mysql服務器的編碼各種編碼狀態,如下:
但其實這些編碼格式只是mysql認為的你的系統的編碼模式,但實際情況並非如此。表現在:客戶端編碼-->mysql認為utf8,但其實你的dos命令行是在我天朝的win7下,那麼你就是gbk的編碼格式,而不是utf8;其他的都是默認的utf8。到這裡就可以看到,客戶端為gbk,連接方式為utf8,服務器存儲方式為utf8,結果返回方式是utf8,那麼,,亂碼的出現原因就呼之欲出了--->兩方編碼不一樣,以gbk敲代碼,結果以u8編碼,然後以utf8發送,以utf8接收。所以怎麼解決呢?
兩種辦法解決亂碼問題:臨時方法和徹底方法。
臨時方法:在dos行下輸入“set names gkk;”然後再查看一下編碼方式,如下:
明確告訴客戶端,我的dos行是以gbk敲進去的,你得用gbk給我編碼;告訴連接橋,我數據是gbk的,你得用gbk給我傳輸;告訴服務端,我的dos行是gbk的,你得用gbk把我存的數據返回給我。現在我們再插入有之前有中文的那行數據,
可以看到,亂碼問題已經不存在了。。。。但是呢,開頭都說了,這中方法是臨時型的,,為何?來,打開另一個dos窗口,查看下所有的編碼方式:
這個時候,你再插入帶有中文的數據,保證還是剛才的錯誤。。。為啥呢?因為"set names gbk;"只針對當前客戶端(就是那個dos窗口)起作用。。打開另一個窗口就不行了,所以這種方法治標不治本。如果每次都這樣,那不得累死了!!(不要跟我說你用可視化的mysql操作軟件,,我們現在的語境是你根本不知道可視化,,,),那麼怎麼一勞永逸的解決這個問題呢?
徹底解決:修改mysql配置文件--->my.ini
找到你的mysql安裝目錄下的my.ini文件,記事本打開,找到-----default-character-set=utf8 這句話,修改utf8為gbk
然後重啟mysql,,好了,亂碼被干掉了。Oh YEAH!!
多說一下,為什麼改成gbk之後就搞定了亂碼。。這中間涉及到了三個數據轉換過程:編碼,解碼,轉碼。
所謂編碼,就是將字符編成二進制數據的過程;
所謂解碼,就是將二進制數據解析為字符的過程;
所謂轉碼,就是將一個字符從a字符集表示的二進制數據轉換成b字符集表示的二進制數據的過程。
在客戶端通過連接橋將gbk的數據發送給服務器的時候,兩方的編碼集其實是不一樣的,數據庫接收到的是gbk,服務器要以utf8存儲,在這個過程中,如果不做些什麼,亂碼是解決不掉的。。其實在這個過程中,服務器自己做了一個轉碼的操作:將接收到的gbk數據轉換成utf8存儲到數據庫中,然後你查詢的時候它自動將utf8的數據轉換成gbk返回給你看。所以,亂碼沒了。