Mybatis日志参数快速替换占位符工具的详细步骤
Mybatislogprintf工具网页地址:http://www.feedme.ltd/log.html
Mybatis执行的sql的打印格式为:
2020-08-0409:16:44-DEBUG-[io-8888-exec-5].mapper.operation.OperationMapper.insert. debug145:==> Preparing:INSERTINTOtulu.t_log_operation(id,module,module_description,type,method,operator,operate_time)VALUES(?,?,?,?,?,?,unix_timestamp(now()))
2020-08-0409:16:44-DEBUG-[io-8888-exec-5].mapper.operation.OperationMapper.insert. debug145:==>Parameters:2743672230717162752(Long),1(Integer),登录(String),3(Integer),com.simba.tuloosa.controller.auth.LoginController.nativeLogin(String),6d63b98cbe5e42d18c126da149162404(String)
2020-08-0409:16:44-DEBUG-[io-8888-exec-5].mapper.operation.OperationMapper.insert. debug145:<== Updates:1
IDEA里有一个插件Mybatislogplugin可以帮我们快速的提取参数拼成完整的SQL语句执行,以快速排错,但是很可惜,他是收费的ε=(´ο`*)))唉,整来整取也没法破解,算了,不如自己写一个挂到公网上,也能复制sql随时拼接,纯js即可。
下面我们来逐步分析一下需要的步骤:
- 首先需要提取出preparedStatement语句
- 提取出所有的参数,String类型还需要手动添加引号
- 将statement中的占位符?替换为对应的参数
很简单吧,就这三步即可。接下来动手操作。
1、提取statement:只需截取从Preparing到行尾的\n即可
//str为完整的三行或两行SQL提取预编译语句 letprepare=str.substring(str.indexOf('Preparing')+11,str.indexOf('\n'))
indexOf(str:string):提取第一个匹配到的字符串的位置,返回其索引值
2、提取参数:只需截取从Parameters到其行尾的\n即可
这时我们需要提取到str的第二个\n换行符,怎么提取某个字符串中的第n个字符串呢?
indexOf()函数在js中是有重载的,默认提取第一个匹配的。它可以接受第二个参数,可以传入一个起始位置,即从position(索引)开始取第一个匹配的。
//jsapi indexOf(searchString:string,position?:number):number;
分析:取第二个\n,我们可以将第一个\n的索引传入再加1;取第三个\n,则将第二个\n的索引传入加1,以此类推,所以这是一个递归函数,实现如下
//返回字符串str中的第n字符串reg在str中的索引值index functionindex(str,reg,n){ if(!str||!reg||n<=0)return-1 //先求出第一个,再递归n-1 if(n===1){ returnstr.indexOf(reg) } //注意n-1的索引后一定要加1,负责会一直是第一个reg的索引 returnstr.indexOf(reg,index(str,reg,n-1)+1) }
接下来先测试一下index函数,打印正确
conststr='helloworldok' constreg='0' console.log(index(str,reg,3))//求第三个o的索引,打印结果是12,正确
完成函数提取,所以回到上面的步骤,继续提取第二个\n的位置
//获取参数字符串,去掉所有空格 constparams=str.substring(str.indexOf('Parameters')+12,index(str,'\n',2)).replace(//g,'')
获取参数后以逗号切割,返回是一个字符串参数数组
constarray=params.split(',') //['2743672230717162752(Long)','1(Integer)','登录(String)','3(Integer)']
提取完毕,则进行第三步的替换
3、替换参数
//遍历数组,每次调用一次replace(old,new)即可,对字符串参数需要加上引号 array.map(item=>{ //获取每个参数值 letnewValue=item.substring(0,item.indexOf('(')) //获取参数类型 consttype=item.substring(item.indexOf('(')+1,item.indexOf(')')) if('String'===type){ newValue="'"+newValue+"'" } prepare=prepare.replace('?',newValue) }) //遍历完毕,所有的占位符也就被参数替换完成啦 console.log(prepare) //INSERTINTOtulu.t_log_operation(id,module,module_description,type,method,operator,operate_time)VALUES(2743672230717162752,1,'登录',3,'com.simba.tuloosa.controller.auth.LoginController.nativeLogin','6d63b98cbe5e42d18c126da149162404',unix_timestamp(now()))
这样我们就实现了整个的js遍历、寻找、替换逻辑,整个过程就是不停的去indexOf(),substring()和replace(),是不是很简单呢,手写一个就不用了去找插件了。
我把这个网页放在了我的公网服务器上,访问地址是http://www.feedme.ltd/log.html
方便直接打开使用。
另外懒得写样式和DOM,所以在线引用了vue.js和elemenui,可能会出现有时候加载js文件速度比较慢的情况。
最后贴出整个HTML代码:
MybatisLogHelper 转换