遇到這種情況,現有項目的數據庫已經建好,數據表也已經創建完成。
問題來的,數據庫不能插入中文,調試時候發現中文數據從發送請求到最后請求處理完成這些步驟,中文還沒有發生亂碼。
只有在存儲到數據庫后查詢數據並顯示才會亂碼。
那么到此可以確定是mysql出現問題了。
那么應該怎么辦呢?哈哈,當然是看我們的度娘啦!
看的下度娘解決方法是:
將數據庫的編碼修改為utf8編碼格式,因為安裝mysql默認使用的字符編碼latin1
what?這個編碼是什么鬼,見都沒見過。
查了下,Latin1是ISO-8859-1的別名。因為ISO-8859-1編碼范圍使用了單字節內的所有空間,在支持ISO-8859-1的系統中傳輸和存儲其他任何編碼的字節流都不會被拋棄
這個latin1編碼是單字節編碼,而一般漢字是需要兩個字節存儲,所以這個編碼格式不支持漢字。
接下來就看怎么改吧
數據庫字符優先級有:系統級、數據庫級、表級、字段。這5個優先級中字段優先級最高。舉個列子。我們要向表中存儲中文數據。如果表的字符編碼是utf8,而字段的字符編碼是latin1。那么如果我們存儲中文還是會出現亂碼,因為使用的編碼是字段的字符編碼latin1
在數據庫創建時如果不設置數據庫的默認字符編碼,即缺省時會使用系統的字符編碼latin1。創建表缺省時使用數據庫的字符編碼,字段同理。
從上面可以得出一個重要結論,創建數據庫時一定要指定默認字符編碼!
1、
首先我們查看mysql數據庫服務器,客戶端,數據庫連接,文件系統等的字符編碼
show variables like '%char%';
+--------------------------+-------------------------------------+------
| Variable_name | Value |......
+--------------------------+-------------------------------------+------
| character_set_client | utf8 |...... -- 客戶端字符集
| character_set_connection | utf8 |......
| character_set_database | latin1|...... -- 數據庫字符集
| character_set_filesystem | binary |......
| character_set_results | utf8 |......
| character_set_server | latin1|...... -- 服務器字符集
| character_set_system | utf8 |......
| character_sets_dir | D:\MySQL Server 5.0\share\charsets\ |......
+--------------------------+-------------------------------------+------
默認安裝完mysql數據庫時,服務器和數據庫使用的編碼是latinn1編碼格式。
這個上面沒有問題,可以先不用考慮
網上看到很多人要修改這個系統級的字符編碼,我也不知道什么原因,改完之后中文亂碼問題就得到解決了
2、
查看數據庫的創建語句。以默認的數據庫mysql為例
show create database mysql
可以發現其的default character set默認字符編碼格式是latin1。由此可以看出,缺省時會自動使用latin1
所以我們需要在創建數據庫時指定默認的編碼格式
create database 數據庫名 CHARACTER SET utf8 COLLATE utf8_general_ci;
修改已創建的數據庫的編碼
alter database 數據庫表名 CHARACTER SET utf8 COLLATE utf8_general_ci;
3、
查看數據庫中匹配到的表的編碼格式。
show table status from 數據庫名 like 'pattern/匹配模式';
查看數據庫中所有表的編碼格式
show table status from mysql like '%%';
4、
修改表的默認編碼格式。有兩種方法
- alter table 表名 character set utf8 COLLATE utf8_general_ci;
- alter table 表名 convert to character set utf8;
第一種是僅僅修改表的字符編碼,而字段的字符編碼還是latin1編碼格式,這種改變沒有意義
可以查看數據表中所有列的字符編碼,就可以發現字段的字符編碼是否發生改變。
show full columns from 表名;
第二種會將表和字段的編碼都更改為utf8編碼格式。
5、
中文亂碼問題得到解決的,但是數據庫里那么多表,我們總不可能一個表一個表的進行修改吧,所以我們要使用存儲過程,
加動態sql語句的方式使用循環自動修改數據庫內的所有數據表的編碼格式。
注意:如果修改完后中文存儲還是亂碼。將連接數據庫的連接后面指定編碼格式為utf8
如果還是不行,那么將mysql默認的字符編碼進行修改,即下面的characterEncoding
jdbcUrl = jdbc:mysql://主機域名:3306/數據庫名?characterEncoding=utf8&useSSL=false&useUnicode=true
useSSL:與服務器進行通信時使用SSL,默認值為“假
參考主要參數,表數據來源Mysql JDBC Url參數說明
| 參數名稱 | 參數說明 | 缺省值 | 最低版本要求 |
| user | 數據庫用戶名(用於連接數據庫) | 所有版本 | |
| password | 用戶密碼(用於連接數據庫) | 所有版本 | |
| useUnicode | 是否使用Unicode字符集,如果參數characterEncoding設置為gb2312或gbk,本參數值必須設置為true | false | 1.1g |
| characterEncoding | 當useUnicode設置為true時,指定字符編碼。比如可設置為gb2312或gbk | false | 1.1g |
| autoReconnect | 當數據庫連接異常中斷時,是否自動重新連接? | false | 1.1 |
| autoReconnectForPools | 是否使用針對數據庫連接池的重連策略 | false | 3.1.3 |
| failOverReadOnly | 自動重連成功后,連接是否設置為只讀? | true | 3.0.12 |
| maxReconnects | autoReconnect設置為true時,重試連接的次數 | 3 | 1.1 |
| initialTimeout | autoReconnect設置為true時,兩次重連之間的時間間隔,單位:秒 | 2 | 1.1 |
| connectTimeout | 和數據庫服務器建立socket連接時的超時,單位:毫秒。 0表示永不超時,適用於JDK 1.4及更高版本 | 0 | 3.0.1 |
| socketTimeout | socket操作(讀寫)超時,單位:毫秒。 0表示永不超時 |
