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

第6回 外だしSQLの様々な機能

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

はじめに

前回は,外だしSQL(OutsideSql)の基本を見ていきました。今回は,様々な状況に合わせた機能をみていきましょう。

一件検索

前回は,リスト検索のみを対象としていました。実際の業務は,外だしSQLを利用する場合のほとんどがリスト検索になることが(経験上)多いため,ベースとなる検索をリスト検索と位置づけて説明しました。しかし,当然一件検索もしたいことがあります。

もう一度,前回利用したSQLのサンプルを思い出しましょう。

リスト1:外だしSQLのサンプル(SQLファイル)

-- #MemberWithMaxPurchasePrice#

-- !MemberWithMaxPurchasePricePmb!
-- !!Integer memberId!!
-- !!String memberName!!

-- 会員IDと名称の前方一致で絞り込んで,会員一覧と購入最大価格を検索。
-- 絞り込み条件はそれぞれ値がnullじゃければ評価する。
select member.MEMBER_ID
     , member.MEMBER_NAME
     , (select max(purchase.PURCHASE_PRICE)
          from PURCHASE purchase
         where purchase.MEMBER_ID = member.MEMBER_ID) as MAX_PURCHASE_PRICE
  from MEMBER member
 /*BEGIN*/where
   /*IF pmb.memberId != null*/member.MEMBER_ID = /*pmb.memberId*/3/*END*/
   /*IF pmb.memberName != null*/and member.MEMBER_NAME like /*pmb.memberName*/'ス' || '%'/*END*/
 /*END*/

そして,リスト検索の場合の呼び出しです。

リスト2:外だしSQLのリスト検索

/**
 * 会員一覧と最大購入価格を検索。
 * 会員名称が「ス」で始まる会員を対象に検索する。
 *
 * @throws Exception
 */
public void test_OutsideSql_selectList_BasicExecution_Tx() throws Exception {
    // ## Arrange ##
    final String path = "sql/member/selectMemberWithMaxPurchasePrice.sql";
    final MemberWithMaxPurchasePricePmb pmb = new MemberWithMaxPurchasePricePmb();
    pmb.setMemberName("ス");
    final Class entityType = MemberWithMaxPurchasePrice.class;

    // ## Act ##
    final List memberList
            = memberBhv.outsideSql().selectList(path, pmb, entityType);

    // ## Assert ##
    for (MemberWithMaxPurchasePrice member : memberList) {
        final String memberName = member.getMemberName();
        final Integer maxPurchasePrice = member.getMaxPurchasePrice();
        log.debug(memberName + " - " + maxPurchasePrice);
        assertTrue(memberName.startsWith("ス"));
    }
}

BehaviorのoutsideSql()からselecList()を呼んでいますね。一件検索をしたいときは,outsideSql()に続いてentityHandling()を呼び出し,selectEntity()を実行します。

リスト3:外だしSQLの一件検索

/**
 * 会員と最大購入価格を一件検索。
 * 会員IDが6の会員を対象に検索する。
 *
 * @throws Exception
 */
public void test_OutsideSql_selectEntity_BasicExecution_Tx() throws Exception {
    // ## Arrange ##
    final Integer expectedMemberId = 6;
    final String path = "sql/member/selectMemberWithMaxPurchasePrice.sql";
    final MemberWithMaxPurchasePricePmb pmb = new MemberWithMaxPurchasePricePmb();
    pmb.setMemberId(expectedMemberId);
    final Class entityType = MemberWithMaxPurchasePrice.class;

    // ## Act ##
    final MemberWithMaxPurchasePrice member
            = memberBhv.outsideSql().entityHandling().selectEntity(path, pmb, entityType);

    // ## Assert ##
    final String memberName = member.getMemberName();
    final Integer maxPurchasePrice = member.getMaxPurchasePrice();
    log.debug(memberName + " - " + maxPurchasePrice);
    assertEquals(expectedMemberId, member.getMemberId());
}

このselectEntity()は,検索結果が0件の時はnullを戻します。ここはConditionBeanのときの一件検索と同じで,nullだったら例外になってほしい場合は,selectEntityWithDeletedCheck()を使います。

リスト4:外だしSQLのチェック付き一件検索

 /**
  * 会員と最大購入価格をチェック付きの一件検索。
  * 存在しない会員IDで検索してチェックに引っかかり例外になる。
  *
  * @throws Exception
  */
 public void test_OutsideSql_selectEntityWithDeletedCheck_BasicExecution_Tx() throws Exception {
     // ## Arrange ##
     final Integer expectedMemberId = 99999;// No Exist
     final String path = "sql/member/selectMemberWithMaxPurchasePrice.sql";
     final MemberWithMaxPurchasePricePmb pmb = new MemberWithMaxPurchasePricePmb();
     pmb.setMemberId(expectedMemberId);
     final Class entityType = MemberWithMaxPurchasePrice.class;
     
     // ## Act & Assert ##
     try {
         memberBhv.outsideSql().entityHandling().selectEntityWithDeletedCheck(path, pmb, entityType);
         fail();
     } catch (EntityAlreadyDeletedException e) {
         // OK
         log.debug(e.getMessage());
     }
 }

著者プロフィール

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

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

コメント

コメントの記入