如何优雅的将Mybatis日志中的Preparing与Parameters转换为可执行SQL
疫情期间大家宅在家里是不是已经快憋出“病”了~~
公司给开了VPN,手机电脑都能连,手机装上APP测试包,就能干活了,所以walking从2020.02.01入京以来,已经窝在家里11天了。这两天在家远程办公,预测下周也要在家办公。。
最近在家隔离期间,其实也是学的少玩的多。这不,今天在看Mybatis源码的时候发现了一款好用的Mybatis插件和一个转换工具,今天就赶忙写出来分享给大伙。
我们大家在工作中应该都是用过Mybatis吧,有时候我们在本地调试的时候,会打开Mybatis的SQL日志打印,那么打印出来的SQL是下图这样的
你可以看到预编译的SQL条件用占位符(?)了select * from User where id = ? ,并不是真实的SQL select * from User where id = 1 。
如果我们想得到真实的SQL,像上图那样参数少的话还可以自己把参数值手动拼上去,但是如果参数多了呢?是不是自己手动填就很麻烦了。
不用MAME麻烦,今天就告诉你如何将mybatis日志的Preparing与Parameters转化为可执行sql。
分享两种方式哈,一种是IDEA的插件mybatis log plugin,另一种是没有条件安装这个插件或者没有IDEA的时候,一种静态页面的方式。
第一种 mybatis log plugin插件
在Idea的setting - plugins里搜索mybatis log plugin,如下图,点击install即可,然后按照提示重启idea就行了。(如下已经安装完成)
然后我们就可以选中SQL日志右键选择:Restore Sql from Selection
然后就可以在Mybatis Log窗口看到真实的SQL了
然后就可以复制出来到别的地方执行了
第二种 静态页面工具
另外还有聪明的同学搞了个静态页面出来,以便于在无法安装上述plugin的时候用。
原作者的文章地址:https://blog.csdn.net/Zale_J/article/details/89402668
只需要搞个html文件,然后把作者的源码贴进去,然后保存,用浏览器打开,再把mybatis日志帖进去点击“转换”即可得到真实SQL。源码我在下面也贴出来了。
效果图:
源代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function f(obj){ var textVa = obj.value; // 获取带问号的SQL语句 var statementStartIndex = textVa.indexOf('Preparing: '); var statementEndIndex = textVa.length-1; for(var i = statementStartIndex; i < textVa.length; i++) { if(textVa[i] == "\n") { statementEndIndex = i; break; } } var statementStr = textVa.substring(statementStartIndex+"Preparing: ".length, statementEndIndex); console.log(statementStr); //获取参数 var parametersStartIndex = textVa.indexOf('Parameters: '); var parametersEndIndex = textVa.length-1; for(var i = parametersStartIndex; i < textVa.length; i++) { if(textVa[i] == "\n") { parametersEndIndex = i; break; } else { console.log(textVa[i]); } } var parametersStr = textVa.substring(parametersStartIndex+"Parameters: ".length, parametersEndIndex); parametersStr = parametersStr.split(","); console.log(parametersStr); for(var i = 0; i < parametersStr.length; i++) { // 如果数据中带括号将使用其他逻辑 tempStr = parametersStr[i].substring(0, parametersStr[i].indexOf("(")); // 获取括号中内容 typeStr = parametersStr[i].substring(parametersStr[i].indexOf("(")+1,parametersStr[i].indexOf(")")); // 如果为字符类型 if (typeStr == "String" || typeStr == "Timestamp") { statementStr = statementStr.replace("?", "'"+tempStr.trim()+"'"); }else{ // 数值类型 statementStr = statementStr.replace("?", tempStr.trim()); } } console.log(statementStr); document.getElementById("d1").innerHTML = statementStr; return textVa; } </script> </head> <body> <textarea name="getStr" id="1" rows="4" cols="100"></textarea> <button type="submit" onclick="f(document.getElementById('1'))">转换</button> <div id="d1"></div> </body> </html>
还有另外一位网友,说原作者的有一点bug,具体什么bug也没说,应该是做了一些优化什么的吧。具体什么我也没有验证。
优化的原文:https://www.cnblogs.com/n031/p/11176346.html
下面是效果图:
优化的代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>mybatis转换</title> <script type="text/javascript"> function f(obj) { var textVa = obj.value; // 获取带问号的SQL语句 var statementStartIndex = textVa.indexOf('Preparing: '); var statementEndIndex = textVa.length - 1; for (var i = statementStartIndex; i < textVa.length; i++) { if (textVa[i] == "\n") { statementEndIndex = i; break; } } var statementStr = textVa.substring(statementStartIndex + "Preparing: ".length, statementEndIndex); console.log(statementStr); //获取参数 var parametersStartIndex = textVa.indexOf('Parameters: '); var parametersEndIndex = textVa.length; for (var i = parametersStartIndex; i < textVa.length; i++) { if (textVa[i] == "\n") { parametersEndIndex = i; break; } else { // console.log(textVa[i]); } } var parametersStr = textVa.substring(parametersStartIndex + "Parameters: ".length, parametersEndIndex); console.log(parametersStr); // 参数列表 var parametersStrArr = parametersStr.split(","); console.log(parametersStrArr); for (var i = 0; i < parametersStrArr.length; i++) { tempStr = parametersStrArr[i].substring(0, parametersStrArr[i].indexOf("(")); // 不含"("是null if(tempStr == ''){ tempStr = "null"; } // 如果数据中带括号需要判断参数类型 typeStr = parametersStrArr[i].substring(parametersStrArr[i].indexOf("(") + 1, parametersStrArr[i].indexOf(")")); if (typeStr == "String" || typeStr == "Timestamp") { statementStr = statementStr.replace("?", "'" + tempStr.trim() + "'"); } else { statementStr = statementStr.replace("?", tempStr.trim()); } } console.log(statementStr); document.getElementById("d1").innerHTML = statementStr; return true; } </script> </head> <body> <button type="submit" onclick="f(document.getElementById('1'))">转换</button><br><br> <textarea style="border:blue solid 2px;" name="getStr" id="1" rows="25" cols="150"></textarea><br> <p style="color:red;font:30px bold;">你的SQL</p> <div style="border:red solid 2px;" id="d1"></div> </body> </html>
这俩种方式具体用哪个视情况而定。感谢这两位作者的聪明才智和无私奉献。
如果感觉有用的话赶紧分享给你的小伙伴吧,现在没时间搞的话先收藏起来吧~
武汉加油!中国加油!!
手机阅读的用户可移至公众号哦,更方便。