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

 更新时间:2022年05月09日 10:31:52   作者:曾经是最好  
这篇文章主要介绍了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 拦截器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java操作另一个Java程序使其重启的简单实现

    Java操作另一个Java程序使其重启的简单实现

    下面小编就为大家带来一篇Java操作另一个Java程序使其重启的简单实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • JAVA中的SPI思想介绍

    JAVA中的SPI思想介绍

    大家好,本篇文章主要讲的是JAVA中的SPI思想介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • springBoot详细讲解使用mybaties案例

    springBoot详细讲解使用mybaties案例

    MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架
    2022-05-05
  • Spring Boot中使用Spring Retry重试框架的操作方法

    Spring Boot中使用Spring Retry重试框架的操作方法

    这篇文章主要介绍了Spring Retry 在SpringBoot 中的应用,介绍了RetryTemplate配置的时候,需要设置的重试策略和退避策略,需要的朋友可以参考下
    2022-04-04
  • 利用Java理解sql的语法(实例讲解)

    利用Java理解sql的语法(实例讲解)

    下面小编就为大家分享一篇利用Java理解sql的语法(实例讲解),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • 在SpringBoot框架下实现Excel导入导出的方法详解

    在SpringBoot框架下实现Excel导入导出的方法详解

    SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程,今天我们就使用纯前对按表格控件带大家了解,如何在Spring Boot框架下实现Excel服务端导入导出,需要的朋友可以参考下
    2023-06-06
  • 详解如何解析pom文件方法示例

    详解如何解析pom文件方法示例

    这篇文章主要为大家介绍了详解如何解析pom文件方法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Java Selenide 简介与用法

    Java Selenide 简介与用法

    Selenium 是目前用的最广泛的Web UI 自动化测试框架,本文给大家介绍下Java Selenide使用,感兴趣的朋友一起看看吧
    2022-01-01
  • JAVA中反射机制和模块化的深入讲解

    JAVA中反射机制和模块化的深入讲解

    很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,下面这篇文章主要给大家介绍了关于JAVA中反射机制和模块化的相关资料,需要的朋友可以参考下
    2021-09-09
  • Java,JSP,Servlet获取当前工程路径(绝对路径)问题解析

    Java,JSP,Servlet获取当前工程路径(绝对路径)问题解析

    这篇文章主要介绍了Java,JSP,Servlet获取当前工程路径(绝对路径)问题解析,需要的朋友可以参考下。
    2017-09-09

最新评论