DBFlute -- 「最新の子テーブルのレコードを結合」への対応


additionalForeignKeyの話の続きです。
http://d.hatena.ne.jp/jflute/20071022/1193032003

fixedConditionを対応したことにより、
「最新の子テーブルのレコードを結合」というパターンにも対応できます。

o 会員(MEMBER)
- MEMBER_ID (PK)
- MEMBER_NAME

o 会員ログイン(MEMBER_LOGIN)
- MEMBER_LOGIN_ID (PK)
- MEMBER_ID (FK) (UQ with LOGIN_DATE)
- LOGIN_DATE (UQ with MEMBER_ID)

会員の一覧を検索したいが、会員の最新のログイン日時も同時に取得したい場合

MEMBERとMEMBER_LOGINは、one-to-manyなのでConditionBeanでは結合できません。
やるとすれば、BehaviorのloadReferer()を利用して別SQLで取得することですが、
わざわざそんなことぐらいでSQLの発行回数を増やしたくありません。
「じゃあ、外だしSQL!?」
わざわざこんなSQLを外だしにしたくありません。

なので、

./dfprop/additionalForeignKeyMap.dfpropにて

map:{
; FK_MEMBER_MEMBER_LOGIN_LATEST = map:{
; localTableName = MEMBER ; foreignTableName = MEMBER_LOGIN
; localColumnName = MEMBER_ID ; foreignColumnName = MEMBER_ID
; fixedCondition =
$$foreignAlias$$.LOGIN_DATE
= (select max(LOGIN_DATE)
from MEMBER_LOGIN
where MEMBER_ID = $$localAlias$$.MEMBER_ID)
; fixedSuffix = AsLatest
}
}
はてな日記の見た目の都合上fixedConditionを改行しています。

と設定して、自動生成します。すると、

MemberCB cb = new MemberCB();
cb.setupSelect_MemberLoginAsLatest();
cb.query().setXxx...

というように、「最新ログイン」を結合することができます。
そして以下のようなSQLが発行されます。

select member.MEMBER_ID, ... , memberLogin.LOGIN_DATE
from MEMBER member
left outer join MEMBER_LOGIN login
on member.MEMBER_ID = login.MEMBER_ID
and login.LOGIN_DATE = (
select max(LOGIN_DATE)
from MEMBER_LOGIN
where MEMBER_ID = member.MEMBER_ID)
where ...

「子供の最新のレコードが有効なレコード(処理したいレコード)」っていう
DB構造も世には結構あるかと思います。
そういったDB構造に出くわしても、上記のような方法で安全に結合することが可能です。