2012-03-08 24 views
5

出於某種奇怪的原因,我似乎無法UTF-8的數據添加到我的MySQL數據庫。當我輸入一個非拉丁字符時,它被存儲爲?????。其他一切都存儲正常。例如,「這是一個example®™」存儲的很好,但「和英辭典」存儲爲「????」。不能存儲在MySQL UTF-8的內容使用Java的PreparedStatement

連接URL是好的:

private DataSource getDB() throws PropertyVetoException { 
    ComboPooledDataSource db = new ComboPooledDataSource(); 
    db.setDriverClass("com.mysql.jdbc.Driver"); 
    db.setJdbcUrl("jdbc:mysql://domain.com:3306/db?useUnicode=true&characterEncoding=UTF-8"); 
    db.setUser("..."); 
    db.setPassword("..."); 
    return db; 
} 

我使用PreparedStatement的你所期望的,我甚至嘗試進入「設置名稱UTF8」有人建議。

Connection conn = null; 
    PreparedStatement stmt = null; 
    ResultSet rs = null; 
    try { 
     conn = db.getConnection(); 

     stmt = conn.prepareStatement("set names utf8"); 
     stmt.execute(); 
     stmt = conn.prepareStatement("set character set utf8"); 
     stmt.execute(); 

        ... set title... 
     stmt = conn.prepareStatement("INSERT INTO Table (title) VALUES (?)"); 
     stmt.setString(1,title); 

     stmt.execute(); 
    } catch (final SQLException e) { 
    ... 

表本身似乎要被罰款。

Default Character Set: utf8 
Default Collation: utf8_general_ci 
... 
Field title: 
Type text 
Character Set: utf8 
Collation: utf8_unicode_ci 

我通過輸入以Unicode測試了它(「和英辭典」特異性)通過GUI編輯器,並從表中選擇 - 和它返回就好了。所以這似乎是JDBC的一個問題。

我錯過了什麼?

+0

你確定'title'有正確的內容嗎?也許你從一個使用ISO的文件讀取它 - 無論什麼? – 2012-03-08 22:11:26

+0

是的,當我在標題上放置一個斷點時,我可以看到它確實是unicode(例如:和英辭典),而不是? – nostromo 2012-03-08 22:33:44

+0

'utf8'是一個字符串,所以用引號括起來:''set names'utf8'「'。不要混淆字符集。 – 2012-03-08 22:55:14

回答

3

有在MySQL服務器2分,以正確地設置UTF-8字符集進行檢查。

數據庫級

這是通過創建它獲得:

CREATE DATABASE 'db' CHARACTER SET 'utf8'; 

表級

所有的表需要在UTF-8還(這似乎是你的情況下)

CREATE TABLE `Table1` (
    [...] 
) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; 

的重要組成部分,是默認字符集= UTF8 COLLATE = utf8_general_ci

最後,如果你的代碼不正確處理UTF-8,你可以迫使你的JVM通過在啓動時更改設置使用utf8編碼:

java -Dfile.encoding=UTF-8 [...] 

,或者使用改變環境變量

"**JAVA_TOOLS_OPTIONS**" to -Dfile.encoding="UTF-8" 

或編程:

System.setProperty("file.encoding" , "UTF-8"); 

(最後一個可能沒有慾望的效果,因爲在JVM上的高速緩存啓動時默認的字符編碼的值)

希望這有助於。

+0

設置jvm的默認編碼對某些事情很有用,但肯定不需要將unicode數據導入和導出數據庫。 – jtahlborn 2012-03-10 14:25:52

+0

根據nostromo昨天關於斷點的評論。我們可以假設他的jvm已經正確地處理了unicode,所以我同意在他的情況下它不是必需的。 – Kharaone 2012-03-10 15:17:52

+0

實際上有三個層次。還有連接級別:http://stackoverflow.com/questions/9283575/getting-incorrectly-encoded-characters-when-retrieving-values-from-mysql-db – 2012-03-14 12:39:29

1

如果您登錄到您的mysql數據庫並運行show variables like 'character%'; 這可能會提供一些見解。

由於您將多字節字符與問號進行一對一的比例,因此很可能連接正在進行字符集轉換,並用單字節的替換字符替換中文字符組。

5

在您的JDBC連接字符串,你只需要設置的字符集編碼是這樣的:

的jdbc:mysql的://本地主機:3306/DBNAME的characterEncoding = UTF8

3

使用stmt.setNString(...)而不是stmt.setString(...)
另外不要忘記檢查數據庫端的列整理。

+0

你節省了我的一天。 – 2017-10-27 02:09:48

0

還要檢查Ubuntu的Ubuntu默認的工作與en_US環境和沒有安裝其他的語言環境locale -a命令。 必須在通過JDBC連接時指定characterEncoding = utf8。