mysql在带有重音utf8字符串的列上选择java

时间:2011-04-27 11:17:43

标签: java mysql encoding utf-8

尝试通过utf-8中的文本列从Java中的表中选择数据时遇到了问题。有趣的是,使用Python中的代码可以很好地使用Java,而不是。

该表如下所示:

CREATE TABLE `x` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `text` varchar(255) COLLATE utf8_bin NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

查询如下所示:

SELECT * FROM x WHERE text = 'ěščřž'"

不能用于检测的Java代码如下:

public class test {
    public static void main(String [] args) {
        java.sql.Connection conn = null;
        System.out.println("SQL Test");
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            conn = java.sql.DriverManager.getConnection(
                    "jdbc:mysql://127.0.0.1/x?user=root&password=root&characterSet=utf8&useUnicode=true&characterEncoding=utf-8&characterSetResults=utf8");
        } catch (Exception e) {
            System.out.println(e);
            System.exit(0);
        }

        System.out.println("Connection established");

        try {
            java.sql.Statement s = conn.createStatement();
            java.sql.ResultSet r = s.executeQuery("SELECT * FROM x WHERE text = 'ěščřž'");
            while(r.next()) {
                System.out.println (
                        r.getString("id") + " " +
                        r.getString("text")
                );
            }
        } catch (Exception e) {
            System.out.println(e);
            System.exit(0);
        }
    }
}

Python代码是:

# encoding: utf8

import MySQLdb

conn = MySQLdb.connect (host = "127.0.0.1",
                        port = 3307,
                        user = "root",
                        passwd = "root",
                        db = "x")
cursor = conn.cursor ()
cursor.execute ("SELECT * FROM x where text = 'ěščřž'")
row = cursor.fetchone ()
print row
cursor.close ()
conn.close ()

两者都以utf8编码存储在文件系统中(使用hexedit检查)。我尝试过不同版本的mysql-connector(目前使用的是5.1.15)。 Mysqld是5.1.54。

分别为Java代码和Python代码的Mysqld日志:

110427 12:45:07     1 Connect   root@localhost on x
110427 12:45:08     1 Query     /* mysql-connector-java-5.1.15 ( Revision: ${bzr.revision-id} ) */SHOW VARIABLES WHERE Variable_name ='language' OR Variable_name = 'net_write_timeout' OR Variable_name = 'interactive_timeout' OR Variable_name = 'wait_timeout' OR Variable_name = 'character_set_client' OR Variable_name = 'character_set_connection' OR Variable_name = 'character_set' OR Variable_name = 'character_set_server' OR Variable_name = 'tx_isolation' OR Variable_name = 'transaction_isolation' OR Variable_name = 'character_set_results' OR Variable_name = 'timezone' OR Variable_name = 'time_zone' OR Variable_name = 'system_time_zone' OR Variable_name = 'lower_case_table_names' OR Variable_name = 'max_allowed_packet' OR Variable_name = 'net_buffer_length' OR Variable_name = 'sql_mode' OR Variable_name = 'query_cache_type' OR Variable_name = 'query_cache_size' OR Variable_name = 'init_connect'
                    1 Query     /* mysql-connector-java-5.1.15 ( Revision: ${bzr.revision-id} ) */SELECT @@session.auto_increment_increment
                    1 Query     SHOW COLLATION
                    1 Query     SET autocommit=1
                    1 Query     SET sql_mode='STRICT_TRANS_TABLES'
                    1 Query     SELECT * FROM x WHERE text = 'ěščřž'
110427 12:45:22     2 Connect   root@localhost on x
                    2 Query     set autocommit=0
                    2 Query     SELECT * FROM x where text = 'ěščřž'
                    2 Quit      

有人有任何建议可能是Python代码工作的原因以及Java代码没有的原因吗? (通过不工作我的意思是没有找到所需的数据 - 连接工作正常)

非常感谢。

2 个答案:

答案 0 :(得分:1)

好的,我的坏。数据库被错误地构建了。它是通过mysql客户端构建的,默认情况下是latin1所以在数据库中数据由utf8编码两次。

问题和两个源代码之间的主要区别在于Python代码没有设置默认字符集(因此它是latin1)而Java代码则是(因此它是utf8)。因此,许多因素的巧合使我认为某些特殊的东西实际上正在发生。

感谢您的回复。

答案 1 :(得分:0)

使用PreparedStatement并将搜索字符串设置为该语句中的位置参数。

阅读本教程关于PreparedStatements - > http://download.oracle.com/javase/tutorial/jdbc/basics/prepared.html

此外,永远不要在包含非ASCII字符的Java代码中创建字符串文字。 如果要传递非ASCII字符,请执行unicode转义。 这应该让你知道我在说什么 - > http://en.wikibooks.org/wiki/Java_Programming/Syntax/Unicode_Escape_Sequences