目次 | 前の項目 | 次の項目 JDBCTM ガイド: 使用の開始


8 - SQL と Java の型のマッピング

この概要は、現在 Java ソフトウェアで作成中の『JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference』からの引用です。この本は JDBC の自習書であるとともに決定版リファレンスマニュアルで、1997 年春に Addison-Wesley Publishing Company から Java シリーズの一部として発行されています。

8.1    概要

SQL のデータ型は、Java のデータ型と同一ではないので、Java の型を使用するアプリケーションと SQL の型を使用するデータベースの間で、データを読み書きするためのなんらかの機構が必要です。

これを達成するために、JDBC は getXXX メソッドと setXXX メソッドのセット、メソッド registerOutParameter、およびクラス Types を用意しています。

この項では、さまざまなクラスやインタフェースに影響するデータ型についての情報をまとめ、SQL の型と Java の型の間のマッピングを示す一覧を参照しやすいように 1 箇所に置きました。

8.2    SQL のデータ型を Java にマッピングする

異なるデータベース製品がサポートする SQL の型の間には、相当な相違があります。異なるデータベースが同一の意味を持つ SQL の型をサポートしている場合でも、それらの型に異なる名前を与えていることがあります。たとえば、主要データベースのほとんどが大きなバイナリ値に対する SQL の型をサポートしていますが、Oracle ではこの型を LONG RAW、Sybase では IMAGE、Informix では BYTE、DB2 では LONG VARCHAR FOR BIT DATA とそれぞれ呼んでいます。

JDBC プログラマは、通常は、ターゲットのデータベースが使用している実際の SQL の型名に気を使う必要はありません。多くの場合、JDBC プログラマは、既存のデータベースのテーブルに対してプログラミングをし、そうしたテーブルを作成した正確な SQL の型名に注意を払う必要はありません。

JDBC は、クラス java.sql.Types で汎用的な SQL の型識別子のセットを定義しています。そのセットの型は、もっとも普通に使用される SQL の型を表すように設計されています。JDBC API によるプログラミングでは、プログラマは通常、ターゲットのデータベースが使用している正確な SQL の型名を意識することなく、そのセットの JDBC 型を使用して汎用的な SQL の型を参照することができます。それらの JDBC 型は、次項で詳しく説明します。

プログラマが SQL の型名を使用する必要があるのは、主に新しいデータベースのテーブルを作成する場合の SQL CREATE TABLE 文の中です。この場合には、プログラマは、そのターゲットのデータベースがサポートしている SQL の型名を使用するように注意する必要があります。特定のデータベースでのさまざまな SQL の型の動作の正確な定義を必要とする場合には、そのデータベースのマニュアルを参照することをお勧めします。

さまざまな異なるデータベース上でテーブルを作成できる移植性の高い JDBC プログラムを作成したい場合には、2 つの主な選択肢があります。1 つ目は、INTEGERNUMERIC、または VARCHAR のようなすべてのデータベースに対して稼動する可能性の高い、非常に広範囲で受け入れられている SQL の型名だけを使用するように制限することです。2 つ目の選択肢は、java.sql.DatabaseMetaData.getTypeInfo メソッドを使用して、どの SQL の型をそのデータベースが実際にサポートしているかを発見し、指定の JDBC 型に一致するデータベース固有の SQL の型名を選択することです。

JDBC は、JDBC データベース型から Java への標準マッピングを定義します。たとえば、JDBC INTEGER は通常、Java int にマッピングされます。これは、JDBC 値を単純な Java 型として読み書きする単純なインタフェースをサポートします。

Java の型は、SQL タイプと正確に同型である必要はありません。パラメータを正確に格納したり取り出したりし、SQL 文からの結果を復旧するのに十分な型の情報でそれらを表現できればよいだけです。たとえば、Java の String オブジェクトは、JDBC CHAR 型のどれにも厳密には一致しませんが、CHARVARCHAR、または LONGVARCHAR を正常に表現するのに十分な型情報を与えます。

8.3    JDBC の型

この項では、異なる JDBC の型とそれらがどのように標準的な SQL の型と Java の型にマッピングされるかを説明します。

8.3.1     CHAR、VARCHAR、および LONGVARCHAR

JDBC の型 CHARVARCHAR、および LONGVARCHAR は密接に関連しています。CHAR は短い固定長の文字列を、VARCHAR は短い可変長の文字列を、LONGVARCHAR は長い可変長の文字列をそれぞれ表します。

