enjoy自定义指令实现sql模板重用

初衷是因为sql文件有些重复代码导致文件太长、冗余太大、不雅观,一开始思路是用#define 指令定义函数来实现,不够优雅,就换成了自定义指令(仅适用于重用的sql中不包含#para指令的情况),实现如下:

1、自定义指令sqlKey代码:

public class SqlKeyDirective extends Directive {
    private Expr key;
    @Override
    public void setExprList(ExprList exprList) {
        int paraNum = exprList.length();
        if (paraNum != 1) {
            throw new ParseException("The parameter of #number directive can not be blank", location);
        }
        key = exprList.getExpr(0);
    }

    @Override
    public void exec(Env env, Scope scope, Writer writer) {
        write(writer, Db.getSql(key.eval(scope).toString()));
    }
}

2、configPlugin中添加注册Sqlkey自定义指令(注意不能加在configEngine中,因为configEngine在configPlugin之后):

arp.getEngine().addDirective("sqlKey", SqlKeyDirective.class);

3、a.sql文件内容:

例如需要查询和统计表a的内容:

### 整理重用的字段,类似mybatis中的sql标签
#sql("baseCloumn")
    id,name
#end

### 重用的sql
#sql("queryA")
    select 
        #sqlKey("a.baseCloumn")  
    from a
#end

### 注意此方式要求重中的sql中不能包含#para指令
#sql("countA")
  select count(id) as num from (
     #sqlKey("a.queryA")
     
     #if(id)
        where id = #para(id)
     #end
     .....很长很长的sql语句...
  ) a
#end

4、使用

查询a表的数据:Db.template("a.queryA").find()
统计a表的数据:Db.template("a.countA", Kv.by("id", "a")).findFirst()

注意此方式因Db.getSql()不支持#para()指令,如重用的sql中用到#para指令需要用#define自定义函数实现。

评论区

JFinal

2023-04-02 16:51

指令扩展是最高级、最强大的扩展方式,实现这个功能是最好的。谢谢分享

后面 arp 中的 enjoy sql 我考将 sqlKey 更名为 sqlId,所以,建议享主将 #sqlKey(...) 指令改为 #sqlId(...),能省点代码量

受伤的蚂蚁

2023-04-02 17:42

@JFinal 好的,一开始用的就是sqlId,后来参考的文档中的“#sql 指令”部分提到了sqlkey,才命名为sqlKey的,个人感觉sqlKey比sqlId美观,但多一个字母...

北流家园网

2023-04-03 08:20

l745230

2023-04-04 14:50

这个用法很赞, 不用在写define了.

热门分享

扫码入社