mybatisplus打印完整sql不带问号

yizhihongxing

MybatisPlus打印完整SQL不带问号

MybatisPlus 是一个优秀的 ORM 框架,提供了一些与 Mybatis 的基本功能相同的增强特性,常常被用在企业级应用中。

在 Mybatis 中,我们可以通过配置参数来开启 SQL 打印,但打印出来的 SQL 中含有问号占位符,不便于我们查看具体的 SQL 语句。

MybatisPlus 默认采用了和 Mybatis 相同的 SQL 打印功能,并输出的 SQL 带有问号,如果我们想要查看完整的 SQL 语句,而不是带有问号的占位符,可以通过以下方法进行配置。

方法一:使用日志输出完整的 SQL 语句

在 application.yml 或 application.properties 中配置以下参数:

logging:
  level:
    com.baomidou.mybatisplus.mapper: debug

这里的配置意味着启用了 MybatisPlus 的 SQL 打印,并将打印级别设置为 debug。MybatisPlus 会在控制台输出完整的 SQL 语句,不带有问号占位符。

但是,这种方法会导致控制台输出大量的 debug 日志,可能会影响系统的性能。所以,我们可以使用第二种方法。

方法二:使用自定义的 SQL 格式化插件

在 MybatisPlus 中,我们可以通过自定义 SQL 格式化插件来实现我们的目标。以下是具体的实现过程:

  1. 首先,我们需要实现一个 SQL 格式化器,将带有问号的 SQL 语句转化为不带问号的字符串:

    ```java
    import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils;
    import org.apache.ibatis.logging.Log;
    import org.apache.ibatis.logging.LogFactory;
    import org.apache.ibatis.mapping.BoundSql;

    /*
    * 自定义的 {@link org.apache.ibatis.mapping.ParameterHandler},
    * 用于打印完整的 SQL 语句,不带有问号占位符
    /
    public class CompleteSqlSqlFormatInterceptor extends SqlFormatInterceptor {

    private static final Log logger = LogFactory.getLog(CompleteSqlSqlFormatInterceptor.class);
    
    @Override
    public Object doIntercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        BoundSql boundSql = (BoundSql) args[1];
        if (logger.isDebugEnabled()) {
            String sql = boundSql.getSql();
            Object parameterObject = args[0];
            String formatSql = SqlUtils.formatSql(sql, parameterObject);
            logger.debug(" SQL:\n" + formatSql);
        }
        return super.doIntercept(invocation);
    }
    

    }

    ```

    需要注意的是,我们继承了 MybatisPlus 提供的 SqlFormatInterceptor 类,并重写了其 doIntercept 方法。在这个方法中,我们先拿到 BoundSql 参数,然后将其中的 SQL 和参数整合到一起,调用 SqlUtils.formatSql 方法来解析 SQL ,返回不带问号占位符的字符串。最后,通过 logger 输出到日志中。

  2. 然后,我们需要将自定义的插件注册到 MybatisPlus 中:

    ```java
    import com.baomidou.mybatisplus.core.MybatisConfiguration;
    import com.baomidou.mybatisplus.core.config.GlobalConfig;
    import com.baomidou.mybatisplus.core.enums.SqlLike;
    import com.baomidou.mybatisplus.core.injector.AbstractMethod;
    import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.baomidou.mybatisplus.core.parser.ISqlParser;
    import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
    import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
    import com.baomidou.mybatisplus.core.toolkit.StringUtils;
    import org.apache.ibatis.builder.MapperBuilderAssistant;
    import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
    import org.apache.ibatis.executor.keygen.KeyGenerator;
    import org.apache.ibatis.logging.Log;
    import org.apache.ibatis.logging.LogFactory;
    import org.apache.ibatis.mapping.;
    import org.apache.ibatis.plugin.
    ;
    import org.apache.ibatis.reflection.MetaObject;
    import org.apache.ibatis.reflection.SystemMetaObject;
    import org.apache.ibatis.scripting.LanguageDriver;
    import org.apache.ibatis.session.Configuration;
    import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.TypeHandler;

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Properties;

    /*
    * MybatisPlus 自定义的 SQL 格式化插件
    /
    @Intercepts(@Signature(
    type = StatementHandler.class,
    method = "prepare",
    args = {Connection.class, Integer.class})
    )
    public class CompleteSqlSqlFormatPlugin implements Interceptor {

    private static final Log logger = LogFactory.getLog(CompleteSqlSqlFormatPlugin.class);
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object target = invocation.getTarget();
        if (target instanceof RoutingStatementHandler) {
            try {
                MetaObject metaObject = SystemMetaObject.forObject(target);
                Configuration configuration = (Configuration) metaObject.getValue("delegate.configuration");
                MybatisConfiguration mc = (MybatisConfiguration) configuration;
                List<ISqlParser> sqlParserList = new ArrayList<>();
                if (mc.getSqlParserAutoFill()) {
                    sqlParserList.addAll(SqlParserHelper.getSqlParserList(mc.isBlockAttack()));
                }
                if (sqlParserList.size() > 0) {
                    GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration);
                    ISqlParser sqlParser = null;
                    String tenantHandlerSql = null;
                    if (StringUtils.isNotBlank(globalConfig.getTenantHandlerSql())
                            && StringUtils.isNotBlank(globalConfig.getTenantIdColumn())
                            && !globalConfig.isExcludeTenantTable()) {
                        tenantHandlerSql = globalConfig.getTenantHandlerSql();
                        sqlParser = SqlParserHelper.getTenantParser(globalConfig.getTenantIdColumn(), tenantHandlerSql);
                    }
                    SqlInfo sqlInfo = SqlParserHelper.getOptimizeCountSql(mc.isCountStyle());
                    for (ISqlParser iSqlParser : sqlParserList) {
                        if (sqlParser != null) {
                            iSqlParser.processIntervalSql(tenantHandlerSql, sqlInfo.getSql(), configuration);
                        }
                        iSqlParser.parser(metaObject.getValue("delegate.boundSql.sql").toString());
                    }
                }
            } catch (Exception e) {
                logger.error("prepar intercept error", e);
            }
        }
        return invocation.proceed();
    }
    
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, new CompleteSqlSqlFormatInterceptor());
    }
    
    @Override
    public void setProperties(Properties properties) {
        // do nothing.
    }
    

    }

    ```

    这里,我们实现了一个 CompleteSqlSqlFormatPlugin 类,同时该类还继承了 MybatisPlus 的 DefaultSqlInjector 类,这样该插件就可以注册到 MybatisPlus 中。在该插件中,我们实现了插件的三个方法:interceptpluginsetProperties。其中,intercept 方法用于判断当前 StatementHandler 类型是否为 RoutingStatementHandler,如果是,则调用我们自己实现的 SQL 格式化器;而 plugin 方法用于包装目标对象,返回一个它的代理对象。最后,我们将自己的插件注册到 MybatisPlus 中。

  3. 最后,我们需要在 application.yml 或 application.properties 中启用插件:

    yaml
    mybatis-plus:
    global-config:
    sql-injector: cn.edu.zzti.plugins.CompleteSqlSqlFormatPlugin
    # 其他配置
    configuration:
    # 其他配置

