1.添加依赖
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency>
2.添加mapper
UserMapper.class
@Mapper public interface UserMapper { User selectById(Long userId); }
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.example.mapper.UserMapper"> <select id="selectById" resultType="com.example.domain.User"> select id, email, password, username from users where id = #{userId} </select> </mapper>
3.application.properties添加mapper.xml文件配置
mybatis.mapper-locations=classpath:mapper/*.xml
4.启动类添加@MapperScan
@MapperScan("com.example.mapper") @SpringBootApplication public class MybatisDemoApplication { public static void main(String[] args) { SpringApplication.run(MybatisDemoApplication.class, args); } }
5.添加拦截器
@Slf4j @Component @Intercepts(value = { @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 SqlInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { log.info("拦截器对象={}", invocation.toString()); Object returnValue = null; try { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; String sqlId = mappedStatement.getId(); if(sqlId.contains("History") || sqlId.contains("Tmp")){ return invocation.proceed(); } Object parameter = null; if (invocation.getArgs().length > 1) { parameter = invocation.getArgs()[1]; } BoundSql boundSql = mappedStatement.getBoundSql(parameter); Configuration configuration = mappedStatement.getConfiguration(); long start = System.currentTimeMillis(); returnValue = invocation.proceed(); long end = System.currentTimeMillis(); long time = (end - start); String sql = getSql(configuration, boundSql, sqlId, time); log.info("拦截器={}", sql); } catch (Exception e) { log.error("拦截器异常"); } return returnValue; } @Override public Object plugin(Object target) { log.info("Interceptor::plugin#target={}", target); if(target instanceof Executor){ return Plugin.wrap(target, this); } return target; } @Override public void setProperties(Properties properties) { } public static String getSql(Configuration configuration, BoundSql boundSql, String sqlId, long time) { String sql = showSql(configuration, boundSql); StringBuilder str = new StringBuilder(100); str.append("【sqlId】").append(sqlId); str.append("【SQL耗时-").append(time).append("-毫秒】"); str.append("【SQL】").append(sql); log.debug(str.toString()); return str.toString(); } public static String showSql(Configuration configuration, BoundSql boundSql) { Object parameterObject = boundSql.getParameterObject(); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); 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)); } } } } return sql; } private static String getParameterValue(Object obj) { String value = null; if (obj instanceof String) { value = "'" + obj.toString() + "'"; value = value.replaceAll("\\\\", "\\\\\\\\"); value = value.replaceAll("\\$", "\\\\\\$"); } else if (obj instanceof Date) { DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA); value = "'" + formatter.format(obj) + "'"; } else { if (obj != null) { value = obj.toString(); } else { value = ""; } } return value; } }
6.拦截器介绍
plugin方法,每种代理类型都会调用该方法plugin#target=org.apache.ibatis.executor.CachingExecutor@aadddeb plugin#target=org.apache.ibatis.scripting.defaults.DefaultParameterHandler@1bb554b0 plugin#target=org.apache.ibatis.executor.resultset.DefaultResultSetHandler@6824a9b0 plugin#target=org.apache.ibatis.executor.statement.RoutingStatementHandler@560f1f4b
2.@Intercepts注解指定需要创建代理的类型,会为该类型创建代理,而后会执行interceptor方法
@Intercepts(value = { @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}) })
type:拦截类型 method:拦截类型接口中定义的方法 args:拦截类型接口中定义的方法参数,method + args才能定位一个方法,可能会有多个重载的同名方法
拦截类型 | 拦截方法 | |
org.apache.ibatis.executor.Executor | ||
org.apache.ibatis.executor.parameter.ParameterHandler | ||
org.apache.ibatis.executor.statement.StatementHandler | ||
org.apache.ibatis.executor.resultset.ResultSetHandler |
标签:拦截器,obj,String,Object,value,sql,Mybatis,class From: https://www.cnblogs.com/heliocc/p/17030379.html