読者です 読者をやめる 読者になる 読者になる

HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

JavaプログラムからMySQLに4バイトのUTF-8文字を放り込んでみる

前の記事で、PHPプログラムからMySQLに4バイトのUTF-8文字を放り込んでみた。

ついでなので、Javaプログラムの場合はどうなるのかを調べてみた。

例のごとく、「𠮟」と書かれた部分は「叱」の異体字だと思って読んでもらえればと。

面倒なので、プログラム自体は割愛するが(待て)、以下のSQL文を順に発行するだけの単純なプログラム。特にMySQLに特化したパラメータを渡すことはしていない。(便宜上、SQL文の末尾にセミコロンをつけている)

DELETE FROM hoge;
-- 従来から定義されている文字
INSERT INTO hoge(idx, str) VALUES(0, '叱');
-- JIS X 0213:2004 で追加された、UTF-8で4バイトになる文字
INSERT INTO hoge(idx, str) VALUES(1, '𠮟');
SELECT idx, str FROM hoge;

実際に実行してみると、以下のようなエラーメッセージを持つSQLExceptionが投げられる。

Incorrect string value: '\xF0\xA0\xAE\x9F' for column 'str' at row 1

これは2つ目のINSERT文を実行しようとしているときに発生するので、間違いなく「UTF-8で4バイトになる文字」が関係しているのだろうが。
で、MySQLJDBCドライバと"utf8mb4"の関係について調べてみると、以下のような記述を見つけた。


Fixed for 5.1.13.

From the changelog:

"Driver doesn't support utf8mb4 for servers 5.5.2 and newer. The
driver now auto-detects servers configured with character_set_server=utf8mb4 or
treats the Java encoding "utf-8" passed via "characterEncoding=..." as utf8mb4 in
the "SET NAMES=" calls it makes when establishing the connection."

よくよく調べてみると、使用しているJDBCドライバのバージョンがv5.1.6だった。
ということで、v5.1.18に置き換えて実行してみると、今度はSELECT文の結果として次のようなものが無事に返ってきた。

| [idx]             (INT       ) | [str]             (VARCHAR   ) |
| 0          (java.lang.Integer) | 叱          (java.lang.String ) |
| 1          (java.lang.Integer) | 𠮟         (java.lang.String ) |

結論。

  • MySQLサーバーのほうの条件は、前回試したときと同じ(v5.5.3以降、"utf8mb4"を指定)
  • MySQLJDBCドライバ(Connector/J)は、v5.1.13以降を使用する