经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MyBatis » 查看文章
spring?boot?Mybatis?拦截器实现拼接sql和修改的代码详解
来源:jb51  时间:2022/5/9 12:22:21  对本文有异议

定义一个 SqlIntercepor 类

  1. import com.culturalCenter.placeManage.globalConfig.Interface.InterceptAnnotation;
  2. import org.apache.ibatis.executor.statement.StatementHandler;
  3. import org.apache.ibatis.mapping.BoundSql;
  4. import org.apache.ibatis.mapping.MappedStatement;
  5. import org.apache.ibatis.plugin.*;
  6. import org.apache.ibatis.reflection.DefaultReflectorFactory;
  7. import org.apache.ibatis.reflection.MetaObject;
  8. import org.apache.ibatis.reflection.SystemMetaObject;
  9. import org.apache.ibatis.session.ResultHandler;
  10. import org.slf4j.Logger;
  11. import org.slf4j.LoggerFactory;
  12. import org.springframework.context.annotation.Configuration;
  13. import org.springframework.stereotype.Component;
  14. import java.lang.reflect.Field;
  15. import java.lang.reflect.Method;
  16. import java.sql.Statement;
  17. import java.util.Properties;
  18. @Intercepts({@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}),
  19. @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
  20. @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})})
  21. @Component
  22. @Configuration
  23. public class SqlInterceptor implements Interceptor {
  24. private Logger logger = LoggerFactory.getLogger(SqlInterceptor.class);
  25. @Override
  26. public Object intercept(Invocation invocation) throws Throwable {
  27. StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
  28. MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
  29. //先拦截到RoutingStatementHandler,里面有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,然后就到BaseStatementHandler的成员变量mappedStatement
  30. MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
  31. //id为执行的mapper方法的全路径名,如com.uv.dao.UserMapper.insertUser
  32. String id = mappedStatement.getId();
  33. logger.info("拦截到当前请求方法的全路径名为--->: " + id);
  34. //sql语句类型 select、delete、insert、update
  35. String sqlCommandType = mappedStatement.getSqlCommandType().toString();
  36. BoundSql boundSql = statementHandler.getBoundSql();
  37. //获取到原始sql语句
  38. String sql = boundSql.getSql();
  39. String mSql = sql;
  40. //获取参数
  41. Object parameter = statementHandler.getParameterHandler().getParameterObject();
  42. logger.info("拦截到当前请求SQL为--->: " + sql + "<------------>请求类型为: " + sqlCommandType);
  43. logger.info("拦截到当前请求参数为--->: " + parameter);
  44. //TODO 修改位置
  45. //注解逻辑判断 添加注解了才拦截//InterceptAnnotation
  46. Class<?> classType = Class.forName(mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf(".")));
  47. String mName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf(".") + 1, mappedStatement.getId().length());
  48. for (Method method : classType.getDeclaredMethods()) {
  49. if (method.isAnnotationPresent(InterceptAnnotation.class) && mName.equals(method.getName())) {
  50. InterceptAnnotation interceptorAnnotation = method.getAnnotation(InterceptAnnotation.class);
  51. if (interceptorAnnotation.flag()) {
  52. mSql = sql + " limit 2";
  53. }
  54. }
  55. }
  56. //通过反射修改sql语句
  57. Field field = boundSql.getClass().getDeclaredField("sql");
  58. field.setAccessible(true);
  59. field.set(boundSql, mSql);
  60. return invocation.proceed();
  61. }
  62. @Override
  63. public Object plugin(Object target) {
  64. return Plugin.wrap(target, new SqlInterceptor());
  65. }
  66. @Override
  67. public void setProperties(Properties properties) {
  68. // this.setProperties(properties);
  69. }

自定义一个注解类实现局部处理SQL修改

InterceptAnnotation 

  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5.  
  6. /**
  7. * 配合SqlInterceptor实现局部拦截
  8. * */
  9. @Target({ElementType.METHOD,ElementType.PARAMETER})
  10. @Retention(RetentionPolicy.RUNTIME)
  11. public @interface InterceptAnnotation {
  12. boolean flag() default true;
  13. }

自定义数据源工厂类

SqlSessionFactoryConfig

  1. package com.culturalCenter.placeManage.globalConfig;
  2. import com.alibaba.druid.pool.DruidDataSource;
  3. import org.apache.ibatis.plugin.Interceptor;
  4. import org.apache.ibatis.session.SqlSessionFactory;
  5. import org.mybatis.spring.SqlSessionFactoryBean;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.context.annotation.Primary;
  10. import org.springframework.core.io.Resource;
  11. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  12. import javax.sql.DataSource;
  13. /**
  14. * @author wulincheng
  15. * @Date 2020年6月23日18:25:22
  16. * 创建SQL连接工厂类
  17. * */
  18. @Configuration
  19. public class SqlSessionFactoryConfig {
  20. @javax.annotation.Resource
  21. DruidDataSource dataSource;
  22. /**
  23. * @Autowired SqlSessionFactory sqlSessionFactory;
  24. * SqlSession session = sqlSessionFactory.openSession();
  25. * //创建sqlMapper
  26. * SqlMapper sqlMapper = new SqlMapper(session);
  27. */
  28. @Bean
  29. @Primary
  30. public SqlSessionFactory sqlSessionFactory() throws Exception {
  31. SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
  32. bean.setDataSource(dataSource);//更多参数请自行注入
  33. bean.setPlugins(new Interceptor[]{new SqlInterceptor()});
  34. Resource[] resources = new PathMatchingResourcePatternResolver()
  35. .getResources("classpath*:mapper/*.xml");
  36. bean.setMapperLocations(resources);
  37. return bean.getObject();
  38. }
  39. }

到此这篇关于spring boot Mybatis 拦截器,实现拼接sql和修改的文章就介绍到这了,更多相关spring boot Mybatis 拦截器内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号