mybtais plus使用拦截器打印完整SQL语句

1、pom文件

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.5</version>
        </dependency>

        <dependency>
            <groupId>com.github.yulichang</groupId>
            <artifactId>mybatis-plus-join-boot-starter</artifactId>
            <version>1.5.3</version>
        </dependency>

2、拦截器



import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * SQL打印拦截器,用于打印完整的SQL语句和参数值
 */

@Slf4j
@Component
public class SqlPrintInnerInterceptor implements InnerInterceptor {

    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {

        // 获取SQL语句
        String sql = showSql(ms.getConfiguration(), boundSql);
        log.info("===========================================");
        log.info("SQL: {}", sql);
        log.info("===========================================");
        log.info("Mapper: {}",ms.getId());

    }

    @Override
    public void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException {

        BoundSql boundSql = ms.getBoundSql(parameter);
        // 获取SQL语句
        String sql = showSql(ms.getConfiguration(), boundSql);
        log.info("===========================================");
        log.info("\nSQL: {}", sql);
        log.info("===========================================");
        log.info("Mapper: {}",ms.getId());
    }

    public static String showSql(Configuration configuration, BoundSql boundSql) {
        Object parameterObject = boundSql.getParameterObject();
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
        if (parameterMappings.size() > 0 && parameterObject != null) {
            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
            if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                sql = sql.replaceFirst("\\?", getParameterValue(parameterObject));

            } else {
                MetaObject metaObject = configuration.newMetaObject(parameterObject);
                for (ParameterMapping parameterMapping : parameterMappings) {
                    String propertyName = parameterMapping.getProperty();
                    if (metaObject.hasGetter(propertyName)) {
                        Object obj = metaObject.getValue(propertyName);
                        sql = sql.replaceFirst("\\?", getParameterValue(obj));
                    } else if (boundSql.hasAdditionalParameter(propertyName)) {
                        Object obj = boundSql.getAdditionalParameter(propertyName);
                        sql = sql.replaceFirst("\\?", getParameterValue(obj));
                    }
                }
            }
        }
        return sql;
    }

    private static String getParameterValue(Object obj) {
        String value = null;
        if (obj instanceof String) {
            value = "'" + obj.toString() + "'";
        } else if (obj instanceof Date) {
            DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
            value = "'" + formatter.format(new Date()) + "'";
        } else {
            if (obj != null) {
                value = obj.toString();
            } else {
                value = "";
            }

        }
        return value;
    }

}

3、mybatis plus插件添加拦截器



import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * mybatis-plus配置
 *
 * @author Mark sunlightcs@gmail.com
 */
@Configuration
public class MybatisPlusConfig {

    /**
     * 添加分页插件和自定义SQL打印插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        
        // 添加分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        
        // 添加自定义SQL打印插件
        interceptor.addInnerInterceptor(new SqlPrintInnerInterceptor());
        
        return interceptor;
    }

}

### 使用 MyBatis-Plus 拦截器实现 SQL 语句的动态拼接 #### 自定义拦截器类 为了实现 SQL 的动态拼接,可以通过创建自定义拦截器来修改 SQL 语句。该拦截器继承 `Interceptor` 接口并重写相应的方法。 ```java import com.baomidou.mybatisplus.core.toolkit.PluginUtils; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.Select; import java.util.Properties; public class DynamicTableNameInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { MetaObject metaStatementHandler = PluginUtils.metaObjectForObject(invocation.getArgs()[0]); String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql"); Statement statement = CCJSqlParserUtil.parse(originalSql); if (statement instanceof Select){ // 修改表名为动态获取到的新表名 ((Select) statement).getFromItem().setAlias(new Table(getDynamicTableName())); // 更新原始 SQL 字符串 metaStatementHandler.setValue("delegate.boundSql.sql", statement.toString()); } return invocation.proceed(); } private String getDynamicTableName() { // 这里可以根据业务逻辑返回不同的表名 return "dynamic_table_name"; } @Override public void setProperties(Properties properties) {} } ``` 此代码片段展示了如何通过解析和重构 JSQL 解析树来更改查询中的表名称[^1]。 #### 注册拦截器 为了让上述自定义拦截器生效,在 Spring Boot 应用程序中注册它: ```yaml mybatis-plus: configuration: interceptors: - com.example.DynamicTableNameInterceptor ``` 或者在 Java 配置文件中添加如下配置: ```java @Configuration @MapperScan("com.example.mapper") public class MyBatisConfig { @Bean public DynamicTableNameInterceptor dynamicTableNameInterceptor(){ return new DynamicTableNameInterceptor(); } @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(DynamicTableNameInterceptor interceptor){ MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); mybatisPlusInterceptor.addInnerInterceptor(interceptor); return mybatisPlusInterceptor; } } ``` 这样就可以让应用程序根据实际运行情况灵活调整所访问的数据表[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值