天天看點

mybatis plus 建立時間建立人,修改時間修改人通用插件

package com.itl.iap.common.base.interceptor;

import com.itl.iap.common.base.dto.UserTDto;
import com.itl.iap.common.base.utils.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.binding.MapperMethod;
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.ibatis.session.defaults.DefaultSqlSession;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version 1.1
 * 版本更新,對象如果是集合采用遞歸的方式添加
 */
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
@Slf4j
@SuppressWarnings("all")
public class SqlInterceptor implements Interceptor {
    /**
     * 建立時間
     */
    private static final String CREATE_TIME = "createDate";
    private static final String CREATER = "creater";
    /**
     * 更新時間
     */
    private static final String UPDATE_TIME = "lastUpdateDate";
    private static final String UPDATE_BY = "lastUpdateBy";
    @Autowired
    private UserUtil userUtil;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        String name = invocation.getMethod().getName();
        if (name.equals("update") || name.equals("install")) {
            return invokeUpdate(invocation);
        } else {
            return invocation.proceed();
        }
    }

    // 修改操作
    private Object invokeUpdate(Invocation invocation) throws Exception {
        // 擷取第一個參數
        Object[] args1 = invocation.getArgs();
        // 去除null
        List<Object> objList = Arrays.stream(args1).filter(x -> x != null).collect(Collectors.toList());
        MappedStatement ms = null;
        Object args = null;   // 擷取參數
        // 指派
        for (Object obj : objList) {
            if (obj instanceof MappedStatement) {
                ms = (MappedStatement) obj;
            } else if (obj instanceof Object) {
                args = obj;
            }
        }
        if (ms == null || args == null) {
            return invocation.proceed();
        }
        SqlCommandType sqlCommandType = ms.getSqlCommandType();
        // 判斷參數類型  是不是MapperMethod.ParamMap 是 就循環更改  不是就是對象直接更改
        if (args instanceof MapperMethod.ParamMap) {
            MapperMethod.ParamMap<Object> mapObj = (MapperMethod.ParamMap<Object>) args;
            for (Map.Entry<String, Object> obj : mapObj.entrySet()) {
                Object paramObj = mapObj.get(obj.getKey());
                if (paramObj instanceof List) {
                    this.objList(paramObj, ms);
                } else {
                    Field[] fields = paramObj.getClass().getDeclaredFields();
                    this.upField(fields, ms, args);
                }
            }
        } else if (args instanceof DefaultSqlSession.StrictMap) {
            DefaultSqlSession.StrictMap<Object> mapObj = (DefaultSqlSession.StrictMap<Object>) args;
            for (Map.Entry<String, Object> obj : mapObj.entrySet()) {
                Object paramObj = mapObj.get(obj.getKey());
                if (paramObj instanceof List) {
                    this.objList(paramObj, ms);
                } else {
                    Field[] fields = paramObj.getClass().getDeclaredFields();
                    this.upField(fields, ms, args);
                }
            }
        } else {
            Field[] fields = args.getClass().getDeclaredFields();
            this.upField(fields, ms, args);
        }
        return invocation.proceed();
    }

    /**
     * 如果是集合就遞歸
     *
     * @param paramObj List 對象
     * @param ms       MappedStatement
     */
    private void objList(Object paramObj, MappedStatement ms) {
        List<Object> listObj = (ArrayList<Object>) paramObj;
        for (Object obj : listObj) {
            if (obj instanceof List) {
                this.objList(obj, ms);
            }
            Field[] declaredFields = obj.getClass().getDeclaredFields();
            this.upField(declaredFields, ms, obj);
        }
    }

    /**
     * 開始執行修改方法
     *
     * @param fields 反射擷取字段清單
     * @param ms     MappedStatement
     * @param args   對象參數
     */
    private void upField(Field[] fields, MappedStatement ms, Object args) {
        // 如果 insert 語句  則添加建立時間建立人 修改時間和修改人
        if (ms.getSqlCommandType() == SqlCommandType.INSERT) {
            this.setAllParams(fields, args, CREATE_TIME, new Date());
            this.setAllParams(fields, args, CREATER, UPDATE_BY.toString());
            this.setAllParams(fields, args, UPDATE_BY, UPDATE_BY.toString());
            this.setAllParams(fields, args, UPDATE_TIME, new Date());
            // 如果是update語句  則添加修改時間修改人
        } else if (ms.getSqlCommandType() == SqlCommandType.UPDATE) {
            this.setAllParams(fields, args, UPDATE_BY, UPDATE_BY.toString());
            this.setAllParams(fields, args, UPDATE_TIME, new Date());
        }
    }

    /**
     * 根據傳遞參數放進行修改
     *
     * @param fields   反射存在的參數
     * @param obj      需要改變的對象
     * @param valueKey 變更的字段
     * @param valObj   變更參數類型
     */
    private void setAllParams(Field[] fields, Object obj, String valueKey, Object valObj) {
        UserTDto user = this.getUser();

        for (int i = 0; i < fields.length; i++) {
            if (valueKey.toLowerCase().equals(fields[i].getName().toLowerCase())) {
                try {
                    if (valObj instanceof Date) {
                        fields[i].setAccessible(true);
                        fields[i].set(obj, new Date());
                        fields[i].setAccessible(false);
                    }
                    if (user != null && user.getUserName() != null) {
                        if (valObj instanceof String) {
                            fields[i].setAccessible(true);
                            fields[i].set(obj, user.getUserName());
                            fields[i].setAccessible(false);
                        }
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }

    // 擷取使用者
    private UserTDto getUser() {
        return userUtil.getUser();
    }

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

    @Override
    public void setProperties(Properties properties) {

    }


}