SimpleWhereのANDとORについて

ANDとORについて、突っ込んで調べてみようと思います。

ServiceClass

public List findOrderVoucherSimpleWhere(Where... wheres) {
return this.jdbcManager.from(OrderVoucher.class).where(wheres).getResultList();
}

ServiceClass2

public List findOrderVoucherSimpleWhere(Where wheres, Where wheres2) {
return this.jdbcManager.from(OrderVoucher.class).where(wheres).where(wheres2).getResultList();
}

ServiceClass3

public List findOrderVoucherSimpleWhere(Long startLength, Long endLength) {
return this.jdbcManager.from(OrderVoucher.class).where(new SimpleWhere().ge("id", startLength).le("id", endLength)).getResultList();
}

サービスクラスには3つの定義、最初はAND、2番目はORを想定しています。

テストケース

public void testSimpleWhereOutsideOR() throws Exception {
SimpleWhere where = new SimpleWhere().ge("id", Long.parseLong("1"));
SimpleWhere where2 = new SimpleWhere().le("id", Long.parseLong("5"));
List lists = orderVoucherService.findOrderVoucherSimpleWhere(where, where2);
assertEquals(lists.size(),5);
}

上記のテストケースの場合、最初、2番目、どちらが呼ばれるのでしょうか?
実行結果を見ると、

where (T1_.ID <= 5)

となっています。あら?
2番目の方がよばれているみたいですね。

Googleで検索すると、ServiceClass2の書き方ですと、最後の引数の値しか呼ばれないようです。
そして、ORの場合、直接記述した方がよいみたいです。
では、どうするのでしょうか?

ServiceClass2

public List findOrderVoucherSimpleWhere(String wheres) {
return this.jdbcManager.from(OrderVoucher.class).where(wheres).getResultList();
}

Where句を直接記述するように想定します。

テストケース

public void testSimpleWhereOutsideOR() throws Exception {
List lists = orderVoucherService.findOrderVoucherSimpleWhere("ID >= 1 OR ID <= 5");
assertEquals(lists.size(),14);
}

上記のように記述しますと、OR条件のSQLが実行されていました。


あらら?
解決策がありました。
SimpleWhere ではなく、ComplexWhereを使うと大丈夫のようです。

テストケース

public void testSimpleWhereOutsideOR2() throws Exception {
ComplexWhere where = new ComplexWhere ().ge("id", Long.parseLong("1")).or().le("id", Long.parseLong("5"));
List lists = orderVoucherService.findOrderVoucherSimpleWhere(where);
assertEquals(lists.size(),14);
}

色々と書いていますが、ServiceClassでメソッドを1つだけ定義し、ANDにもORにも、両方対応する事が可能です。パラメーターの型をStringにすれば、直接条件を記述する事ができます。使い方を理解すると、かなり強力な武器になりますね。