使用AI 编写一个Mybatis SQL日志解析工具

使用AI 编写一个Mybatis SQL日志解析工具

背景

尝试使用智谱清言 AI 编写一个工具,将Mybatis SQL日志解析为可以执行的SQL语句。

操作

准备初始代码

首先网站上找了一个有BUG的简单的实现 https://blog.csdn.net/x541211190/article/details/107410409

用提示词让AI分析代码

将以上代码贴给AI,并增加提示词分析上面代码的的功能,让AI分析代码。
分析结果如下:

这段HTML代码定义了一个简单的网页界面,目的是为了解析Mybatis框架的SQL日志,并将其转换为可执行的SQL语句。下面是代码的详细分析:
1. **HTML结构**:- 定义了一个标题“输入Mybatis SQL日志:”,和一个多行文本输入框`<textarea>`用于用户粘贴Mybatis的SQL日志。- 提供了两个按钮,“清空”用于清除文本框内容,“解析SQL”用于触发SQL解析功能。- 另有一个标题“解析为可执行SQL:”,和一个用于显示解析后SQL语句的多行文本框。- 提供了一个“复制SQL”按钮,用于将解析后的SQL语句复制到剪贴板。- 最后有一个`<div>`元素用于显示复制成功的提示信息。
2. **JavaScript功能**:- `f(obj)`函数:此函数接收textarea对象作为参数,提取其中的文本值,然后解析出SQL语句和参数。- 定位SQL语句的开始和结束位置,并提取出来。- 定位参数的开始和结束位置,并提取参数列表。- 遍历参数列表,根据参数的类型(字符串或时间戳为字符串类型,其他为数值类型),替换SQL语句中的占位符`?`。- 将解析后的SQL语句显示在页面上。- `copySQL()`函数:此函数用于将解析后的SQL语句复制到剪贴板。- 通过`select()`方法选择文本。- 使用`document.execCommand("Copy")`执行复制命令。- 显示复制成功的提示信息,并设置3秒后消失。- `clearLog(obj)`函数:此函数用于清空textarea中的内容。
3. **样式**:- 使用内联样式定义了文本框和按钮的大小、颜色等视觉样式。- 使用了`<font>`标签来定义标题的颜色,虽然这不是HTML5推荐的写法,但它仍然有效。
4. **用户交互**:- 用户可以将Mybatis的SQL日志粘贴到第一个文本框。- 点击“解析SQL”按钮后,JavaScript函数会解析日志,并将可执行的SQL语句显示在第二个文本框中。- 用户可以点击“复制SQL”按钮将解析后的SQL语句复制到剪贴板。
整体而言,这个网页界面是一个实用的工具,可以帮助开发者快速从Mybatis的日志中提取并转换出可执行的SQL语句,方便数据库的调试和优化。

用提示词让AI 找出代码的问题

分析解析日志的算法存在哪些问题? ,分析结果如下:

解析日志的算法存在以下问题:
1. **假设日志格式固定**:算法假设日志的格式是固定的,例如,`Preparing:`和`Parameters:`后面的内容格式和位置都是固定的。如果日志格式发生变化,例如空格数不同、换行位置变化或者增加了新的日志信息,算法可能无法正确解析。
2. **缺乏错误处理**:算法中没有错误处理机制。如果日志中不存在`Preparing:`或`Parameters:`,或者格式不正确,算法将无法正常工作,且不会提供任何错误信息。
3. **对参数类型的处理有限**:算法只处理了`String`和`Timestamp`类型的参数,将其用单引号括起来,其他类型直接替换。这种处理方式忽略了其他可能需要特殊处理的类型,例如`Date`或`Boolean`,也没有考虑到数值类型可能需要防止SQL注入的问题。
4. **参数解析不准确**:算法中参数解析的部分使用了`substring`和`indexOf`来提取参数值和类型,但如果参数值本身包含括号或者逗号,这将导致错误的解析。
5. **性能问题**:算法中使用了多次循环和字符串操作来解析日志,这可能在处理大量数据时导致性能问题。
6. **SQL注入风险**:算法直接将参数值替换到SQL语句中,对于数值类型没有进行任何转义或处理,这可能导致SQL注入攻击。
7. **缺乏对复杂SQL语句的支持**:如果SQL语句中本身就包含问号(?),算法会将这些问号错误地认为是参数占位符。
为了改进这个算法,可以考虑以下措施:
- 使用正则表达式来解析日志,这样可以更准确地处理不同格式的日志。
- 添加错误处理逻辑,对于无法解析的日志提供明确的错误信息。
- 对于不同类型的参数,使用适当的处理方式,例如对于数值类型使用参数化查询来防止SQL注入。
- 对于可能包含特殊字符的参数值,使用更可靠的解析方法,例如先提取所有参数,然后根据位置来替换SQL语句中的占位符。
- 提高算法性能,例如通过减少不必要的字符串操作和循环。
- 确保算法能够处理复杂的SQL语句,包括那些本身就包含问号的语句。

