关于mybatis:打印个SQL还不老实

53次阅读

共计 3312 个字符,预计需要花费 9 分钟才能阅读完成。

打印个 SQL 还不诚实

摘要

  1. Mybatis 开启 sql 打印,还不把参数给拼接到 sql 语句中,给本地开发带来极大不不便
  2. Mybatis-Plus 是通过收集日志实现 sql 语句与参数联合,有些 IDEA 对这个插件还反对的不好
  3. 不如本人搞个小工具,只有是本地形式启动的,将在控制台输入所有的查问和更新 sql 语句,并监听 sql 执行工夫

小工具来了

  1. 注入
@Configuration
public class MybatisConfig {
    @Bean
    @Conditional(LocalStartCondition.class)
    public SqlCheckInterceptor performanceInterceptor() {return new SqlCheckInterceptor();
    }
}
  1. 注入条件
public class LocalStartCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, @Nullable AnnotatedTypeMetadata annotatedTypeMetadata) {return "local".equals(conditionContext.getEnvironment().getActiveProfiles()[0]);
    }
}
  1. 拦截器
@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
})
public class SqlCheckInterceptor implements Interceptor {private static final Log logger = LogFactory.getLog(SqlCheckInterceptor.class);
    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public Object intercept(Invocation invocation) throws Throwable {MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object parameterObject = null;
        if (invocation.getArgs().length > 1) {parameterObject = invocation.getArgs()[1];
        }
        long start = SystemClock.now();
        Object result = invocation.proceed();
        long timing = SystemClock.now() - start;
        String statementId = mappedStatement.getId();
        BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);
        Configuration configuration = mappedStatement.getConfiguration();
        String sql = getSql(boundSql, parameterObject, configuration);
        if (logger.isInfoEnabled()) {
            String formatSqlStr = StringPool.NEWLINE +
                    "SQL-in-method===>:" + statementId + StringPool.NEWLINE +
                    "Execute-time====>:" + timing + "ms" + StringPool.NEWLINE +
                    "SQL-script===>:" + StringPool.NEWLINE +
                    sql + StringPool.NEWLINE;
            logger.info(formatSqlStr);
        }
        return result;
    }

    @Override
    public Object plugin(Object target) {if (target instanceof Executor) {return Plugin.wrap(target, this);
        }
        return target;
    }

    @Override
    public void setProperties(Properties properties) { }

    private String getSql(BoundSql boundSql, Object parameterObject, Configuration configuration) {String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
        if (parameterMappings != null) {for (ParameterMapping parameterMapping : parameterMappings) {if (parameterMapping.getMode() != ParameterMode.OUT) {
                    Object value;
                    String propertyName = parameterMapping.getProperty();
                    if (boundSql.hasAdditionalParameter(propertyName)) {value = boundSql.getAdditionalParameter(propertyName);
                    } else if (parameterObject == null) {value = null;} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {value = parameterObject;} else {MetaObject metaObject = configuration.newMetaObject(parameterObject);
                        value = metaObject.getValue(propertyName);
                    }
                    sql = replacePlaceholder(sql, value);
                }
            }
        }
        return sql;
    }

    private String replacePlaceholder(String sql, Object propertyValue) {
        String result;
        if (propertyValue != null) {if (propertyValue instanceof String) {result = "'"+ propertyValue +"'";} else if (propertyValue instanceof Date) {result = "'"+ DATE_FORMAT.format(propertyValue) +"'";
            } else {result = propertyValue.toString();
            }
        } else {result = "null";}
        return sql.replaceFirst("\\?", Matcher.quoteReplacement(result));
    }
}

废话

** 粘贴代码的同时想想实现原理,对晋升魂力有帮忙。**

正文完
 0