需求分析
在操作系统每次添加的时候我们都会去添加创建时间、创建人、修改人、修改时间这些属性。一般在类中进行处理设置值,但是基于数据库的规约,每张表中都包含以上的字段,那我们在调用的时候是否可以考虑通过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);
}
}