2011-04-27 7 views
-1

Java에서 MySQL의 테이블에서 utf-8에있는 텍스트 열을 사용하여 데이터를 선택하려고 할 때 문제가 발생했습니다. 흥미로운 점은 파이썬에서 코드를 사용하면 잘 작동한다는 것입니다. 자바에서는 그렇지 않습니다.악센트 부호가있는 utf8 문자열이있는 열에서 mysql을 선택하십시오.

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; 

쿼리는 다음과 같습니다 :

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); 
     } 
    } 
} 
:

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

exptected대로 작동하지 않습니다 자바 코드는 다음과 같다 다음과 같이

표 본다

파이썬 코드 :

# 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입니다.

는 자바 코드를 기록하고 각각의 파이썬 코드 mysqld를 :

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  

사람이 파이썬 코드가 작동하는 이유와 자바 코드하지 않는 이유를 원인 일 수 있습니다 어떤 제안이 있습니까? (작동하지 않음으로써 원하는 데이터를 찾지 못함 - 연결이 정상적으로 작동 함)

고맙습니다.

답변

1

좋아, 나쁘다. 데이터베이스가 잘못 작성되었습니다. 이것은 기본적으로 latin1 인 mysql 클라이언트를 통해 구축되었으므로 데이터베이스에서 데이터는 utf8에 의해 두 번 인코딩되었습니다.

두 소스 코드 간의 주요한 차이점은 Python 코드가 Java 코드와 달리 (즉, latin1) 기본 charset을 설정하지 않는다는 것입니다 (따라서 utf8 임). 그래서 나는 여러 가지 요인이 우연히 만났기 때문에 실제로 뭔가 특별한 일이 일어나고 있다고 생각하게되었습니다.

어쨌든 귀하의 회신에 감사드립니다.

0

PreparedStatement를 사용하고 검색 문자열을 해당 명령문의 위치 매개 변수로 설정하십시오.

는자는 PreparedStatements에 대해이 튜토리얼을 읽기 - http://download.oracle.com/javase/tutorial/jdbc/basics/prepared.html

은 또한, 비 ASCII 문자가 포함 된 자바 코드에서 리터럴 문자열을 만들 수 없습니다>. 비 ASCII 문자를 전달하려면 유니 코드를 이스케이프 처리해야합니다. 이것은 내가 무슨 말을하고 있는지를 말해 줄 것이다. ->http://en.wikibooks.org/wiki/Java_Programming/Syntax/Unicode_Escape_Sequences

+0

감사합니다. 나는 그것이 PreparedStatement의 것조차도 작동하지 않는다는 것을 언급하는 것을 잊었다. 원래는 데이터베이스에서 데이터를 얻었으므로 비 ASCII 리터럴도 문제가되지 않았습니다. 그럼에도 불구하고 코드에 넣으려고했는데 작동하지 않았습니다. a = "\ uC49B \ uC5A1 \ uC48D \ uC599 \ uC5BE"및 "ps.setString (1, a)"와 같이 seraching하는 문자열을 인코딩했습니다. @ alexander-pogrebnyak – ticcky

+0

hmmm, errgr, 절대, 제발 그만해, 너 무슨 말을 했어? (Win과 As400 OS에서) 나는 그 문제에 대해 전혀 알지 못했다. 둘 다 여기에서 설명했듯이, 자바는 엄격한 유니 코드이고, 유니 코드는 모든 체코 어를 안다. 및 폴란드 비 ASCII 문자, 오늘 JDBC는 charset 및 데이터 정렬이 db 쪽에서 올바르게 설정된 경우 모든 유니 코드 char을 허용합니다 ... – mKorbel

+0

@ticcky. 검색 문자열을 잘못 인코딩했습니다.'UTF-8'을 사용했으며 Java는 내부 문자열 인코딩에 UTF-16을 사용합니다. 첫 글자 'ě'는 '\ u011B'가 아니라 '\ uC49B'로 인코딩되어야합니다. 따라서 전체 쿼리 문자열 리터럴은 "\ u011B \ u0161 \ u010D \ u0159 \ u017E" –

관련 문제