JDBC CHAR に対応する SQL CHAR 型は SQL-92 で定義され、すべての主要なデータベースによってサポートされています。文字列の長さを指定するパラメータを取ります。したがって、CHAR(12) は 12 文字長の文字列を定義します。すべての主要なデータベースは、CHAR 長を最高 254 文字までサポートしています。

JDBC VARCHAR に対応する SQL VARCHAR 型は SQL-92 で定義され、すべての主要なデータベースによってサポートされています。文字列の最大長を指定するパラメータを取ります。したがって、VARCHAR(12) はその長さが最高 12 文字長の文字列を定義します。すべての主要なデータベースは、VARCHAR の長さを最高 254 文字までサポートしています。文字列値が VARCHAR 変数に割り当てられると、データベースは割り当てられた文字列の長さを記憶し、それの SELECT 時に正確に元の文字列を返します。

JDBC LONGVARCHAR 型には、一貫した SQL マッピングが存在しません。すべての主要なデータベースは、少くとも 1 ギガバイトまでサポートする、ある種の非常に長い可変長の文字列をサポートしますが、SQL の型名は異なります。

Java のプログラマは、CHARVARCHAR、および LONGVARCHARの SQL 文字列の 3 つの型を区別する必要がありません。それぞれは Java の String として表現することができ、期待された正確なデータ型を知らなくても SQL 文を正しく読み書きすることができます。

CHARVARCHAR、および LONGVARCHAR は、String または char[] のどれにでもマッピングすることができますが、String の方が通常の使用のためにはより適切です。また、String クラスにより、Stringchar[] の間の変換がより簡単になります。String オブジェクトを char[] に変換するメソッドがあり、また char[]String オブジェクトに調整するコンストラクタもあります。

対処すべき問題の 1 つは、CHAR(n) 型の固定長 SQL 文字列をどのように処理するかです。最適なのは、JDBC ドライバ (または DBMS) が空白で適切なパディングを行うことです。したがって CHAR(n) フィールドがデータベースから取り出されたとき、ドライバがそれを長さが n の Java の String オブジェクトに変換しますが、これには末尾にパディングの空白がいくつか含まれている可能性があります。これとは逆に、String オブジェクトが CHAR(n) フィールドに送信されると、ドライバまたはデータベース、あるいはその両方が必要なパディング用空白を文字列の末尾に追加し、その長さを n にします。

メソッド ResultSet.getString は、新しい String オブジェクトを割り当てたり返したりしますが、データを CHARVARCHAR、および LONGVARCHAR フィールドから取り出すことをお勧めします。これは通常のデータを取り出すには適切ですが、JDBC の LONGVARCHAR 型を使用して何メガバイトかの文字列を格納する場合は扱いにくいことがあります。このようなケースを処理するために、LONGVARCHAR インタフェースの 2 つのメソッドにより、プログラマが LONGVARCHAR の値を任意のサイズの塊でシーケンシャルにデータを読み取れる Java 入力ストリームとして取り出すことができるようにしています。これらのメソッドは getAsciiStreamgetUnicodeStream で、LONGVARCHAR 列に格納されているデータを ASCII または Unicode 文字のストリームとして配信します。

8.3.2     BINARY、VARBINARY、および LONGVARBINARY

JDBC の型 BINARYVARBINARY、および LONGVARBINARY は密接に関連しています。BINARY は小さい固定長のバイナリ値を、VARBINARY は小さな可変長のバイナリ値を、LONGVARBINARY は大きな可変長のバイナリ値をそれぞれ表します。

以上の BINARY 型は標準化されておらず、サポートは主要なデータベース間で相当に変動します。

JDBC BINARY に対応する SQL BINARY 型は、非標準の SQL の拡張で、一部のデータベースに実装されているにすぎません。バイナリバイトの数を指定するパラメータを取ります。したがって、BINARY(12) は 12 バイトのバイナリ型を定義します。通常、BINARY 値は 254 バイトに限定されています。

JDBC VARBINARY に対応する SQL VARBINARY 型は、非標準の SQL の拡張で、一部のデータベースに実装されているにすぎません。バイナリ バイトの最大数を指定するパラメータを取ります。したがって、VARBINARY(12) はその長さの最大長が 12 バイトであるバイナリ型を定義します。通常、VARBINARY 値は 254 バイトに限定されています。バイナリ値が VARBINARY 変数に割り当てられると、データベースは割り当てられた値の長さを記憶し、それの SELECT 時に、元の値を正確に返します。

