mybatisplus打印完整sql不带问号

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日

相关文章

  • 服务器安全策略 IP安全策略设置方法

    服务器安全策略 IP安全策略设置方法攻略 服务器安全策略是确保服务器系统安全的重要措施之一。其中,IP安全策略是一种常见的设置方法,用于限制服务器对特定IP地址或IP地址范围的访问。下面是详细的攻略,包括设置IP安全策略的步骤和两个示例说明。 步骤一:了解服务器安全策略 在开始设置IP安全策略之前,首先需要了解服务器安全策略的基本概念和原理。服务器安全策略是…

    other 2023年7月31日
    00
  • jq实现数字增加或者减少的动画

    使用jq实现数字增加或减少的动画的完整攻略 在网页设计中,有时需要对数字进行动态增加或减少的效果展示,以吸引用户的注意力。一种常见的处理方式是使用jQuery(简称jq)实现数字增加或减少的动画效果。本文将为您提供一份使用jq实现数字增加或减少的动画的完整攻略,包括实现思路、解决方法和两个示例说明。 实现思路 使用jq实现数字增加或减少的动画的实现思路如下:…

    other 2023年5月5日
    00
  • 关于Win10下MySQL5.7.17免安装版基本配置教程(图文详解)

    下面就来详细讲解一下“关于Win10下MySQL5.7.17免安装版基本配置教程(图文详解)”的完整攻略。 1. 下载MySQL 首先,我们需要下载MySQL,可以在官网上下载免安装版MySQL:https://dev.mysql.com/downloads/mysql/。 建议下载zip压缩包,然后解压到我们指定的目录,比如:D:\mysql-5.7.17…

    other 2023年6月27日
    00
  • JAVA中static方法的用法实例详解

    JAVA中static方法的用法实例详解 1. static方法概述 在JAVA中,static方法是指被声明为静态的方法。静态方法不需要实例化类对象即可调用,可以直接通过类名来访问。static方法在类加载时就已经存在于内存中,不依赖于类的实例。以下是关于static方法的几个要点:- static方法可以通过类名来调用,不需要创建对象实例。- stati…

    other 2023年6月28日
    00
  • sql将多行数据合并成一行

    当然,我很乐意为您提供有关“SQL将多行数据合并成一行”的完整攻略。以下是详细的步骤和两个示例: 1. SQL将多行数据合并成一行 在SQL中,有多种方法可以将多行数据合并成一行。以下是一些常见的方法: GROUP_CONCAT:将多行数据合并为一个字符串,可以使用分隔符分隔。 LISTAGG:将多行数据合并为一个字符串,可以使用分隔符分隔。 XMLAGG:…

    other 2023年5月6日
    00
  • WinForm遍历窗体所有子控件的方法

    WinForm遍历窗体所有子控件的方法 在WinForm编程中,我们有时需要遍历窗体上的所有子控件,比如找出所有的按钮、文本框等控件进行相应的操作。下面介绍两种常用的方法。 方法一:递归函数遍历子控件 首先定义一个递归函数,该函数接收一个参数parentControl,表示要遍历的窗体或控件。该函数使用foreach循环遍历parentControl控件的所…

    other 2023年6月26日
    00
  • 360路由器c301最新固件支持万能中继

    360路由器C301最新固件支持万能中继 最近我们的360路由器C301推出了最新的固件版本V1.2.0,其中最重要的更新是增加了万能中继功能。 什么是万能中继功能? 万能中继又称WDS(Wireless Distribution System),是一种无线中继技术。它允许一个无线路由器通过连接到另一个无线路由器的网络,将网络信号和数据通过WDS传输到其他设…

    其他 2023年3月28日
    00
  • Linux系统修改环境变量PATH的技巧图解

    Linux系统修改环境变量PATH的技巧图解 什么是环境变量PATH? 在Linux系统中,环境变量PATH指的是一个包含多个路径的字符串变量,用于告诉系统在哪些目录中可以找到可执行文件。 例如,当我们在终端中输入一个命令,例如ls,系统会自动在PATH路径中定义的目录里寻找ls命令,从而执行该命令。 为什么要修改环境变量PATH? 有时候,我们需要在自定义…

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