Java で(JDBCで)MySQL データベースに日本語文字を書き込んだ時に文字化けする、という問題に遭遇した時の対処方法を紹介します。

まず、MySQL データベースを自分で用意する場合にはあまり起こらないことだと思っています。起こらないというか、起こっても自分で MySQL サーバーやクライアントの文字コード設定を変えれば対処できることだと思っています。

ところが最近は PaaS が流行っていることもあり、自分でデータベースサーバーを構築するのではなく、「用意されたデータベースのインスタンスを作って使う」という使い方が可能になり、用意された(自分で設定したわけではない)データベースを使うだけ、という手法も多く使われはじめています(IBM Bluemix とか、AWS の RDS とか、・・)。これはこれで簡単で便利なのですが、いざ問題が起こった場合にサーバーの管理者ではないため、設定を変更できる部分とできない部分があったり、そもそもどういう設定で動いているのかを確認できたりできなかったりします。そしてその結果として、今回のような文字化けの問題が発生したりします(デフォルトのデータベース文字コードが分からない、当然のように UTF-8 だと思って UTF-8 で書き込んだら文字化けした、というパターン)。

これを回避するにはデータベースの設定がどのようになっていたとしても UTF-8 前提で接続して、UTF-8 を明示して書き込む、という実装が必要になるわけです。


これが Java(JDBC) と MySQL で問題になったりします(同じ MySQL でも PHP では特に意識せずに文字化けも回避して使えていたが、同じ処理を Java で行うと文字化けする、といったことが起こります)。コードのテキストそのものが UTF-8 で記述されていても起こります。要は上記で書いたような部分が自動判別では実現できておらず、コードとして実装する必要があるからです。

Java(JDBC) で MySQL に対して UTF-8 を明示して接続するには、このように記述する必要があります:
    :
    :
  Connection conn = null;

  String dburi = "mysql://mysql.test.com/mydb?useUnicode=true&characterEncoding=utf8";

  try{
    Class.forName( "com.mysql.jdbc.Driver" );
    conn = DriverManager.getConnection( "jdbc:" + dburi, mysql_username, mysql_password );
  }catch( Exception e ){
    e.printStackTrace();
  }

    :
    :

上記青字部分が指定している箇所です。useUnicode でユニコード指定を名言し、characterEncoding でそのエンコードを utf8 に指定しています。

この方法でコネクションを取得すると、読み書き時の文字化けを回避できました。まあ全ての文字化けのケースにこの方法が有効とはいえませんが、原因不明の文字化けが発生した際の回避方法の1つとして。