用提示词让AI修复代码的指定问题

修复其中的2,3,4,5,7的问题 修复后的结果

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Mybatis SQL日志解析</title><script type="text/javascript">function f(obj) {try {var textVa = obj.value;var logs = textVa.split('Preparing: '); // Split by "Preparing: "var results = [];logs.forEach(function(log) {// Check if this line contains "Preparing:" or "Parameters:"if (log.indexOf('Preparing:') === -1 && log.indexOf('Parameters:') === -1) {return; // Skip this line if it doesn't contain "Preparing:" or "Parameters:"}// 获取带问号的SQL语句var statementStartIndex = log.indexOf('Preparing: ');if (statementStartIndex !== -1) {var statementStr = log.substring(statementStartIndex + "Preparing: ".length).trim();} else {throw new Error("未找到SQL语句");}// 获取参数var parametersStartIndex = log.indexOf('Parameters: ');if (parametersStartIndex !== -1) {var parametersStr = log.substring(parametersStartIndex + "Parameters: ".length).trim();} else {// If "Parameters:" is not found, we assume there are no parametersparametersStr = "null";}// 解析参数var parameters = parametersStr.split(/,(?![^()]*\))/g); // 使用正则表达式正确分割参数// 替换SQL语句中的占位符for (var i = 0; i < parameters.length; i++) {var paramValue = parameters[i].trim();if (paramValue === "null") {// 如果参数是null,直接替换为NULLstatementStr = statementStr.replace("?", "NULL");} else {// 否则,根据类型替换参数var typeStr = paramValue.substring(paramValue.indexOf("(") + 1, paramValue.indexOf(")"));paramValue = paramValue.substring(0, paramValue.indexOf("(")).trim();if (typeStr === "String" || typeStr === "Timestamp") {paramValue = "'" + paramValue.replace("'", "''") + "'";}statementStr = statementStr.replace("?", paramValue);}}results.push(statementStr);});document.getElementById("d1").innerHTML = results.join("\n\n");} catch (e) {console.error(e);alert("解析SQL时发生错误:" + e.message);}}function copySQL() {var SQL = document.getElementById("d1");navigator.clipboard.writeText(SQL.value).then(function() {var msg = document.getElementById("msg");msg.innerHTML = "已复制到剪切板";setTimeout(function () {msg.innerHTML = "";}, 3000);}).catch(function(err) {console.error("复制失败:", err);alert("复制SQL时发生错误:" + err.message);});}function clearLog(obj) {obj.value = "";}</script>
</head>
<body>
<h2><font color="#00bfff"> 输入Mybatis SQL日志:</font></h2>
<textarea id="sqlLog" rows="13" cols="140" style="font-size:20px"></textarea>
<div style="border:0px deepskyblue solid;width:1425px;height:50px;text-align:right"><button style="color:mediumblue;width:100px;height:60px" type="button" onclick="clearLog(document.getElementById('sqlLog'))">清空</button><button style="color:mediumblue;width:100px;height:60px" type="submit" onclick="f(document.getElementById('sqlLog'))">解析SQL</button>
</div>
<h2><font color="#32cd32">解析为可执行SQL:</font></h2>
<textarea id="d1" rows="13" cols="140" style="font-size:20px"></textarea>
<div style="border:0px deepskyblue solid;width:1425px;height:50px;text-align:right"><button style="color:mediumblue;width:100px;height:60px" type="button" onclick="copySQL()">复制SQL</button>
</div>
<div id="msg" style="color:cornflowerblue;border:0px black solid;width:800px;height:20px;text-align:right;font-style: initial;font-size: large"></div>
</body>
</html>

用提示词让AI 继续分析代码

分析的结果如下:

上面的代码是一个HTML页面,包含JavaScript脚本,用于解析Mybatis SQL日志并生成可执行的SQL语句。具体功能如下:
1. 页面中包含一个文本域(sqlLog),用于输入Mybatis SQL日志。
2. 点击"解析SQL"按钮,会触发f()函数,对输入的SQL日志进行解析。
3. f()函数首先使用split()方法按"Preparing: "分割输入的日志字符串,然后遍历分割后的日志数组。
4. 对于每个日志条目,判断是否包含"Preparing:"或"Parameters:",如果不包含则跳过。
5. 获取带问号的SQL语句和参数,然后解析参数。
6. 对于SQL语句中的每个问号占位符,根据参数的类型替换为实际的参数值。
7. 将解析后的SQL语句显示在另一个文本域(d1)中。
8. 点击"复制SQL"按钮,会触发copySQL()函数,将解析后的SQL语句复制到剪切板。
9. 点击"清空"按钮,会清空sqlLog文本域中的内容。
10. 解析过程中如果发生错误,会弹出错误提示框。

用提示词让AI修改为支持多组日志的版本

需要修改为支持多组Mybatis SQL日志的解析,并且提供的日志中可能有非Mybatis SQL日志的行

AI 输出的版本如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Mybatis SQL日志解析</title><script type="text/javascript">function f(obj) {try {var textVa = obj.value;var logs = textVa.split('\n'); // Split by newlinevar results = [];var currentStatement = null;logs.forEach(function(log) {// Check if this line contains "Preparing:" or "Parameters:"if (log.indexOf('Preparing:') !== -1) {if (currentStatement !== null) {// If we have a current statement, push it to the resultsresults.push(currentStatement);}// Start a new statementcurrentStatement = log.substring(log.indexOf('Preparing:') + "Preparing:".length).trim();} else if (log.indexOf('Parameters:') !== -1 && currentStatement !== null) {// If we find parameters and have a current statement, parse the parametersvar parametersStr = log.substring(log.indexOf('Parameters:') + "Parameters:".length).trim();var parameters = parametersStr.split(/,(?![^()]*\))/g); // Use regex to split correctlyfor (var i = 0; i < parameters.length; i++) {var paramValue = parameters[i].trim();if (paramValue === "null") {currentStatement = currentStatement.replace("?", "NULL");} else {var typeStr = paramValue.substring(paramValue.indexOf("(") + 1, paramValue.indexOf(")"));paramValue = paramValue.substring(0, paramValue.indexOf("(")).trim();if (typeStr === "String" || typeStr === "Timestamp") {paramValue = "'" + paramValue.replace("'", "''") + "'";}currentStatement = currentStatement.replace("?", paramValue);}}// Add the final statement to the results and reset currentStatementresults.push(currentStatement);currentStatement = null;}});// If there's a remaining statement, push it to the resultsif (currentStatement !== null) {results.push(currentStatement);}document.getElementById("d1").value = results.join("\n\n");} catch (e) {console.error(e);alert("解析SQL时发生错误:" + e.message);}}function copySQL() {var SQL = document.getElementById("d1");navigator.clipboard.writeText(SQL.value).then(function() {var msg = document.getElementById("msg");msg.innerHTML = "已复制到剪切板";setTimeout(function () {msg.innerHTML = "";}, 3000);}).catch(function(err) {console.error("复制失败:", err);alert("复制SQL时发生错误:" + err.message);});}function clearLog(obj) {obj.value = "";}</script>
</head>
<body><h2><font color="#00bfff"> 输入Mybatis SQL日志:</font></h2>
<textarea id="sqlLog" rows="13" cols="140" style="font-size:20px"></textarea>
<div style="border:0px deepskyblue solid;width:1425px;height:50px;text-align:right"><button style="color:mediumblue;width:100px;height:60px" type="button" onclick="clearLog(document.getElementById('sqlLog'))">清空</button><button style="color:mediumblue;width:100px;height:60px" type="submit" onclick="f(document.getElementById('sqlLog'))">解析SQL</button>
</div><h2><font color="#32cd32">解析为可执行SQL:</font></h2>
<textarea id="d1" rows="13" cols="140" style="font-size:20px"></textarea>
<div style="border:0px deepskyblue solid;width:1425px;height:50px;text-align:right"><button style="color:mediumblue;width:100px;height:60px" type="button" onclick="copySQL()">复制SQL</button>
</div><div id="msg" style="color:cornflowerblue;border:0px black solid;width:800px;height:20px;text-align:right;font-style: initial;font-size: large"></div></body>
</html>

测试验证

将代码保存为一个后缀为html的文件,用浏览器打开,随便复制一段Mybatis SQL日志,测试效果基本没问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/774472.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【WEEK4】 【DAY5】AJAX第二部分【中文版】

2024.3.22 Friday 接上文【WEEK4】 【DAY4】AJAX第一部分【中文版】 目录 8.4.Ajax异步加载数据8.4.1.新建User.java8.4.2.在pom.xml中添加lombok、jackson支持8.4.3.更改tomcat设置8.4.4.修改AjaxController.java8.4.5.新建test2.jsp8.4.5.1.注意&#xff1a;和WEB-INF平级&…

.NET Core教程:入门与实践实例

.NET Core教程&#xff1a;入门与实践实例 在信息技术飞速发展的今天&#xff0c;掌握一门高效的编程技术成为了每个开发者不可或缺的技能。在众多编程框架中&#xff0c;.NET Core以其跨平台、高性能和易扩展的特性&#xff0c;受到了广大开发者的青睐。本文将通过实例&#…

一文解析:固定电感器结构、作用及其与扼流圈和可变电感器的差异

固定电感器是一种电子元件又称固定线圈&#xff0c;用于在电路中产生固定的电感值。电感是指导致电流变化时产生电动势的能力&#xff0c;通常用亨利&#xff08;Henry&#xff09;作为单位。固定电感器的电感值是预先确定的&#xff0c;通常以特定的数值标识&#xff0c;例如1…

免疫荧光染色

每次要将手/样品伸进细胞培养箱&#xff0c;生物培养平台D 中时&#xff0c;都要喷洒酒精消毒。 以两个样品/两个培养基为例 从细胞培养箱&#xff08;37度&#xff0c;5%CO2浓度&#xff09;取出要染色的细胞&#xff1b;放在显微镜下观察&#xff0c;观察细胞是否趴壁以及细…

【正点原子FreeRTOS学习笔记】————(10)FreeRTOS时间管理

这里写目录标题 一、延时函数介绍&#xff08;了解&#xff09;二、延时函数解析&#xff08;熟悉&#xff09;三、延时函数演示实验&#xff08;掌握&#xff09; 一、延时函数介绍&#xff08;了解&#xff09; 相对延时&#xff1a;指每次延时都是从执行函数vTaskDelay()开始…

onnxruntime 中的 Gather 算子

上一篇文章中介绍了 Division by Invariant Integers using Multiplication 的原理&#xff0c;很多框架均才用该算法优化除法运算。onnxruntime 是已知实现中最为简洁的&#xff0c;因此本文结合 onnxruntime 的 Gather 实现进行介绍。 Gather 算子是一个索引类算子&#xff0…

Python(django)之单一接口展示功能前端开发

1、代码 建立apis_manage.html 代码如下&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>测试平台</title> </head> <body role"document"> <nav c…

S7-200 SMART 选型指南及详细技术参数

S7-200 SMART 选型指南 选型指南 硬件能力 功能 CPU外形结构与电源需求计算 直流安装 交流安装 电源需求与计算 S7-200 SMART CPU模块提供5VDC和24VDC电源&#xff1a; CPU有一个内部电源&#xff0c;用于为CPU、扩展模块、信号板提供电源和满足其他24 VDC用户电源需求。请使…

数据结构二叉树计算公式

这些是关于二叉树、完全二叉树、B-树以及树的深度和高度的一些基本概念和重要性质。让我们一一解读这些性质: 二叉树的计数公式:给定 n 个节点,可以构造的不同二叉树数量是 (\frac{(2n)!}{n! \cdot (n+1)!})。这是一个来自组合数学的结果,称为 Catalan 数。这个公式非常重要…

鸿蒙HarmonyOS应用开发之使用Node-API接口进行线程安全开发

场景介绍 napi_create_threadsafe_function是Node-API接口之一&#xff0c;用于创建一个线程安全的JavaScript函数。主要用于在多个线程之间共享和调用&#xff0c;而不会出现竞争条件或死锁。例如以下场景&#xff1a; 异步计算&#xff1a;如果需要进行耗时的计算或IO操作&a…

Scala介绍与环境搭建

Scala环境搭建与介绍 一、Scala环境搭建 1、环境准备与下载 2、验证Scala 3、IDEA新建项目&#xff0c;配置Scala&#xff0c;运行Hello world 二、Scala介绍 1、Scala 简介 2、Scala 概述 一、Scala环境搭建 1、环境准备与下载 JDK1.8 Java Downloads | Oracle 下载需求版本…

如何将python项目转变成deb安装包

先将python项目转变成可执行文件 1. 首先确保你的python项目可以正常执行 2.安装pyinstaller模块&#xff0c;pip install pyinstaller -i Simple Index 3.确定好你的项目的文件入口&#xff0c;也就是运行的文件.py 4. 开始打包成单文件&#xff0c;pyinstaller -F <第…

美团春招内幕揭秘:2024最全面Spring CORS面试题解析,跨域问题大师级指南!

随着现代Web应用越来越多地采用前后端分离的架构&#xff0c;跨域资源共享&#xff08;CORS&#xff09;成为了Web开发中不可或缺的一部分。对于构建复杂、响应迅速的Web应用&#xff0c;了解并正确实施CORS策略是确保应用安全、高效运行的关键。美团&#xff0c;作为中国领先的…

STM32学习笔记(6_7)- TIM定时器的编码器接口原理

无人问津也好&#xff0c;技不如人也罢&#xff0c;都应静下心来&#xff0c;去做该做的事。 最近在学STM32&#xff0c;所以也开贴记录一下主要内容&#xff0c;省的过目即忘。视频教程为江科大&#xff08;改名江协科技&#xff09;&#xff0c;网站jiangxiekeji.com 现在开…

【Java程序设计】【C00374】基于(JavaWeb)Springboot的社区疫情管理系统(有论文)

TOC 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击卡片…

教学软件哪个好?这个一站式智慧教学系统值得推荐!

过去培训机构老师授课的场景主要在线下&#xff0c;可以使用大屏幕 PPT 来完成培训的交付&#xff0c;而现在随着数字化基础设施的完善&#xff0c;同时为了尽可能覆盖更多的人&#xff0c;依赖线下的培训场景也逐步转移到线上来完成&#xff0c;因此也对在线教学工具产生了需…

服务器硬件基础知识详解

服务器硬件基础知识涵盖了多个关键组件及其功能&#xff0c;以下是详细的介绍&#xff1a; 一. 处理器&#xff08;CPU&#xff09;&#xff1a; 处理器&#xff08;CPU&#xff0c;Central Processing Unit&#xff09;&#xff0c;即中央处理器&#xff0c;是电子计算机的主…

【前端学习——css篇】3.隐藏元素的方法

https://github.com/febobo/web-interview 3.隐藏元素的方法 diplay:none; 元素在页面消失&#xff0c;并且不占据页面空间 opacity:0; 设置元素透明度&#xff0c;仅元素不可见&#xff0c;占用空间 visibility:hidden; 元素不可见&#xff0c;占据页面空间&#xff0c;无…

如何用OBD创建OceanBase集群

OBD创建集群的方式适用于迅速搭建集群以进行测试工作。但是在涉及线上环境的部署时&#xff0c;推荐采用OCP进行集群的创建与管理。 有关OBD 的一些详细信息&#xff0c;可以去 github 了解&#xff0c;GitHub - oceanbase/obdeploy: A deployer and package manager for Ocea…

东方博宜 1521. 计算分数加减表达式的值

东方博宜 1521. 计算分数加减表达式的值 #include<iostream> #include<iomanip> using namespace std; int main() {double n ;cin >> n ;double sum ;sum 0.0 ;double j ;j 1.0 ;for (int i 1 ; i < n ; i){sum 1.0 / i * j ; j * -1 ;}cout <…