获取mybatis可执行sql

本文介绍如何通过Spring和MyBatis结合,利用SqlHelper工具类获取可执行的SQL语句。该工具类依赖SqlSessionFactory,提供反射、参数处理等功能,方便在业务代码中获取Mapper接口对应的SQL。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我是通过spring和mybatis结合做的这个事情,通过spring去管理SqlHelper工具类

1:建立一个SqlHelper工具类,

2:类里面必须有一个属性SqlSessionFactory。   

3:在你业务类里面,直接注入SqlHelper类,这样你就可以直接在你的业务类里面调用工具类,(工具类里面有好几个接口,自己可以根据实际情况适用)

4:在代码的最后我会贴一部分实例代码来给出结果

5:不多说了,下面贴SqlHelper工具类代码

package com.heygam.common.util;


import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Component
public class SqlHelper {


@Autowired
private  SqlSessionFactory sqlSessionFactory;
private  final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
private  final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();




/**
* 反射对象,增加对低版本Mybatis的支持
*
* @param object 反射对象
* @return
*/
public  MetaObject forObject(Object object) {
return MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
}


/**
* 通过接口获取sql
*
* @param mapper
* @param methodName
* @param args
* @return
*/
public  String getMapperSql(Object mapper, String methodName, Object... args) {
MetaObject metaObject = forObject(mapper);
SqlSession session = (SqlSession) metaObject.getValue("h.sqlSession");
Class mapperInterface = (Class) metaObject.getValue("h.mapperInterface");
String fullMethodName = mapperInterface.getCanonicalName() + "." + methodName;
if (args == null || args.length == 0) {

<think>好的,我现在需要帮助用户解决如何使用Arthas查看MyBatis执行SQL语句的问题。首先,我得回顾一下用户的问题和相关引用内容,确保自己理解正确。 用户提供的引用中有三个来源。引用[1]提到Arthas可以查看拼接好参数的SQL、Redis、ES命令,并给出了相关命令的链接。引用[2]说明了MyBatis控制台如何打印SQL执行信息,包括执行方法、SQL和耗时,并提到了Mapper方法、Execute SQL和Spend Time。引用[3]则指出可以通过RoutingStatementHandler来查看动态拼接的SQL语句。 用户的问题是具体如何使用Arthas来查看MyBatis生成的SQL。首先,我需要确认Arthas的常用命令,比如trace、watch、ognl等。然后,结合MyBatis的内部类,比如RoutingStatementHandler或BaseExecutor,可能需要监控这些类的方法执行。 根据引用[3],MyBatis在动态拼装SQL时会使用RoutingStatementHandler,所以可能需要在执行SQL的相关方法上设置监控点。例如,RoutingStatementHandler的query或update方法可能包含构建好的SQL语句。此外,BaseExecutor类的query方法也可能涉及SQL处理。 接下来,我需要考虑Arthas的具体操作步骤。用户可能需要使用watch命令来观察特定方法的入参或返回值。例如,监视RoutingStatementHandler的prepare方法,或者BaseExecutor的query方法,查看参数中的boundSql对象,因为boundSql包含最终的SQL语句。 同时,用户可能希望获取到带有实际参数的完整SQL,而不仅仅是预编译的语句。这时候需要从boundSql对象中提取sql字段和parameterObject的内容,并组合成可执行SQL。引用[2]中提到MyBatis可以打印完整执行SQL,自动填充参数,这说明MyBatis内部确实有处理参数替换的逻辑,可能通过ParameterHandler实现。 因此,使用Arthas的watch命令来捕获boundSqlsql属性,或者查看ParameterHandler处理后的参数,可能可以得到完整的SQL语句。此外,引用[1]提到Arthas可以查看拼接好的SQL,可能需要使用ognl表达式直接访问对象的属性。 另外,还要考虑是否需要动态开启MyBatisSQL日志。例如,通过Arthas修改日志级别,或者触发MyBatis的日志配置,这可能涉及到调用LoggerFactory的方法,或者调整相关Logger的级别。 步骤可能包括: 1. 启动Arthas并附加到目标Java进程。 2. 使用sc命令查找RoutingStatementHandler或BaseExecutor的类路径。 3. 使用watch命令监控特定方法,提取boundSql对象的sql和参数。 4. 结合参数替换,生成可执行SQL语句。 5. 或者使用ognl命令直接调用方法获取SQL信息。 需要注意是否正确处理了参数替换,例如字符串需要加引号,数字直接替换等。此外,可能需要处理多个参数的情况,比如参数是Map或者多个对象的情况。 最后,验证这些步骤是否可行,可能需要参考Arthas的官方文档或相关示例,确保命令的正确性。同时,提醒用户注意生产环境使用Arthas的风险,比如性能影响或安全性问题。</think>### 使用Arthas调试MyBatis执行SQL语句步骤 #### 1. **启动Arthas并附加到目标进程** 通过以下命令启动Arthas并选择需要监控的Java进程: ```bash java -jar arthas-boot.jar ``` #### 2. **定位MyBatis核心类** MyBatis执行SQL的关键类为 `org.apache.ibatis.executor.statement.RoutingStatementHandler`,其内部通过 `BoundSql` 对象存储完整的SQL和参数。使用Arthas的 `sc` 命令确认类路径: ```bash sc *RoutingStatementHandler ``` #### 3. **监控SQL生成过程** 使用 `watch` 命令拦截 `RoutingStatementHandler` 的 `parameterize` 方法(该方法负责绑定参数),并提取 `BoundSql` 中的SQL和参数: ```bash watch org.apache.ibatis.executor.statement.RoutingStatementHandler parameterize 'target.boundSql.sql + "\nParams: " + Arrays.toString(target.boundSql.parameterMappings)' -n 5 -x 3 ``` - `target.boundSql.sql`:获取动态生成的SQL语句。 - `target.boundSql.parameterMappings`:提取参数映射信息[^3]。 #### 4. **直接获取可执行SQL** 通过 `ognl` 命令直接调用 `BoundSql` 对象获取完整SQL(需触发一次SQL执行): ```bash ognl '@org.apache.ibatis.session.SqlSessionUtils@getSqlSession(@org.springframework.context.ApplicationContext@getBean("sqlSessionFactory")).getConfiguration().getMappedStatement("Mapper方法全路径").getBoundSql(参数对象).getSql()' ``` - 替换 `Mapper方法全路径` 如 `com.example.UserMapper.selectById`。 - 参数对象需通过JSON或Java语法构造[^1]。 #### 5. **动态开启MyBatis原生日志** 修改日志级别,直接在控制台打印SQL: ```bash logger --name org.apache.ibatis --level DEBUG ``` 执行SQL后,控制台会输出类似: ```text DEBUG [main] - ==> Preparing: SELECT * FROM user WHERE id = ? DEBUG [main] - ==> Parameters: 1(Integer) ``` #### 6. **性能与安全性建议** - **生产环境谨慎操作**:Arthas的 `watch` 命令可能增加方法调用耗时。 - **过滤监控范围**:通过 `-c` 参数限制类加载器,避免监控无关类。 - **结合日志框架**:推荐优先使用MyBatis内置日志配置(如 `log4j`)[^2]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值