皇天后土网

Mybatis 自定义参数拦截器

Mybatis 自定义参数拦截器

参考资料:

  1. 使用MyBatis拦截器后,定义摸鱼时间又长了。参数🐟

目录

  • 一. 🤔需求场景
  • 二. 🤠前期准备
  • 三. 💪自定义拦截器
  • 四. 👉添加拦截器到配置类中
  • 五. 😋效果

一. 🤔需求场景

如下图所示

  • 有一个订单信息表,拦截每当插入或者更新一条数据的时候,红框所示部分的字段都需要进行赋值处理.
  • 如果还有其他表中也存在红框中的所示字段,每次插入或者更新时也都需要进行赋值操作,很是繁琐。
    在这里插入图片描述
    🐳有没有一种办法,定义能再插入或者更新数据库指定字段的时候,自动替我们处理呢?这就用到了Mybatis中的拦截器.

二. 🤠前期准备

⏹定义一个接口,用来标记实现了此接口的参数类中的参数会被自动处理

public interface AutoHandleParam { }

⏹定义order_info表的映射实体类

import lombok.Data;import java.util.Date;@Datapublic class OrderInfoEntity implements AutoHandleParam {     private String orderId;    private String orderName;    private String createUserId;    private Date createTime;    private String updateUserId;    private Date updateTime;}

⏹查询接口

public interface OrderInfoMapper {     void insertOrderInfo(OrderInfoEntity entity);    void updateOrderInfo(OrderInfoEntity entity);}

⏹反射封装类ReflectionUtil,详情见这篇文章 Java 封装反射工具类


三. 💪自定义拦截器

import com.example.jmw.common.utils.ReflectionUtil;import com.example.jmw.entity.AutoHandleParam;import org.apache.ibatis.executor.Executor;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.plugin.*;import org.springframework.stereotype.Component;import org.springframework.util.ObjectUtils;import java.util.Arrays;import java.util.Date;import java.util.List;import java.util.Properties;@Component@Intercepts({         @Signature(            type = Executor.class, method = "update",            args = { MappedStatement.class, Object.class}        )})public class MybatisParamInterceptor implements Interceptor { 		// 需要拦截的Mybatis中的操作    private final static String INSERT = "INSERT";    private final static String UPDATE = "UPDATE";    private final static ListsqlCommandTypeList = Arrays.asList(INSERT, UPDATE);    @Override    public Object intercept(Invocation invocation) throws Throwable {         MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];        // 获取Mybatis的当前操作方法名称        String sqlCommandType = mappedStatement.getSqlCommandType().name();        if (!sqlCommandTypeList.contains(sqlCommandType)) {             return invocation.proceed();        }        if (invocation.getArgs().length < 2) {             return invocation.proceed();        }        // 获取Mybatis插入或更新时传入的参数对象        Object paramEntity = invocation.getArgs()[1];        this.interceptInsertOrUpdateMethod(sqlCommandType, paramEntity);        return invocation.proceed();    }    /**     * 插入或更新时的参数拦截方法     * @param methodName Mybatis方法名称     * @param paramEntity 参数实体类     */    private void interceptInsertOrUpdateMethod(String methodName, Object paramEntity) {         // 如果该对象没有实现AutoHandleParam接口的话,就不需要自动添加参数        if (!(paramEntity instanceof AutoHandleParam)) {             return;        }        // 系统默认的用户名        String userId = "系统用户名" + System.currentTimeMillis();        // 当前的系统时间        Date systemDate = new Date();        // 若Mybatis的当前方法为INSERT        if (INSERT.equals(methodName)) {             // 若实体类中存在此字段            if (ReflectionUtil.existsField(paramEntity, "createUserId")) {                 Object createUserId = ReflectionUtil.invokeGetterMethod(paramEntity, "createUserId");                if (ObjectUtils.isEmpty(createUserId) || "".equals(createUserId.toString())) {                     // 通过反射将用户ID放入实体类中                    ReflectionUtil.invokeSetterMethod(paramEntity, "createUserId", userId);                }            }            if (ReflectionUtil.existsField(paramEntity, "createTime")) {                 Object createTime = ReflectionUtil.invokeGetterMethod(paramEntity, "createTime");                if (ObjectUtils.isEmpty(createTime) ) {                     ReflectionUtil.invokeSetterMethod(paramEntity, "createTime", systemDate);                }            }            return;        }        // 若Mybatis的当前方法为UPDATE        if (UPDATE.equals(methodName)) {             if (ReflectionUtil.existsField(paramEntity, "updateUserId")) {                 ReflectionUtil.invokeSetterMethod(paramEntity, "updateUserId", userId);            }            if (ReflectionUtil.existsField(paramEntity, "updateTime")) {                 ReflectionUtil.invokeSetterMethod(paramEntity, "updateTime", systemDate);            }        }    }    @Override    public Object plugin(Object target) {         return Plugin.wrap(target, this);    }    @Override    public void setProperties(Properties properties) {     }}

四. 👉添加拦截器到配置类中

import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.SqlSessionFactoryBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;import javax.sql.DataSource;@Configurationpublic class DataSourceConfig {     // 注入数据源    @Resource    private DataSource dataSource;    // 注入自定义参数拦截器    @Resource    private MybatisParamInterceptor paramInterceptor;    @Bean    public SqlSessionFactory sqlSessionFactorySecondary() throws Exception {         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();        // 设置数据源        sqlSessionFactoryBean.setDataSource(dataSource);        // 设置拦截器(可设置多个)        Interceptor[] plugins = { paramInterceptor};        sqlSessionFactoryBean.setPlugins(plugins);        return sqlSessionFactoryBean.getObject();    }}

五. 😋效果

⭕操作之前,表中没有数据

在这里插入图片描述


⏹插入一条数据

  • 可以看到我们并没有向参数实体类中传入用户ID和创建时间,拦截但是拦截器替我们向实体类中放入了参数,因此最终用户ID和创建时间插入到数据库中了。
    在这里插入图片描述

⏹更新一条数据

  • 可以看到指定的定义订单名称被更新,并且更新用户ID和更新时间也被自动处理到数据库中
    在这里插入图片描述

未经允许不得转载:皇天后土网 » Mybatis 自定义参数拦截器