はじめに
前回はDBFluteの環境を構築し、
今回はDBFluteのコア機能であるConditionBeanを実際に使ってみましょう。
お知らせ
この連載にて利用するExampleのソース
以下がSVNリポジトリのURLです。
H2データベースを組み込みで利用しているため、
また、
今回のConditionBeanの例題プログラムも全てこのプロジェクトにて実装されています。ぜひチェックアウトしてDBFluteをいじり倒して見て下さい!
ConditionBean
条件絞り込み
Equal
まず、
条件値は全てバインド変数としてハンドリングされます。条件の組み立てはConditionBeanのquery()メソッドを必ず利用します。
続いてメソッドを補完すると、
/**
* 会員ID「3」の会員を検索
*
* @throws Exception
*/
public void test_ConditionBean_Query_Equal_Tx() throws Exception {
// ## Arrange ##
final Integer expectedMemberId = 3;
final MemberCB cb = new MemberCB();
cb.query().setMemberId_Equal(expectedMemberId);
// ## Act ##
final Member member = memberBhv.selectEntityWithDeletedCheck(cb);
// ## Assert ##
assertNotNull(member);
assertEquals(expectedMemberId, member.getMemberId());
}
そして、
/**
* 会員ID「1」、かつ、会員アカウント「Stojkovic」の会員を検索
*
* @throws Exception
*/
public void test_ConditionBean_Query_Equal_TwoOrMoreCondition_Tx() throws Exception {
// ## Arrange ##
final Integer expectedMemberId = 1;
final String expectedMemberAccount = "Stojkovic";
final MemberCB cb = new MemberCB();
cb.query().setMemberId_Equal(expectedMemberId);
cb.query().setMemberAccount_Equal(expectedMemberAccount);
// ## Act ##
final Member member = memberBhv.selectEntityWithDeletedCheck(cb);
// ## Assert ##
assertNotNull(member);
assertEquals(expectedMemberId, member.getMemberId());
assertEquals(expectedMemberAccount, member.getMemberId());
}
もし、
例えば、
/**
* 会員IDにnullを設定
*
* @throws Exception
*/
public void test_ConditionBean_Query_Equal_ArgumentNull_Tx() throws Exception {
// ## Arrange ##
final MemberCB cb = new MemberCB();
cb.query().setMemberId_Equal(null);
// ## Act & Assert ##
try {
memberBhv.selectEntityWithDeletedCheck(cb);
fail();
} catch (EntityDuplicatedException e) {
// OK
log.debug(e.getMessage());
}
}
/**
* 会員名に空文字を設定
*
* @throws Exception
*/
public void test_ConditionBean_Query_Equal_ArgumentEmptyString_Tx() throws Exception {
// ## Arrange ##
final MemberCB cb = new MemberCB();
cb.query().setMemberName_Equal("");
// ## Act ##
final int count = memberBhv.selectCount(cb);
// ## Assert ##
assertEquals("条件なしの件数と同じであること", memberBhv.getCountAll(), count);
}
よってConditionBeanでは、
/**
* 会員IDと会員名と会員ステータスを画面から入力されたと想定
*
* @throws Exception
*/
public void test_ConditionBean_Query_Equal_SearchInputExample_Tx() throws Exception {
// ## Arrange ##
// これらは画面入力値を想定
final Integer memberId = 3;
final String memberName = null;
final String memberStatusCode = "FML";
final MemberCB cb = new MemberCB();
// ここで特にif文でnullチェックをする必要はない。
cb.query().setMemberId_Equal(memberId);
cb.query().setMemberName_Equal(memberName);
cb.query().setMemberStatusCode_Equal(memberStatusCode);
// ## Act & NonAssert##
// 会員ID「3」かつ会員ステータス「FML(正式会員)」という条件になる
// --> where MEMBER_ID = 3 and MEMBER_STATUS_CODE = 'FML'
final List<Member> memberList = memberBhv.selectList(cb);
log.debug(memberList);
}
また、
/**
* 会員ID「3」の設定をした後、会員ID「4」を設定
*
* @throws Exception
*/
public void test_ConditionBean_Query_Equal_OverrideCondition_Tx() throws Exception {
// ## Arrange ##
final Integer beforeMemberId = 3;
final Integer afterMemberId = 4;
final MemberCB cb = new MemberCB();
cb.query().setMemberId_Equal(beforeMemberId);
cb.query().setMemberId_Equal(afterMemberId);
// ## Act ##
final Member member = memberBhv.selectEntityWithDeletedCheck(cb);
// ## Assert ##
assertNotNull(member);
assertEquals("後に設定した値が有効になること", afterMemberId, member.getMemberId());
}
しかし、
ただし、
では同じカラムに対する同じ演算子で
明らかに意味が無いため、
/**
* 会員ID「3」の設定をした後、会員ID「3」を設定
*
* @throws Exception
*/
public void test_ConditionBean_Query_Equal_AbsolutelySameCondition_Tx() throws Exception {
// ## Arrange ##
final Integer beforeMemberId = 3;
final Integer afterMemberId = beforeMemberId;
final MemberCB cb = new MemberCB();
cb.query().setMemberId_Equal(beforeMemberId);
cb.query().setMemberId_Equal(afterMemberId);
// ## Act ##
final Member member = memberBhv.selectEntityWithDeletedCheck(cb);
// ## Assert ##
assertNotNull(member);
assertEquals(beforeMemberId, member.getMemberId());
}
The value has already registered at equal of MEMBER.memberId: value=3
NotEqual
では、
「NotEqual」
/**
* 会員ID「3」でない会員を検索
*
* @throws Exception
*/
public void test_ConditionBean_Query_NotEqual_Tx() throws Exception {
// ## Arrange ##
final Integer expectedMemberId = 3;
final MemberCB cb = new MemberCB();
cb.query().setMemberId_NotEqual(expectedMemberId);
// ## Act ##
final List<Member> memberList = memberBhv.selectList(cb);
// ## Assert ##
assertNotNull(memberList);
assertNotSame(0, memberList.size());
final Member notContainsMember = new Member();
notContainsMember.setMemberId(expectedMemberId);
if (memberList.contains(notContainsMember)) {
fail();
}
}
GreaterThan
「GreaterThan」
/**
* 会員ID「3」より大きい会員IDを持った会員を検索
*
* @throws Exception
*/
public void test_ConditionBean_Query_GreaterThan_Tx() throws Exception {
// ## Arrange ##
final Integer expectedMemberId = 3;
final MemberCB cb = new MemberCB();
cb.query().setMemberId_GreaterThan(expectedMemberId);
// ## Act ##
final List<Member> memberList = memberBhv.selectList(cb);
// ## Assert ##
assertNotNull(memberList);
assertNotSame(0, memberList.size());
for (final Member member : memberList) {
if (member.getMemberId() <= 3) {
fail();
}
}
}
GreaterEqual
「GreaterEqual」
/**
* 会員ID「3」以上の会員IDを持った会員を検索
*
* @throws Exception
*/
public void test_ConditionBean_Query_GreaterEqual_Tx() throws Exception {
// ## Arrange ##
final Integer expectedMemberId = 3;
final MemberCB cb = new MemberCB();
cb.query().setMemberId_GreaterEqual(expectedMemberId);
// ## Act ##
final List<Member> memberList = memberBhv.selectList(cb);
// ## Assert ##
assertNotNull(memberList);
assertNotSame(0, memberList.size());
for (final Member member : memberList) {
if (member.getMemberId() < 3) {
fail();
}
}
}
LessThan
「LessThan」
/**
* 会員ID「3」より小さい会員IDを持った会員を検索
*
* @throws Exception
*/
public void test_ConditionBean_Query_LessThan_Tx() throws Exception {
// ## Arrange ##
final Integer expectedMemberId = 3;
final MemberCB cb = new MemberCB();
cb.query().setMemberId_LessThan(expectedMemberId);
// ## Act ##
final List<Member> memberList = memberBhv.selectList(cb);
// ## Assert ##
assertNotNull(memberList);
assertNotSame(0, memberList.size());
for (final Member member : memberList) {
if (member.getMemberId() >= 3) {
fail();
}
}
}
LessEqual
「LessEqual」
/**
* 会員ID「3」以下の会員IDを持った会員を検索
*
* @throws Exception
*/
public void test_ConditionBean_Query_LessEqual_Tx() throws Exception {
// ## Arrange ##
final Integer expectedMemberId = 3;
final MemberCB cb = new MemberCB();
cb.query().setMemberId_LessEqual(expectedMemberId);
// ## Act ##
final List<Member> memberList = memberBhv.selectList(cb);
// ## Assert ##
assertNotNull(memberList);
assertNotSame(0, memberList.size());
for (final Member member : memberList) {
if (member.getMemberId() > 3) {
fail();
}
}
}
PrefixSearch
ちょっと毛並みが変わります。前方一致検索を意味する
SQLでは
/**
* 会員名が「ス」で始まる会員を検索
*
* @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();
}
}
}
アプリケーションにおいて前方一致は一番よく利用される曖昧検索かと思われます。
そのため、
特徴としては、
...from MEMBER where MEMBER.MEMBER_NAME like 'ス%'
InScope
ある列に対して複数の値を条件に検索する
SQLでは
/**
* 会員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」
SQLでは
/**
* 会員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();
}
}
}
次回
基本的な演算子は一通り登場しました。さらには応用的なものが他にもあるのですが、
今回はソートや結合とかが全く出てきていません。気になっている方もいらっしゃるかと思いますので、