DBFluteConfig

DBFluteConfigとは?

アプリケーション実行時にDBFluteのランタイム環境を調整するコンフィグです。

DBFluteプロパティとは違い、設定ファイルではなく、allcommon配下に自動生成されるシングルトンのクラスとなっています。 自動生成時に(挙動を)固定してしまうのではなく、アプリケーションの実行環境で柔軟に切り替えられるようにするためです。

e.g. DBFluteConfigインスタンスの取得 @Java
DBFluteConfig config = DBFluteConfig.getInstance();

様々なコンフィグが用意されていて、それぞれのメソッドで設定を行うことができます。 おいそれと変更してはいけないプロパティがオンパレードなため、 設定するときは必ず設定前にロックを解除し、設定後にロックを掛けるという微妙に面倒な作業と共にすることを習慣としています。

e.g. DBFluteConfigで queryTimeout の設定 {300秒} @Java
DBFluteConfig config = DBFluteConfig.getInstance();
config.unlock();
config.setDefaultStatementConfig(new StatementConfig().queryTimeout(300));
config.lock();

初期化される前に設定すること

DBFluteが初期化される前(DIコンテナが初期化される前)に設定されることが大前提 であり、それ以降の設定は推奨されません。(DBFluteの初期化が終わると、ロックし忘れを防止するために自動的にロックが掛けられます)

どうしてもアプリ稼働途中で変更をしたいというような場面がある場合は、 ソースをしっかり読んで挙動を確認し、十分テストした上で利用することが求められます。

どこで設定すればいいの?

環境依存の設定なのか、どの環境でも必ず設定したい固定的な設定なのかによって変わります。

例えば、WEBアプリ上では設定したいが、バッチでは設定したくない、テスト環境では設定したくない、もしくは、設定する値が変わる、 というような環境依存の設定であれば、それぞれの環境における初期化領域で設定をします。 必要に応じて、単体テストの環境でも設定します。

一方で、どの環境でも必ず設定したい固定的な設定の場合は、DBFluteの初期化と同期させると良いでしょう。littleAdjustmentMap.dfprop の extendedDBFluteInitializerClass で DBFluteInitializer を継承した独自のクラスを設定することができます(@since 0.9.8.4)。再自動生成後、その独自のクラスの中で固定的な DBFluteConfig の設定が書いてあれば、どの環境であろうとDBFluteの初期化時に一緒に呼び出されることになります。 この方法を利用しなくても、DIコンテナによってはそれ自身の機能で差し替えができることがありますが要領は一緒です。

e.g. DBFluteInitializerを継承した独自クラスを作成 @Package
src/main/java
 |-com.example...
    |-dbflute
       |-allcommon
       |-bsbhv
       |-...
       |-exentity
       |-nogen // means no-generate
          |-ExtendedDBFluteInitializer // どこにどんな名前で作るかは任意
e.g. DBFluteInitializerを継承した独自クラスを指定 @littleAdjustmentMap.dfprop
...
; extendedDBFluteInitializerClass = com.exa...nogen.ExtendedDBFluteInitializer
...

具体的には、DBFluteInitializer の prologue メソッドをオーバーライドし、その中で設定処理を書きます。 ただし、必ずスーパークラスの prologue メソッド自体を呼び出すことを忘れてはいけません。

e.g. DBFluteInitializerを継承した独自クラスでDBFluteConfigの設定 @Java
...
    @Override
    protected void prologue() {
        super.prologue();

        DBFluteConfig config = DBFluteConfig.getInstance();
        config.unlock();
        config.set...
        config.lock();
    }
...

設定されたときのログ

どのコンフィグにおいても、設定されたときはINFOレベルのログが出力されます。 とても重要な設定であること、かつ、初期化時に一回だけ設定されるのが前提であることからそのようにしています。

emptyStringQueryAllowed

ConditionBean の一律のデフォルトの挙動として、空文字の条件設定を許可します(@since 0.9.7.8)。 全ての ConditionBean が cb.allowEmptyStringQuery() が呼び出されたのと同じ状態になります。

