我正在尝试从MySql数据库读取UTF-8字符串,我使用它创建:
CREATE DATABASE april
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
我使用以下方式制作感兴趣的表:
DROP TABLE IF EXISTS `article`;
CREATE TABLE `article` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` longtext NOT NULL,
`date_created` timestamp DEFAULT NOW(),
PRIMARY KEY (`id`)
) CHARACTER SET utf8;
如果我在MySql命令行util中 select * from article
,我得到:
OIL sands output at Nexen’s Long Lake project dropped in February.
但是,当我这样做时
ResultSet rs = st.executeQuery(QUERY);
long id = -1;
String text = null;
Timestamp date = null;
while (rs.next()) {
text = rs.getString("text");
LOGGER.debug("text=" text);
}
我得到的输出是:
text=OIL sands output at Nexen’s Long Lake project dropped in February.
我通过以下方式获取我的连接:
DriverManager.getConnection("jdbc:" + this.dbms + "://" + this.serverHost + ":" + this.serverPort + "/" + this.dbName + "?useUnicode&user=" + this.username + "&password=" + this.password);
我也试过,而不是useUnicode
参数:
characterEncoding=UTF-8
and
characterEncoding=utf8
我也尝试过,而不是行text = rs.getString("text")
rs.getBytes("text");
String[] encodings = new String[]{"US-ASCII", "ISO-8859-1", "UTF-8", "UTF-16BE", "UTF-16LE", "UTF-16", "Latin1"};
for (String encoding : encodings) {
text = new String(temp, encoding);
LOGGER.debug(encoding + ": " + text);
}
// Which outputted:
US-ASCII: OIL sands output at Nexen��������s Long Lake project dropped in February.
ISO-8859-1: OIL sands output at Nexenââ¬â¢s Long Lake project dropped in February.
UTF-8: OIL sands output at Nexen’s Long Lake project dropped in February.
UTF-16BE: 佉䰠獡湤猠潵瑰畴琠乥硥滃ꋢ芬ꉳ⁌潮朠䱡步⁰牯橥捴牯灰敤渠䙥扲畡特�
UTF-16LE: 䥏⁌慳摮畯灴瑵愠⁴敎數썮겂蓢玢䰠湯慌敫瀠潲敪瑣搠潲灰摥椠敆牢慵祲�
UTF-16: 佉䰠獡湤猠潵瑰畴琠乥硥滃ꋢ芬ꉳ⁌潮朠䱡步⁰牯橥捴牯灰敤渠䙥扲畡特�
Latin1: OIL sands output at Nexenââ¬â¢s Long Lake project dropped in February.
我使用文件中的一些预定义的sql将字符串加载到DB中。该文件是UTF-8编码的。
mysql -u april -p -D april < insert_articles.sql
此文件包含以下行:
INSERT INTO article (text) value ("OIL sands output at Nexen’s Long Lake project dropped in February.");
当我使用以下内容在我的应用程序中打印出该文件时
BufferedReader reader = new BufferedReader(new FileReader(new File("/home/path/to/file/sql_article_inserts.sql")));
String str;
while((str = reader.readLine()) != null) {
LOGGER.debug("LINE: " + str);
}
我得到了正确的预期输出:
LINE: INSERT INTO article (text) value ("OIL sands output at Nexen’s Long Lake project dropped in February.");
非常感谢任何帮助。
一些系统细节: 我在linux上运行(Ubuntu)
编辑:
*编辑指定操作系统
*编辑读取sql输入文件的详细输出
*编辑以指定有关数据如何插入数据库的更多信息
*编辑修复代码中的拼写错误,并澄清示例。
答案 0 :(得分:2)
您是否可能使用不正确的编码读取日志文件? windows-1252,我猜。
UTF-8: OIL sands output at Nexen’s Long Lake project dropped in February.
如果这出现在日志中,请执行日志文件的十六进制转储。如果数据是UTF-8,则您希望序列Nexen’s
变为4E 65 78 65 6E E2 80 99 73
。如果某个其他应用程序将其读作本机ANSI编码,则会将其解码为Nexen’s
。
要确认,您还可以转储返回值的各个字符,以查看它们在UTF-16中是否正确:
//untested
for(char ch : text.toCharArray()) {
System.out.printf("%04x%n", (int) ch);
}
我假设所有数据都在BMP,因此您只需在Unicode charts中查找结果。
答案 1 :(得分:1)
尝试将数据库本身设置为UTF-8。创建数据库时:
CREATE DATABASE mydb
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
另见MySQL reference on connection charsets和MySQL reference on configuring charsets for applications
答案 2 :(得分:0)
JDBC URL中的参数仅定义驱动程序与服务器通信的方式。如果服务器默认不使用UTF8,则这些参数也不会改变它。
连接后尝试执行以下SQL查询吗? (这应该在服务器端将当前连接切换到UTF8):
SET names utf8
答案 3 :(得分:0)
涉及多种字符编码。
如果终端设置错误,您可能在mysql中插入了损坏的数据。 (如果您的终端是iso-8859-1,并且您读取的文件是UTF-8,例如)假设linux,mysql应该查看env LC_CTYPE(但我不是100%确定它确实如此。)
JDBCD驱动程序负责将数据库字符编码转换为JVM内部格式(UTF16),因此不应该成为问题。但是您可以使用simpel java程序对其进行测试,该程序会插入硬编码字符串并将其读回。打印原始和收到的字符串 - 它们应该是相同的。但; 如果两者都错, 您的终端字符集定义有问题。
使用像“HejÅÄÖ”这样的字符串来表演戏剧......
另外,编写一个小程序,使用转换为UTF-8的printwriter将相同的字符串打印到文件,并验证用于读取日志的工具是否正确打印该文件。如果没有,则再次怀疑终端设置。
String test = "Test HEJ \u00C5\u00C4\u00D6 ÅÄÖ";
// here's how to define what character set to use when writing to a fileOutputStream
PrintWriter pw = new PrintWriter("test.txt","UTF8");
pw.println(test);
pw.flush();
pw.close();
System.out.println(test);
输出 - &gt;测试HEJÅÄÖÅÄÖ
文件test.txt的内容应该看起来一样。