JDBC LONGVARBINARY 型に対応する一貫した SQL の型は存在しません。すべての主要なデータベースは、少くとも 1G バイトのデータをサポートする、ある種の非常に大きな可変長のバイナリ型をサポートしますが、その SQL の型名は異なります。

BINARYVARBINARY、および LONGVARBINARY は、Java ではバイト配列として、すべて同じように表現できます。要求されている BINARY データ型を正確に知らなくても、SQL 文を正しく読み書きできるため、Java プログラマがそれらの型を区別する必要はありません。

BINARYVARBINARY の値を取り出すために推奨されるメソッドは、ResultSet.getBytes です。JDBC LONGVARBINARY 型の列が、何メガバイト長ものバイト配列を格納している場合には、getBinaryStream メソッドをお勧めします。LONGVARCHAR の場合と同様に、このメソッドは Java プログラマが LONGVARBINARY 値を、あとでより小さな塊で読むことができる Java 入力ストリームとして取り出すことを可能にします。

8.3.3     BIT

JDBC 型 の BIT は、0 か 1 を取り得る単一のビット値を表します。

SQL-92 は、SQL BIT 型を定義します。しかし、JDBC BIT 型とは異なり、この SQL-92 BIT 型は、固定長のバイナリ列を定義するパラメータ化した型として使用することができます。SQL-92 は、単一のビットを表すのに単純な非パラメータ化 BIT 型の使用も許しています。この使用は、JDBC BIT 型に対応しています。SQL-92 BIT 型は、「完全な」 SQL-92 においてだけ要求され、現在、主要なデータベースの一部にしかサポートされていません。したがって、移植性を望むコードでは、広くサポートされている JDBC SMALLINT 型の方を使用することをお勧めします。

JDBC BIT 型に対して推奨される Java マッピングは、Java の boolean 型とするものです。

8.3.4     TINYINT

JDBC 型の TINYINT は、0 から 255 までの 8 ビットの符号なし整数値を表します。

対応する SQL の型の TINYINT は現在、主要なデータベースの一部でしかサポートされていません。したがって、移植性を望むコードでは、広くサポートされている JDBC SMALLINT 型の方を使用することをお勧めします。

JDBC TINYINT 型に対して推奨されている Java マッピングは、Java byte か Java short のどれかです。8 ビットの Java byte 型は -128 から 127 までの符号付きの値を表すので、より大きな TINYINT 値に対して常に適切になるとは限りません。ただし、16 ビットの Java short は常にすべての TINYINT 値を保持することができます。

8.3.5     SMALLINT

JDBC 型の SMALLINT は、-32768 から 32767 までの 16 ビットの符号付き整数値を表します。

対応する SQL の型の SMALLINT は SQL-92 で定義され、すべての主要がデータベースによってサポートされています。SQL-92 標準では、SMALLINT の精度を実装に任せていますが、実際には、すべての主要なデータベースは少なくとも 16 ビットをサポートしています。

JDBC SMALLINT 型に対して推奨される Java マッピングは、Java short とするものです。

8.3.6     INTEGER

JDBC 型の INTEGER は、-2147483648 から 2147483647 までの 32 ビットの符号付き整数値を表します。

対応する SQL の型の INTEGER は SQL-92 で定義され、すべての主要なデータベースによって広くサポートされています。SQL-92 標準では、 INTEGER の精度を実装に任せていますが、実際には、すべての主要なデータベースは少なくとも 32 ビットをサポートしています。

JDBC INTEGER 型に対して推奨される Java マッピングは、Java intとするものです。

8.3.7     BIGINT

JDBC 型の BIGINT は、-9223372036854775808 から 9223372036854775807 までの 64 ビットの符号付き整数値を表します。

対応する SQL の型の BIGINT は、SQL の 非標準の拡張です。実際、SQL BIGINT 型は、主要などのデータベースにも現在実装されていません。したがって、移植性を期待されるコードでは、その使用を避けることをお勧めします。

JDBC BIGINT 型に対して推奨される Java マッピングは、Java long とするものです。

8.3.8     REAL

JDBC 型の REAL は、7 桁の仮数部をサポートする「単精度」の浮動小数点数です。

