Mybatis插件开发——系统添加修改参数初始化

Scroll Down

需求分析

在操作系统每次添加的时候我们都会去添加创建时间、创建人、修改人、修改时间这些属性。一般在类中进行处理设置值,但是基于数据库的规约,每张表中都包含以上的字段,那我们在调用的时候是否可以考虑通过Mybatis进行入手,免入繁琐的重复设置操作。

设计思路

通过拦截Mybatis的UPATE和INSERT的操作,反射修改参数类,或者修改SQL的参数。

代码实现

抽象类

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;

/**
 * @author 王守钰
 * @program quan
 * @date 2020年05月12日 15:21
 * @description: Mybatis参数初始化拦截器
 */
@Slf4j
public abstract class AbstractMybatisParamInitInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        if (invocation.getTarget() instanceof Executor
                && invocation.getArgs().length == 2) {
            MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
            SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
            Object args = invocation.getArgs()[1];
            switch (sqlCommandType){
                case INSERT:
                    initCreateParams(args);
                    break;
                case UPDATE:
                    initUpdateParams(args);
                    break;
                default:
                    break;
            }
        }
        return invocation.proceed();
    }

    /**
     * 初始化参数
     * @param args
     */
    protected abstract void initCreateParams(Object args);

    /**
     * 初始化更新参数
     * @param args
     */
    protected abstract void initUpdateParams(Object args) ;

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
}

实现类


import com.wangshouyu.common.mybatis.interceptor.AbstractMybatisParamInitInterceptor;
import com.wangshouyu.common.utils.params.ParamsInitUtils;

import java.util.Date;
import java.util.Map;

/**
 * @author 王守钰
 * @program quan
 * @date 2020年05月12日 16:24
 * @description: Mybatis初始化参数拦截器
 */
 @Intercepts(@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}))
public class MybatisParamInitIntercept extends AbstractMybatisParamInitInterceptor {

    private UserService userService;

    public MybatisParamInitIntercept(UserService userService) {
        this.userService = userService;
    }

    @Override
    protected void initCreateParams(Object args) {
        Date current = new Date();
        if(args instanceof Map){
            Map map = (Map) args;
            map.put("created_time", current);
            map.put("created_by", userService.getUserId());
            map.put("updated_time", current);
            map.put("updated_by", userService.getUserId());
        }else {
            ParamsInitUtils.initCreateInfo(args, userService.getUserId());
        }
    }

    @Override
    protected void initUpdateParams(Object args) {
        Date current = new Date();
        if(args instanceof Map){
            Map map = (Map) args;
            map.put("updated_time", current);
            map.put("updated_by", userService.getUserId());
        }else {
            ParamsInitUtils.initUpdateInfo(args, userService.getUserId());
        }
    }
}

参数初始化工具

package com.wangshouyu.common.utils.params;

import org.joda.time.DateTime;

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

/**
 * @author 王守钰
 * @version 1.0
 * @program quan
 * @date 2020年04月22日 21:16
 * @description: 参数初始化工具
 */
public class ParamsInitUtils {

    private ParamsInitUtils() {
    }

    /**
     * 创建时间
     */
    private static final String[] CREATE_TIMES_PARAMS = {"createTime", "createAt", "createdTime"};

    /**
     * 创建人
     */
    private static final String[] CREATOR_IDS_PARAMS = {"creatorId", "createdBy"};

    /**
     * 更新时间
     */
    private static final String[] UPDATE_TIMES_PARAMS = {"updateTime", "modifyTime", "updateAt", "updatedTime"};

    /**
     * 更新人ID
     */
    private static final String[] UPDATOR_IDS_PARAMS = {"updatorId", "modifierId", "updatedBy"};

    /**
     * 系统操作
     */
    private static final String SYSTEM = "system";


    /**
     * 设置创建时间
     * @param object
     */
    public static void initCreateTime(Object object){
        initParams(object, new Date(), CREATE_TIMES_PARAMS);
    }

    /**
     * 设置创建人
     * @param object
     * @param value
     */
    public static void initCreatorId(Object object, Object value){
        initParams(object, value, CREATOR_IDS_PARAMS);
    }

