好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

spring boot Mybatis 拦截器实现拼接sql和修改的代码详解

定义一个 SqlIntercepor 类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

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 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

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 拦截器内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

原文链接:https://HdhCmsTestcnblogs测试数据/Mr-lin66/p/13218467.html

查看更多关于spring boot Mybatis 拦截器实现拼接sql和修改的代码详解的详细内容...

  阅读:39次