으악 DB에 한글이 안들어가요.

Exception in thread "main" java.sql.SQLException: Incorrect string value: '\xEB\xB0\xB1\xEA\xB8\xB0...' for column 'name' at row 1

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3515)

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3447)

at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1951)

at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2101)

at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2554)

at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1761)

at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2046)

at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1964)

at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1949)

at springbook.user.dao.UserDao.add(UserDao.java:23)

at springbook.user.dao.UserDao.main(UserDao.java:60)



mysql> SHOW VARIABLES LIKE '%olla%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | utf8_general_ci   |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)

mysql> 

Class.forName("com.mysql.jdbc.Driver");

Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?characterEncoding=UTF-8", "spring","book");


방법을 찾았습니다만, 쉽지 않은 문제였습니다. DB에 대한 이해가 필수겠지요. varchar(20)을 longtext  로 잡았습니다.

create table users (

id varchar(10) primary key,

name longtext not null,

password varchar(10) not null

) DEFAULT CHARSET=utf8;



현재 DB 설정과 내용은 다음과 같습니다.
kenuheoyimacbookpro-4:bin kenu$ ./mysql -u spring -p springbook
Enter password: 
...
Server version: 5.5.8 MySQL Community Server (GPL)

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
...
mysql> show variables like '%olla%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | utf8_general_ci   |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)

mysql> select * from users;
+-----------+-----------+----------+
| id        | name      | password |
+-----------+-----------+----------+
| whiteship | 백기선    | married  |
+-----------+-----------+----------+
1 row in set (0.00 sec)

mysql> 



java와 utf8 환경에서 한글 깨지는 현상에 대한 gruter님 질문 관련 포스팅입니다. 제한적인 상황이라는 것은 참고해주시면 좋겠습니다.

테스트는 다음과 같이 했습니다.
XP, jdk1.6.03, eclipse 3.3.1 JEE 환경
새로운 workspace 만들고 java project 하나 만들었습니다.
기본 설정에서 "한글UTF8" 문자열을 콘솔뷰에 찍는 프로그램을 만듭니다.
설정에서 java 소스파일의 인코딩타입을 utf8로 변경합니다.
사용자 삽입 이미지

사용자 삽입 이미지


콘솔에서 확인합니다.
사용자 삽입 이미지


인코딩 변환으로 소스의 한글이 깨어져 보이기 때문에 한글부분을 수정했습니다.
사용자 삽입 이미지

콘솔에서 확인합니다.
사용자 삽입 이미지


이 테스트에서 내릴 수 있는 결론은 파일 인코딩 타입 변환에 따른 한글이 깨어질 수 있다 정도입니다.

설정을 모두 해제하시고, 인코딩 변환 부분을 최소화 시켜서 작업하는 것이 좋을 것 같습니다.
웹이 보편화되면서 브라우저에서의 문자세트에 대한 얘기도 점점 많아지고 있습니다. 글자가 깨져 보이는 경우는 바로 이 문자세트가 맞지 않아서인데, 세상의 모든 언어들을 한 화면에 표시하기 위한 방식이 UTF8입니다. 물론 포토샵 등으로 이미지를 통해서 한 화면에 표시하는 방법도 있기는 하죠. 철푸덕. ^^;
동일한 내용의 파일이 문자세트에 따라 어떤 차이가 있는지 간략히 살펴보겠습니다.
text

text

필자가 좋아하는 에디터인 울트라에디트를 이용해서 적어놓은 글자들입니다. ctrl+H를 하면 16진수 형태의 코드로 보여지는데 다음과 같습니다.
사용자 삽입 이미지

ANSI charset

컴퓨터가 내부적으로 기억하는 코드를 볼 수 있습니다. h에 해당하는 68은 16진수로 표기된 것이고 10진수로 바꾸면 6*16+8 = 96+8 = 104 입니다. 104번째 해당하는 문자라는 것을 알 수 있죠. 0D 0A 부분이 보일 텐데, windows에서 엔터를 치면 이렇게 두 문자(2 bytes)가 자동으로 만들어집니다. java에서 "\r\n" 이라고 하는 표시하는 것과 일맥상통하죠. 뒤 이어 한글은 두 자리로 되어있는데, "가"는 B0 A1, "나"는 B3 AA 로 컴퓨터가 기억하고 있다는 것을 알 수 있습니다.

울트라에디트에서 이것을 utf8로 변환해보겠습니다. 다시 ctrl+H를 눌러서 일반텍스트 편집화면으로 되돌립니다.
메뉴의 파일(F)에서 "변환"을 선택하고 ASCII -> UTF8(Unicode 편집) 항목을 선택합니다.
conversion

conversion

파일의 코드셋이 변경되었습니다. 다른 이름으로 저장해보겠습니다.
파일의 크기가 바뀐 것을 감지하셨는지 모르겠네요. ^^; hello_utf8.txt로 저장을 했는데 이 파일을 열어서 ctrl+H를 해보면 다음과 같습니다.
utf8 hex view

utf8 hex view

h앞에 세 문자가 더 들어간 것을 볼 수 있습니다. "EF BB BF". 그리고 영어부분은 이전과 같은데 한글부분의 문자가 2바이트 단위에서 3바이트 단위로 늘어났습니다. 즉 "가"가 EA BO 80 이고 "나"가 EB 82 98 입니다.

정리를 하자면 같은 내용의 문자열을 표시한다고 해도 문자세트(코드세트, charset)에 따라서 내부적으로 기억하는 방식은 다르다는 것입니다.

한 가지 더, utf8편집을 위해서 ultraedit 만 필요한 것은 아닙니다. windows의 메모장에서도 편집이 가능합니다. 저장할 때 파일명을 적고 아래에 있는 인코딩을 ANSI에서 UTF-8로 정해주면 됩니다.
메모장 utf8

메모장 utf8


아, Mac에서는 Smultron (http://smultron.sourceforge.net/)이라는 편집기를 사용하고 있습니다.
읽어주셔서 감사합니다. ^^

+ Recent posts