1. 程式人生 > >如何優雅的將Mybatis日誌中的Preparing與Parameters轉換為可執行SQL

如何優雅的將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>

 

這倆種方式具體用哪個視情況而定。感謝這兩位作者的聰明才智和無私奉獻。

 如果感覺有用的話趕緊分享給你的小夥伴吧,現在沒時間搞的話先收藏起來吧~

武漢加油!中國加油!!


 

手機閱讀的使用者可移至公眾號哦,更方便。