告别SQL盲猜!5种打印SQL语句的实战方案

Arthas 线上环境调试 打印方法输入输出 Arthas 线上环境调试 打印方法输入输出 Arthas curl -L https://arthas.aliyun.com/install.sh | sh vi as.sh 设置JAVA_HOME 查看进程: jps 启动: ./as.sh 进程号 watch -b com.tianan.v2x.axtagent.web.controller.api.MessagePushController rss ‘“params[0]=”+params[0]’ watch -b com.tianan.v2x.a 阅读详情

01 引言

在我们日常开发中,SQL的打印我们不太关注。因为线下的调试,我们通过断点,日志等方式可以快速定位问题。

但是提测之后或者线上,发现数据与预期的数据不符,需要对比SQL的条件。线上的不能随意发布代码,导致排查问题变的困难。

本期,我们从线下到线上整理一下几种好用的打印SQL的方案:

  • ORM内置日志功能
  • P6Spy框架
  • 日志框架
  • Mybaits拦截器
  • AOP切面
  • Arthas打印SQL

02 ORM内置日志功能

Mybaits是一款非常优秀的ORM框架,DAO层的设计它占了半壁江山。而其内部配置本身支持SQL的打印,线下测试的时候,我们经常会将次配置打开,以便随时了解SQL的执行情况。

properties配置

# 控制台输出SQL
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

xml配置

mybatis-configuration.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
		<setting name="logImpl" value="STDOUT_LOGGING"/>
	</settings>
</configuration>

properties配置和xml配置,任意配置一项即可。

结果

打印的参数和结果都有了,这样的SQL已经足够我们排查问题。但是不太方便复制值别人查看,需要替换参数才行。Idea的插件Mybatis log free可以帮我们自动填充参数,用起来简直不要太爽。

03 P6Spy 实现

GitHub地址:https://github.com/p6spy/p6spy

这是一款第三方的数据库日志框架,里面提供了很多配置,可以随意定制日志格式。配置详见:

https://p6spy.readthedocs.io/en/latest/configandusage.html

3.1 Maven依赖

<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>${latest.version}</version>
</dependency>

3.2 配置修改

# 数据源
spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:p6spy:mysql://127.0.0.1:3306/test
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test

需要修改源数据源的参数,具有代码侵入性。

3.3 创建 spy.properties

# 部分配置
module.log=com.p6spy.engine.logging.P6LogFactory
appender=com.p6spy.engine.spy.appender.StdoutLogger
logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
customLogMessageFormat=%(executionTime)ms | SQL: %(sqlSingleLine)

3.4 结果

结果可以看到数据库连接的信息,预执行的SQL以及执行的SQL。

04 日志框架

日志框架的方式,是可以指定任意包的。

配置:

# logging.level.xxxx=debug
logging.level.com.simonking.boot.mybaits.mapper.UserInfoNativeMapper=debug

这里指定我们需要打印的Mapper。

结果:

这种方式也是我们生产上经常使用的动态监控某个包下SQL的方案。此方案需要借助配置中心apollo、nacos等,动态更新日志的级别,已达到按需打印SQL的目的。

05 Mybaits拦截器

Mybaits拦截器,之前的文章里介绍过,就不再赘述。我们需要拦截的是org.apache.ibatis.executor.statement.StatementHandler的prepare()方法。

@Intercepts({@Signature(
        type = StatementHandler.class,
        method = "prepare",
        args = {Connection.class, Integer.class})
})
@Component
public class SqlPrintInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler handler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = handler.getBoundSql();
        // 获取原始SQL
        String sql = boundSql.getSql();

        Object param = boundSql.getParameterObject();

        // 美化SQL输出
        System.out.println("\n=============== SQL日志 ===============");
        System.out.println("原始SQL:" + sql);
        System.out.println("SQL: " + sql.replaceAll("\\s+", " ").trim());
        System.out.println("参数: " + JSON.toJSONString(param));
        System.out.println("=====================================");

        return invocation.proceed();
    }
}

结果

06 AOP动态拦截

AOP的做法,需要熟悉调用SQL的方法。实现起来门槛较高,需要了解具体的参数。

我们这里拦截Mapper,和日志框架类似。

@Aspect
@Component
public class SqlLoggerAspect {

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Around("execution(* com.simonking.boot.mybaits.mapper.UserInfoNativeMapper.*(..))")
    public Object logSql(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature)pjp.getSignature();
        Method method = signature.getMethod();
        String namespace = method.getDeclaringClass().getName();
        String methodName = method.getName();

        Configuration configuration = sqlSessionFactory.getConfiguration();
        MappedStatement mappedStatement = configuration.getMappedStatement(namespace + "." + methodName);