対応する SQL の型の REAL は SQL-92 で定義され、すべての主要なデータベースによって、一般的ではありませんが、広くサポートされています。SQL-92 標準では、REAL の精度を実装に任せていますが、実際には、すべての主要なデータベースは少なくとも 7 桁の仮数精度をサポートしています。

JDBC REAL 型に対して推奨される Java マッピングは、Java float とするものです。

8.3.9     DOUBLE

JDBC 型の DOUBLE は、15 桁の仮数部をサポートする「倍精度」の浮動小数点数です。

対応する SQL の型は、DOUBLE PRECISION であり SQL-92 で定義され、すべての主要なデータベースによって、広くサポートされています。SQL-92 標準では、DOUBLE PRECISION の精度を実装に任せていますが、実際には、すべての主要なデータベースは少なくとも 15 桁の仮数精度をサポートしています。

JDBC DOUBLE 型に対して推奨される Java マッピングは、Java double とするものです。

8.3.10     FLOAT

JDBC 型の FLOAT は、基本的には JDBC 型の DOUBLE と等価です。FLOATDOUBLE の両方を提供したのは、以前のデータベースの API との一貫性を維持しようとしたためですが、混乱を起こす危険性が考えられます。FLOAT は、15 桁の仮数部をサポートする「倍精度」浮動小数点数です。

対応する SQL の型の FLOAT は SQL-92 で定義されています。SQL-92 標準では、FLOAT の精度を実装に任せていますが、実際には、FLOAT をサポートするすべての主要なデータベースは少なくとも 15 桁の仮数精度をサポートしています。

この FLOAT 型に対して推奨される Java マッピングは、Java double とするものです。ただし、倍精度の SQL FLOAT と単精度の Java float との間の混乱が予想されるため、JDBC プログラマは、通常の場合には、FLOAT よりも JDBC DOUBLE 型を使用することをお勧めします。

8.3.11     DECIMAL と NUMERIC

JDBC 型の DECIMALNUMERIC は非常に似ています。両方とも、固定精度の 10 進数を表します。

対応する SQL の型の DECIMALNUMERIC はSQL-92 で定義され、非常に広範囲に実装されています。この 2 つの SQL の型は、精度とスケールのパラメータを取ります。精度は、サポートされている 10 進数の総桁数で、スケールは、小数点以下の桁数です。スケールは常に、精度以下になる必要があります。したがって、たとえば、「12.345」の精度は 5 であり、スケールは 3 となります。「.11」の精度は 2 であり、スケールは 2 となります。JDBC は、すべての DECIMALNUMERIC の両方の型が、少なくとも 15 の精度とスケールをサポートすることを要求します。

DECIMALNUMERIC の唯一の相違は、SQL-92 仕様が、NUMERIC 型が正確に指定の精度で表現されることを要求する一方で、DECIMAL 型では、型の生成時に指定された精度を超えた精度を追加することを実装に許している点にあります。したがって、型の NUMERIC(12,4) で作成された列は、常に正確に 12 桁で表され、型の DECIMAL(12,4) で作成された列は、より大きな桁数で表されることもあります。

DECIMALNUMERIC の型に対して推奨される Java マッピングは、やはり絶対精度を持つ固定小数点数で表される Java 型の java.math.BigDecimal です。java.math.BigDecimal 型は、数学演算を可能として、BigDecimal 型を他の BigDecimal 型、整数型、および浮動少数点型と加減乗除することができます。

DECIMALNUMERIC の値を取り出すために推奨されるメソッドは、ResultSet.getBigDecimal です。JDBC はまた、単純な Strings または char の配列としてこれらの SQL の型へのアクセスを可能にします。したがって、Java プログラマは、getString を使用して NUMERIC または DECIMAL の結果を受け取ることができます。ただし、これにより、アプリケーションの作成者が文字列上で算術計算をすることが必要になるので、DECIMAL または NUMERIC を通貨の値として使用する一般的な場合が、むしろ扱いにくくなります。これらの SQL の型を Java の数値型のどれかとして取り出すことも可能です。

8.3.12     DATE、TIME、および TIMESTAMP

時間に関連する JDBC の型には以下の 3 つがあります。

標準の Java クラス java.util.Date は、これら 3 つの JDBCの date と time の型に正確には一致しないので (標準の Java クラスは DATETIME の情報はあるが、ナノ秒はない)、JDBC は java.util.Date の 3 つのサブクラスを定義して、SQL の型に対応しています。これらは以下のとおりです。

