JDBC和MySQL部分适用于UTF8

时间:2015-12-18 13:32:23

标签: java mysql jdbc utf-8

我在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连接器问题?

2 个答案:

答案 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:感谢您帮助更好地理解问题。