        Map<String, Object> map = new HashMap<>();
        Object obj = pjp.getArgs()[0];
        Class<?> clazz = obj.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String fieldName = field.getName();
            Object value = field.get(obj);
            map.put(fieldName, value);
        }

        BoundSql boundSql = mappedStatement.getBoundSql(map);

        System.out.println("[AOP SQL] " + boundSql.getSql());
        System.out.println("[AOP SQL 参数]: " + JSON.toJSONString(map));
        return pjp.proceed();
    }
}

结果

07 Arthas打印SQL

Arthas是一款Java在线诊断工具,之前也介绍过。用它也可以打印SQL。

# 全部参数
watch org.apache.ibatis.executor.SimpleExecutor doQuery '{params[0].resource,params[0].id,params[4].sql,params[4].parameterObject,returnObj,throwExp}' 'params[0].id.contains("xxx.xxxMapper")' -x 3

# 只打印sql和参数
watch org.apache.ibatis.executor.SimpleExecutor doQuery '{params[4].sql,returnObj}' 'params[0].id.contains("xxx.xxxMapper")' -x 3

结果:

这种方式在生产上应用也非常使用,根据需要抓取需要的SQL信息。

但是这样的方法是对SQL的注解脚本无效,如:@Select、@Update等

08 小结

线下的SQL打印可以随意玩,怎么方便怎么来。但是线上的打印SQL的方案就需要谨慎。如果开启打印SQL,那么频繁打印SQL不仅存在数据安全问题,还会引起CPU标高或者线程池变满(我已经被毒打过了,不要轻易去试)。

线上还是推荐按需收集SQL,推荐采用配置中心实时修改日志级别,或者Arthas按需采集SQL。

SQL注入进阶:报错注入、延时注入与Python自动化盲注实战 SQL注入作为Web安全领域的核心漏洞类型,其本质是攻击者通过构造恶意SQL语句,欺骗后端数据库执行非授权操作。理解其原理需要掌握数据库查询机制与用户输入处理间的安全边界。从技术价值看,深入SQL注入技术不仅能揭示数据泄露风险,更是构建有效防御体系的基础。在实际应用场景中,当网站不直接显示查询结果或错误信息时,传统的联合查询注入便告失效,此时需要借助更高级的技巧如报错注入和延时注入。报错注入利用数据库函数(如updatexml、extractvalue)的执行错误来泄露信息,而延时注入则依赖条件语句触发时间 阅读详情

相关推荐

告别Excel!用Grid++Report设计批量打印标签,5分钟搞定仓库发货单

本文介绍如何利用Grid++Report快速设计批量打印标签,替代传统的Excel方案,解决仓库发货单打印中的格式错乱、分组困难等问题。通过详细的模板设计、智能分组和条码集成方案,帮助电商和仓储物流企业提升效率,实现5分钟搞定批量打印任务。

weixin_30617737的博客 539

Mybatis打印SQL语句常用方式

在使用mybatis进行开发的时候,由于可以动态拼接sql,这样大大方便了我们。但是也有一定的问题,当我们动态sql拼接的块很多的时候,我们要想从*mapper.xml中直接找出完整的sql就会非常的难,这个时候经常会需要把组合之后的完整SQL语句打印出来,对调试非常有帮助的。在Mybatis的配置文件中添加debug标签,设置为true即可打印SQL语句和参数信息,同时也会输出相关的结果集信息。在Mybatis的配置文件中配置log4j或其他日志框架,然后配置输出级别、输出格式等。

yangzhihua的专栏 1万+

告别Excel!用Grid++Report设计批量打印标签,5分钟搞定仓库货架卡

本文介绍了如何使用Grid++Report快速设计批量打印仓库货架标签,解决Excel打印中的格式错位、效率低下和分组困难等问题。通过可视化模板设计、智能分组和条码组件,5分钟即可完成专业标签打印,大幅提升仓库管理效率。

weixin_33716941的博客 349

arthas实用命令

打印mybatis查询某个dao的特定sql tt命令,时空隧道,记录多次执行数据 查询多个方法的执行过程和耗时 查询mongo的执行语句

qq_601254926 1142

告别Excel!用JimuReport的SQL数据源,5分钟搞定学生信息报表(附完整SQL语句)

本文介绍了如何利用JimuReport的SQL数据源快速生成学生信息报表,告别繁琐的Excel操作。通过实战演示,展示了从数据库连接、SQL查询到报表设计的全流程,5分钟内即可完成包含分页统计、条件筛选和多格式导出的智能报表,显著提升教育行业数据处理效率。

weixin_28717431的博客 334

告别Excel!用JimuReport积木报表+SQL数据源,5分钟搞定动态学生信息报表

