DB2の取扱い

基本情報

対応バージョン
DB2 8 以上
JDBCドライバの同梱
なし
(推奨)JDBCドライバ
db2jcc.jar (Exampleで利用)

データベース接続設定

データベース接続設定(databaseInfoMap.dfprop)について。

データベース接続設定の仕様 @databaseInfoMap.dfprop
map:{
    ; driver = com.ibm.db2.jcc.DB2Driver
    ; url      = jdbc:db2://[host]:[port]/[dbname]
    ; schema   = [SCHEMA]
    ; user     = [dbuser]
    ; password = [dbpassword]
}
  • catalog はURLから自動判別されるため設定不要
  • schema は大文字で指定
  • [xxx]の[]は単なる表現上(ドキュメント上)の囲み

以下、実際のExampleプロジェクトでの設定例です。

e.g. dbflute-db2-exampleの場合 {host=localhost,port=50000} @databaseInfoMap.dfprop
map:{
    ; driver   = com.ibm.db2.jcc.DB2Driver
    ; url      = jdbc:db2://localhost:50000/dfexdb
    ; schema   = DFEXDB
    ; user     = db2admin
    ; password = ...
}

データ型マッピング

データベース上のデータ型とプログラム型との(デフォルトの)マッピングについて。

java.lang.String
CHAR, VARCHAR, CLOB, DBCLOB
java.lang.Integer
SMALLINT, INTEGER, {DECIMAL(1-9, 0)}
java.lang.Long
BIGINT, {DECIMAL(10-18, 0)}
java.math.BigDecimal
FLOAT, DOUBLE, REAL, DECIMAL(n, m)
java.util.Date
DATE
java.sql.Time
TIME
java.sql.Timestamp
TIMESTAMP
byte[]
BLOB

自動マッピング

DECIMAL に関しては、自動マッピング機能が利用可能です。

現場フィット - NUMERICの自動マッピング

未サポートのデータ型

GRAPHIC
*未検証
VARGRAPHIC
*未検証
LONG VARGRAPHIC
*未検証
...CHAR FOR BIT DATA
byte[]にマッピングされるが...*未検証

主キーでの自動採番

自動採番(連番)の仕組みとして シーケンスIdentity のどちらかを利用します。

Identity情報はメタデータから取得できるので、設定なしで利用可能です。

ページング検索の条件

row_number() 関数を利用します。

ConditionBeanのPaging

e.g. ConditionBeanでページング検索 {81-100} @DisplaySql
select *
  from (
select plain.*, row_number() over() as rn
  from (
select ...
  from ...
 where ...
 order by ...
       ) plain
       ) ext
 where ext.rn > 80
   and ext.rn <= 100

OutsideSqlのManualPaging

e.g. OutsideSqlのManualPagingでページング検索 {81-100} @OutsideSql
/*IF pmb.isPaging()*/
select *
  from (
select plain.*, row_number() over() as rn
  from (
select ...
-- ELSE select count(*)
/*END*/
  from ...
 where ...
 /*IF pmb.isPaging()*/
 order by ...
       ) plain
       ) ext
 where ext.rn > /*pmb.pageStartIndex*/80
   and ext.rn <= /*pmb.pageEndIndex*/100
 /*END*/

TypedParameterBean における ManualPaging の自動判別ロジックは、"row_number()" という文字列が含まれることです。(大文字小文字は区別せず)

更新ロックの取得

ConditionBean の lockForUpdate() では、for update with RS を利用します。

e.g. ConditionBeanで更新ロックの取得 (cb.lockForUpdate()) @DisplaySql
select ...
  from MEMBER dfloc
 where ...
   and ...
 for update with RS

プロシージャ

ストアドプロシージャ を(DBFluteの機能としての)プロシージャとしてサポートしています。

(ストアドファンクション *未検証)

INパラメータ
サポート
OUTパラメータ
サポート
INOUTパラメータ
サポート
プロシージャリターン
サポート (*1)
ResultSetパラメータ
DBMSにて未サポート
ResultSetリターン
DBMSにて未サポート
NotParamResult
サポート
パッケージプロシージャ
DBMSにて未サポート ※そもそもパッケージの概念なし
プロシージャシノニム
DBMSにて未サポート ※エリアスはプロシージャで利用不可

*1: プロシージャリターンの有無の情報がメタデータから取得できないため、ProcedurePmb のプロシージャリターン対応のプロパティは、Exクラスに手動で作成する必要があります。PROCEDURE_PARAMETER の定数アノテーションは、"return, -1" という固定値を指定します。

e.g. ProcedurePmbのExクラスでプロシージャリターンのプロパティを手動で定義 {returnValue} @Java
public static final Integer returnValue_PROCEDURE_PARAMETER = "return, -1";
protected Integer _returnValue;
public Integer getReturnValue() {
    return _returnValue;
}
public void setReturnValue(Integer returnValue) {
    _returnValue = returnValue;
}

別スキーマのプロシージャ

別スキーマのプロシージャもオプションで自動生成でき...*未検証

別スキーマ(AdditionalSchema)

