Перехватчик Mybatis печатает полный SQL
Я написал один раньше:Перехватчик Mybatis реализует типы хранения и запроса данных Geometry
в основном оMybatis
Использование перехватчиков. Судя по количеству лайков🤣, вы знаетеGeometry
Не так много людей с типами данных, этот типMySQL
Тип данных, который обрабатывает географические данные, такие как широта и долгота.
Давайте поговорим об этом сегодня, как его использоватьMybatis
Печать перехватчика завершенаSQL
.
MybatisPlus
Принести свой собственныйSQL
Профилирующий перехватчик:com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor
И эта печатная частьSQL
, как показано ниже:
НоSQL
есть заполнители?
Да, он неполный, мы предпочитаем видеть его непосредственноSQL
.
если естьBug
, когда мы просматриваем журнал, мы можем непосредственно видетьSQL
, и его можно запустить сразу после копирования, разве это не радует?
Полный код перехватчика
package com.ler.manager.interceptor;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandlerRegistry;
/**
* @author lww
* @date 2020-09-01 00:13
*/
@Slf4j
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
RowBounds.class, ResultHandler.class})})
public class PrintSqlInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
Object parameter = null;
if (invocation.getArgs().length > 1) {
parameter = invocation.getArgs()[1];
}
String sqlId = mappedStatement.getId();
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
Configuration configuration = mappedStatement.getConfiguration();
long start = System.currentTimeMillis();
Object returnValue = invocation.proceed();
long time = System.currentTimeMillis() - start;
showSql(configuration, boundSql, time, sqlId);
return returnValue;
}
private static void showSql(Configuration configuration, BoundSql boundSql, long time, String sqlId) {
Object parameterObject = boundSql.getParameterObject();
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//替换空格、换行、tab缩进等
String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
if (parameterMappings.size() > 0 && parameterObject != null) {
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
sql = sql.replaceFirst("\\?", getParameterValue(parameterObject));
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);
for (ParameterMapping parameterMapping : parameterMappings) {
String propertyName = parameterMapping.getProperty();
if (metaObject.hasGetter(propertyName)) {
Object obj = metaObject.getValue(propertyName);
sql = sql.replaceFirst("\\?", getParameterValue(obj));
} else if (boundSql.hasAdditionalParameter(propertyName)) {
Object obj = boundSql.getAdditionalParameter(propertyName);
sql = sql.replaceFirst("\\?", getParameterValue(obj));
}
}
}
}
logs(time, sql, sqlId);
}
private static String getParameterValue(Object obj) {
String value;
if (obj instanceof String) {
value = "'" + obj.toString() + "'";
} else if (obj instanceof Date) {
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
value = "'" + formatter.format(new Date()) + "'";
} else {
if (obj != null) {
value = obj.toString();
} else {
value = "";
}
}
return value.replace("$", "\\$");
}
private static void logs(long time, String sql, String sqlId) {
StringBuilder sb = new StringBuilder()
.append(" Time:").append(time)
.append(" ms - ID:").append(sqlId)
.append(StringPool.NEWLINE).append("Execute SQL:")
.append(sql).append(StringPool.NEWLINE);
log.info(sb.toString());
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties0) {
}
}
-
intercept
,plugin
,setProperties
Эти три метода реализованы интерфейсамиInterceptor
метод в .
-
invocation.getArgs()
Результат одинMappedStatement
, один - информация о параметрах.
-
showSql
ребро?
Заменяется фактическим значением параметра. -
logs
Соберите журнал. - наконец
Mybatis
Настройте его в классе конфигурации
Структура таблицы
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` int(11) DEFAULT NULL,
`location` geometry DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
интерфейс отладки
@ApiOperation("添加")
@PostMapping(value = "/add", name = "添加")
public HttpResult add() {
User user = new User();
user.setName(123456);
user.setLocation("POINT(121.58623 31.150897)");
user.insert();
return HttpResult.success();
}
Эффект следующий:
Вы можете видеть, что отображается полный SQL, а также время выполнения. Идеально!
Наконец
Приглашаю всех обратить внимание на мой официальный аккаунт, вместе учиться и вместе добиваться успехов. давай 🤣