本文介绍了如何使用JimuReport积木报表结合SQL数据源快速生成动态学生信息报表,告别繁琐的Excel操作。通过零代码设计器和智能SQL数据集,用户可在5分钟内完成报表创建,实现数据实时更新、多维度筛选和一键导出,显著提升工作效率。

weixin_30709061的博客 439

arthas学习

arthas使用

g3230863的博客 2210

告别MyBatis的‘?‘占位符:用P6Spy在Spring Boot里打印可直接执行的SQL(附完整配置)

本文详细介绍了如何在Spring Boot项目中集成P6Spy工具,以解决MyBatis和Hibernate日志中SQL预编译占位符带来的调试不便。通过P6Spy,开发者可以打印可直接执行的完整SQL语句,提升调试效率和性能分析能力。文章包含完整的配置步骤、高级日志格式定制以及生产环境最佳实践,帮助开发者快速掌握这一实用工具。

weixin_30652897的博客 169

mybatis配置输出执行sql日志

配置日志打印sql 方式一,设置mybatis日志输出类## 标题 #输出查询结果 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl #不输出查询结果 #mybatis.configuration.log-impl=org.apache.ibatis.logging.log4j2.Log4j2Impl 方式二,设置mapper接口日志等级为debug logging.level.com.xxx.xxx.da

blood_Z的博客 1万+

SpringBoot中高效SQL调试与日志优化方案

SQL调试是数据库开发中的关键环节,传统问号占位符日志需要人工拼接参数,效率低下。通过拦截器技术可在运行时捕获完整SQL语句,结合MyBatis的BoundSql对象能准确还原动态SQL的真实执行形态。这种方案不仅提升开发调试效率,还能实现慢查询监控等扩展功能。在SpringBoot生态中,基于MyBatis-Plus拦截器机制进行改造,既保持框架兼容性又避免性能损耗。典型应用场景包括快速定位NPE异常、分析动态SQL生成逻辑等,配合多数据源适配和敏感信息过滤,可满足生产环境安全要求。

weixin_30647423的博客 317

CKAD-CN 考试知识点分享(2) CronJob

成功创建 CronJobppi,每 5 分钟执行一次计算任务;配置了和;设置,超时自动终止;确保 Pod 不重启;手动创建ppi-testJob 验证功能正常;所有任务要求均已满足。

轻的博客 333

告别SQL盲猜!6种方案带你玩转SQL打印

MyBatis框架内置了SQL打印功能,通过简单配置即可在控制台输出完整SQL语句。P6Spy是第三方数据库日志框架,提供高度定制化的日志格式配置。

数据狐(DataFox19970-108-018) 250

c语言串口编程详解

串口: 一种异步通信接口,通常用于低速数据传输。RS-232: 最常见的串口标准,定义了电气特性、连接器和信号线。UART: 通用异步收发传输器,是实现串口通信的硬件模块。通过以上内容,你应能够理解并实现C语言在Windows和Linux平台上的串口编程。希望这本手册能帮助你在实际项目中顺利进行串口通信开发。如果有任何疑问或需要进一步的帮助,请随时提问。

jkzyx123的博客 2224

积木报表批量打印实战:告别手动排版,5分钟搞定千张单据套打

你是否还在为每天需要打印上百张单据而头痛?还在手动调整Excel模板,一页页地复制粘贴数据?🎯 积木报表的批量打印功能将彻底改变你的工作方式,让你从繁琐的打印任务中解放出来! ## 业务痛点:传统打印方式的困境 想象一下这些场景: - 月底需要打印300张发票,手动操作需要整整一天 - 快递面单排版总是错位,浪费大量纸张 - 证书套打时数据位置不准,反复调整耗费精力 传统打印方式面临的核心

gitblog_01012的博客 1060

【Educoder作业】※ 数字图像——绿幕抠像

这次作业比上一篇博客基本得多,大多都是基础函数的运用。没啥说的,就整个sizesizesize即可。 T2 获取一个像素 T3 图像反色 T4 修改透明度 ′RGBA′'RGBA'′RGBA′也是一种图像格式 T5 抠图 T6 添加场景 这个主要是pastepastepaste函数里面的maskmaskmask参量没整明白,转载一篇博客供参考。...

JZYshuraK的博客 7571

Kubernetes集群资源优化实战:Volcano调度器如何帮你省下30%GPU算力

本文详细介绍了如何通过Volcano调度器的Binpack策略优化Kubernetes集群中的GPU资源利用率,解决AI模型训练中的资源碎片化问题。通过实战配置和调优指南,帮助用户提升30%的GPU算力利用率,显著降低任务等待时间和硬件成本。

weixin_30832143的博客 507

告别Excel!用Grid++Report设计批量打印标签,从数据库到打印机一气呵成

