DBアクセスを定番化しよう DBFlute入門

第1回 DBFluteの概要

この記事を読むのに必要な時間:およそ 5 分

参照系メソッドの一覧は,リスト3を確認してください。

リスト3 Behavior参照系メソッド一覧

検索タイプメソッド存在チェック(※1)重複チェック(※2)
件数 int selectCount(MemberCB cb)--
1件 Member selectEntity(MemberCB cb)×
Member selectEntityWithDeletedCheck(MemberCB cb)
Member selectByPKValueWithDeletedCheck(Integer memberId)
n件ListResultBean<Member> selectList(MemberCB cb)--
ページング PagingResultBean<Member> selectPage(MemberCB cb)--

※1)結果が0件の場合は EntityAlreadyDeletedException が発生します。

※2)結果が2件以上の場合は EntityDuplicatedException が発生します。

基本的な検索機能を持ったメソッドが並んでいますが,特徴的な項目として「存在チェック⁠⁠・⁠重複チェック」というものがあります。

通常,1件検索の結果が0件であったら,それは次のことを表します。

  • 条件が間違っているかもしれない
  • データが間違っているかもしれない
  • 他のユーザが削除したかもしれない(すれ違い)

S2Daoの1件検索メソッドは,nullを返します。そのため,上記のようなことが発生した場合,何も考慮しなければNullPointerExceptionが発生する可能性があります。正しくハンドリングするためには,nullを判定して,それ相応の例外を明示的に発生させなければなりませんリスト4⁠。

リスト4 S2Daoの1件検索でのnullハンドリング

MemberCB cb = new MemberCB();
cb.query().setMemberId_Equal(3); // 会員IDが「3」であること

Member member =  memberBhv.selectEntity(cb);
if (member == null) {
    throw new XxxException(...);
}
Integer memberId = member.getMemberId();
...

しかし,1件検索はシステムの至るところで存在し,かつ,面倒で忘れやすいものです。

Behaviorでは,selectEntityWithDeletedCheck()がその存在チェックを内包しますリスト5⁠。

リスト5 Behaviorの存在チェックありの1件検索

MemberCB cb = new MemberCB();
cb.query().setMemberId_Equal(3); // 会員IDが「3」であること

// 該当レコードが無い場合は,
// 例外(EntityAlreadyDeletedException)が発生
Member member =  memberBhv.selectEntityWithDeletedCheck(cb);

// memberがnullであることはありえないので,
// NullPointerExceptionが発生する恐れはない。
Integer memberId = member.getMemberId();
...

これは,非常に地味ですが,実際の開発現場で効果を発揮します。少なくともNullPointerExceptionではなく,明示的な例外(明示的なメッセージを含む)を発生させることで,いざ例外が発生したときの原因究明のスピードが格段に違います。

また,1件検索の結果が2件以上であったら,それは次のことを表します。

  • 条件が間違っているかもしれない
  • データが間違っているかもしれない
  • DBの制約が抜けているかもしれない

S2Daoの1件検索メソッドは,例えば3件取得した場合に先頭の1件を返します。そのため,上記のようなことが発生した場合,間違いに気付かずにシステムが動いてしまう可能性があります。これは開発プロジェクトでは致命的なものです。

Behaviorでは,selectEntity()やselectEntityWithDeletedCheck()などがその重複チェックを内包しますリスト6⁠。

リスト6 Behaviorの重複チェックありの1件検索

MemberCB cb = new MemberCB();
cb.query().setMemberId_Equal(3); // 会員IDが「3」であること

// 2件以上取得した場合は,
// 例外(EntityDuplicatedException)が発生
Member member =  memberBhv.selectEntityWithDeletedCheck(cb);
Integer memberId = member.getMemberId();
...

こちらも,非常に地味ですが,実際の開発現場で効果を発揮します。間違っているものは,しっかり間違いとして扱う処理がBehaviorには既に組み込まれているのです。

著者プロフィール

久保雅彦(くぼまさひこ)

DBFluteメインコミッタ。主にオープン系の開発に従事。DB設計・DB周りの実装などを担当することが多い。