我有一份准备好的声明:
PreparedStatement st;
在我的代码中我尝试使用st.setString方法。
st.setString(1, userName);
userName的值是şakça。 setString方法将'şakça'更改为'?akça'。它不识别UTF-8字符。我该如何解决这个问题?
感谢。
答案 0 :(得分:38)
这种方式搞砸的方式实际上令人印象深刻。如果您使用的是MySQL,请尝试在JDBC连接URL的末尾添加characterEncoding=UTF-8
参数:
jdbc:mysql://server/database?characterEncoding=UTF-8
您还应该检查表/列字符集是否为UTF-8。
答案 1 :(得分:7)
每当数据库将字符更改为?
时,它就意味着所讨论的字符的代码点完全超出了表格配置使用的字符编码范围。
问题的原因:ç
位于ISO-8859-1范围内且与UTF-8(U+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连接编码也正确配置。如果Java / JDBC错误地使用了ISO-8859-1,则持久化结果将为Åakça
(ş
存在字节0xC5
和0x9F
,表示{ ISO-8859-1中的{1}}和Å
以及代表字节a
和ç
的{{1}}存在
ISO-8859-1中的0xC3
和0xA7
。
答案 2 :(得分:3)
setString方法将'şakça'更改为 '?akça'
你怎么知道setString改变了这个?或者你看到数据库中的内容并决定这个吗?
可能是数据库没有为UTF-8配置,或者只是用于查看数据库事件的工具(SQL * PLUS for Oracle ...)无法显示UTF-8。
答案 3 :(得分:0)
您可以使用以下查询在预准备语句中设置unicode字符串。
PreparedStatement st= conn.prepareStatement("select * from users where username=unistr(?)");// unistr method is for oracle
st.setString(1, userName);