プロジェクト全体で空文字に業務的な意味があるような場合、そのようなカラムが多く存在する場合に有効です。 ただし、条件値に "空文字という業務的な値" と "値がないこと" という両方のパターンが混在する場合は、このコンフィグは利用せずに ConditionBean の設定で都度調整することが推奨されます。

ConditionBean の基本仕様と異なる挙動をするため、ドキュメントの内容や Example と実際の挙動が厳密に一致しません。このコンフィグを利用する場合は、必ずディベロッパーに通知が行き届くようにする必要があります。

このコンフィグは TwoEdgedSword 認定のされた機能です。

emptyStringParameterAllowed

ParameterBean の一律のデフォルトの挙動として、空文字の条件設定を許可します(@since 0.9.7.8)

プロジェクト全体で空文字に業務的な意味があるような場合、そのようなカラムが多く存在する場合に有効です。 ただし、条件値に "空文字という業務的な値" と "値がないこと" という両方のパターンが混在する場合は、このコンフィグは利用せずに ParameterBean の設定(オーバーライド拡張)で都度調整することが推奨されます。

このコンフィグを有効にした場合、当然のことですが、パラメータコメントの IF コメントでよく利用される FOO != null という条件は、空文字の場合に true となりません。空文字でも true と判定したい場合は、空文字を意識した条件に変更する必要があります。

ParameterBean の基本仕様と異なる挙動をするため、ドキュメントの内容や Example と実際の挙動が厳密に一致しません。このコンフィグを利用する場合は、必ずディベロッパーに通知が行き届くようにする必要があります。

このコンフィグは TwoEdgedSword 認定のされた機能です。

invalidQueryChecked

ConditionBean の一律のデフォルトの挙動として、nullや空文字などの無効な条件が設定された場合に例外にします((@since 0.9.7.8))。 全ての ConditionBean が cb.checkInvalidQuery() が呼び出されたのと同じ状態になります。

プロジェクト全体でnullや空文字などの無効な値が設定されたときに例外になってもよいと確定する場合に有効です。 ただし、"無効な値の場合は例外にしたい" という場面と "無効な値の場合は条件を無効にしたい" という場面の両方が混在する場合は、 プロジェクト全体でどちらのパターンの方が多いかを深く検討して利用する必要があります。 そういった場合 DBFlute では、よほどの極端な割合でない限り基本的にこのコンフィグを利用せず、 そもそも外部から渡って来たデータはしっかり入り口で必ずアプリで明示的にチェックする、保険を掛けるにしても ConditionBean の CheckInvalidQuery を利用して都度対応する、といったやり方を推奨しています。

ConditionBean の基本仕様と異なる挙動をするため、ドキュメントの内容や Example と実際の挙動が厳密に一致しません。このコンフィグを利用する場合は、必ずディベロッパーに通知が行き届くようにする必要があります。

このコンフィグは TwoEdgedSword 認定のされた機能です。

これに対応する ParameterBean の機能はありません。ParameterBean は自由度の高い外だしSQLで利用されるため、一律のチェックによる例外は逆に混沌を生み出す可能性があると想定しているためです。

queryLogLevelInfo

QueryLog のレベルを INFO に設定します(通常は、DEBUGレベル)。 アプリ要件で QueryLog を本番環境などでも出力する必要がある場合に有効です。 ただし、当然のことですが、(微々たるものではありますが)表示用SQLの生成処理とログ出力の分、パフォーマンスに影響します。

このコンフィグは TwoEdgedSword 認定のされた機能です。

executeStatusLogLevelInfo

ExecuteStatusLog のレベルを INFO に設定します(通常は、DEBUGレベル)。 アプリ要件で QueryLog を本番環境などでも出力する必要がある場合に有効です。 ただし、当然のことですが、(微々たるものではありますが)表示用SQLの生成処理とログ出力の分、パフォーマンスに影響します。

