如题:我既想规避特殊 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) 使用指令使用了