- Mybatis 开启 sql 打印,还不把参数给拼接到 sql 语句中,给本地开发带来极大不不便
- Mybatis-Plus 是通过收集日志实现 sql 语句与参数联合,有些 IDEA 对这个插件还反对的不好
- 不如本人搞个小工具,只有是本地形式启动的,将在控制台输入所有的查问和更新 sql 语句,并监听 sql 执行工夫
- 注入
@Configuration
public class MybatisConfig {
@Bean
@Conditional(LocalStartCondition.class)
public SqlCheckInterceptor performanceInterceptor() {return new SqlCheckInterceptor();
}
}
- 注入条件
public class LocalStartCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, @Nullable AnnotatedTypeMetadata annotatedTypeMetadata) {return "local".equals(conditionContext.getEnvironment().getActiveProfiles()[0]);
}
}
- 拦截器
@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));
}
}
** 粘贴代码的同时想想实现原理,对晋升魂力有帮忙。**