外だしSQLのパラメータコメント
そもそもパラメータコメントとは?についてはこちら
基本仕様
パラメータコメントの基本仕様として以下があります。
-
コメントの構文として基本的に「/**/」を利用する。
→ 行コメント「--」は一部機能を除いて利用しない。
-
「/*IF ...*/」・「/*pmb...*/」というように「/*」の次に空白を入れない。
→ 「/* IF ...*/」・「/* pmb...*/」としてしまうとパラメータコメントとして認識されない。
-
パラメータコメント中の変数名やプロパティ名は大文字小文字を区別する。
→ memberIdというプロパティ名なら、「/*IF pmb.memberId*/」でOK、「/*IF pmb.MEMBERID*/」でNG
→ C#版の場合は、通常プロパティ名は先頭が大文字になるので注意。「/*IF pmb.MemberId*/」 -
S2Daoの「SQLコメント」とほぼ同じ仕様。
→ 一部拡張された機能がある。
バインド変数コメント
アプリケーションから渡される値をバインド変数として扱うコメント構文です。
Where句で利用します。
ex) バインド変数コメントの利用
where MEMBER_ID = /*pmb.memberId*/3
and MEMBER_NAME like /*pmb.memberName*/'ス' || '%'
and MEMBER_STATUS_CODE in /*pmb.memberStatusCodeList*/('FML', 'WDL')
「/**/」コメントのなかに変数値を記述することでバインド変数コメントとなります。
渡されたParameterBeanからドット「.」つなぎでプロパティを辿ることが可能です。
「/*pmb.aaaBean.bbbBean.cccBean...*/」と幾らでも辿ることが可能です。
コメント直後の値は、テスト値としてアプリケーション実行時には無視されます。
数値の場合は数字をそのまま記述し、文字列や日付の場合はシングルクォーテーション「'」で囲います。
「in句」の場合は、指定するパラメータ(上記の例だとpmb.memberStatusCodeList)がリスト型パラメータである必要があります。 また、テスト値も必ず「('FML', 'WDL')」という形式で書くようにして下さい。
プロパティを辿る際に途中でjava.util.Mapが存在した場合、そのMapのキー値で辿ることが可能です。
「/*pmb.aaaBean.bbbMap.cccKey.dddBean...*/」(cccKeyはbbbMapのキー値)というように記述することが可能です。
これはS2Daoの仕様から拡張した点となります。
C#版においてIDictionaryでこの機能を利用することはできません(JavaLikeのMapならOK)。
埋め込み変数コメント
アプリケーションから渡される値を埋め込み変数(単なる文字列置換)として扱うコメント構文です。
SQLの実行前に埋め込み変数コメントをアプリケーションから渡された値で文字列置換します。
バインド変数を使いたくない場合や、一部SQLをプログラム上で組み立てる場合に利用します。
ex) 埋め込み変数コメントの利用(generatedSqlは'limit 80, 20'と指定されることを想定)
where MEMBER_ID = /*$pmb.memberId*/3
/*$pmb.generatedSql*/
宣言の先頭に「$」を付けることで埋め込み変数コメントになります。
よって、バインド変数コメントとは一文字違いとなります。
テスト値の扱いやプロパティの辿り方、Map型プロパティの扱いはバインド変数コメントと同様です。
通常は、埋め込み変数コメント内でバインド変数コメントを利用することはできません。
しかし、不定数の条件を組み立てたいときなど、それができないと困ることもあります。
プログラムで明示的に指定した場合のみ、埋め込み変数コメント内のバインド変数コメントを有効にすることが可能です。
これはS2Daoの仕様から拡張した点となります。詳しくはこちら
IFコメント
アプリケーションから渡される値を判定して条件分岐するコメント構文です。
Where句条件の付与判定や、結合の有無判定など様々な用途で利用できます。
ex) IFコメントの利用
where
/*IF pmb.memberId != null*/MEMBER_ID = /*pmb.memberId*/3/*END*/
/*IF pmb.memberName != null*/and MEMBER_NAME like /*pmb.memberName*/'ス' || '%'/*END*/
/*IF pmb.validOrderBy*/
order by MEMBER_NAME desc
/*END*/
「/**/」コメントで「IF」と最初に付けて、分岐条件を記述することでIFコメントとなります。
直近のENDコメント(後述)まで分岐判定の範囲となります。
IFコメント内で利用できる構文は以下の通りです:
- Java版 : OGNL
- C#版 : JScript.NET
プロパティの辿り方やMap型プロパティの扱いはバインド変数コメントと同様です。
例題のようにWhere句でIFコメントを利用する場合は、基本的にはBEGINコメントと一緒に併用します。
ELSEコメント
IFコメントに対応するELSEの分岐判定を有効にするコメント構文です。
必ずIFコメントと併用します。
ex) ELSEコメントの利用(カラム列挙か件数取得かを分岐)
/*IF pmb.isPaging()*/
select member.MEMBER_ID
, member.MEMBER_NAME
, memberStatus.MEMBER_STATUS_NAME
-- ELSE select count(*)
/*END*/
from MEMBER member
「--」コメントで「ELSE」と書いた後にIFコメントがFALSEだったときに評価されて欲しい文字列を記載することでELSEコメントとなります。
必ずIFコメントとENDコメントの間に記述します。
IFコメントとELSEコメントの間で別の「--」コメントを利用することはできません。
ex) ELSEコメントの利用でダメなパターン
/*IF pmb.isPaging()*/
select member.MEMBER_ID
, member.MEMBER_NAME -- ★ここのコメントがダメ
, memberStatus.MEMBER_STATUS_NAME
-- ELSE select count(*)
/*END*/
from MEMBER member
このように実装すると例外が発生してしまいます。これはS2Daoと同じ仕様となります。★ですが、これは非常にハマリポイントになってしまうので、将来的に改善したいなと考えております(2007/12/31現在)。
BEGINコメント
Where句の動的表現を可能にするコメント構文です。
必ずIFコメントと併用します。
BEGINコメント内のIFコメントが全てFALSEの場合に「where」という文字列を除去します。
また、IFコメントの結果「where and ...」という風になってしまった場合に不要な「and」を除去します。
ex) BEGINコメントの利用(IFコメントとの併用)
/*BEGIN*/
where
/*IF pmb.memberId != null*/MEMBER_ID = /*pmb.memberId*/3/*END*/
/*IF pmb.memberName != null*/and MEMBER_NAME like /*pmb.memberName*/'ス' || '%'/*END*/
/*END*/
/*IF pmb.validOrderBy*/
order by MEMBER_NAME desc
/*END*/
「/**/」コメント内に「BEGIN」と書くことでBEGINコメントになります。
直近のENDコメント(後述)まで判定の範囲となります。通常はWhere句をそのまま囲みます。
BEGINコメントを利用することで、Where句構文のいやらしい文字列操作をする必要がなくなります。
Where句を動的に扱うほとんどの外だしSQLで利用します。
ENDコメント
IFコメントやBEGINコメントのスコープを定義するコメント構文です。
既にたくさん登場しているので説明するまでもないかと思われます。