JDBC の 3 つの時間関連のクラスはすべて java.util.Date のサブクラスなので、java.util.Date が期待されている場所で使用することができます。たとえば、国際化メソッドは java.util.Date オブジェクトを引数として取るので、JDBC 時間関連クラスのどれかのインスタンスとして渡すことができます。

JDBC Timestamp オブジェクトには、その親の日付と時間の構成要素と、それとは別にナノ秒の構成要素もあります。java.util.Date オブジェクトが期待されている箇所で、java.sql.Timestamp オブジェクトを使用すると、ナノ秒の構成要素は失われます。ただし、java.util.Date オブジェクトが 1 ミリ秒の精度で格納されているので、321 java.sql.Timestamp オブジェクトを java.util.Date オブジェクトに変換したときにこの程度の精度を保つことは可能です。これは、ナノ秒構成要素の中のナノ秒を (ナノ秒の数値を 1,000,000 で割ることにより ) まったくのミリ秒に変換してから、結果を java.util.Date オブジェクトに加算します。999,999 ナノ秒まではこの変換によって失われますが、結果として生じる java.util.Date オブジェクトは 1 ミリ秒以内の誤差の精度を持ちます。

以下の部分的なコードは、1 ミリ秒以内の精度を持つ java.util.Date オブジェクト に java.sql.Timestamp オブジェクトを変換する例です。

    Timestamp t = new Timestamp(100, 0, 1, 15, 45, 29, 987245732);
    java.util.Date d;
    d = new java.util.Date(t.getTime() + (t.getNanos() / 1000000));

8.4    マッピングの例

Java プログラムがデータをデータベースから取り出すという状況では、必ずなんらかの形でマッピングとデータ変換が必要です。ほとんどの場合、JDBC プログラマは、自分が対象としているデータベースの仕組みについての知識を持っています。たとえば、データベースにどのようなテーブルがあり、それらのテーブルの各列のデータ型が何かを知っています。したがって、ResultSetPreparedStatement、および CallableStatement のインタフェースで固定的に入力したアクセスメソッドを使用することができます。この項では、3 つの異なるシナリオを示すとともに、それぞれで必要なデータのマッピングと変換について説明します。

8.4.1    簡単な SQL 文

もっとも一般的なケースでは、ユーザが簡単な SQL 文を実行して、結果を持つ ResultSet オブジェクトを受け取ります。データベースが返し、ResultSet 列に格納される値は、JDBC のデータ型を持っています。ResultSet.getXXX メソッドへの呼び出しは、その値を Java のデータ型として取り出します。たとえば、ResultSet 列に JDBC の FLOAT 値が入っている場合、メソッド getDouble はその値を Java の double として取り出します。8.6.6 項の一覧は、どの getXXX メソッドがどの JDBC の型を取り出すために使用されるかを示します。ResultSet 列の型がわからないユーザは、メソッド ResultSet.getMetaData を呼び出してから、ResultSetMetaData メソッド getColumnType または getColumnTypeName を起動することにより、その情報を取得することができます。以下のコードの一部分は、結果セットの列の列タイプ名の取得方法を示します。

    String query = "select * from Table1";
    ResultSet rs = stmt.executeQuery(query);
    ResultSetMetaData rsmd = rs.getMetaData();
    int columnCount = rsmd.getColumnCount();
    for (int i = 1; i <= columnCount; i++)  {
      String s = rsmd.getColumnTypeName(i);
      System.out.println ("Column " + i + " is type " + s);
    }

8.4.2    IN パラメータの付いた SQL 文

もう 1 つのシナリオでは、ユーザが入力パラメータを取る SQL 文を送信します。この場合、ユーザは PreparedStatement.setXXX メソッドを呼び出して、各入力パラメータに値を割り当てます。たとえば、PreparedStatement.setLong(1, 2345678) は、最初のパラメータに 2345678 という値を Java の long として割り当てます。ドライバは、データベースに送信するために、2345678 を JDBC の BIGINT に変換します。ドライバがデータベースにどの JDBC の型を送信するかは、Java の型から JDBC の型への標準マッピングによって決定されます。この標準マッピングは、8.6.2 項の一覧に示されています。

8.4.3    INOUT パラメータの付いた SQL 文

さらにもう 1 つのシナリオでは、ユーザがストアドプロシージャを呼び出し、値をその INOUT パラメータに割り当て、結果から値を取り出し、パラメータから値を取り出します。このケースはあまり一般的ではなく、通常の場合より複雑ですが、マッピングとデータ変換の好例となるでしょう。

