Mybatis⽇志参数快速替换占位符⼯具
Mybatis log printf⼯具⽹页地址:
Mybatis执⾏的sql的打印格式为:
2020-08-0409:16:44-DEBUG -[io-8888-exec-5].mapper.operation.OperationMapper.insert.        debug 145:==>  Preparing: INSERT INTO tulu.t_log_op eration (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.        debug 145:==> Parameters:2743672230717162752(L ong),1(Integer),登录(String),3(Integer), com.ller.auth.LoginController.nativeLogin(String),6d63b98cbe5e42d18c126da149162404(S tring)
2020-08-0409:16:44-DEBUG -[io-8888-exec-5].mapper.operation.OperationMapper.insert.        debug 145:<==    Updates:1
IDEA⾥有⼀个插件Mybatis log plugin可以帮我们快速的提取参数拼成完整的SQL语句执⾏,以快速排错,但是很可惜,他是收费的ε= (´ο`*)))唉,整来整取也没法破解,算了,不如⾃⼰写⼀个挂到公⽹上,
也能复制sql随时拼接,纯js即可。
下⾯我们来逐步分析⼀下需要的步骤:
1. ⾸先需要提取出preparedStatement语句
2. 提取出所有的参数,String类型还需要⼿动添加引号
3. 将statement中的占位符?替换为对应的参数
很简单吧,就这三步即可。接下来动⼿操作。
1、提取statement:只需截取从Preparing到⾏尾的\n即可
// str为完整的三⾏或两⾏SQL    提取预编译语句
let prepare = str.substring(str.indexOf('Preparing')+11, str.indexOf('\n'))
indexOf(str: string):提取第⼀个匹配到的字符串的位置,返回其索引值
2、提取参数:只需截取从Parameters到其⾏尾的\n即可
这时我们需要提取到str的第⼆个\n换⾏符,怎么提取某个字符串中的第n个字符串呢?
indexOf()函数在js中是有重载的,默认提取第⼀个匹配的。它可以接受第⼆个参数,可以传⼊⼀个起始位置,即从position(索引)开始取第⼀个匹配的。
// js api
indexOf(searchString: string, position?: number): number;
分析:取第⼆个\n,我们可以将第⼀个\n的索引传⼊再加1;取第三个\n,则将第⼆个\n的索引传⼊加1,以此类推,所以这是⼀个递归函数,实现如下
// 返回字符串str中的第n字符串reg在str中的索引值index
function index(str, reg, n){
if(!str ||!reg || n <=0)return-1
// 先求出第⼀个,再递归n-1
if(n ===1){
return str.indexOf(reg)
}
// 注意n-1的索引后⼀定要加1,负责会⼀直是第⼀个reg的索引
return str.indexOf(reg,index(str, reg, n -1)+1)
}
接下来先测试⼀下index函数,打印正确
const str ='hello world ok'
const reg ='0'
console.log(index(str, reg,3))// 求第三个o的索引,打印结果是12,正确
完成函数提取,所以回到上⾯的步骤,继续提取第⼆个\n的位置
// 获取参数字符串,去掉所有空格
const params = str.substring(str.indexOf('Parameters')+12,index(str,'\n',2)).replace(//g,'')
获取参数后以逗号切割,返回是⼀个字符串参数数组
const array = params.split(',')
// ['2743672230717162752(Long)','1(Integer)','登录(String)','3(Integer)']
提取完毕,则进⾏第三步的替换
3、替换参数
// 遍历数组,每次调⽤⼀次replace(old, new)即可,对字符串参数需要加上引号
array.map(item =>{
// 获取每个参数值
let newValue = item.substring(0, item.indexOf('('))
// 获取参数类型
const type = item.substring(item.indexOf('(')+1, item.indexOf(')'))
if('String'=== type){
newValue ="'"+ newValue +"'"
}
prepare = prepare .replace('?', newValue)
})
// 遍历完毕,所有的占位符也就被参数替换完成啦
console.log(prepare)
// INSERT INTO tulu.t_log_operation (id, module, module_description, type, method, operator, operate_time) VALUES (2743672230717162752, 1, '登录', 3, 'com.ller.auth.LoginController.nativeLogin', '6d63b98cbe5e42d18c126da149162404', unix_timestamp(now()))
这样我们就实现了整个的js遍历、寻、替换逻辑,整个过程就是不停的去indexOf(),substring()和replace(),是不是很简单呢,⼿写⼀个就不⽤了去插件了。
另外懒得写样式和DOM,所以在线引⽤了vue.js和elemenui,可能会出现有时候加载js⽂件速度⽐较慢的情况。
最后贴出整个HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Mybatis Log Helper</title>
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>
<link rel="shortcut icon" href=""/>
<script src="unpkg/vue@2.6.11/dist/vue.js"></script>
<!--引⼊样式-->
<link rel="stylesheet" href="unpkg/element-ui/lib/theme-chalk/index.css">
<!--引⼊组件库-->
<script src="unpkg/element-ui/lib/index.js"></script>
<style>
<style>
#app {
margin-top:70px;
display: flex;
idea debugjustify-content: space-evenly;
align-items: center;
font-family:"Helvetica Neue", Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅⿊", Arial, sans-serif; }
</style>
</head>
<body>
<div id="app">
<el-input type="textarea" v-model="pre" placeholder="请复制输⼊Mybatis打印的⽇志,须完整Prepareing语句和Parameter语句"
:rows="28" ></el-input>
<el-button type="success" @click="convert" >转换</el-button>
<el-input type="textarea" v-model="res" placeholder="输出结果"
:rows="28" ></el-input>
</div>
<script type="text/javascript">
const app =new Vue({
el:'#app',
data(){
return{
// 原始str
pre:'',
// 输出结果
res:''
}
},
methods:{
convert(){
const str =this.pre
if(str.indexOf('Preparing')==-1|| str.indexOf('Parameters')==-1){
this.$message({
message:'请将Preparing和Parameters语句复制进来',
type:'error',
center:true
})
}
// str为完整的三⾏或两⾏SQL    提取预编译语句
let prepare = str.substring(str.indexOf('Preparing')+11, str.indexOf('\n'))
// 获取参数,去空格
const params = str.substring(str.indexOf('Parameters')+12,index(str,'\n',2)).replace(/ /g,'')
// 参数数组
const array = params.split(',')
// 循环替换占位符,字符串⽅式替换每次替换第⼀个
array.map(item =>{
// 获取每个参数值
let newValue = item.substring(0, item.indexOf('('))
// 获取参数类型
const type = item.substring(item.indexOf('(')+1, item.indexOf(')'))
if('String'=== type){
newValue ="'"+ newValue +"'"
}
prepare = prepare .replace('?', newValue)
})
}
}
})
// 返回字符串str中的第n字符串reg在str中的索引值index
function index(str, reg, n){
if(!str ||!reg || n <=0)return-1
if(!str ||!reg || n <=0)return-1
// 先求出第⼀个,再递归n-1
if(n ===1){
return str.indexOf(reg)
}
// 注意n-1的索引后⼀定要加1,负责会⼀直是第⼀个reg的索引return str.indexOf(reg,index(str, reg, n -1)+1)
}
// 测试index函数
const str ='hello world ok'
const reg ='o'
console.log(index(str, reg,3))
</script>
</body>
</html>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。