好了,至此,我们已经成功地实现了 MybatisPlus 打印完整 SQL 不带问号的功能。相比于方法一中使用日志输出完整的 SQL,这种方法更加灵活,能够更好地适应不同场景下的需求。

参考文献:

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mybatisplus打印完整sql不带问号 - Python技术站

(1)
上一篇 2023年3月28日
下一篇 2023年3月28日

相关文章

  • 小米2/2s修改系统内存分区图文教程

    小米2/2s修改系统内存分区图文教程 介绍 小米2/2s是一款老旧的手机型号,但仍然有很多用户在使用。如果你想要提升手机的性能,一种方法是修改系统内存分区。本教程将详细介绍如何在小米2/2s上进行这个操作。 步骤 步骤一:备份数据 在进行任何系统修改之前,务必备份手机中的重要数据。这样可以避免数据丢失的风险。 步骤二:解锁手机的Bootloader 要修改小…

    other 2023年8月1日
    00
  • c++语言中虚函数实现多态的原理详解

    当一个类中有虚函数时,编译器会在这个类的对象中生成一个虚函数表,表中存储着虚函数的地址。当这个类产生派生类并且派生类中也定义了虚函数时,这个派生类会继承父类的虚函数表,然后在自己的虚函数表中添加自己的虚函数或者重载父类中的虚函数,这个过程叫做动态联编。 使用虚函数可以实现多态,多态可以让不同的子类对象调用相同的虚函数,实现统一的行为表现,提高了代码的复用性和…

    other 2023年6月26日
    00
  • Java 超详细讲解类的定义方式和对象的实例化

    Java 超详细讲解类的定义方式和对象的实例化攻略 简介 在 Java 中,定义一个类是定义一个新的数据类型的基础。类是用来描述具有相同属性(数据元素)和行为(操作元素)的对象的集合,它是现实中对象的抽象。在本文中,我们将详细讲解类的定义方式和对象的实例化的步骤。 定义一个类 定义一个类包含以下几个步骤: 1. 使用 class 关键字定义类 在 Java …

    other 2023年6月26日
    00
  • C语言汉诺塔的简单了解

    C语言汉诺塔的简单了解 什么是汉诺塔? 汉诺塔是一个古老的印度数学问题,也被称为河内塔问题。汉诺塔的游戏内容是将三根柱子(A、B、C)上的盘子按照一定的规则移动到另一个柱子上,移动过程中要求大盘子在小盘子上面。在程序语言中,汉诺塔常用来作为递归函数的案例。 汉诺塔的规则 每次只能移动一个盘子。 盘子只能从上面取下放在一根另外的柱子上。 移动过程中大盘子要在小…

    other 2023年6月27日
    00
  • iOS开发之适配iOS10以及Xcode8

    iOS开发之适配iOS10以及Xcode8 简介 随着iOS 10的推出以及Xcode 8的正式发布,许多iOS开发者发现在新版本的开发环境中需要对项目进行一些适配工作才能确保应用程序在iOS 10上正常运行,本文将详细介绍如何适配iOS 10以及Xcode 8开发环境。 环境适配 在Xcode 8中,苹果引入了一些新特性以及变化,因此需要对开发环境进行一些…

    other 2023年6月26日
    00
  • Java项目导入IDEA的流程配置以及常见问题解决方法

    Java项目导入IDEA的流程配置以及常见问题解决方法 1. 导入Java项目到IDEA 打开IDEA,点击菜单栏的 \”File\” -> \”New\” -> \”Project\”。 在弹出的窗口中选择 \”Java\”,然后点击 \”Next\”。 在下一步中,选择项目的根目录,并选择项目类型(Maven、Gradle等)。 点击 \”F…

    other 2023年10月12日
    00
  • 关于python:b64解码问题

    以下是关于“关于python:b64解码问题”的完整攻略,包含两个示例。 关于python:b64解码问题 在Python中,我们可以使用base64库对字符串进行编码和解码。但是,在解码时可能会遇到一些问题。以下是关于如何解决b64解码问题的详细攻略。 1. 解码 在解码时,我们可能会遇到解码错误的情况。以下是一个示例: import base64 # 解…

    other 2023年5月9日
    00
  • c#笔记获取程序当前目录

    以下是“C#笔记获取程序当前目录的完整攻略,过程中至少包含两条示例说明”。 C#笔记获取程序当前目录的完整攻略 在C#中,我们可以使用多种方法获取程序当前目录。以下是一份关于C#获取程序当前目录的攻略,包括两个示例说明。 1. C#获取程序当前目录的基础知识 在开始获取程序当前目录之前,我们需要掌握一些基础知识,例如: C#的基础知识,包括C#的安装、配置、…

    other 2023年5月10日
    00
合作推广
合作推广
分享本页
返回顶部