このシナリオではまず、PreparedStatement.setXXX メソッドを使用して、INOUT パラメータに値を割り当てます。加えて、パラメータも出力に使用されるので、プログラマは各パラメータをデータベースが返す値の JDBC 型で登録する必要があります。これは、クラス Types に定義された JDBC の型の 1 つを取るメソッド CallableStatement.registerOutParameter を使って行います。プログラマは、ResultSet.getXXX を使用して、ResultSet オブジェクトに返された結果を取り出し、CallableStatement.getXXX メソッドを使用して出力パラメータに格納された値を取り出します。

ResultSet.getXXX で使用される XXX 型は、場合によってはかなり柔軟です。8.6.6 項の一覧は、どの JDBC タイプを取り出すのに、どの ResultSet.getXXX メソッドを使用できるかを示します。

CallableStatement.getXXX で使用される XXX 型は、そのパラメータに登録された JDBC の型にマッピングする必要があります。たとえば、データベースが、JDBC REAL というタイプの出力値を返すと期待されている場合、パラメータはjava.sql.Types.REAL として登録されている必要があります。次に JDBC REAL 値を取り出すためには、メソッドCallableStatement.getFloat を呼び出す必要があります。JDBC の型から Java の型へのマッピングは、8.6.1 項の一覧に示されています。 メソッド getFloat は、出力パラメータに格納されている値を JDBC REAL から Java float に変換してから返します。多様なデータベースに対応し、アプリケーションの移植性を高めるために、値を出力パラメータから取り出す前に、値を ResultSet オブジェクトから取り出すことをお勧めします。

以下のコードは、ともに INOUT パラメータが 2 つ付いた getTestData という名前のストアドプロシージャを呼び出す方法を示します。まず、Connection オブジェクト con が、CallableStatement オブジェクト cstmt を作成します。次に、メソッド setByte が最初のパラメータに Java byte25 を設定します。ドライバは、25 を JDBC TINYINT に変換し、データベースに送信します。メソッド setBigDecimal が、2 番目のパラメータを 83.75 という入力値に設定します。ドライバは、この java.math.BigDecimal オブジェクトを JDBC NUMERIC の値に変換します。次に、2 つのパラメータが OUT パラメータとして登録され、最初のパラメータが JDBC TINYINT、2 番目のパラメータが小数点第 2 位までを持つ JDBC DECIMAL になります。cstmt が実行されると、ResultSet.getXXX を使用して値が ResultSet オブジェクトから取り出されます。メソッド getString は最初の列の値を Java String オブジェクトとして取得し、getInt は 2 番目の列の値を Java int として取得し、getInt は 3 番目の列の値を Java int として取得します。

