ParameterBean
Sql2Entityで自動生成される ParameterBean についてのページです。
- ParameterBeanとは?
- ParameterBeanの自動生成
- ParameterBeanマーク
- ParameterBeanのオプション
- プロパティ項目の自動判別
- プログラム型のパッケージ解決
- ParameterBeanの構造
ParameterBeanとは?
SQLへ渡すパラメータ(引数)は実開発ではかなり多くなりがちです。引数が多くなればなるほどメソッドはわかりにくいものになります。 DBFluteの外だしSQLでは、SQLへ渡すパラメータオブジェクト を利用し、呼び出しメソッドの引数を必ず "一つのオブジェクト" という形にします。そのパラメータオブジェクトのことを ParameterBean と呼びます。
TypedParameterBean
また、何のSQLを呼び出すか? 戻り値Entityの型は何か? といった情報も合わせて型付けされた ParameterBean を TypedParameterBean と呼びます。
プロシージャ対応のParameterBean
ParameterBeanには、プロシージャ対応のもの(ProcedurePmb)が存在します。 同じParameterBeanではありますが、生成の課程や役割などにちょっとした違いがあります。 このページでは、ProcedurePmbでないParameterBeanがメインに説明されています。
空文字は null として扱われる
ParameterBeanのString型のプロパティの空文字は null として扱われます。よって、外だしSQLで空文字なのか null なのかを意識する必要はなく、IFコメントで "nullでないこと" という条件で分岐可能です。(ただし、ListやMap型プロパティの要素のString型の値はそのまま空文字として扱われます)
e.g. String型プロパティは空文字かどうかは条件に含めてなくてもOK @OutsideSql
/*IF pmb.memberName != null*/
...
/*END*/
地味なことですが、画面側フレームワークによっては "存在しない値" の表現が空文字だったり null だったりとします。ParameterBeanではそういった細かいことを極力気にしないで済むようにしています。
ParameterBeanの自動生成
Sql2Entityで自動生成される
ParameterBeanは、Sql2Entityタスクで自動生成されます。 出力先ディレクトリと出力クラスのパッケージは、デフォルトではGenerateタスクで自動生成されるクラスと同じで、Behavior のパッケージ配下の pmbean パッケージに出力されます。
外だしSQLに、ParameterBeanを生成したいというマーク (ParameterBeanマーク) を記述し、Sql2Entityタスクを実行することでParameterBeanが自動生成されます。 (ParameterBeanのみの自動生成の場合は、Sql2Entityタスクで該当の外だしSQLが実際のDBに実行されませんが、外だしSQLは必ず 2Way-SQL で記述されていることを前提とすることに変わりはありません)
古いクラスは削除される
外だしSQLのどこにも記述されていない既存の古いParameterBeanは(ファイルシステム上から)削除されます。 古いParameterBeanを利用しているプログラムはコンパイルエラーとして検知できます。
ParameterBeanマーク
基本仕様
ParameterBeanの生成を示すマークは、SQLの行コメントで、!df:pmb! という形で記述します。これを ParameterBeanマーク と呼びます。生成されるクラス名は以下のような感じ。
- SimpleMemberPmb
- 例えば、MemberBhv_selectSimpleMember.sql であれば
CustomizeEntityとは違い "どういったプロパティ構造を保持するか" をメタデータとして取得することができません。 そこで、プロパティ項目を パラメータコメントから自動判別 して導出するためのマークを付与します。同じくSQLの行コメント形式 "-- " で、!!AutoDetect!! と記述します。これで、パラメータコメントで利用するプロパティを持った ParameterBean が自動生成されます。
e.g. "MemberBhv_selectSimpleMember.sql" に対応する ParameterBean を生成 @OutsideSql
-- !df:pmb!
-- !!AutoDetect!!
select ...
from ...
where MEMBER_ID = /*pmb.memberId*/3
and MEMBER_NAME like /*pmb.memberName*/'S%'
自動判別を利用せずに、明示的にプロパティを宣言することもできます。 同じくSQLの行コメント形式 "-- " で、"!![プログラム型 プロパティ名]!!" という形で記述します。
e.g. "MemberBhv_selectSimpleMember.sql" に対応する ParameterBean を生成 @OutsideSql
-- !df:pmb!
-- !!Integer memberId!!
-- !!String memberName!!
select ...
from ...
where MEMBER_ID = /*pmb.memberId*/3
and MEMBER_NAME like /*pmb.memberName*/'S%'
プログラム上でパッケージ名を指定しなければいけないプログラム型において、よく利用される型(Date, Timestamp, List など)においてはパッケージ名は自動解決され、それらクラスに関してはパッケージ名を省略することができます。
自動判別と明示的宣言を併用することもできます。その場合、同じプロパティは明示的宣言の方が優先されます。 自動判別を使いつつ、微調整をしたいときに明示的宣言を併用すると良いでしょう。
その他補足仕様
一つの外だしSQLに CustomizeEntityマーク と一緒に記述することができます。逆に CustomizeEntityマーク がなくても利用できます。(その場合は、ParameterBean だけを自動生成することになりますが、TypedParameterBean としての利用はできません)
ParameterBean のクラス名を明示的に指定することもできます。
SQLの行コメントで、"![ParameterBeanのクラス名]!" という形で記述します。主に、他のSQLで ParameterBean を再利用するなど、SQL名に依存しない名前を付けたいようなときに利用します。
e.g. SimpleMemberPmb という名前の ParameterBean を生成 @OutsideSql
-- !SimpleMemberPmb!
-- !!String memberId!!
-- !!Date fromBirthdate!!
select ...
from ...
ParameterBeanのオプション
ParameterBeanには様々なオプションがあります。効果的に使いましょう。
クラスのオプション
- ページング検索のオプション
- -- !df:pmb extends Paging!
プロパティのオプション
- LikeSearch条件のオプション
- :like, :likeContain, :likePrefix, ... ※もしくは自動判別
- DateFromTo条件のオプション
- :fromDate, :toDate, :fromDate(option), ...
- 区分値条件のオプション
- :cls(MemberStatus)
- 参照カラムのオプション
- :ref(MEMBER.MEMBER_STATUS_CODE), ref(MEMBER)
- プロパティのコメント
- -- !!...!! // ..., :comment(...)
プロパティ項目の自動判別
AutoDetect の概要
プロパティ項目をIFコメントやバインド変数コメントなどから自動判別することが可能です。
- プロパティ項目の自動判別
- -- !!AutoDetect!!
- 代理判定メソッドの自動判別
- /*IF pmb.existsPurchase()*/
AutoDetect の Example
e.g. プロパティ項目を自動判別 @OutsideSql
-- !df:pmb!
-- !!AutoDetect!!
select ...
from ...
where MEMBER_ID = /*pmb.memberId*/3
and MEMBER_NAME like /*pmb.memberName*/'S%'
e.g. IFコメントで代理判定メソッドを指定 @OutsideSql
-- !df:pmb!
-- !!AutoDetect!!
select ...
from ...
where ...
...
/*IF pmb.existsPurchase()*/
and exists (select PURCHASE_ID
from PURCHASE
...
/*END*/
プログラム型のパッケージ解決
明示的宣言で指定するプログラム型のパッケージ名は、頻繁に利用されることが想定されるクラスに関しては自動で解決されます。
基本的なパッケージ解決
以下のクラスは自動で解決されます。
- BigDecimal
- java.math.BigDecimal
- Date
- java.util.Date
- Timestamp
- java.sql.Date
- Time
- java.sql.Time
- List
- java.util.List
- Map
- java.util.Map
e.g. パッケージが解決されるので指定がシンプルに @OutsideSql
-- !df:pmb!
-- !!BigDecimal big1!!
-- !!Date birthdate!!
-- !!Timestamp formalizedDatetime!!
-- !!List<Integer> countList!!
select ...
from ...
DomainEntityのパッケージ解決
DBFluteが自動生成する DomainEntity に関しては、"$$Domain$$.[entity-name]" という形式で記述することでパッケージ名が解決されます。@since 0.9.7.1
e.g. DomainEntityを指定 @OutsideSql
-- !df:pmb!
-- !!$$Domain$$.Member member!!
select ...
from ...
CustomizeEntityのパッケージ解決
同様に、CustomizeEntity に関して、"$$Customize$$.[entity-name]" という形式で記述することでパッケージ名が解決されます。@since 0.9.7.1
e.g. CustomizeEntityを指定 @OutsideSql
-- !df:pmb!
-- !!$$Customize$$.SimpleMember member!!
select ...
from ...
ParameterBeanのパッケージ解決
さらに、ParameterBean に関して、"$$Pmb$$.[pmb-name]" という形式で記述することでパッケージ名が解決されます。@since 0.9.7.1
e.g. (別の)ParameterBeanを指定 @OutsideSql
-- !df:pmb!
-- !!$$Pmb$$.SimpleMemberPmb memberPmb!!
select ...
from ...
CDefのパッケージ解決
また、区分値定義の "CDef" クラスに関して、"$$CDef$$" と記述することでパッケージ名が解決されます。ENUM をプロパティ型にしたい場合に有効ですが、区分値を条件にする際の支援機能は別途あるため、 基本的にはリストの要素型として扱うケース(@since 0.9.8.0)での利用が想定されています。
e.g. CDefを指定 @OutsideSql
-- !df:pmb!
-- !!$$CDef$$.MemberStatus status!!
select ...
from ...
e.g. CDefをリストの要素として指定 @OutsideSql
-- !df:pmb!
-- !!List<$$CDef$$.MemberStatus> statusList!!
select ...
from ...
それ以外はフルパッケージ指定
それ以外で、かつ、プログラミング言語上の文法的にパッケージ補完が必要なクラスに関しては、フルパッケージで指定します。
e.g. フルパッケージでプロパティの型を指定 @OutsideSql
-- !df:pmb!
-- !!com.example.DokujiDate fromBirthdate!!
select ...
from ...
ParameterBeanの構造
ParameterBeanは FetchBeanインターフェース および ParameterBeanインターフェース を実装し、 GenerationGap (ジェネレーションギャップ)になっています。
アプリケーションで意識するメソッドは全て set で始まるメソッド(検索条件の指定)となります。
getメソッドの空文字フィルタ
アプリケーションで意識することはないメソッドですが、パラメータの get メソッドでは空文字は null にフィルタされます。Exクラスによる拡張でクラスごともしくはプロパティごとにこの挙動を変えることはできます。 但し、内部構造が変わる可能性もありますので、必ずオーバーライド漏れを検知できるように拡張して下さい。
Serializableである
ParameterBeanは、Serializable です。@since 0.9.7.0