このコンフィグは TwoEdgedSword 認定のされた機能です。

logDateFormat

SQL実行時に出力される表示用SQLの日付型の条件値の表示フォーマットを設定します。 デフォルトのフォーマットが都合悪いときに利用します。 java.util.Dateにマッピングされたカラムに対して有効です。SimpleDateFormatが解釈できる形式で指定します。

e.g. 独自の日付型フォーマットを設定 {スラッシュを利用} @Java
DBFluteConfig config = DBFluteConfig.getInstance();
config.setLogDateFormat("yyyy/MM/dd");

フォーマットされた後の日付表現の前後に、独自の文字列を追加したい場合は、"${yyyy-MM...}" 形式でフォーマットを囲って、その前後に独自の文字列を記述して設定します。

e.g. 日付フォーマットでdateリテラルを付与 @Java
DBFluteConfig config = DBFluteConfig.getInstance();
config.setLogDateFormat("date ${yyyy/MM/dd}");

主に、Oracleのtimestampリテラルの付与の用途などで利用します。但し、Oracleに関しては既にデフォルトで timestamp リテラルが付与されるようになっているため、必要になる場面はあまりないと想定されています。 (そのOracleのデフォルト設定をフォーマットだけちょっと変えて上書きするような場合には必要になります)

logTimestampFormat

SQL実行時に出力される表示用SQLの日時型の条件値の表示フォーマットを設定します。 デフォルトのフォーマットが都合悪いときに利用します。 java.sql.Timestampにマッピングされたカラムに対して有効です。SimpleDateFormatが解釈できる形式で指定します。

e.g. 独自の日時型フォーマットを設定 {スラッシュを利用} @Java
DBFluteConfig config = DBFluteConfig.getInstance();
config.setLogTimestampFormat("yyyy/MM/dd HH:mm:ss.SSS");

リテラルの付与に関しては、logDateFormat と同様です。

defaultStatementConfig

全ての検索に適用するデフォルトの StatementConfig を設定します。設定した StatementConfig インスタンスがDBFlute内部で利用されます。設定後にそのインスタンスの設定値を変更してはいけません。

cursorSelectFetchSize

全てのカーソル検索に適用するデフォルトの FetchSize (JDBCのパラメータ) を設定します。 カーソル検索におけるパフォーマンスの調整や、JDBCドライバの特殊な仕様に対応する場合に利用します。

littleAdjustmentMap.dfprop でも、このコンフィグの値を設定できます。

dataSourceHandler

DBFlute内部で DataSource からのコネクションの取得処理をフィルタします。 利用している DBCP の環境次第で調整が必要になるときに有効です。

DBFlute内部でこの機能を利用しているものもあります。Spring Framework と Commons DBCP を組み合わせたときのスレッドトランザクションの実現の際、このコンフィグを使って Spring の DataSourceUtils を利用しています(自動登録されます)。

Spring Frameworkの取扱い - Commons DBCP との組み合わせ

physicalConnectionDigger

論理コネクションから物理コネクションを取得するコールバック処理を設定します(@since 0.9.7.6)

DBFluteは、DIコンテナ経由でアプリから渡された DataSource を利用してコネクションを取得しています。 ゆえに、DBFluteはそのコネクションが論理的なものなのか物理的なものなのかは意識していません。 通常は、それで全く問題ありませんが、一部機能でどうしても物理コネクションが必要になることがあります。 その機能を利用する時のために、アプリの DBCP 構成に合わせた物理コネクション処理を登録します。

代表的な例として、Oracleのプロシージャパラメータに、TABLE型やOBJECT型のデータを指定するときに利用します。 (基本的には、DBMSのJDBCドライバに依存せざるを得ない機能を使うときに必要になる可能性があります)

sqlExceptionDigger

抽象例外から SQLException を取得するコールバック処理を設定します(@since 0.9.7.8)

