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

第3回 ConditionBeanで色々な条件組み立て

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

PrefixSearch

ちょっと毛並みが変わります。前方一致検索を意味する「PrefixSearch」ですリスト14⁠。

SQLでは「where COLUMN_NAME like 'xxx%'」という条件になります。同じカラムに対する同じ演算子の条件を複数指定すると,最後に設定した条件が有効になります。

リスト14:PrefixSearch

/**
 * 会員名が「ス」で始まる会員を検索
 * 
 * @throws Exception
 */
public void test_ConditionBean_Query_PrefixSearch_Tx() throws Exception {
    // ## Arrange ##
    final String expectedMemberNamePrefix = "ス";
    final MemberCB cb = new MemberCB();
    cb.query().setMemberName_PrefixSearch(expectedMemberNamePrefix);

    // ## Act ##
    final List<Member> memberList = memberBhv.selectList(cb);

    // ## Assert ##
    assertNotNull(memberList);
    assertNotSame(0, memberList.size());
    for (final Member member : memberList) {
        log.debug("memberName=" + member.getMemberName());
        if (!member.getMemberName().startsWith(expectedMemberNamePrefix)) {
            fail();
        }
    }
}

アプリケーションにおいて前方一致は一番よく利用される曖昧検索かと思われます。 そのため,このように明示的なメソッドとして用意されています。

特徴としては,ワイルドカード(%)はConditionBean内部にて解決されるため,プログラム側で明示的に付与する必要がないということが挙げられます。ログを見てみると,しっかりワイルドカードが付与されていることがわかりますリスト15⁠。

リスト15:「PrefixSearch」のログ一部抜粋

...from MEMBER  where MEMBER.MEMBER_NAME like 'ス%'
InScope

ある列に対して複数の値を条件に検索する「InScope」ですリスト16⁠。

SQLでは「where COLUMN_NAME in ('a', 'b')」という条件になります。同じカラムに対する同じ演算子の条件を複数指定すると,指定した分条件がAND条件で追加されます。

リスト16:InScope

/**
 * 会員ID「3」・「6」・「7」の会員を検索
 * 
 * @throws Exception
 */
public void test_ConditionBean_Query_InScope_Tx() throws Exception {
    // ## Arrange ##
    final MemberCB cb = new MemberCB();
    final List<Integer> expectedMemberIdList = new ArrayList<Integer>();
    expectedMemberIdList.add(3);
    expectedMemberIdList.add(6);
    expectedMemberIdList.add(7);
    cb.query().setMemberId_InScope(expectedMemberIdList);

    // ## Act ##
    final List<Member> memberList = memberBhv.selectList(cb);

    // ## Assert ##
    assertNotNull(memberList);
    assertNotSame(0, memberList.size());
    for (final Member member : memberList) {
        log.debug("memberId=" + member.getMemberId());
        if (!expectedMemberIdList.contains(member.getMemberId())) {
            fail();
        }
    }
}
NotInScope

「InScope」の否定版を意味する「NotInScope」ですリスト17⁠。

SQLでは「where COLUMN_NAME not in ('a', 'b')」という条件になります。同じカラムに対する同じ演算子の条件を複数指定すると,指定した分条件がAND条件で追加されます。

リスト17:NotInScope

/**
 * 会員ID「3」・「6」・「7」でない会員を検索
 * 
 * @throws Exception
 */
public void test_ConditionBean_Query_NotInScope_Tx() throws Exception {
    // ## Arrange ##
    final MemberCB cb = new MemberCB();
    final List<Integer> expectedMemberIdList = new ArrayList<Integer>();
    expectedMemberIdList.add(3);
    expectedMemberIdList.add(6);
    expectedMemberIdList.add(7);
    cb.query().setMemberId_NotInScope(expectedMemberIdList);

    // ## Act ##
    final List<Member> memberList = memberBhv.selectList(cb);

    // ## Assert ##
    assertNotNull(memberList);
    assertNotSame(0, memberList.size());
    for (final Member member : memberList) {
        log.debug("memberId=" + member.getMemberId());
        if (expectedMemberIdList.contains(member.getMemberId())) {
            fail();
        }
    }
}

次回

基本的な演算子は一通り登場しました。さらには応用的なものが他にもあるのですが,先に他のもっと基本的なところを見ていきたいと思います。

今回はソートや結合とかが全く出てきていません。気になっている方もいらっしゃるかと思いますので,次回はConditionBeanのソートや結合等の基本的な機能を見ていきます。

著者プロフィール

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

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