【SQL求助】使用SQL模板情况下,#(变量) 中含有 #p(参数)如何处理?

public static void main(String[] args) {

    ActiveRecordPlugin ar = new ActiveRecordPlugin(getDataSource());
    ar.start();

    Kv params = Kv.by("sb", "select name from account where id = #p(id)").set("id", 1);
    String sql = "select id,(#(sb)) from table where id = #p(id)";

    String ret = Db.templateByString(sql, params).getSqlPara().getSql();
    System.out.println(ret);
}

输出:

select id,(select name from account where id = #p(id)) from table where id = ?


上面的sql是演示SQL,实际的业务sql非常复查,所有子sql是通过业务判断才能传进模板。也许我走进死逻辑胡同了,但确实有这种场景 #(sb) 。这个子sql一开始是没有带id=#p(id)的,而是写死的值,但是这种写法,存在SQL注入漏洞。

或许我只能通过校验子sql的入参是否合法,然后 改成如下:

Kv params = Kv.by("sb", "select name from account where id = '#(id')").set("id", 1);
String sql = "select id,(#(sb)) from table where id = #p(id)";

但我的目的是想让子sql的参数也用预编译。

大家有没有什么好的办法?@JFinal

评论区

杜福忠

2021-02-24 10:36

好像目前默认没有处理方法,除非指令扩展自己做一个#sqlAdd(sb) ,利用里面的_SQL_PARA_二次充填sqlPara.addPara和输出sql。 但是感觉不如直接提取变量 sql=sql.replace("#(sb)", sb) 这样直观。。。

小徐同学

2021-02-24 11:12

@杜福忠 确实 您这个思路也行 谢谢。

小徐同学

2021-02-25 09:19

@杜福忠 制造一个空指令先用gettemplatebyString()处理下#p函数也行,但是无论哪种方式,如果主sql放到模板文件,就没办法取出来了。。jfinal并没有提供api直接从sql模板取出原样的sql

要输就输给追求

2021-02-25 09:45

@小徐同学 可以自己实例化一个enjoy对象处理从SQL模板文件读取SQL的问题,这样就能返回字符串,然后再交给Db.gettemplatebyString()处理。

要输就输给追求

2021-02-25 09:49

Jfinal 要是能arp.setEngine()这个问题就好处理了

hzh740053757

2021-02-25 10:48

杜福忠

2021-02-25 11:33

@小徐同学 新enjoy对象覆盖系统默认指令#p还有#para了,感觉还是在arp对象里面增加一个指令比较好。 默认可以取到的啊,稍等我写个例子代码哈

小徐同学

2021-02-25 11:42

@杜福忠 你看上面同学提的,已经完美解决了。

杜福忠

2021-02-25 11:42

@小徐同学 https://jfinal.com/share/2369 看看这个

热门反馈

扫码入社