2011-04-27 35 views
-1

当尝试从UTF-8中的文本列中的Java中的Java表中选择数据时遇到问题。有趣的是,在Python中的代码运行良好,而在Java中却不行。mysql在具有重音utf8的列上选择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代码不作为exptected工作如下:

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日志Java代码分别Python代码:

110427 12:45:07  1 Connect [email protected] 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 [email protected] on x 
        2 Query  set autocommit=0 
        2 Query  SELECT * FROM x where text = 'ěščřž' 
        2 Quit  

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

非常感谢。

回答

1

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

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

无论如何感谢您的回复。

0

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

阅读本教程的用预处理 - >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

+0

谢谢。我忘了提及它甚至没有与PreparedStatement一起工作。本来,我也从数据库中获得数据,所以非ASCII字面也不是问题。尽管如此,我试图将两者都纳入代码中,但它不起作用。余编码我正在seraching为作为串:一个= “\ uC49B \ uC5A1 \ uC48D \ uC599 \ uC5BE” 和所谓的 “ps.setString(1,A)”。 @亚历山大Pogrebnyak – ticcky 2011-04-27 11:59:04

+0

嗯,errgr,没有,请停止,你说什么(在Win和As400操作系统)我从来没有遇到过问题,因为你们都在这里讨论,Java是严格的Unicode,Unicode知道所有捷克和波兰非ASCII字符,今天JDBC接受所有Unicode字符,如果是字符集和归类上分贝侧正确设置..., – mKorbel 2011-04-27 12:08:51

+0

@ticcky。您错误地编码了您的搜索字符串。您使用'UTF-8',Java使用UTF-16进行内部字符串编码。你的第一个字母'ě'应该被编码为'\ u011B',而不是'\ uC49B'。所以,你的整个查询字符串应该看起来像“\ u011B \ u016​​1 \ u010D \ u0159 \ u017E” – 2011-04-27 12:24:39