sql打印的一种暴力解决方式
Sql log 失效
以 MyBatis 为例,因为其他辅助框架的不同,或者某些条件限制,导致日志按照官网配置后可能出现仍然无法打印的情况,这时候可能就会想到写sql拦截器自己拦截生成sql填充参数,但可能需要一定的开发时间。
本文直接挑明一种暴力打印的方式,不清楚是否广泛可用,但有兴趣的老哥们可以试一下。
Java 类加载优先级
会按照 classpath 的顺序去加载,遇到 全限定名相同的类
时只会加载第一个,而 classpath 目录的默认值是 .
, 也就是当前目录。
换句话说当项目跑起来的时候会优先加载自己写的 class
, 这是暴力方法的基础。
Sql的执行方法
以 MyBatis Mysql
为例,一直 debug
跟踪到 JDBC
层会找到这个方法 PrepareStatement.execute
方法(批量执行对应的(PrepareStatement.executeBatchInternal
)),最开始的时候在这里找到了生成最终 payloadPacket
估计就是客户端发送包里有sql, 后来转念一想这个类中应该有个差不多生成 sql
的方法,的确就是 PrepareStatement.asSql
,到这其实结合刚刚的Java加载优先级机制暴力的方法已经出来了。
具体方案
将jdbc
包中的 souce code
下载下来,(jetbrains idea
的话只需要点击下这个类的右上角有个 download source
的方法)下载成功后,按照该类包的路径在项目中创建一个同路径的包,然后将其放进去,同时修改 PrepareStatement.execute
, 在其首部执行 (log.info(asSql()))
即可。(这里的 log
是 lombok
的@SLF4J
生成的,可以根据自己的喜好选择打印的方式)
- Post title:sql打印的一种暴力解决方式
- Post author:ReZero
- Create time:2021-01-23 14:33:00
- Post link:https://rezeros.github.io/2021/01/23/sql-log-cheat/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
Comments