DB2の取扱い
- 基本情報
- データベース接続設定
- データ型マッピング
- 主キーでの自動採番
- ページング検索の条件
- 更新ロックの取得
- プロシージャ
- データベース依存機能
- DBMS独自の利用方法
- DBMS独自の注意点
- Exampleのススメ
- DBFlute内部での取扱い
- 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 に関しては、自動マッピング機能が利用可能です。
未サポートのデータ型
- 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;
}
別スキーマのプロシージャ
別スキーマのプロシージャもオプションで自動生成でき...*未検証
自動生成対象プロパティの有効項目
- 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 にした場合は、(自動)ページング処理の実現方式がポインタシフトではなくループスルーに変わります。
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),
...
)