SimpleWhereVisitor.java
package com.github.mygreen.sqlmapper.core.where.simple;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.github.mygreen.sqlmapper.core.where.Where;
import com.github.mygreen.sqlmapper.core.where.WhereVisitor;
/**
*
*
*
* @author T.TSUCHIE
*
*/
public class SimpleWhereVisitor implements WhereVisitor {
/**
* SQL中のパラメータ変数。
*
*/
private List<Object> paramValues = new ArrayList<>();
/**
* 組み立てたクライテリア
*/
private StringBuilder criteria = new StringBuilder();
/**
* 組み立てたクライテリアを取得します。
* @return クライテリア
*/
public String getCriteria() {
return criteria.toString();
}
/**
* SQLのパラメータ変数を取得します。
* SQLのプレースホルダ―順に設定されています。
* @return SQL中のパラメータ変数。
*/
public List<Object> getParamValues() {
return Collections.unmodifiableList(paramValues);
}
/**
* {@inheritDoc}
*
* @throws IllegalArgumentException サポート対象外の引数を指定したときスローされます。
*/
@Override
public void visit(Where where) {
if(where instanceof SimpleWhere) {
visit((SimpleWhere) where);
} else if(where instanceof SimpleWhereBuilder) {
visit((SimpleWhereBuilder) where);
} else {
throw new IllegalArgumentException("unknown where class : " + where.getClass().getName());
}
}
/**
* {@link SimpleWhere} を処理します。
* <p>条件式を {@literal AND}でつなげます。</p>
* @param where 条件式
*/
public void visit(final SimpleWhere where) {
for(Term term : where.getTerms()) {
if(criteria.length() > 0) {
criteria.append(" and ");
}
term.accept(this);
}
}
/**
* {@link SimpleWhereBuilder} を処理します。
* <p>条件式を {@literal OR}でつなげます。</p>
* @param where 条件式
*/
public void visit(final SimpleWhereBuilder where) {
List<String> result = new ArrayList<>();
// 式の項がまだ持っているときは、子要素に追加する。
where.or();
// 子要素の式を組み立てる。
if(!where.getChildrenWhere().isEmpty()) {
for(Where subWhere : where.getChildrenWhere()) {
SimpleWhereVisitor subVisitor = new SimpleWhereVisitor();
subVisitor.visit(subWhere);
String sql = subVisitor.getCriteria();
if(!sql.isEmpty()) {
result.add(sql);
paramValues.addAll(subVisitor.getParamValues());
}
}
}
if(result.size() == 1) {
// 1つしかない場合は、そのまま設定する。
criteria.append(result.get(0));
} else {
for(String sql : result) {
if(criteria.length() > 0) {
criteria.append(" or ");
}
criteria.append("(").append(sql).append(")");
}
}
}
/**
* 式({@link Exp})を処理します。
* @param exp 処理対象の式。
*/
public void visit(Exp exp) {
criteria.append(exp.getExp());
for(int i=0; i < exp.valuesSize(); i++) {
paramValues.add(exp.getValueAt(i));
}
}
/**
* {@link WhereTerm}を処理します。
* SQL式は括弧{@literal (...)}で囲みます。
* @param whereTerm 処理対象のwhere句
*/
public void visit(WhereTerm whereTerm) {
Where subWhere = whereTerm.getWhere();
SimpleWhereVisitor subVisitor = new SimpleWhereVisitor();
subVisitor.visit(subWhere);
criteria.append("(")
.append(subVisitor.getCriteria())
.append(")");
paramValues.addAll(subVisitor.getParamValues());
}
}