[???] / [Java FAQ] / [S134]
S134: JDBC(日本語の扱い)

[S134-Q01]
Back
JDBCドライバを使って、データベースと日本語データをやりとりするには? [S134-A01] 日本語対応のJDBCドライバを使用することにより、特に問題なく日本語 データを取り扱うことができます。 JDK付属のJDBCドライバとしては、JDK1.2に付属のJDBC-ODBCブリッジ ドライバは日本語に対応しています。 JDK1.1に付属のJDBC-ODBCブリッジドライバでは、日本語データを正しく 扱えないことが確認されています。 日本語対応していないJDBCドライバを使用する場合は、S134-03 を参 照してください。 また、次のURLは大変参考になるので、一度目を通すことをお薦めします。 http://ux01.so-net.ne.jp/~kikuta/jdbcnote/jdbcnote.html
[S134-Q02]
Back
JDBCドライバで日本語名のテーブルにアクセスするにはどうすれば? [S134-A02] 日本語で定義したテーブル名、フィールド名をSQL文の文字列内で 指定する時には ESC文字+ダブルクォーテーションマークで囲むよう にします。 例) int id = 1002003004; String name = "'にっぽん たろう'"; String sqltxt ="INSERT INTO \"日本語 テーブル\"" + "(\"ID Number\",\"氏 名\") "+ "VALUES("+id+","+name+")"; 日本語に対応しているJDBCドライバを用いている場合はこれだけ でアクセスできます。なお、この方法については、次の環境で確認 がされています。JDKのバージョンはJDK1.2以降です。 PostgreSQL 6.5.2 + Linux sun.jdbc.odbc.JdbcOdbcDriver(JDK1.3版)+Access97+Windows95 Oracle JDBC V8.0.5.0.4(Thin) classes111.zip+Oracle8+SunOS 日本語に対応していないJDBCドライバを用いている場合は、SQL 文を変換する必要があるでしょう。S134-03 を参考にして下さ い。
[S134-Q03]
Back
日本語化されていないJDBCドライバを使って、データベースと日本語 データをやりとりするには? [S134-A03] これから開発を始めるのであれば、日本語化されているJDBCドライ バを使いましょう。 日本語化されていないJDBCドライバを使わざるを得ない場合は、次を 参考にして下さい。 -- JDK1.1以降を使用する場合 日本語化されていないJDBCドライバで日本語のデータをやりとりす るのに保証された方法はありません。経験的に、次のようにすると 扱えることがわかっています。 * http://ux01.so-net.ne.jp/~kikuta/jdbcnote/jdbcnote.html を 参考にさせていただきました。 (検索) 1.ストリームを使う ResultSet rs = stmt.executeQuery(query); InputStreamReader isr = new InputStreamReader( rs.getAsciiStream(index) ); BufferedReader in = new BufferedReader(isr); StringWriter sw = new StringWriter(); try { int c; while((c = in.read()) != -1) sw.write(c); in.close(); } catch (IOException e){ } String result = sw.toString(); 2.StringクラスのgetBytes()メソッドを使う ResultSet rs = stmt.executeQuery(query); String s = rs.getString(index); try { String result = new String(s.getBytes("8859_1")); } catch (IOException e){ } どちらも、検索した日本語データがresultに入ります。 (挿入・更新・削除) String sqltxt ="INSERT INTO \"日本語 テーブル\"" + "(\"ID Number\",\"氏 名\") "+ "VALUES("+id+","+name+")"; sqltxt = new String(sqltext.getBytes("SJIS"),"8859_1"); int num = stmt.executeUpdate(sqltxt); * なぜ、これでうまくいくのでしょう? JDBC-ODBCブリッジドライバを使っていて、ODBCドライバでは 文字列型のデータを Shift-JISコードのバイト列として扱って いるとします。 このとき、"漢字OK"という文字列のバイトデータは 1バイトず つ16進数で表現すると、次のようになります。 8A BF 8E 9A 4F 4B このバイトデータを ResultSet.getString()で取り出すと、日 本語に対応していないJDBCドライバは、 1バイトデータを Uni- codeに変換する処理を行い、2バイトの上位バイトに0x00を、 下位バイトに 1バイトのデータを埋め込みます。 0x008A, 0x00BF, 0x008E, 0x009A, 0x004F, 0x004B したがって、この Unicode文字列をISO 8859-1でエンコーディ ングし、8A BF 8E 9A 4F 4B に戻し、これを Shift-JISコード のバイト列から Unicode文字列に変換してあげれば良いのです。 挿入・更新・削除の場合は SQL文全体に対してこの逆の操作を 行っているのです。 * これらの方法の問題点: 日本語に対応していないJDBCドライバについて、次のような前 提を置いていることです。 ・データ更新時には Unicode文字列の上位 1バイトを無条件 で削除する。 ・問い合わせ時には上位1バイトに無条件で0x00を、下位 1 バイトに 1バイトのデータを埋め込んだ作ったバイト列を Unicode文字列として返す。 さらに詳細を知りたい場合は、 http://java-house.etl.go.jp/ml/archive/j-h-b/011682.html#body を参考にして下さい。 -- JDK1.0.2を使用する場合 JDBCドライバの状況はJDK1.1を使用する場合と同様です。ただ し、String型データのエンコーディングを指定するメソッドが 提供されていませんので、この機能を自作する必要があります。
[S134-Q04]
Back
日本語対応していないJDBCドライバを使うときに、どうやって指定する文字 のエンコーディングを決めるのですか? [S134-A04] 基本的には、JDBCドライバと通信するプログラムが動作するプラットフォー ムに合わせて決めます。 JDBCドライバのタイプごとに、指針を示します。 ClientとServerが接続している部分を -|- と表記します。 1.Type1(JDBC-ODBC Bridge) Java Program - JDBC - ODBC -|- DB Server ODBCがサポートしている文字コードを指定します。 例えば、Java ProgramをWindowsで動かす場合は、次のようになります。 Windows95 | WindowsNTなど Java Program - JDBC - ODBC -|- DB Server (Unicode) (SJIS) (自動) ODBC -|- DB Server の部分では、Middlewareが入る場合もありますが、 通常は Middlewareでの文字コードの変換は自動的に対応してくれるはず なので省略します。 例えば、OracleとSQL*Netを使った場合は、次のようになります。 Windows95 | Solaris Java Program - JDBC - ODBC - SQL*Net -|- SQL*Net - Oracle (Unicode) (SJIS) (SJIS) (自動) (EUC) 2.Type2 Java Program - JDBC - Middleware -|- Middleware - DB Server Middlewareがサポートしている文字コードを指定します。 例えば、Java ProgramをWindows95で動かし、DB ServerをSolarisで動か す場合は、次のようになります。 Windows95 | Solaris Java Program - JDBC - Middleware -|- Middleware - DB Server (Unicode) (SJIS) (自動) (EUC) 3.Type3 Java Program - JDBC -|- Middleware - DB Server JDBCとMiddlewareの性能によって変わるはずです。通常は、Type4と 同様に考えれば良いと思います。 4.Type4 Java Program - JDBC -|- DB Server DB Server がどの文字コードを前提として動作しているかを調べ、そ の文字コードを指定します。 例えば、Java ProgramをWindows95で動かし、EUCの文字コードを前提 として動作しているSolaris上のDB Serverと接続する場合は、次のよ うになります。 Windows95 | Solaris Java Program - JDBC -|- DB Server (Unicode) (EUC) Web (Three Tier Architecture) System などでも、上記の考え方を あてはめれば、想像がつくはずです。 例えば、Web BrowserをWindows95で動かし、Windows NT上のServlet を通して、EUCの文字コードを前提として動作しているSolaris上の DB Serverとデータのやりとりをする場合は、次のようになります。 Windows95 | Windows NT | Solaris Web Browser -|- Web Server+Servlet - JDBC -|- DB Server (SJIS) (Unicode) (EUC)
[S134-Q05]
Back
Oracleの表のLONG型の列に、ある日本語コードのテキストデータを入れたいのですが? [S134-A05] 通常のカラムとしてデータを設定してみましょう。 JDK1.1のJDBCの仕様ではストリームを通して正しい国際化処理を期待 するのは無理です。setUnicodeStream(), setAsciiStream()などのス トリームを使うと,データベース内のデータは文字化けしてしまいま す。

Back
contributor: KOYAMA. Hiroshi
コメントの送り先:Java FAQ BBS