条件文はSQLの構築で最も複雑になりやすいものです。
Criteriaは条件文を表現する抽象クラスで、
その子クラスには比較を表現するCompareのようにひとつの条件を表すものと
AndやOrのように複数の条件を保持するものがあります。
Compare
'=', '<' などの二つの要素の比較を表現します。
コンストラクタに列としてStingを渡した場合、
1番目の引数はカラム名、3番目の引数は値と解釈されます。
Criteria comparison = new Compare("column", "=", "value");
=> column = 'value'
二つの要素のいずれかのSQL表現が空の場合はこの条件文全体が空となります。
空文字列を検索条件としたい場合は
Valueオブジェクトを作成して空白を許容するようにセットする必要があります。
Criteria comparison = new Compare("column", "=", "");
=> 空文字列
Value value = new Value("");
value.setBlankable(true);
Criteria comparison = new Compare("column", "=", value);
=> column = ''
外部結合は、SQL Server であれば演算子に '*=' '=*' を指定します。
Oracleの場合はカラムを外部結合とする Column#setOuterJoin(boolean)
を使用します。また、テーブルにも Table#setOuterJoin(boolean) メソッドがあり、
TableをColumnにセットした場合はTableの外部結合フラグを引き継ぎます。
Table table1 = new Table("table1");
Table table2 = new Table("table2");
table1.setOuterJoin(true);
Compare criteria = new Compare(
new Column("column1", table1), "=", new Column("column2", table2));
=> table1.column1(+) = table2.column2
CriteriaText
CriteriaTextは条件文を表すテキストで基本的にはテキストをそのままSQLとして出力します。
オブジェクト構造をコーディングするよりテキストで書いた方が早い場合はこれを使用してください。
テキストに'?'が含まれる場合はバインド変数と解釈され、
渡された引数をSQLに埋込むかパラメータに蓄積します。
この場合はパラメータのいずれかがSQLとして空の場合にはこの条件全体が空となります。
Criteria criteria = new CriteriaText("(column1 || '-' || column2) = ?", "9999-99");
SqlQueryVisitor visitor = new SqlQueryVisitor();
criteria.accept(visitor);
=> (column1 || '-' || column2) = '9999-99'
Like
文字列のパターンマッチングを行います。
Criteria like = new Like("column", Like.CONTAINS, "abc");
SqlQueryVisitor sqlVisitor = new SqlQueryVisitor();
like.accept(sqlVisitor);
=> column LIKE '%abc%'
PrecompiledQueryVisitor precompiledVisitor = new PrecompiledQueryVisitor();
like.accept(precompiledVisitor);
=> column LIKE ?
=> パラメータとして"%abc%"を保持
部分一致の Like.CONTAINS のほかに前方一致の Like.STARTS_WITH と
Like.ENDS_WITH を用意してあります。
それ以外のパターンを使用する場合は2番目の引数でパターンを指定します。
パターンの中に '?' があると、順に3番目以降の引数で置換していきます。
Criteria like = new Like("column", "?_?", "abc", "def");
SqlQueryVisitor sqlVisitor = new SqlQueryVisitor();
like.accept(sqlVisitor);
=> column LIKE '%abc%column LIKE 'abc_def'
PrecompiledQueryVisitor precompiledVisitor = new PrecompiledQueryVisitor();
like.accept(precompiledVisitor);
=> column LIKE ?
=> パラメータとして"abc_def"を保持
Likeのコンストラクタの1番目の引数にStringを渡した場合はカラム名と解釈されます。
またすべての要素のうちひとつでも空の要素があるとこの条件全体が空となります。
Between
範囲指定です。
Criteria between = new Between("column", new BigDecimal("1.23"), new BigDecimal("3.45"));
=> column BETWEEN 1.23 AND 3.45
IN演算子
Inのパラメータはひとつずつ設定する以外に
配列やCollection、またはSELECT文をセットすることができます。
パラメータのうち空でない要素がひとつもない場合はこの条件全体が空になります。
String[] array = new String[] { "a", "b", "c" };
Criteria in = new In("column", array);
=> column IN ('a', 'b', 'c')
Exists
SELECT文を要素とする存在チェックです。
SelectStatement select = new SelectStatement("table", "*");
Criteria exists = new Exists(select);
=> EXISTS (SELECT * FROM table)
IsNull
列の値がNULLであるか、もしくはNULLでないかの判断条件です。
コンストラクタの引数にStringを渡した場合はカラム名と解釈されます。
Criteria isNull = new IsNull("column");
=> column IS NULL
IS NOT NULL の場合はNotで修飾します。
Criteria isNull = new Not(new IsNull("column"));
=> column IS NOT NULL
And, Or
複数の条件文を 'AND' もしくは 'OR' で連結します。
空でない要素がひとつも存在しない場合はこの条件全体が空となり、
空でない要素がひとつだけの場合はその条件自体をSQLとして出力します。
このオブジェクトの要素として AndかOrがセットされた場合は
子要素を括弧で括ります。
Criteria and = new And(
new Compare("column1", "=", "value1"));
CriteriaGroup or = new Or(
new Compare("column2", "=", "value2"),
new Compare("column3", "=", "value3"));
and.add(or);
=> column1 = 'value1' AND (column2 = 'value2' OR column3 = 'value3')
Not
引数で渡された条件文の先頭に 'NOT' を付加します。
必要に応じて条件文を括弧で括ります。
Criteria orgroup = new Or(
new Compare("column1", "=", "value1"),
new Compare("column2", "=", "value2"));
Criteria not = new Not(orgroup);
=> NOT (column1 = 'value1' OR column2 = 'value2')