Java PreparedStatement UTF-8 字符问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3828818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:34:24  来源:igfitidea点击:

Java PreparedStatement UTF-8 character problem

javadatabasejdbcutf-8character-encoding

提问by kamaci

I have a prepared statement:

我有一个准备好的声明:

PreparedStatement st;

and at my code i try to use st.setString method.

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

st.setString(1, userName);

Value of userName is ?ak?a. setString methods changes '?ak?a' to '?ak?a'. It doesnt recognize UTF-8 characters. How can i solve this problem?

userName 的值是?ak?a。setString 方法将 '?ak?a' 更改为 '?ak?a'。它不识别 UTF-8 字符。我怎么解决这个问题?

Thanks.

谢谢。

回答by Joshua Martell

The number of ways this can get screwed up is actually quite impressive. If you're using MySQL, try adding a characterEncoding=UTF-8parameter to the end of your JDBC connection URL:

这可能被搞砸的方式数量实际上非常令人印象深刻。如果您使用的是 MySQL,请尝试characterEncoding=UTF-8在 JDBC 连接 URL 的末尾添加一个参数:

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

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

You should also check that the table / column character set is UTF-8.

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

回答by BalusC

Whenever a database changes a character to ?, then it simply means that the codepoint of the character in question is completely out of the range for the character encoding as the table is configured to use.

每当数据库将字符更改为 时?,就意味着该字符的代码点完全超出了表配置使用的字符编码范围。

As to the cause of the problem: the ?lies within ISO-8859-1range and has exactly the same codepoint as in UTF-8(U+00E7). However, the UTF-8 codepoint of ?lies completely outside the range of ISO-8859-1 (U+015Fwhile ISO-8859-1 only goes up to U+00FF). The DB won't persist the character and replace it by ?.

至于问题的原因:?位于ISO-8859-1范围内并且具有与UTF-8( U+00E7)完全相同的代码点。然而,UTF-8 代码点?完全超出了 ISO-8859-1 的范围(U+015F而 ISO-8859-1 只能达到 U+00FF)。DB 不会保留该字符并将其替换为?.

So, I suspect that your DB table is still configured to use ISO-8859-1 (or in one of other compatible ISO-8859 encodings where ?has the same codepoint as in UTF-8).

因此,我怀疑您的数据库表仍配置为使用 ISO-8859-1(或其他兼容的 ISO-8859 编码之一,其中?具有与 UTF-8 相同的代码点)。

The Java/JDBC API is doing its job perfectly fine with regard to character encoding (Java uses Unicode all the way) and the JDBC DB connection encoding is also configured correctly. If Java/JDBC would have incorrectly used ISO-8859-1, then the persisted result would have been ?ak?§a(the ?exist of bytes 0xC5and 0x9Fwhich represents ?and ain ISO-8859-1 and the ?exist of bytes 0xC3and 0xA7which represents ?and §in ISO-8859-1).

Java/JDBC API 在字符编码方面做得非常好(Java 一直使用 Unicode)并且 JDBC DB 连接编码也被正确配置。如果爪哇/ JDBC会不正确地使用ISO-8859-1,则持久性结果将是?ak?§a(该?字节的存在0xC50x9F它代表?a在ISO-8859-1和?字节的存在0xC30xA7它代表 ?§在ISO-8859- 1)。

回答by Nivas

setString methods changes '?ak?a' to '?ak?a'

setString 方法将 '?ak?a' 更改为 '?ak?a'

How do you know that setString changes this? Or do you see the content in the database and decide this?

你怎么知道 setString 改变了这一点?或者你看到数据库中的内容并决定这个?

It could be that the database is not configured for UTF-8, or simply that the tool you use to see the contects of the database (SQL*PLUS for Oracle...) is not capable of diaplaying UTF-8.

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

回答by Prateep Gedupudi

you can use query as below to set unicode strings in prepared statement. PreparedStatement st= conn.prepareStatement("select * from users where username=unistr(?)");// unistr method is for oracle st.setString(1, userName);

您可以使用如下查询在准备好的语句中设置 unicode 字符串。 PreparedStatement st= conn.prepareStatement("select * from users where username=unistr(?)");// unistr method is for oracle st.setString(1, userName);