JFinal

登录 注册

sql查询再添助力, JFinal框架dao层模块ActiveRecord指令扩展

import ax.utilext.asInstanceOf
import cn.hutool.core.util.ReflectUtil
import com.jfinal.plugin.activerecord.ActiveRecordException
import com.jfinal.plugin.activerecord.SqlPara
import com.jfinal.template.Directive
import com.jfinal.template.Env
import com.jfinal.template.io.Writer
import com.jfinal.template.stat.Scope
import java.lang.RuntimeException
/*------------------------
      author: 张天笑
      date: 2018/11/12
      time: 0:08
    sql查询再添助力, JFinal框架dao层模块ActiveRecord指令扩展
    语言:
        Kotlin
    依赖:
        Kotlin标准库
        JFinal3.x
        Hutool一反射方法
    演示:
        val params = hashMapOf<String, Any?>()
        params.put("name", "张天笑")
        params.put("age", 21)
        params.put("id_card", "411***********2212")
        // #p 指令传入参数, #end结尾,
        // map中若存在name且不为null, 则 #p #end 之间第一行保留
        // map中若存在age且不为null, 则 #p #end 之间第二行保留
        // map中若存在id_card且不为null, 则 #p #end 之间第三行保留
        //kt是支持多行字符串的, 这里只是为了一眼看上去更加明了
        var sql = "select x from t where true" +
                "#p(name,age,id_card)" +
                "and t.name = ?" +
                "and t.age = ?" +
                "and t.id_card = ?" +
                "#end"
        Db.use().findByStrTpl(sql,params)
    辅助函数:
            fun DbPro.getSqlParaByString(sql: String, param: Map<String, Any?>): SqlPara {
                param as HashMap<String, Any?>
                val engine = this.config.sqlKit.engine
                val template = engine.getTemplateByString(sql)
                val sqlPara = SqlPara()
                param["_SQL_PARA_"] = sqlPara
                val string = template.renderToString(param)
                param.remove("_SQL_PARA_")
                sqlPara.setSql(string)
                return sqlPara
            }
    findByStrTpl:
            // 返回 List<Record>
            fun DbPro.findByStrTpl(sql_tpl: String, param: Map<String, Any?> = hashMapOf()): List<Record> {
                val sql_para = getSqlParaByString(sql_tpl, param)
                val para: Array<Any> = sql_para.para
                return find(sql_para.sql, *para)
            }
-------------------------*/
class PDirective : Directive() {
    override fun exec(env: Env, scope: Scope, writer: Writer) {
        val sb = ReflectUtil.getFieldValue(this.stat, "content")?.asInstanceOf<StringBuilder>()
        if (sb == null) throw RuntimeException("检查p指令内容是否没写~, 请")
        //按回车换行解析出的每一行字符串
        val fragments = sb.split("\n").filter { it.isNotEmpty() }
        //不为空白字符串, 不为空串, 且包含问号
        val para_framments = fragments.filter { it.isNotBlank() && it.isNotEmpty() && it.contains("?") }
        //传入指令的参数列表
        val directory_params = exprList.exprArray
        //带有问号的字符串片段长度 与参数列表长度不同
        if (para_framments.size != directory_params.size) {
            throw ActiveRecordException("带有问号的字符串片段长度 与参数列表长度不同")
        }
        val sqlPara = scope.get("_SQL_PARA_") as SqlPara
        var i = 0
        fragments.forEach {
            if (it.contains("?")) {
                val name = directory_params[i++]
                val value = name.eval(scope)
                if (value != null) {
                    sqlPara.addPara(value)
                    write(writer, it)
                    write(writer, "\n")
                }
            }
        }
        //  stat.exec(env, scope, writer)
    }
    override fun hasEnd() = true
}


评论