2010-09-30 96 views
9

我有一份準備好的聲明:Java的PreparedStatement的UTF-8字符的問題

PreparedStatement st; 

,並在我的代碼,我嘗試使用st.setString方法。

st.setString(1, userName); 

userName的值是şakça。 setString方法將'şakça'更改爲'?akça'。它不識別UTF-8字符。我怎麼解決這個問題?

謝謝。

+1

您使用的數據庫是?並且它是否被配置爲在該列中接受Unicode(或任何你需要的şakça)? – Thilo 2010-09-30 08:06:56

回答

35

這可以搞砸的方式實際上相當令人印象深刻。如果你使用MySQL,嘗試添加一個characterEncoding=UTF-8參數您JDBC連接URL的末尾:

jdbc:mysql://server/database?characterEncoding=UTF-8

您也應該檢查表/列字符集爲UTF-8。

+1

?characterEncoding = UTF-8不適用於我。我試過?characterEncoding = utf8,它的工作原理。 – user4757345 2014-10-27 19:13:25

+0

這兩個「爲我工作」。對我而言,差異在於「utf8」缺少很多符號,而「UTF-8」則涵蓋了所有符號。 – 2016-05-26 07:47:03

+0

就像一個魅力 – YyYo 2016-06-22 20:45:34

3

了setString方法的改變 'şakça' 到 '?akça'

你怎麼知道了setString改變呢?或者你看到數據庫中的內容並決定這一點?

可能是因爲數據庫未配置爲UTF-8,或者僅僅是用於查看數據庫角色的工具(SQL * PLUS for Oracle ...)無法顯示UTF-8 。

7

只要數據庫將字符更改爲?,則表示該字符的代碼點完全超出了字符編碼的範圍,因爲該表配置爲使用該字符。

至於問題的原因:ç在於ISO-8859-1範圍內,且具有完全相同的編碼點作爲UTF-8U+00E7)。但是,ş的UTF-8編碼點完全位於ISO-8859-1(U+015F,而ISO-8859-1僅上升到U + 00FF)的範圍之外。數據庫將不會持續該角色並將其替換爲?。因此,我懷疑你的數據庫表仍然配置爲使用ISO-8859-1(或者其他兼容ISO-8859編碼之一,其中ç與UTF-8具有相同的代碼點)。

Java/JDBC API在字符編碼方面的工作非常完美(Java始終使用Unicode),並且JDBC DB連接編碼也正確配置。如果爪哇/ JDBC將具有正確使用ISO-8859-1,則持久性結果將是Åakça(字節0xC5ş存在和0x9F表示Å和在ISO-8859-1 a和字節0xC3ç存在和0xA7,其代表ISO-8859-1中的 ç)。

0

您可以使用下面的查詢來在準備好的語句中設置unicode字符串。 PreparedStatement st= conn.prepareStatement("select * from users where username=unistr(?)");// unistr method is for oracle st.setString(1, userName);