换种方式,打印 MyBatis 执行 SQL 语句!
一、前言
片面了!
一月三舟,托尔斯泰说:“多么伟大的作家,也不过就是在书写自己的片面而已”。何况是我,何况是我们!
虽然我们不书写文章,但我们写需求、写代码、写注释,当我们遇到了需要被讨论的问题点时,往往变成了争论点。这个好、那个差、你用的都是啥啥啥!
当你把路走窄了,你所能接受到的新的思路、新的想法、新的视野,以及非常重要的收入,也都会随之减少。只有横向对比、参考借鉴、查漏补缺,才能让你的头脑中会有更多的思路,无论是在写代码上、还是在理财上、还是在生活上。
二、需求目的
你是否有在使用 IntelliJ IDEA 做开发的过程,需要拿到执行 SQL 语句,复制出来做验证的时候,总是这样的语句:SELECT * FROM USER WHERE id = ? AND name = ? 又需要自己把 ? 号 替换成入参值呢?
当然这个需求其实并不大,甚至你还可以使用其他方式解决。那么在本章节会给你提供一个新的思路,可能你几乎是没过的方式进行处理。
那么在这个章节的案例中我们用到基于 IDEA Plugin 开发能力,把字节码插桩探针,基于 Javaagent 的能力,注入到代码中。再通过增强后的字节码,获取到 com.mysql.jdbc.PreparedStatement -> executeInternal 执行时的对象,从而拿到可以直接测试的 SQL 语句。
三、案例开发
1. 工程结构
公众号:bugstack虫洞栈 回复:idea 即可下载全部 IDEA 插件开发源码
在此 IDEA 插件工程中,工程结构分为2块:
- probe-agent:探针模块,用于编译打包提供字节码增强服务,给 probe-plugin 模块使用
- probe-plugin:插件模块,通过 java.programPatcher加载字节码增强包,获取并打印执行数据库操作的 SQL 语句。
2. 字节码增强获取 SQL
此处的字节码增强方式,采用的 Byte-Buddy 字节码框架,它的使用方式更加简单,在使用的过程中有些像使用 AOP 的拦截方式一样,获取到你需要的信息。
此外在 gradle 打包构建的时候,需要添加 shadowJar 模块,把 Premain-Class 打包进去。这部分代码中可以查看
2.1 探针入口
cn.bugstack.guide.idea.plugin.PreAgent
- 通过 Byte-buddy 配置,拦截匹配的类和方法,因为这个类和方法下,可以获取到完整的执行 SQL 语句。
2.2 拦截 SQL
cn.bugstack.guide.idea.plugin.MonitorMethod
- 拦截方法入参是一种可配置操作,比如 @This Object obj是为了获取当前类的执行对象,@Origin Method method是为了获取执行方法。
- 在 finally 块中,我们可以通过反射拿到当前类的属性信息,以及反射拿到执行的 SQL,并做打印输出。
2.3 编译打包
在测试和开发 IDEA Plugin 插件之前,我们需要先进行一个打包操作,这个打包就是把字节码增强的代码打包整一个 Jar 包。在 build.gradle -> shadowJar
- 打包编译后,就可以在 build -> libs 下看到 Jar:probe-agent-1.0-SNAPSHOT-all.jar这个 Jar 就是用来做字节码增强处理的。
2.4 测试验证
这里在把写好的字节码增强组件给插件使用之前,可以做一个测试验证,避免每次都需要启动插件才能做测试。
单元测试
- VM options:-javaagent:你的路径\libs\probe-agent-1.0-SNAPSHOT-all.jar
- 注意在测试运行的时候,你要给 ApiTest 配置 VM options 才能打印拦截 SQL 信息
测试结果
- 好啦,这样我们就可以拦截可以复制执行的 SQL 语句了,接下来我们再做下 IDEA Plugin 的处理。
3. 通过插件开发引入探针 Jar
接下来我们要把开发好的字节码增强 Jar 包,复制到 IDEA Plugin 插件开发模块中的 libs(可自己创建) 下,之后在 plugin.xml 配置加载 implementation fileTree(dir: 'libs', includes: ['*jar']) 这样就可以程序中,找到这个 jar 包并配置到程序中。
3.1 复制 jar 到 libs 下
3.2 build.gradle 配置加载
- 通过 implementation fileTree引入加载文件树的方式,把我们配置好的 Jar 加载到程序运行中。
3.3 程序中引入 javaagent
cn.bugstack.guide.idea.plugin.PerRun
- 通过继承 JavaProgramPatcher类,实现patchJavaParameters方法,通过 configuration 属性来配置我们自己需要被加载的-javaagent包。
- 这样在通过 IDEA 已经安装此插件,运行代码的时候,就会执行到这个拦截和打印 SQL 的功能。
3.4 plugin.xml 添加配置
- 之后你还需要把开发好的加载类,配置到 java.programPatcher这样就可以程序运行的时候,被加载到了。
四、测试验证
- 准备好一个有数据库操作的工程,需要的是 JDBC,如果是其他的,你需要自己扩展
- 启动插件后,打开你的工程,运行单元测试,查看打印区
启动插件
- 如果你是新下载代码,那么可以在 probe-plugin -> Tasks -> intellij -> runIde 中进行运行启动。
单元测试
测试结果
- 通过测试结果可以看到,我们可以获取到直接拿去测试验证的 SQL 语句了,就不用在复制带问号的 SQL 还得修改后测试了。
五、总结
- 首先我们是在本章节初步尝试使用多模块的方式来创建工程,这样的方式可以更加好维护各类一个工程下所需要的代码模块。你也可以尝试使用 gradle 创建多模块工程
- 对于字节码插桩增强的使用方式,本篇只是一个介绍,这项技术还可以运用到更多的场景,开发出各种提升研发效率的工具。
- 了解额外的 Jar 包是怎么加载到工程的,以及如何通过配置的方式让 javaagent引入自己开发好的探针组件。
相关文章
- 数据分析领域的七大热门职业
- 如何利用OpenTelemetry识别数据库依赖关系?
- 七种常用数据分析思维,解决90%分析难题
- 从0到1,搭建决策分析模型
- 一个注解优雅的实现接口数据脱敏
- Spark的两种核心Shuffle详解
- 数据研发该如何做好业务方管理
- 你真的了解ELT和ETL吗?
- 社交媒体分析在未来业务中将发挥着至关重要的作用
- 不会体系化建模,那数据治理不就是瞎搞吗?
- 聊聊HBase海量数据高效入仓解决方案
- SparkSQL 在企业级数仓建设的优势
- Truncate、Delete和Drop的六大区别!你知道几个?
- 《大数据》保护法来了!看看都有谁被罚了?具体内容是什么?
- 数据是新石油,提炼新石油要遵循四个原则
- 未来大数据时代下的智能交通是什么样的?
- 大数据究竟有多“大”?谷歌搜索的规模为 62 PB,排名倒数第一
- 元宇宙时代即将到来,你准备好了吗?
- OpenHarmony数据转码应用开发实战(中)
- 数据湖三剑客,大数据时代的新范式?