MySQL выбрать в Java на столбце с ударной строкой UTF8 - PullRequest
0 голосов
/ 27 апреля 2011

Я столкнулся с проблемой при попытке выбрать данные из таблицы в MySQL на Java по текстовому столбцу в utf-8.Интересно, что с кодом на 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-разъем (в настоящее время используется 5.1.15).Mysqld - это 5.1.54.

Mysqld log для кода Java и кода Python соответственно:

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 ]

1 голос
/ 27 апреля 2011

Хорошо, мой плохой.База данных была неправильно построена.Он был построен через клиент mysql, который по умолчанию имеет значение latin1, поэтому в базе данных данные дважды кодируются с помощью utf8.

Проблема и основное различие между двумя исходными кодами заключается в том, что код Pythonустановить кодировку по умолчанию (следовательно, это latin1), в то время как код Java делает (поэтому это utf8).Так что именно совпадение многих факторов заставило меня думать, что на самом деле происходит что-то необычное.

Спасибо за ваши ответы в любом случае.

0 голосов
/ 27 апреля 2011

Используйте PreparedStatement и задайте строку поиска в качестве позиционного параметра для этого оператора.

Прочтите этот учебник о PreparedStatements -> http://download.oracle.com/javase/tutorial/jdbc/basics/prepared.html

Кроме того, никогда не создавайте строковый литерал в коде Java, который содержит символы не ASCII. Если вы хотите передать не-ASCII символы, используйте для них юникод. Это должно дать вам представление о чем я говорю -> http://en.wikibooks.org/wiki/Java_Programming/Syntax/Unicode_Escape_Sequences

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...