DBFluteは、DIコンテナ経由でアプリから渡された DataSource を利用してコネクションを取得していますが、利用している DBCP の仕組み次第では SQLException 以外の例外を戻す可能性があり、DBFluteの一律の例外である SQLFailureException に翻訳できない可能性があります。ほとんどの場合、それで困る場面はあまり想定されませんが、万が一困るような場合に、(JDBCをラップした)DBCP から発生した抽象例外から SQLException を抽出するロジックを設定して SQLFailureException に統一することができます。

デフォルトでは、発生した例外の getCause() から SQLException を抽出するロジックが登録されています。 また、Seasar(S2Container) を利用している場合は、それに加えて S2Container の SQLRuntimeException から SQLException を抽出するロジックが登録されています。 (詳しくは、自動生成されたソースコードをご覧下さい)

sequenceCacheKeyGenerator

シーケンスキャッシュのキーを生成する処理を差し替えます。シーケンスキャッシュの単位のデフォルトは、 "テーブルごとのシーケンス" ですが、そのキーの単位を変更したい場合に有効です。

sqlClauseCreator

ConditionBean の 内部でSQLを組み立てるクラス、SqlClause のファクトリクラスを差し替えます。 ConditionBean で発行されるSQLを拡張したいときに利用します。(ただし、拡張リスクがあります)

tableSqlNameFilter

自動組み立てをする SQL のテーブル名をフィルタします(@since 0.9.7.6)。 主に以下のような状況での利用が想定されます。

スキーマ名の修飾を環境ごとに切り替える
例えば、SQL上ではテーブル名にスキーマ名の修飾が必要な上に、かつ、 開発環境と本番環境でのスキーマ構成が統一できないような場合に有効です。 (環境ごとに切り替える必要のないスキーマ名の修飾(静的な修飾)であれば、別途機能として用意されていますのでそちらをご利用下さい)
現場フィット - 自動組み立てSQLのテーブル名にスキーマ名を付与
アプリのステータス次第で実行時にテーブル名を切り替える
例えば、テーブル名に suffix を付けるなどしてテーブル構造を冗長化させていて、 実行時のアプリのステータスやデータなどによって、登録や検索するテーブルを切り替える必要がある場合に有効です。
e.g. PUBLICというスキーマ名をテーブル名に付与する @Java
final String schema = "PUBLIC"; // 実業務ではアプリのプロパティなどから取得 
DBFluteConfig.getInstance().setTableSqlNameFilter(new SqlNameFilter() {
    public String filter(String sqlName, String correspondingDbName) {
        return schema + "." + sqlName;
    }
});

このフィルタは、Behavior や ConditionBean などのSQLの自動組み立て処理が対象であり、外だしSQLには影響しません。 外だしSQLのフィルタは、同じく DBFluteConfig の outsideSqlExecutorFactory を利用することで実現できます。

dbflute-multipledb-seasar-example にて、Example があります。

DBFlute Example - 特定環境

このフィルタの設定は、必ずコンテナの初期化の前に設定する必要があります。そもそも DBFluteConfig はそういった利用を想定していますが、このコンフィグは初期化後にロックを解除して設定しても反映されない可能性があります。 具体的には、各テーブルの DBMeta クラスが、クラスロードされたときにこのフィルタが設定されます。 フィルタが設定された後は、SQLが実行されるごとにフィルタ処理が実行されます。 (極端に重いフィルタ処理はするべきではありません)

また、Generateタスク実行時に TableSqlName をフィルタするような機能を併用する場合、コールバックの引数は既にそのフィルタが実行された値となります。 具体的には、スキーマ名の静的な修飾を行う SchemaTableName や、予約語テーブル名のためのクォーテーション処理などです。

現場フィット - スキーマ修飾テーブル

