我在Linux上使用MySQL 5.6.27,Java Connector 5.1.36,我对一些塞尔维亚语/克罗地亚语/斯洛文尼亚语字符有疑问。
数据库以
启动./bin/mysqld_safe --user=mysql --bind_address=localhost --character-set-server=utf8 &
使用
创建数据库-- CREATE USER 'my_test'@'localhost' IDENTIFIED BY 'my_test';
-- CREATE DATABASE my_test DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
-- GRANT ALL PRIVILEGES ON my_test.* TO 'my_test'@'localhost' IDENTIFIED BY 'my_test';
USE my_test;
CREATE TABLE proba
(
content TEXT NOT NULL
) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
INSERT INTO proba(content)
VALUES ('markovič marko SURČIN');
INSERT INTO proba(content)
VALUES ('Nikolić Nikola Ćićevac');
INSERT INTO proba(content)
VALUES ('petroviš đura Đeram');
INSERT INTO proba(content)
VALUES ('Milošević Miloš Šabac');
INSERT INTO proba(content)
VALUES ('jovanović žarko Žarkovo');
使用
将此转储导入MySQL/usr/local/mysql-5.6.27/bin/mysql --user=my_test --password < schema.sql
Java客户端使用
获取数据public class Serbian
{
public static void main(String[] args) throws ClassNotFoundException, SQLException
{
Connection conn = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/my_test?user=my_test&password=my_test&useUnicode=true&characterEncoding=UTF-8&collation=utf8_unicode_ci");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT content FROM proba");
while(rs.next())
{
String s = rs.getString("content");
System.out.println(s);
}
rs.close();
}
catch (SQLException exc)
{
exc.printStackTrace();
}
finally
{
conn.close();
}
}
}
结果是
markovič marko SUR??IN
Nikoli?? Nikola ??i??evac
petroviš ??ura Đeram
Miloševi?? Miloš Šabac
jovanovi?? žarko Žarkovo
(问号实际上是编辑报告的无效字符)。换句话说,字母Č,Ć,ć,đ无效,而Ž,ž,č,Š,š,Đ是有效的。 UTF8部分工作很奇怪。有什么我应该尝试一下,或者这似乎是一个MySQL / Java连接器问题?
答案 0 :(得分:0)
评论字段太短。还不是“最终”答案。
你的字母Č应该是hexdump,显示为c4 3f,这是无效的utf-8。
尽管
for(byte b : "Č".getBytes("UTF-8")) {
System.out.println("-> " + Integer.toHexString(b));
}
结果
-> ffffffc4
-> ffffff8c
\uc48c
再次正确打印为Č。
您可以检查是否从getString()
移至getNString()
更改结果。
等一下
“c4 3f”到处都有一些“缺失”字符应该是。十六进制已经坏了。
答案 1 :(得分:0)
这是解决方案。尽管添加了
,但SQL文件保持不变SET NAMES 'utf8' COLLATE 'utf8_general_ci';
没有受伤。必须通过添加开关--default-character-set=utf8
:
/usr/local/mysql-5.6.27/bin/mysql --user=my_test --password --default-character-set=utf8 < schema.sql
如果没有此参数,查询中的十六进制字符串(SELECT hex(content) FROM proba;
)会显示包含不存在的UTF8字符的损坏的十六进制字符串。最后,Java代码必须处理UTF8,因此在while循环中,以下行获取UTF8字符串:
System.out.println(new String(rs.getString("content").getBytes(Charset.forName("UTF-8"))));
执行程序并重定向到文件(java -cp ".:./mysql-connector-java-5.1.36-bin.jar" Serbian > java.log
)不会有麻烦,所以一切都很好:
markovič marko SURČIN
Nikolić Nikola Ćićevac
petroviš đura Đeram
Milošević Miloš Šabac
jovanović žarko Žarkovo
@Jan,@ GordThompson:感谢您帮助更好地理解问题。