(外だしSQL)dynamicBinding()

概要

主に、検索条件の個数がアプリの入力値によって変動する不定数の検索条件のために、パラメータコメントの解析を実行時に行って 動的なバインド変数コメントを利用できるようにするオプション です。

会話上では、(外だしSQLの)だいなみっくばいんでぃんぐ と表現します。

このオプションは非推奨機能となりました

以下の利用により、このオプションは非推奨機能となりました。@since 0.9.7.0

  • FORコメントがサポートされた @since 0.9.7.0
  • このオプションを利用しなくても埋め込み変数コメントの中でバインド変数コメント(その他、IFコメントなども)を利用できるようになった @since 0.9.7.0

将来においてこのオプション機能が削除される可能性があります。

外だしSQLの解析は基本一度だけ

外だしSQLは、DBFlute内部にて基本的には一度だけ解析され、どのようなパラメータコメントを持っているのかなどを保持し、 処理が呼び出されたときにすぐにSQLを実行できるようにしています。もし、呼び出しのたびに解析していたら、毎回解析コストが掛かってしまいます。

但し、その状態だと、パラメータコメント、特にバインド変数コメントに関して、静的な情報として扱われているため、 呼び出しの度に変わる不定数の条件には対応できません。 例えば、埋め込み変数コメントの中に、バインド変数コメントを含めても、バインド変数として認識されません。 バインド変数を利用せずに条件値をそのまま埋め込んだ文字列で実行すると、要件次第ですが、セキュリティ的にもパフォーマンス的にも良くありません。

解析を呼び出しのたびに行う

DBFluteでは、動的なバインド変数を実現するために、 (明示的なオプションとして)呼び出しの度にパラメータコメントを解析するような挙動に変更するオプションが用意されています。

例えば、埋め込み変数コメントの中にバインド変数コメントを含めても、 バインド変数として認識されるようにできます(但し、ネストしたプロパティでは不可。例えば、"pmb.fooDto.barName")。

この場合、解析コストに関しては、局所的ということで割り切る必要があります。

パラメータコメントの解析コスト

SQLがよほど巨大(パラメータコメントの数が5000や10000)でない限りはほんのわずかの処理ではあるので、 実際に利用してみて(明らかな)パフォーマンス上の違和感がないようであればあまり気にする必要はないと考えられます。

実装方法

メソッドの呼び出し

outsideSql()メソッドの後、dynamicBinding() メソッドを呼び出します。この機能はオプションであり、様々なメソッドで利用できます。

e.g. 外だしSQLの動的バインド変数をリスト検索で利用 (Eclipseでコード補完) @Java
memberBhv.o // .o と打って enter
--
memberBhv.outsideSql().d // .d と打って enter
--
memberBhv.outsideSql().dynamicBinding().s // .s と打って enter
--
memberBhv.outsideSql().dynamicBinding().selectList(...);
e.g. 外だしSQLの動的バインド変数を様々なメソッドと組み合わせ @Java
memberBhv.outsideSql().dynamicBinding().manualPaging().selectPage(...)
memberBhv.outsideSql().dynamicBinding().cursorHandling().selectCursor(...)

外だしSQLとParameterBean

e.g. 外だしSQLに動的なSQL文の一部を展開する埋め込み変数コメントを定義 @OutsideSql
-- !df:pmb!
-- !!String dynamicClause!!
-- !!Map<String, String> dynamicMap:like!!
select ...
  from ...
 where ...
  /*$pmb.dynamicClause*/
  • テスト値は、2Way-SQLの実現を意識して調整(省略もOK)
e.g. 外だしSQLに動的なSQL文の一部を展開するパラメータを設定 @Java
Map<String, String> dynamicMap = new HashMap<String, String>();
StringBuilder sb = new StringBuilder();
for (...) {
    String key = "key" + index;
    sb.append(" and FOO like /*pmb.dynamicMap.")
            .append(key).append("*/null");
    dynamicMap.put(key, currentValue);
}
pmb.setDynamicClause(sb.toString());
pmb.setDynamicMap(dynamicMap, new LikeSearchOption().likeContain());