ComparisionOpHandler.java
package com.github.mygreen.sqlmapper.core.where.metamodel;
import com.github.mygreen.sqlmapper.metamodel.Path;
import com.github.mygreen.sqlmapper.metamodel.Visitor;
import com.github.mygreen.sqlmapper.metamodel.expression.Constant;
import com.github.mygreen.sqlmapper.metamodel.expression.Expression;
import com.github.mygreen.sqlmapper.metamodel.operation.Operation;
import com.github.mygreen.sqlmapper.metamodel.operator.ComparisionOp;
/**
* 比較演算子({@link ComparisionOp})に対する処理を定義します。
*
*
* @author T.TSUCHIE
*
*/
public class ComparisionOpHandler extends OperationHandler<ComparisionOp> {
@Override
protected void init() {
// 比較演算子 - General
addTemplate(ComparisionOp.EQ, "{0} = {1}");
addTemplate(ComparisionOp.NE, "{0} <> {1}");
addTemplate(ComparisionOp.IN, "{0} in {1}");
addTemplate(ComparisionOp.NOT_IN, "{0} not in {1}");
addTemplate(ComparisionOp.BETWEEN, "{0} between {1} and {2}");
addTemplate(ComparisionOp.GOE, "{0} >= {1}");
addTemplate(ComparisionOp.GT, "{0} > {1}");
addTemplate(ComparisionOp.LOE, "{0} <= {1}");
addTemplate(ComparisionOp.LT, "{0} < {1}");
}
@Override
public void handle(ComparisionOp operator, Operation<?> expr, Visitor<VisitorContext> visitor, VisitorContext context) {
if(operator == ComparisionOp.BETWEEN) {
handleBetween(operator, expr, visitor, context);
return;
}
Expression<?> left = expr.getArg(0);
Expression<?> right = expr.getArg(1);
VisitorContext leftContext = new VisitorContext(context);
VisitorContext rightContext = new VisitorContext(context);
// 左辺の評価
invoke(operator, left, visitor, leftContext);
/*
* 比較演算子の場合、左変=プロパティパス、右辺=定数で構成される場合、
* 定数をプロパティの変換規則に従い変換する。
*/
if(isPropertyPath(left) && right instanceof Constant) {
visitConstantWithPropertyPath((Path<?>)left, (Constant<?>)right, rightContext);
} else {
invoke(operator, right, visitor, rightContext);
}
// 評価した結果を親のコンテキストに追加する
String sql = formatWithTemplate(operator, leftContext.getCriteria(), rightContext.getCriteria());
context.appendSql(sql);
context.addParamValues(leftContext.getParamValues());
context.addParamValues(rightContext.getParamValues());
}
private void handleBetween(ComparisionOp operator, Operation<?> expr, Visitor<VisitorContext> visitor, VisitorContext context) {
Expression<?> left = expr.getArg(0);
Expression<?> right1 = expr.getArg(1);
Expression<?> right2 = expr.getArg(2);
VisitorContext leftContext = new VisitorContext(context);
VisitorContext rightContext1 = new VisitorContext(context);
VisitorContext rightContext2 = new VisitorContext(context);
// 左辺の評価
invoke(operator, left, visitor, leftContext);
/*
* 比較演算子の場合、左変=プロパティパス、右辺=定数で構成される場合、
* 定数をプロパティの変換規則に従い変換する。
*/
if(isPropertyPath(left) && right1 instanceof Constant) {
visitConstantWithPropertyPath((Path<?>)left, (Constant<?>)right1, rightContext1);
} else {
invoke(operator, right1, visitor, rightContext1);
}
if(isPropertyPath(left) && right2 instanceof Constant) {
visitConstantWithPropertyPath((Path<?>)left, (Constant<?>)right2, rightContext2);
} else {
invoke(operator, right2, visitor, rightContext2);
}
// 評価した結果を親のコンテキストに追加する
String sql = formatWithTemplate(operator, leftContext.getCriteria(), rightContext1.getCriteria(), rightContext2.getCriteria());
context.appendSql(sql);
context.addParamValues(leftContext.getParamValues());
context.addParamValues(rightContext1.getParamValues());
context.addParamValues(rightContext2.getParamValues());
}
}