自定义Mybatis拦截器实现自动添加创建人修改人等公共字段

摘要

本文通过自定义Mybatis拦截器拦截Executor接口实现在插入和修改操作时自动添加创建人修改人等公共字段,话不多说,直接上代码

定义Mybatis拦截器

package com.syb.springboottestdemo.interceptor;

import com.syb.springboottestdemo.dto.GoodsDTO;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.Field;
import java.util.Properties;

/**
* @Author: syb
* @Description: 自定义mybatis拦截器
* @DateTime: 2022/8/23 17:03
* @Params:
* @Return
*/
@Intercepts({
        @Signature(
                type = Executor.class ,
                method = "update",
                args={MappedStatement.class,Object.class})
})
/**
 * 2.各个参数的含义:
 * @Intercepts:标识该类是一个拦截器;
 * @Signature:指明自定义拦截器需要拦截哪一个类型,哪一个方法;
 *        2.1 type:对应四种类型中的一种;
 * 	2.2 method:对应接口中的哪个方法;
 * 	2.3 args:对应哪一个方法参数类型(因为可能存在重载方法);
 */
public class MybatisInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //invocation.getArgs()得到的结果就是args中的参数,第一个元素肯定是MappedStatement,第二个元素是我们传递给sql语句的参数
        //如果没有传递则只能得到一个元素,也就是invocation.getArgs().length的长度是1
        //如果相关的动态代理接口没有传递参数,则我们不需要对传递给sql语句的参数进行处理,直接放行动态代理接口方法
        if(invocation.getArgs().length == 1){
            //只要执行了invocation.proceed()方法才会对动态代理接口进行放行,否则动态代理接口不会执行
            return invocation.proceed();
        }

        //获取动态代理接口传递给sql语句的参数实体
        Object parameter = invocation.getArgs()[1];
        System.out.println(parameter);

        //获取Sql语句的类型,也即是Sql语句是增删改查中的哪一个
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();

        //修改人或者是创建人
        String man = "";
        if(sqlCommandType.equals(SqlCommandType.INSERT)){
            man = "createBy";
        }
        if(sqlCommandType.equals(SqlCommandType.UPDATE)){
            man = "updateBy";
        }

        //通过反射获取我们传递给sql语句也即是动态代理接口中的实体属性
        Field[] fields = GoodsDTO.class.getDeclaredFields();
        for(Field field : fields){
            //安全性访问检查:设置为true
            field.setAccessible(true);

            String fieldName = field.getName();

            if(fieldName.equals(man)){
                BeanUtils.setProperty(parameter,man,"simple");
                System.out.println(parameter);
            }
        }

        return invocation.proceed();
    }


    @Override
    public Object plugin(Object target) {
        //plugin方法主要是将拦截器中定义的增强功能(也就是拦截器)和原来的核心对象合并起来,成为最终的核心对象wrap,然后把这个对象返回
        Object wrap = Plugin.wrap(target, this);
        return wrap;
    }

    @Override
    public void setProperties(Properties properties) {
        //这个方法里面可以取出来我们mybatis的配置文件中插件中配置的属性
    }
}

注入拦截器

package com.syb.springboottestdemo.config;

import com.syb.springboottestdemo.interceptor.MybatisInterceptor;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisConfig {
    @Bean
    ConfigurationCustomizer mybatisConfigurationCustomizer() {
        return new ConfigurationCustomizer() {
            @Override
            public void customize(org.apache.ibatis.session.Configuration configuration) {
                configuration.addInterceptor(new MybatisInterceptor());
            }
        };
    }
}

使用说明

在xml文件中书写时直接使用,因为参数在拦截器中已经实现了注入

<insert id="insert">
        insert into goods(name,create_by)
        values (#{name},#{createBy})
    </insert>
posted @   Cv工程师120621号  阅读(1035)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示

目录导航