arthas获取mybatis执行sql
时间: 2025-07-15 14:30:48 浏览: 3
<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命令来捕获boundSql的sql属性,或者查看ParameterHandler处理后的参数,可能可以得到完整的SQL语句。此外,引用[1]提到Arthas可以查看拼接好的SQL,可能需要使用ognl表达式直接访问对象的属性。
另外,还要考虑是否需要动态开启MyBatis的SQL日志。例如,通过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]。
---
###
阅读全文
相关推荐


















