like指令的升级版(v2)

不说什么了,直接上代码

public class LikeDirective extends Directive {

	private int index = -1;

	private int length = 0;

	private ExprList exprList;

	// 前模糊
	private boolean beforeFuzzy = true;
	// 后模糊
	private boolean afterFuzzy = true;
	
	@Override
	public void setExprList(ExprList exprList) {
		if (exprList.length() < 1 || exprList.length() > 3) {
			throw new ParseException("参数数量错误,必须在1到3之间", location);
		}
		this.length = exprList.length();
		Expr expr = null;
		//三个参数的时候取中间的
		if (length == 3) {
			expr = exprList.getExpr(1);
		}else {
			expr = exprList.getExpr(0);
		}
		if (expr instanceof Const && ((Const) expr).isInt()) {
			index = ((Const) expr).getInt();
			if (index < 0) {
				throw new ParseException("The index of para array must greater than -1", location);
			}
		}
		this.exprList = exprList;
	}

	@Override
	public void exec(Env env, Scope scope, Writer writer) {
		SqlPara sqlPara = (SqlPara) scope.get("_SQL_PARA_");
		getFuzzy(scope);
		//左右都不模糊直接 = 
		if (!beforeFuzzy && !afterFuzzy) {
			write(writer, "= ?");
		} else {
			write(writer, "like concat(");
			//左模糊
			if (beforeFuzzy) {
				write(writer, "'%', ");
			}
			write(writer, "?");
			//右模糊
			if (afterFuzzy) {
				write(writer, ", '%'");
			}
			write(writer, ")");
		}
		// 参数
		Expr expr = null;
		//三个参数的时候取中间的
		if (length == 3) {
			expr = exprList.getExpr(1);
		}else {
			expr = exprList.getExpr(0);
		}
		if (index == -1) {
			sqlPara.addPara(expr.eval(scope));
		} else {
			Object[] paras = (Object[]) scope.get("_PARA_ARRAY_");
			if (paras == null) {
				throw new TemplateException("The #para(" + index + ") directive must invoked by getSqlPara(String, Object...) method", location);
			}
			if (index >= paras.length) {
				throw new TemplateException("The index of #para directive is out of bounds: " + index, location);
			}
			sqlPara.addPara(paras[index]);
		}
	}

	public void getFuzzy(Scope scope) {
		//两个参数时
		if (length == 2) {
			Object object = exprList.getExpr(1).eval(scope);
			//boolean 时为开关模糊
			if (object instanceof Boolean) {
				beforeFuzzy = afterFuzzy = (Boolean) object;
			} 
			//数字时 大于0为右模糊  小于0未左模糊
			else if (object instanceof Number) {
				beforeFuzzy = ((Number) object).intValue() < 0;
				afterFuzzy = ((Number) object).intValue() > 0;
			}
			//字符串时 
			else if (object instanceof String) {
				String str = ((String) object);
				beforeFuzzy = str.equalsIgnoreCase("l") || str.equalsIgnoreCase("left") || str.equals("-1");
				afterFuzzy = str.equalsIgnoreCase("r") || str.equalsIgnoreCase("right") || str.equals("1");
			}
		}
		//三个参数时
		else if(length == 3) {
			{
				//第一个参数 为左模糊状态
				Object object = exprList.getExpr(0).eval(scope);
				if (object instanceof Boolean) {
					beforeFuzzy = (Boolean) object;
				} else if (object instanceof Number) {
					beforeFuzzy = ((Number) object).intValue() == 1;
				} else if (object instanceof String) {
					String str = ((String) object);
					beforeFuzzy = str.equals("1") || str.equalsIgnoreCase("true");
				}
			}
			{
				//第三参数 为右模糊状态
				Object object = exprList.getExpr(2).eval(scope);
				if (object instanceof Boolean) {
					afterFuzzy = (Boolean) object;
				} else if (object instanceof Number) {
					afterFuzzy = ((Number) object).intValue() == 1;
				} else if (object instanceof String) {
					String str = ((String) object);
					afterFuzzy = str.equals("1") || str.equalsIgnoreCase("true");
				}
			}
		}
		
	}

}

使用

image.png

输出效果

image.png

评论区

l745230

2020-09-08 17:53

不模糊这个参数感觉多余了. #like(name) #likeLeft(name) #likeRight(name) 更好记忆

hzh740053757

2020-09-08 17:59

@l745230 后面两个参数支持表达式的哦

l745230

2020-09-09 08:17

@hzh740053757 感觉表达式什么的意义不大,最终3种%的场景.

JJfinal

2020-09-09 11:34

#like(true, user_name, false) 第一感觉这样好记点 true表示有% false没有%

JFinal

2020-09-09 12:01

@JJfinal 你的这个设计符合直觉:#like(true, user_name, false)

JFinal

2020-09-09 12:02

@hzh740053757 建议改成 #like(true, user_name, false) 这个设计

hzh740053757

2020-09-09 14:46

@JJfinal @JFinal 稍稍改了下