A2공간 - 도움되는 글을 쓰자

ani2life.egloos.com

포토로그 마이가든


그냥 잡담

※방명록은 따로 없고 무조건 최신글에 댓글 남기시면 됩니다. ^^

위드블로그



MySQL Connector/J로 JDBC 사용시 인코딩 문제 개발/플밍



제목을 적는데 무척 고민했습니다.
누군가가 웹의 자료를 검색 했을때 쉽게 찾고 정확한 자료를 제공해 주고 싶기 때문입니다.
이 글의 제목을 '인코딩 문제'가 아닌 '한글 문제'라고 적는게 검색하는 사람들에게 더 도움이 될 듯하지만 정확하게 말하자면 한글만의 문제가 아닌 인코딩 문제이기 때문입니다. (은근슬적 본문에 '한글 문제'라고 적는 재치!)

문제점



EUC-KR이 기본 문자셋인 MySQL에 JDBC로 아래와 같이 접속하여 데이터를 삽입하면 한글이 깨져서 기록되는 문제가 발생합니다.


String Url = "jdbc:mysql://주소:포트번호/DB이름";
Connection Conn = DriverManager.getConnection(Url, "아이디", "암호");


해결방법



우선 Connector/J 버전에 따라 아래의 내용이 맞지 않을 수 있습니다.
저는 MySQL 4.0.26, Connector/J 5.0.3 버전에서 테스트 하였습니다.


String Url = "jdbc:mysql://주소:포트번호/DB이름";
String Property = "?characterEncoding=EUC_KR";
Connection Conn = DriverManager.getConnection(Url + Property, "아이디", "암호");


2번 라인의 속성을 추가해줘야 MySQL이 데이터를 저장할때 EUC-KR로 파일에 저장됩니다.
(※ EUC-KR이 아닌 EUC_KR 입니다. Connector/J의 버전에 따라 EUCKR인 것도 있습니다.)

잡다한 내용



characterEncoding에 대해서는 아래와 같은 설명이 있습니다.(제가 영어를 너무 못해서 원문과 같이 올립니다. 번역보고 웃지 말아주세요.ㅠㅠ)

If 'useUnicode' is set to true, what character encoding should the driver use when dealing with strings? (defaults is to 'autodetect')
- 신뢰없는 해석 : useUnicode가 ture라면 문자열을 교환시 드라이버가 어떤 문자 인코딩을 사용하는지?(기본값은 자동찾기)

useUnicode는 기본값이 true이므로 굳이 useUnicode=true&characterEncoding=EUC_KR 라고 쓸 필요는 없습니다.

useUnicode에 대해서는 아래와 같은 설명이 있습니다.

Should the driver use Unicode character encodings when handling strings? Should only be used when the driver can't determine the character set mapping, or you are trying to 'force' the driver to use a character set that MySQL either doesn't natively support (such as UTF-8), true/false, defaults to 'true'
- 신뢰없는 해석 : 문자열 접근시 드라이버가 어떤 유니코드 문자 인코딩을 사용하는가? 드라이버가 문자를 매치시키지 못할때나, 문자셋 이용을 드라이버로 당신이 '강제' 시도할때 MySQL이 어느한쪽만을 지원하지 못하므로(UTF-8 처럼) 사용된다(?), true/false, 기본값은 'true'이다

죄송합니다. 제가 봐도 무슨 말인지 모르겠습니다. 번역을 신뢰하지 말아주세요.

왜 이런 문제가 발생하는 것일까요? 저도 이 부분이 궁금합니다.

나름대로 가설을 세워봤습니다.
우선 JSP 즉, JAVA에서 문자를 유니코드로 처리합니다.
넘어온 값의 인코딩이 무엇이던지 메모리에 저장되는건 유니코드 입니다.

이 유니코드 데이터를 MySQL에 전달할테고 MySQL은 데이터를 파일에 출력하기 위해서 적절한 인코딩을 선택할 것입니다.
그런데 MySQL은 데이터를 출력할 DB파일의 기본 인코딩이 무엇인지 알고 있을텐데 왜 깨져서 기록되는 것일까요?
이 문제에서 막혀버리고 말았습니다.

영어실력이 딸려서 이런 복잡한 부분은 찾아볼 엄두가 나지 않습니다.
누구 확실히 아시는 분이 계시다면 가르쳐 주시길 바랍니다. :)

이 유니코드 데이터를 MySQL은 바이트로 기록하기 위해 어떠한 인코딩으로 처리할 것인지 우리는 Connector/J의 characterEncoding에 원하는 인코딩을 설정하여 저장합니다.

불러올 때도 마찬가지로 MySQL에서 불러온 바이트 데이터를 JAVA의 문자열로 변환하기 위해서 인코딩을 알려주어야 합니다.


#참고자료 http://dev.mysql.com/doc/connector/j/en/connector-j-reference-charsets.html

MySQL to Java Encoding Name Translations. 

MySQL Character Set NameJava-Style Character Encoding Name
asciiUS-ASCII
big5Big5
gbkGBK
sjisSJIS (or Cp932 or MS932 for MySQL Server < 4.1.11)
cp932Cp932 or MS932 (MySQL Server > 4.1.11)
gb2312EUC_CN
ujisEUC_JP
euckrEUC_KR
latin1ISO8859_1
latin2ISO8859_2
greekISO8859_7
hebrewISO8859_8
cp866Cp866
tis620TIS620
cp1250Cp1250
cp1251Cp1251
cp1257Cp1257
macromanMacRoman
macceMacCentralEurope
utf8UTF-8
ucs2UnicodeBig


트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://ani2life.egloos.com/tb/2732387 [도움말]

덧글

  • 지율 2006/12/14 16:59 # 삭제 답글

    My SQL이 파일 시스템 기록시엔 해당 컬럼의 인코딩 셋으로 다시 변경해서 저장하긴 하지만, 문제는 자기(MySQL 서버)가 받은 쿼리문이 뭐로 인코딩 되어있는지 도통 알 수 없으니, 문제가 됩니다. 일단 풀어야 다지 인코딩을 해서 저장을 하던 말건 할 수 있겠죠. MySQL이 받아 보는건 단순한 쿼리문일 뿐이지, 인코딩 정보는 전혀 없거든요. 따라서 쿼리문 안에 존재하는 한글같은 문자열이 문제가 됩니다. 실제 그 컬럼이 어떻게 저장되느냐는 나중 문제입니다.

    따라서 데이터가 DB에 어떤 형태로 저장되든 상관 없이 JDBC드라이버와 MySQL사이에 주고 받는 쿼리문이 무슨 인코딩 셋트냐 하는 정보를 추가적으로 주지 않으면 MySQL서버가 쿼리를 어떻게 이해할지는 장담할 수 없는 것이 당연합니다.
댓글 입력 영역

올블로그 올블릿