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日

相关文章

  • Go语言实现的一个简单Web服务器

    Go语言实现一个简单的Web服务器是非常容易的。本教程将引导您完成编写自己的服务器的过程: 1. 初始化一个Go模块 使用go mod init命令初始化一个新的Go模块: $ go mod init example.com/webserver 这将创建一个名为webserver.mod的文件和一个空的main.go文件。 2. 编写服务器代码 在main.…

    other 2023年6月27日
    00
  • C++构造函数初始化列表的实现详解

    下面我就详细地讲解一下“C++构造函数初始化列表的实现详解”的攻略和示例: C++构造函数初始化列表的实现详解 1. 什么是C++构造函数初始化列表? 在C++中,构造函数可以用来初始化一个对象的成员变量和基类对象。通常,我们使用赋值语句来达到这个目的,例如: class Point { public: Point(int x, int y) { m_x =…

    other 2023年6月20日
    00
  • Win10快速预览版19624怎么手动下载更新升级?

    如果您想手动下载并安装Windows10快速预览版19624更新,则可以按照以下步骤: 步骤一:获取更新包下载链接 在Microsoft官方网站上,有可用的Windows10最新的insider预览版更新包下载链接。您可以使用这个链接下载更新包。 示例1:如果您要获取与“Win10快速预览版19624”对应的更新包下载链接,可以按照以下步骤操作: 1.1. …

    other 2023年6月27日
    00
  • GO语言字符串常用操作小结

    GO语言字符串是程序中经常用到的数据类型之一,而GO语言也提供了丰富的字符串操作函数,便于我们对字符串进行处理。下面,我来为大家详细讲解一下GO语言字符串常用操作的攻略。 字符串声明 在GO语言中,可以使用双引号或反引号来声明字符串变量。一般情况下,使用双引号声明字符串变量,反引号则用于声明包含换行符和特殊字符的字符串变量。 // 使用双引号 var str…

    other 2023年6月20日
    00
  • 淘宝营销之做好用户体验的6点要诀

    淘宝营销之做好用户体验的6点要诀 在淘宝营销中,提供良好的用户体验是至关重要的。下面是6个要诀,可以帮助您在淘宝平台上提供出色的用户体验。 1. 优化商品页面 确保您的商品页面清晰、简洁,并提供详细的商品描述和高质量的图片。用户应该能够轻松地找到所需的信息,并对商品有清晰的了解。例如,您可以使用清晰的标题和子标题来突出商品的特点,使用高清晰度的图片展示商品的…

    other 2023年7月27日
    00
  • MySql如何去除字符串前缀,两边,后缀

    MySql如何去除字符串前缀、两边和后缀 在MySQL中,可以使用内置的字符串函数来去除字符串的前缀、两边和后缀。下面是详细的攻略: 去除字符串前缀 要去除字符串的前缀,可以使用SUBSTRING()函数结合LENGTH()函数来实现。具体步骤如下: 使用SUBSTRING()函数截取字符串,指定起始位置为前缀的长度加1。 使用LENGTH()函数获取字符串…

    other 2023年8月6日
    00
  • citespace中介中心性什么意思

    Citespace中介中心性什么意思 Citespace是一个用于科学文献计量分析的软件,可以帮助用户发现论文之间的关联和演化趋势。在使用Citespace进行分析时,一个重要的概念是“中介中心性”。 中介中心性是指节点对其他节点之间的信息传递起到的中介作用。在Citespace中,节点可以理解为作者、学科、机构等研究主体。因此,一个节点的中介中心性越高,就…

    其他 2023年3月28日
    00
  • pythonlist转json

    当然,我很乐意为您提供有关“Python List转JSON”的完整攻略。以下是详细的步骤和两个示例: 1. 什么是JSON? JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写。它基于JavaScript语言的一个子集,但是可以被多种编语言使用,包括Python。 2. Python List转JSO…

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