自動生成対象プロパティの有効項目

Catalog
利用不可 (メタデータとしてカタログ名が取得できないため)
Schema
サポート
Name
サポート

データベース依存機能

データベース依存機能を有効にした場合の利用可能な機能について。

分離レベルに応じてロックの方法を変更する

分離レベルによってロックの方法を変更することが出来ます。

反復可能読み取り(RR)、読み取り固定(RS)、カーソル固定(CS)、非コミット読み取り(UR)のいずれかを指定することができます。

e.g. selectした行を反復可能読み取り(RR)でロック @Java
cb.lockWithRR();
// select ... for update with RR

DBMS独自の利用方法

ALIAS(別名)の利用

databaseInfoMap.dfprop の variousMap の objectTypeTargetList に ALIAS を追加することで、自動生成対象にすることができます。

テーブル参照のALIAS自動生成の特徴

  • 通常のテーブルと全く同じようにプログラム上で扱うことができる
  • ALIASのメタデータ(PK、FK、UQなど)を完全サポート (参照先テーブルから取得)
  • ALIASの参照先テーブル自体は(直接利用しないなら)自動生成対象から除外してもよい
  • FK先テーブルにALIASがある場合はそのALIASの方に対して(のみ)関連が作成される

プロシージャ参照のALIAS

DB2は、プロシージャのALIASをサポートしていません。

別スキーマの利用

別スキーマのテーブルを自動生成できます。 但し、DB2自体にはデータベースという概念はありますが、JDBCにおけるカタログをサポートしていないため(メタデータとしてカタログ名が取得できないため)、 別カタログ(別データベース)のスキーマは自動生成できません

但し、ALIAS が利用できる環境であれば、別スキーマのテーブルを参照する ALIAS を自動生成対象に含めることで代替することができます。 ALIAS であれば、外だしSQL(OutsideSql)でもSQL上のテーブルのスキーマ修飾を意識する必要がありません。

DBMS独自の注意点

NullsFirst/Lastの実現

nulls first/last 構文をサポートしていないため、case when 構文を使って NullsFirst/Last を実現しています。union 句での case when 構文がサポートされないため、UnionQuery と NullsFirst/Last を合わせてることはできません。 (また、パフォーマンス上の懸念が多少あるので、大量データのときには注意して下さい)

BLOB、CLOBを使う場合の注意点

DB2のJDBCドライバでは、ResultSetType が ScrollInsensitive、ScrollSensitive の場合に BLOB、CLOB が取得できません。

DBFluteのデフォルトは ForwardOnly ですが 外だしSQLの自動ページング(AutoPaging)では ScrollInsensitive が(デフォルトで)利用されますので、外だしSQLで BLOB、CLOB をページング検索するときは、手動ページング(ManualPaging)を利用するか、StatementConfig で ForwardOnly に設定して検索するようにして下さい。但し、ForwardOnly にした場合は、(自動)ページング処理の実現方式がポインタシフトではなくループスルーに変わります。

OutsideSql - configure() (StatementConfig)

Exampleのススメ

DB2 を使ったExample実装 (テスト環境) があります。

DBFlute内部での取扱い

DBFlute内部でどのようにDB2と付き合っているか、特殊なパターンを挙げます。 将来的に同じ状況・同じ方法かどうかは保証されませんので、ここに書かれることに依存した利用はしないようにして下さい。 (DBFluteを深く理解するためのドキュメントと思って下さい)

Identity(always)のメタデータ
通常、Identityはテーブルとの関連がJDBCのメタデータとして取得できるので、明示的な設定は不要なのですが、DB2の "generated always as identity" を利用するとメタデータが取得できないため、DBFlute内部でDB2のスキーマ情報テーブルを直接検索して情報を補完しています。
全角の "%" や "_" もワイルドカード
DB2は、全角の "%" や "_" もワイルドカードとして扱われるため、曖昧検索のエスケープ処理にて、これらも対象としています。 但し、DBMSごとの分岐がとてもしづらい部分での処理のため、DBMSに関わらずエスケープしています。 (全角をワイルドカードにしない他のDBMSでは単にエスケープ文字が無視されるだけで、動作に問題ないことはテストで確認されている)

DB2補足資料

シーケンスを作成

e.g. シーケンスを作成 {SEQ_MEMBER} @SQL
create sequence SEQ_MEMBER as INT start with 1 increment by 1

シーケンスを取得

e.g. シーケンスを取得 {SEQ_MEMBER} @SQL
values nextval for SEQ_MEMBER

Identity設定

e.g. Identity設定 {MEMBER_IDにIdentity(by default)} @SQL
create table MEMBER(
    MEMBER_ID int generated by default as identity NOT NULL PRIMARY KEY,
    MEMBER_NAME VARCHAR(200),
    ...
)
e.g. creaet文でIdentity設定 {MEMBER_IDにIdentity(by always)} @SQL
create table MEMBER(
    MEMBER_ID int generated by always as identity NOT NULL PRIMARY KEY,
    MEMBER_NAME VARCHAR(200),
    ...
)