自定义 escapePara 指令规避特殊 sql value

    如题:我既想规避特殊 value 又想已 #para 的方式处理 sql,我的实现方式是重写 ParaDirective 的 exec 方法,直接上代码

import java.lang.reflect.Field;
import java.util.List;

import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.activerecord.sql.ParaDirective;
import com.jfinal.template.Env;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.Scope;

public class EscapeParaDirective extends ParaDirective {

	// 拿到 SqlPara paraList 字段,方便后面 escape value
	static Field paraList;
	static {
		try {
			paraList = SqlPara.class.getDeclaredField("paraList");
			paraList.setAccessible(true);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public void exec(Env env, Scope scope, Writer writer) {
		super.exec(env, scope, writer);
		SqlPara sqlPara = (SqlPara) scope.get("_SQL_PARA_");
		try {
			List<Object> list = (List<Object>) paraList.get(sqlPara);
			// 没有数据 skip
			if (list == null || list.size() == 0) {
				return;
			}
			// 移除最后添加的 value 并拿到移除的 value
			Object oldValue = list.remove(list.size() - 1);
			list.add(escape(String.valueOf(oldValue)));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	static String escape(String value) {
		if (value != null) {
			if (value.indexOf('#') != -1)
				value = value.replaceAll("#", "##");
			if (value.indexOf('_') != -1)
				value = value.replaceAll("_", "#_");
			if (value.indexOf('%') != -1)
				value = value.replaceAll("%", "#%");
		}
		return value;
	}
}


最后在 sk.getEngine().addDirective("escapePara", EscapeParaDirective.class); 添加,即可用 #escapePara(0) 使用指令使用了

评论区

JFinal

2019-03-26 18:14

速度超快,这么快就实现了这个功能,赞

热门分享

扫码入社