次に、CallableStatement.getXXX メソッドが、出力パラメータに格納された値を取り出します。メソッド getByteJDBC TINYINT を Java byte として取り出し、getBigDecimal が小数点第 2 位までを持つ JDBC DECIMAL を、java.math.BigDecimal オブジェクトとして取り出します。パラメータが入出力パラメータの場合、setXXX メソッドは getXXX と同じ Java 型のものを使用します (setByte および getByte と同様)。registerOutParameter メソッドは、それを Java の型からマッピングされる JDBC の型に登録します。byte は、8.6.2 項の一覧で示されるように、JDBC TINYINT にマッピングされます。

    CallableStatement cstmt = con.prepareCall(
          "{call getTestData(?, ?)}");
    cstmt.setByte(1, 25);
    cstmt.setBigDecimal(2, 83.75);
    // register the first parameter as a JDBC TINYINT and the second
    //parameter as a JDBC DECIMAL with two digits after the decimal point
    cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
    cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 2);
    ResultSet rs = cstmt.executeUpdate();
    // retrieve and print values in result set
    while(rs.next()) {   
      String name = rs.getString(1);
      int score = rs.getInt(2);
      int percentile = rs.getInt(3);
      System.out.print("name = " + name + ", score = " + score + ", "
      System.out.println("percentile = " + percentile);          
    // retrieve values in output parameters  
    byte x = cstmt.getByte(1); 
    java.math.BigDecimal n = cstmt.getBigDecimal(2, 2); 
一般化すると、CallableStatement.getXXXXXXPreparedStatement.setXXX メソッドは Java の型です。setXXX メソッドについては、データベースに送信する前に、(8.6.2 項の一覧中の標準マッピングを使用して) ドライバが Java の型を JDBC の型に変換します。getXXX メソッドについては、getXXX メソッドに返される前に、データベースによって返された SQL の型をドライバが (8.6.1 項の一覧中の標準マッピングを使用して) Java の型に変換します。

メソッド registerOutParameter は常に、JDBC の型を引数として取り、メソッド setObject は JDBC の型を引数として取ります。

オプションの 3 番目の引数に、JDBC の型が供給される場合、メソッド setObject により、パラメータの値が Java の型から指定された JDBC の型に明示的に変換されることに注意してください。変換後の JDBC の型が setObject に供給されていない場合は、パラメータ値は Java の型からの標準マッピングの JDBC の型に変換されます ( 8.6.2 項の一覧を参照)。ドライバは、パラメータをデータベースに送信する前に、明示的または暗黙的な変換を行います。

8.5    動的データアクセス

ユーザがアクセスしたいのは、コンパイル時にそのデータ型がわかっている結果またはパラメータである場合がほとんどです。ただし、汎用的なブラウザまたはクエリーツールなどのアプリケーションは、アクセスするデータベーススキーマを知らない状態でコンパイルされます。このため、JDBC では静的データアクセスに加えて、完全に動的なデータアクセスもサポートしています。

3 つのメソッドと 1 つの定数が、コンパイル時にデータ型が不明な値にアクセスするのを支援します。

たとえば、アプリケーションが、さまざまな型を ResultSet オブジェクトの中で結果として受け付けることを可能にしたい場合には、ResultSet.getObject を使用することができます。

ResultSet.getObjectCallableStatement.getObject の両メソッドは Java Object として値を取り出します。Object は、すべての Java オブジェクトに対する基礎クラスなので、任意の Java クラスのインスタンスは Object のインスタンスとして取り出すことが可能です。ただし、Java の型 booleancharbyteshortintlongfloat、および double は、組込み型の「プリミティブ」型なので、Object クラスのインスタンスにはなりません。結果として、以上の型は、getObject メソッドでは取り出すことができません。ただし、それらのプリミティブ型には、ラッパーとして稼動する、それぞれに対応するクラスがあります。それらのクラスのインスタンスはオブジェクトであり、すなわち、ResultSet.getObjectCallableStatement.getObject の両メソッドによって取り出すことが可能になります。8.6.3 項の一覧は、JDBC 型から Java Object 型へのマッピングを示します。この一覧は、JDBC 型から Java 型への標準マッピングとは異なり、各プリミティブの Java 型はそのラッパークラスが取って代わります。ただし、JDBC TINYINT と JDBC SMALLINT は、Java クラスの Integer にマッピングされます。

メソッド getObject は、ユーザ定義の Java の型を取り出すのにも使用できます。抽象データ型 (ADT)、または一部のデータベース システムのその他のユーザ定義の型の出現によって、一部のベンダーがこれらの型を取り出すときに getObject を使用する方が便利であるとみなす場合もあります。

8.6    データ型のマッピング一覧

この項には、JDBC と Java のデータの型に関連する以下の一覧を記載します。

8.6.1 項 - Java の型にマッピングされる JDBC の型

8.6.2 項 - JDBC の型にマッピングされる Java の型

8.6.3 項 - Java のオブジェクト型にマッピングされる JDBC の型

8.6.4 項 - JDBC の型にマッピングされる Java のオブジェクト

8.6.5 項 -setObject による変換

8.6.6 項 - ResultSet.getXXX メソッドにより取り出される JDBC の型

8.6.1    Java の型にマッピングされる JDBC の型

JDBC の型 Java の型
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp

8.6.2    JDBC の型にマッピングされる Java の型

以下の一覧は、一覧 8.6.1 とは逆に、Java の型から JDBC の型へのマッピングを示します。

Java の型 JDBC の型
String VARCHAR または LONGVARCHAR
java.math.BigDecimal NUMERIC
boolean BIT
byte TINYINT
short SMALLINT
int INTEGER
long BIGINT
float REAL
double DOUBLE
byte[] VARBINARY または LONGVARBINARY
java.sql.Date DATE
java.sql.Time TIME
java.sql.Timestamp TIMESTAMP

文字列のマッピングは通常 VARCHAR ですが、値が VARCHAR の値に対するドライバの限界を超えている場合は、LONGVARCHAR になります。byte[]VARBINARY、および LONGVARBINARY の値についても同様です。

8.6.3    Java のオブジェクト型にマッピングされる JDBC の型

booleanint のような Java の組み込み型は Object のサブタイプでないため、getObject/setObject メソッドについての JDBC の型から Java のオブジェクト型へのマッピングには、多少の違いがあります。このマッピングは以下の一覧に示します。

JDBC の型 Java のオブジェクト型
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT Boolean
TINYINT Integer
SMALLINT Integer
INTEGER Integer
BIGINT Long
REAL Float
FLOAT Double
DOUBLE Double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp

8.6.4    JDBC の型にマッピングされる Java のオブジェクト型

Java のオブジェクト型 JDBC の型
String VARCHAR または LONGVARCHAR
java.math.BigDecimal NUMERIC
Boolean BIT
Integer INTEGER
Long BIGINT
Float REAL
Double DOUBLE
byte[] VARBINARY または LONGVARBINARY
java.sql.Date DATE
java.sql.Time TIME
java.sql.Timestamp TIMESTAMP

String に対するマッピングは通常 VARCHAR ですが、値が VARCHAR 値に対するドライバの限界を超えている場合は、 LONGVARCHAR になることに注意してください。byte[]VARBINARY、および LONGVARBINARY の値についても同様です。

8.6.5    setObject による変換

メソッド setObject は Java オブジェクトの型を JDBC の型に変換します。

  T
I
N
Y
I
N
T
S
M
A
L
L
I
N
T
I
N
T
E
G
E
R
B
I
G
I
N
T
R
E
A
L
F
L
O
A
T
D
O
U
B
L
E
D
E
C
I
M
A
L
N
U
M
E
R
I
C
B
I
T
C
H
A
R
V
A
R
C
H
A
R
L
O
N
G
V
A
R
C
H
A
R
B
I
N
A
R
Y
V
A
R
B
I
N
A
R
Y
L
O
N
G
V
A
R
B
I
N
A
R
Y
D
A
T
E
T
I
M
E
T
I
M
E
S
T
A
M
P
String x x x x x x x x x x x x x x x x x x x
java.math.BigDecimal x x x x x x x x x x x x x            
Boolean x x x x x x x x x x x x x            
Integer x x x x x x x x x x x x x            
Long x x x x x x x x x x x x x            
Float x x x x x x x x x x x x x            
Double x x x x x x x x x x x x x            
byte[]                           x x x      
java.sql.Date                     x x x       x   x
java.sql.Time                     x x x         x  
java.sql.Time- stamp                     x x x       x x x

Java のオブジェクト型から JDBC の型への変換

8.6.6     ResultSet.getXXX メソッドにより取り出される JDBC の型

「x」は、メソッドが SQL の型を取り出すことが「可能であること」を意味します。「X」は、そのメソッドが SQL の型として「推奨されていること」を意味します。

  T
I
N
Y
I
N
T
S
M
A
L
L
I
N
T
I
N
T
E
G
E
R
B
I
G
I
N
T
R
E
A
L
F
L
O
A
T
D
O
U
B
L
E
D
E
C
I
M
A
L
N
U
M
E
R
I
C
B
I
T
C
H
A
R
V
A
R
C
H
A
R
L
O
N
G
V
A
R
C
H
A
R
B
I
N
A
R
Y
V
A
R
B
I
N
A
R
Y
L
O
N
G
V
A
R
B
I
N
A
R
Y
D
A
T
E
T
I
M
E
T
I
M
E
S
T
A
M
P
getByte X x x x x x x x x x x x x            
getShort x X x x x x x x x x x x x            
getInt x x X x x x x x x x x x x            
getLong x x x X x x x x x x x x x            
getFloat x x x x X x x x x x x x x            
getDouble x x x x x X X x x x x x x            
getBigDecimal x x x x x x x X X x x x x            
getBoolean x x x x x x x x x X x x x            
getString x x x x x x x x x x X X x x x x x x x
getBytes                           X X x      
getDate                     x x x       X   x
getTime                     x x x         X x
getTimestamp                     x x x       x   X
getAsciiStream                     x x X x x x      
getUnicodeStream                     x x X x x x      
getBinaryStream                           x x X      
getObject x x x x x x x x x x x x x x x x x x x



目次 | 前の項目 | 次の項目
jdbc@wombat.eng.sun.com または jdbc-odbc@wombat.eng.sun.com
Copyright (C) 1996, 1997 Sun Microsystems, Inc. All rights reserved.