    /**
     * 初始化创建信息
     * @param object
     * @param value
     */
    public static void initCreateInfo(Object object, Object value){
        Date current = new Date();
        // 创建信息
        initParams(object, current, CREATE_TIMES_PARAMS);
        initCreatorId(object, value);
        // 修改信息
        initParams(object, current, UPDATE_TIMES_PARAMS);
        initUpdatorId(object, value);
    }

    /**
     * 设置更新时间
     * @param object
     */
    public static void initUpdateTime(Object object){
        initParams(object, new Date(), UPDATE_TIMES_PARAMS);
    }

    /**
     * 设置更新人
     * @param object
     * @param value
     */
    public static void initUpdatorId(Object object, Object value){
        initParams(object, value, UPDATOR_IDS_PARAMS);
    }

    /**
     * 初始化更新信息
     * @param object
     * @param value
     */
    public static void initUpdateInfo(Object object, Object value){
        initUpdateTime(object);
        initUpdatorId(object, value);
    }

    /**
     * 系统更新
     * @param object
     */
    public static void initSystemUpdateInfo(Object object){
        initUpdateInfo(object, SYSTEM);
    }

    /**
     * 系统创建
     * @param object
     */
    public static void initSystemCreateInfo(Object object){
        initCreateInfo(object, SYSTEM);
    }

    /**
     * 初始化参数
     * @param object
     * @param value
     * @param params
     */
    private static void initParams(Object object, Object value, String ... params){
        Class<?> clazz = object.getClass();
        while (clazz != null){
            for (String param : params){
                try {
                    // 获取该类的成员变量
                    Field field = clazz.getDeclaredField(param);

                    if(null == field){
                        continue;
                    }

                    // 取消语言访问检查
                    field.setAccessible(true);
                    field.set(object, value);
                }catch (Exception e){
                }
            }
            clazz = clazz.getSuperclass();
        }

    }
}

Mybatis配置开启


import com.wangshouyu.common.intercept.MybatisParamInitIntercept;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @author 王守钰
 * @version 1.0
 * @program quan
 * @date 2020年04月22日 20:25
 * @description: mybatis配置文件
 */
@Configuration
@EnableTransactionManagement
@MapperScan("com.wangshouyu.**.mapper")
public class MybatisConfig {


    @Bean
    public MybatisParamInitIntercept mybatisParamInitIntercept(UserService userService){
        return new MybatisParamInitIntercept(userService);
    }
}

Mybatis-Plus拓展配置

import com.wangshouyu.common.mybatis.interceptor.AbstractMybatisParamInitInterceptor;
import com.wangshouyu.common.utils.params.ParamsInitUtils;

import java.util.Date;
import java.util.Map;

/**
 * @author 王守钰
 * @program quan
 * @date 2020年05月12日 16:24
 * @description: Mybatis初始化参数拦截器
 */
 @Intercepts(@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}))
public class MybatisParamInitIntercept extends AbstractMybatisParamInitInterceptor implements MetaObjectHandler {

    private UserService userService;

    public MybatisParamInitIntercept(UserService userService) {
        this.userService = userService;
    }

    @Override
    protected void initCreateParams(Object args) {
        Date current = new Date();
        if(args instanceof Map){
            Map map = (Map) args;
            map.put("created_time", current);
            map.put("created_by", userService.getUserId());
            map.put("updated_time", current);
            map.put("updated_by", userService.getUserId());
        }else {
            ParamsInitUtils.initCreateInfo(args, userService.getUserId());
        }
    }

    @Override
    protected void initUpdateParams(Object args) {
        Date current = new Date();
        if(args instanceof Map){
            Map map = (Map) args;
            map.put("updated_time", current);
            map.put("updated_by", userService.getUserId());
        }else {
            ParamsInitUtils.initUpdateInfo(args, userService.getUserId());
        }
    }
    
    @Override
    public void insertFill(MetaObject metaObject) {
        Date current = new Date();
        setInsertFieldValByName("createdTime", current, metaObject);
        setInsertFieldValByName("updatedTime", current, metaObject);

        setInsertFieldValByName("createdBy", userService.getUserId(), metaObject);
        setInsertFieldValByName("updatedBy", userService.getUserId(), metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        Date current = new Date();
        setInsertFieldValByName("updatedTime", current, metaObject);
        setInsertFieldValByName("updatedBy", userService.getUserId(), metaObject);

    }
}