news 2026/2/3 9:01:21

告别手动替换!MyBatis SQL日志一键解析工具(附完整源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
告别手动替换!MyBatis SQL日志一键解析工具(附完整源码)

告别手动替换!MyBatis SQL日志一键解析工具(附完整源码)

在日常开发中,我们经常需要通过 MyBatis 日志排查 SQL 问题,但 MyBatis 输出的日志中,SQL 语句的参数会以?占位符显示,例如:

Preparing: SELECT id, name, age FROM user WHERE id = ? AND status = ? Parameters: 1001(Integer), 1(Byte)

如果要直接在数据库中执行这条 SQL,需要手动将?替换为实际参数,不仅麻烦还容易出错(尤其是参数较多时)。今天给大家分享一个MyBatis SQL 日志一键解析工具,无需复杂配置,粘贴日志即可生成可直接执行的 SQL,彻底解放双手!

一、工具核心功能

  1. 🚀 自动提取日志中的 SQL 语句和参数
  2. 🧹 智能处理参数类型后缀(如(Integer)(String)自动剔除)
  3. ✅ 空值识别(null自动转为 SQL 标准NULL
  4. ⚠️ 异常场景提示(缺失关键字、参数与占位符不匹配等)
  5. 📋 一键复制可执行 SQL(兼容新旧浏览器)
  6. 🎨 友好 UI 设计(支持自适应、垂直resize、错误高亮提示)

二、使用教程(3步搞定)

步骤1:复制 MyBatis 日志

从日志文件或控制台中,复制包含Preparing:Parameters:的完整日志片段(示例如下):

Preparing: INSERT INTO order (order_no, user_id, amount, create_time) VALUES (?, ?, ?, ?) Parameters: 20240520001(String), 10086(Long), 99.9(Double), 2024-05-20 14:30:00(Timestamp)

步骤2:粘贴并解析

打开工具页面,将复制的日志粘贴到「输入Mybatis SQL日志」文本框,点击「解析SQL」按钮:

  • 若日志格式正确,会自动生成可执行 SQL 并显示在下方输出框
  • 若格式错误(如缺失关键字、参数不匹配),会显示红色错误提示

步骤3:复制执行

点击「复制SQL」按钮,即可将解析后的 SQL 复制到剪贴板,直接粘贴到数据库客户端执行:

INSERTINTOorder(order_no,user_id,amount,create_time)VALUES('20240520001','10086','99.9','2024-05-20 14:30:00')

三、核心代码解析(修复与优化点)

1. 解决原代码的关键问题

(1)参数类型后缀处理

原代码仅去除括号,导致张三(String)转为'张三String',修复后用正则提取纯参数:

// 正确剔除参数后的类型后缀(如 (String)、(Integer))constcleanParam=param.replace(/\s*\(.*?\)$/,'').trim();// 空值转为 SQL 标准 NULLreturncleanParam.toLowerCase()==='null'?'NULL':`'${cleanParam}'`;
(2)兼容现代浏览器的复制功能

废弃过时的document.execCommand("Copy"),改用navigator.clipboard,并保留降级方案:

asyncfunctioncopySQL(){try{// 现代浏览器优先使用 Clipboard APIawaitnavigator.clipboard.writeText(sqlText);showMessage('已成功复制到剪贴板!');}catch(err){// 降级处理:兼容旧浏览器sqlDom.select();document.execCommand('copy');showMessage('已成功复制(兼容模式)!');}}
(3)边界情况容错

添加空输入、关键字缺失、参数与占位符不匹配的判断:

if(!inputLog){showMessage('请输入MyBatis SQL日志内容!',true);return;}if(preparingIndex===-1){showMessage('未找到"Preparing: "标记!',true);return;}if(parametersIndex===-1){showMessage('未找到"Parameters: "标记!',true);return;}// 校验占位符与参数数量一致性constplaceholderCount=(statementStr.match(/\?/g)||[]).length;if(placeholderCount!==parameters.length){showMessage(`警告:占位符(${placeholderCount})与参数(${parameters.length})不匹配!`,true);}

2. UI/UX 优化

  • 文本域支持垂直resize,添加占位提示
  • 错误提示用红色高亮,普通提示用蓝色
  • 输出框设为只读,防止误修改
  • 按钮添加hover效果,提升交互体验

四、完整源码(可直接保存为HTML文件)

<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>MyBatis SQL Log Parser</title><style>.container{width:96%;margin:2% auto;}.button-3{appearance:none;background-color:#2ea44f;border:1px solidrgba(27,31,35,.15);border-radius:6px;box-shadow:rgba(27,31,35,.1)0 1px 0;box-sizing:border-box;color:#fff;cursor:pointer;display:inline-block;font-family:-apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif;font-size:14px;font-weight:600;line-height:20px;padding:6px 16px;margin:5px 0;text-align:center;text-decoration:none;user-select:none;vertical-align:middle;white-space:nowrap;}.button-3:hover{background-color:#2c974b;}textarea{width:100%;padding:12px 20px;box-sizing:border-box;border:2px solid #ccc;border-radius:4px;background-color:#f8f8f8;font-size:16px;resize:vertical;min-height:200px;margin:10px 0;}#msg{color:cornflowerblue;width:100%;height:20px;text-align:right;font-size:16px;margin:5px 0;}.error-msg{color:#dc3545!important;}h2{color:#333;margin:20px 0 10px;}</style></head><bodyclass="container"><h2>📥 输入Mybatis SQL日志:</h2><textareaid="sqlLog"placeholder="请粘贴包含 Preparing: 和 Parameters: 的完整日志(示例如下): Preparing: SELECT * FROM user WHERE id = ? Parameters: 1001(Integer)"></textarea><divstyle="width:100%;text-align:right"><buttonclass="button-3"type="button"onclick="clearLog()">🗑️ 清空</button><buttonclass="button-3"type="submit"onclick="parseSQL()">🔍 解析SQL</button></div><h2>📤 解析为可执行SQL:</h2><textareaid="parsedSql"readonlyplaceholder="解析后的SQL会显示在这里,可直接复制执行"></textarea><divstyle="width:100%;text-align:right"><buttonclass="button-3"type="button"onclick="copySQL()">📋 复制SQL</button></div><divid="msg"></div><scripttype="text/javascript">functionparseSQL(){constinputLog=document.getElementById('sqlLog').value.trim();constparsedSqlDom=document.getElementById('parsedSql');constmsgDom=document.getElementById('msg');// 重置状态parsedSqlDom.value='';msgDom.className='';msgDom.innerHTML='';// 空输入校验if(!inputLog){showMessage('请输入MyBatis SQL日志内容!',true);return;}// 关键标记定位constpreparingTag='Preparing: ';constparametersTag='Parameters: ';constpreparingIndex=inputLog.indexOf(preparingTag);constparametersIndex=inputLog.indexOf(parametersTag);// 标记存在性校验if(preparingIndex===-1){showMessage('未找到 "Preparing: " 标记,请检查日志格式!',true);return;}if(parametersIndex===-1){showMessage('未找到 "Parameters: " 标记,请检查日志格式!',true);return;}if(preparingIndex>parametersIndex){showMessage('日志顺序错误:Preparing 应在 Parameters 之前!',true);return;}// 提取并优化SQL语句(去除多余空格/换行)letstatementStr=inputLog.substring(preparingIndex+preparingTag.length,parametersIndex).trim().replace(/\s+/g,' ');// 提取并处理参数constparametersPart=inputLog.substring(parametersIndex+parametersTag.length).trim();constparameters=parametersPart?parametersPart.split(', ').map(param=>{constcleanParam=param.replace(/\s*\(.*?\)$/,'').trim();returncleanParam.toLowerCase()==='null'?'NULL':`'${cleanParam}'`;}):[];// 占位符与参数数量校验constplaceholderCount=(statementStr.match(/\?/g)||[]).length;if(placeholderCount!==parameters.length){showMessage(`⚠️ 警告:占位符(${placeholderCount})与参数(${parameters.length})数量不匹配!`,true);}// 替换占位符parameters.forEach(param=>{statementStr=statementStr.replace('?',param);});// 输出结果parsedSqlDom.value=statementStr;showMessage('✅ 解析成功!');}asyncfunctioncopySQL(){constsqlText=document.getElementById('parsedSql').value.trim();constmsgDom=document.getElementById('msg');msgDom.className='';if(!sqlText){showMessage('❌ 暂无可复制的SQL内容!',true);return;}try{awaitnavigator.clipboard.writeText(sqlText);showMessage('✅ 已复制到剪贴板!');}catch(err){try{constsqlDom=document.getElementById('parsedSql');sqlDom.select();document.execCommand('copy');showMessage('✅ 已复制(兼容模式)!');}catch(err2){showMessage('❌ 复制失败,请手动复制!',true);}}}functionclearLog(){document.getElementById('sqlLog').value='';document.getElementById('parsedSql').value='';document.getElementById('msg').innerHTML='';}functionshowMessage(message,isError=false){constmsgDom=document.getElementById('msg');msgDom.className=isError?'error-msg':'';msgDom.innerHTML=message;setTimeout(()=>msgDom.innerHTML='',3000);}</script></body></html>

五、使用注意事项

  1. 日志格式要求:必须同时包含Preparing:Parameters:关键字,且顺序正确
  2. 支持的参数类型:String、Integer、Long、Double、Timestamp 等常见类型
  3. 空值处理:日志中的null(不区分大小写)会自动转为 SQL 标准NULL
  4. 浏览器兼容性:支持 Chrome、Firefox、Edge 等现代浏览器,旧浏览器(如 IE)可能存在复制功能兼容问题

六、拓展方向(可选)

  1. 支持批量解析:同时解析多条 MyBatis 日志
  2. 自定义参数格式:允许用户配置参数引号(单引号/双引号)
  3. 日志格式适配:支持不同框架(如 MyBatis-Plus)的日志输出格式
  4. 导出功能:将解析后的 SQL 导出为 .sql 文件

如果大家在使用过程中遇到问题,或者有更好的优化建议,欢迎在评论区留言交流!觉得有用的话,别忘了点赞收藏哦~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/29 13:32:12

医疗影像AI开发革命:MONAIBundle极速配置新范式

在医疗影像AI开发领域&#xff0c;传统的手工编码模式正面临前所未有的挑战。研究人员在数据预处理、模型训练、性能评估等环节耗费大量时间&#xff0c;而临床部署的复杂性更是让许多优秀算法止步于实验室阶段。MONAIBundle的出现&#xff0c;标志着医疗AI开发正式进入"配…

作者头像 李华
网站建设 2026/1/31 14:23:27

CVAT标注工具入门指南:5分钟学会基本操作

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 使用CVAT标注工具&#xff0c;创建一个简单的图像分类任务。上传10张猫和狗的图片&#xff0c;用矩形框标注出动物位置&#xff0c;并打上类别标签。导出标注结果&#xff0c;生成T…

作者头像 李华
网站建设 2026/1/29 13:45:14

Simulink仿真:基于图腾柱PFC的单相整流器

simulink仿真-图腾柱 基于图腾柱PFC的单相整流器输入220V交流电 稳定输出400V直流电 电网电流电压同相位直接上干货&#xff01;今天要聊的是用Simulink实现基于图腾柱的无桥PFC整流器。这玩意儿能把220V交流电整成400V直流电&#xff0c;关键是能让电网电流和电压保持同相位—…

作者头像 李华
网站建设 2026/1/29 13:33:41

大型网站日志管理:logrotate实战经验分享

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个模拟大型网站日志管理的演示系统&#xff0c;包含&#xff1a;1. 高流量日志生成器 2. 多节点日志收集 3. 基于logrotate的自动轮转配置 4. 日志压缩和归档策略 5. 监控告警…

作者头像 李华