本文详细介绍了如何利用Grid++Report实现从数据库到打印机的批量标签打印自动化流程。通过可视化模板设计、数据源直连和批量执行引擎,企业可大幅提升打印效率,降低错误率。特别适用于电商发货单、产品标签等高频打印场景,帮助用户彻底告别Excel手动操作的繁琐与低效。

weixin_30522183的博客 525

新手必看:用Simulink搭建飞跨电容三电平逆变器的完整流程(附SPWM配置技巧)

本文详细介绍了使用Simulink搭建飞跨电容三电平逆变器(FCNPC)的完整流程,特别聚焦于SPWM调制策略的配置技巧。通过模块拆解、参数设置和波形优化的三步法,配合实操截图和典型参数表,帮助新手快速掌握多电平逆变器的建模与仿真技能,适用于电力电子学习和项目开发。

weixin_30664051的博客 288

告别手工填表!积木报表套打功能让批量打印如此简单

还在为每天重复填写上百张单据而烦恼吗?手动调整每一份表格的数据位置,眼睛都快看花了?别担心,积木报表的套打功能就是为你量身定制的解决方案! 想象一下这样的场景:你只需要设计一次模板,就能自动完成上千份单据的批量打印,而且数据与模板完美契合,零误差、高效率。这就是我们今天要介绍的积木报表套打功能,一个能让你从繁琐手工劳动中解放出来的神器。 ## 一、为什么你需要套打功能? ### 1.1 传统

gitblog_00216的博客 829

【Excel VBA 编程】表格内自动生成进度条

在表格中生成进度条,进度条需要自适应单元格的宽度,根据不同进度区间变换颜色,并且按照进度数据大小显示其长短

wei1019的专栏 1521

【WRF数据准备】气象驱动数据-ERA5再分析数据(Copernicus)

【WRF数据准备】气象驱动数据-ERA5再分析数据

WW、forever的博客 5539

告别手工编码!JEECG在线打印设计器让业务人员也能轻松设计模板

JEECG在线打印设计器通过类Excel的可视化界面,让业务人员无需编码即可轻松设计打印模板,大幅提升企业单据打印效率。支持拖拽操作、多数据源对接和智能数据处理,适用于合同、订单等多种场景,实现零代码快速部署与集成。

delta的博客 1093

lammps教程:in文件结构详解以及一个比较实用的in文件模板

lammps软件只是一个求解器,没有可视化的前处理和后处理软件,所有的命令只能通过代码的方式输入到求解器进行求解计算。 所有的命令都被写到一个称为“in”的文件里,对于初学者来说,熟悉in文件的编写是一个难点。 in文件其实就是一个文本文档,也没有要求文件名或者后缀名中必须带有“in”字样,用任何文件名均可运行。 in文件里的代码是按照编写的顺序进行解释执行,对于大部分命令行来说,前后顺序影响并不是很大,但是,对于一些命令,在执行过程中需要某个参数,则这个参数的定义和计算必须写在命令执行之前。 例如,对晶体

lammps_jiayou的博客 2万+

SQL注入攻击原理与防御实战:从DVWA靶场到参数化查询

SQL注入作为Web安全领域的经典漏洞,其核心原理在于应用程序未能正确区分数据与代码的边界,导致用户输入被误解析为可执行的SQL指令。从技术实现层面看,当用户提交的数据未经充分验证或转义,直接拼接到数据库查询语句中时,攻击者即可通过构造特殊输入来操纵查询逻辑,实现数据窃取、权限绕过甚至服务器控制。这种漏洞的技术价值在于其攻击门槛低、危害性高,常被用作渗透测试的入门课题,例如在DVWA、sqli-labs等靶场中广泛出现。在实际应用场景中,无论是登录认证、数据查询还是内容管理模块,只要涉及动态SQL拼接,都可

chaoyv 363

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

告别手动猜解:用BurpSuite Intruder的集束炸弹模式自动化搞定SQL布尔盲注

本文深入解析如何利用BurpSuite Intruder的集束炸弹模式自动化完成SQL布尔盲注攻击。通过多参数独立组合爆破技术,显著提升数据库名、表名及敏感数据的提取效率,将传统手工操作从数小时缩短至几分钟。重点介绍了字典配置、结果过滤和并发控制等实战技巧,适用于渗透测试和CTF比赛场景。

weixin_33681778的博客 609

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

报销单 / 申请单打印不用愁!JNPF 打印设计全流程,一键拿捏

打印设计支持自定义打印的格式包括打印版本、组件、数据源等设置,与表单设计的列表和详情页面,或工作流程的列表和详情结合使用。

JNPF 专注低代码开发 906

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: 营销级二维码生成术:Java如何打造专属标识
下一篇: Knife4j:实时接口文档的利器
智_永无止境
博客等级 码龄10年 803粉丝 406原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智_永无止境

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值