spring boot Mybatis 拦截器实现拼接sql和修改的代码详解
作者:曾经是最好
这篇文章主要介绍了spring boot Mybatis 拦截器实现拼接sql和修改,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
定义一个 SqlIntercepor 类
import com.culturalCenter.placeManage.globalConfig.Interface.InterceptAnnotation; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.DefaultReflectorFactory; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.apache.ibatis.session.ResultHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.sql.Statement; import java.util.Properties; @Intercepts({@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}), @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}), @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})}) @Component @Configuration public class SqlInterceptor implements Interceptor { private Logger logger = LoggerFactory.getLogger(SqlInterceptor.class); @Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory()); //先拦截到RoutingStatementHandler,里面有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,然后就到BaseStatementHandler的成员变量mappedStatement MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement"); //id为执行的mapper方法的全路径名,如com.uv.dao.UserMapper.insertUser String id = mappedStatement.getId(); logger.info("拦截到当前请求方法的全路径名为--->: " + id); //sql语句类型 select、delete、insert、update String sqlCommandType = mappedStatement.getSqlCommandType().toString(); BoundSql boundSql = statementHandler.getBoundSql(); //获取到原始sql语句 String sql = boundSql.getSql(); String mSql = sql; //获取参数 Object parameter = statementHandler.getParameterHandler().getParameterObject(); logger.info("拦截到当前请求SQL为--->: " + sql + "<------------>请求类型为: " + sqlCommandType); logger.info("拦截到当前请求参数为--->: " + parameter); //TODO 修改位置 //注解逻辑判断 添加注解了才拦截//InterceptAnnotation Class<?> classType = Class.forName(mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf("."))); String mName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf(".") + 1, mappedStatement.getId().length()); for (Method method : classType.getDeclaredMethods()) { if (method.isAnnotationPresent(InterceptAnnotation.class) && mName.equals(method.getName())) { InterceptAnnotation interceptorAnnotation = method.getAnnotation(InterceptAnnotation.class); if (interceptorAnnotation.flag()) { mSql = sql + " limit 2"; } } } //通过反射修改sql语句 Field field = boundSql.getClass().getDeclaredField("sql"); field.setAccessible(true); field.set(boundSql, mSql); return invocation.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target, new SqlInterceptor()); } @Override public void setProperties(Properties properties) { // this.setProperties(properties); }
自定义一个注解类实现局部处理SQL修改
InterceptAnnotation
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 配合SqlInterceptor实现局部拦截 * */ @Target({ElementType.METHOD,ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface InterceptAnnotation { boolean flag() default true; }
自定义数据源工厂类
SqlSessionFactoryConfig
package com.culturalCenter.placeManage.globalConfig; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import javax.sql.DataSource; /** * @author wulincheng * @Date 2020年6月23日18:25:22 * 创建SQL连接工厂类 * */ @Configuration public class SqlSessionFactoryConfig { @javax.annotation.Resource DruidDataSource dataSource; /** * @Autowired SqlSessionFactory sqlSessionFactory; * SqlSession session = sqlSessionFactory.openSession(); * //创建sqlMapper * SqlMapper sqlMapper = new SqlMapper(session); */ @Bean @Primary public SqlSessionFactory sqlSessionFactory() throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource);//更多参数请自行注入 bean.setPlugins(new Interceptor[]{new SqlInterceptor()}); Resource[] resources = new PathMatchingResourcePatternResolver() .getResources("classpath*:mapper/*.xml"); bean.setMapperLocations(resources); return bean.getObject(); } }
到此这篇关于spring boot Mybatis 拦截器,实现拼接sql和修改的文章就介绍到这了,更多相关spring boot Mybatis 拦截器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!