Java PreparedStatement UTF-8 字符问题

10

我有一个预处理语句:

PreparedStatement st;

我在代码中尝试使用st.setString方法。

st.setString(1, userName);

userName的值为şakça。setString方法将'shakcha'更改为'?akça',它无法识别UTF-8字符。如何解决这个问题?

谢谢。


1
你使用的是哪个数据库?并且它是否配置为在该列中接受Unicode(或者你需要的şakça)? - Thilo
亲爱的kamaci,你好。请问有可能和您保持联系吗?最好的祝福。 - RF1991
4个回答

42

这个问题可能会出现的方式实际上相当令人印象深刻。如果你正在使用MySQL,可以尝试在JDBC连接URL的末尾添加characterEncoding=UTF-8参数:

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

您还应该检查表/列的字符集是否为UTF-8。


3
对我来说,?characterEncoding=UTF-8不起作用。我尝试了使用?characterEncoding=utf8,并且它是有效的。 - utarid
两者对我都有效。对我来说,区别在于"utf8"缺少很多符号,而"UTF-8"则包含了所有符号。 - Joel Christophel

7
每当数据库将一个字符更改为?时,这意味着该字符的代码点完全超出了表所配置的字符编码范围。
至于问题的原因: ç位于 ISO-8859-1 范围内,并且与 UTF-8 中的代码点完全相同( U + 00E7 )。然而,ş的UTF-8代码点完全超出了ISO-8859-1的范围( U + 015F ,而ISO-8859-1只到U + 00FF)。数据库不会保留该字符并用?代替它。
因此,我怀疑您的DB表仍然配置为使用ISO-8859-1(或其他兼容的ISO-8859编码之一,其中ç具有与UTF-8相同的代码点)。
Java / JDBC API在字符编码方面做得非常好(Java从头到脚都使用Unicode),JDBC DB连接编码也已正确配置。如果Java / JDBC错误地使用ISO-8859-1,则持久化的结果将是Åakçaş由字节0xC50x9F组成,表示ISO-8859-1中的Åa,而ç由字节0xC30xA7组成,代表ISO-8859-1中的ç)。

3

setString方法将 'şakça' 改为 '?akça'

您是如何知道setString方法会改变这个内容的?或者您是通过数据库中的内容来判断的?

可能是因为数据库没有配置UTF-8,或者您用于查看数据库内容的工具(如Oracle的SQL*PLUS)无法显示UTF-8。


0

您可以使用以下查询来在预编译语句中设置Unicode字符串。 PreparedStatement st= conn.prepareStatement("select * from users where username=unistr(?)");// unistr方法适用于Oracle st.setString(1, userName);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接