利用する際は、環境が変わってスキーマ名が変わっても動作するというテスト もしくは テーブル名を切り替えても動作するというテスト を必ず行うようにして下さい。 例えば、開発環境でずっと同じスキーマ名で試していて、いきなりにスキーマ名の違う本番環境にアップするというのは、そのテストが抜け落ちていることになります。 結合テストで自然とテストすることになるかもしれませんが、結合テストと開発環境はスキーマ名が同じである可能性もあります。 そもそも、予期せぬリスクを回避するために、結合テストが始まるもっと前の早い段階で確認されることが推奨されます。

outsideSqlPackage

外だしSQLの配置パッケージを変更します。

このコンフィグは TwoEdgedSword 認定のされた機能です。

outsideSqlExecutorFactory

Behavior の outsideSql() メソッド経由で利用する OutsideSqlExecutor クラスの ファクトリを差し替えます。外だしSQLの挙動を拡張するのに有効です。(ただし、拡張リスクがあります)

通常、outsideSql() の後に続けてメソッドを利用するため、クラス名をディベロッパーが意識していないことが多いため、馴染みのないクラスとなっていますが、 外だしSQLの根幹になるクラスを差し替えることができます。頑張れば、外だしSQLの読み込み処理をフックして、フィルタを掛けるようなこともできます。 利用する時は、デフォルトで利用されている DefaultOutsideSqlExecutorFactory を使うと良いでしょう。OutsideSqlContextFactory も差し替えることができます(@since 0.9.7.6)。 OutsideSqlFilter (外だしSQLのフィルタ)を指定することもできます(@since 0.9.7.6)。(詳しくはソースにて)

このコンフィグは TwoEdgedSword 認定のされた機能です。

gearedCipherManager

ConditionBean や Behavior(の更新系の処理) において、(主にはSQL関数の)暗号化・復号化処理を連動させることができます。 @since 0.9.8.4

useSqlLogRegistry

Seasar の SqlLogRegistry 機能を利用できるように設定します。 ただし、DBFluteとしては、CallbackContext を使って同じことが代替できるため、非推奨となっています。

このコンフィグは TwoEdgedSword 認定のされた機能です。

fullTextSearchOperand

全文検索用の検索条件の演算子を差し替えます。 全文検索をサポートしていて、かつ、調整のオプションがある DBMS (例えば、PostgreSQL)のみ、このコンフィグが存在します。

ValueType

独自の ValueType を設定することができます。

ValueType

基本ValueType

プログラム型をキーに ValueType を指定します。 独自のプログラム型を利用する場合などに有効です。typeMappingMap.dfprop と連携して利用することがほとんどの利用パターンです。ただし、厳重注意のもと利用すること。 特にデフォルトで登録されている ValueType を差し替えた場合、DBFluteが正常に動作しない可能性もあります。

e.g. 独自の基本ValueTypeを登録 @Java
DBFluteConfig config = DBFluteConfig.getInstance();
config.registerBasicValueType(KorondeItai.class, new KolobValueType());

プラグインValueType

名前をキーに ValueType を指定します。設定したキーを指定して、どのカラムでどの ValueType を指定するか手動で設定します。 ピンポイントで このカラムだけ、この ValueType を利用するようにしたい という場合に有効です。ただし、厳重注意のもと利用すること。 特にデフォルトで登録されている ValueType を差し替えた場合、DBFluteが正常に動作しない可能性もあります。

e.g. 独自のプラグインValueTypeを登録 @Java
DBFluteConfig config = DBFluteConfig.getInstance();
config.registerPluginValueType("korondeItai", new KolobValueType());
e.g. 独自のプラグインValueTypeを利用 @Java
// EntityのExクラスにて
public static final String memberName_VALUE_TYPE = "korondeItai";

定数アノテーションの [プロパティ名]_VALUE_TYPE のプロパティ名は、JavaBeansルールに従うこと。 例えば、"T_NAME" カラムだったら、プロパティ名は、"TName"。(tNameではない)

ConditionBean の検索条件のバインド変数においては、このプラグインValueTypeは利用されません。 データの取得処理や、登録・更新などのバインド変数に限ります。

このコンフィグは TwoEdgedSword 認定のされた機能です。