Bootstrap

mybatis拦截器自动填充公共字段

在开发的过程中 ,在持久化的过程中可能会遇到表中都有公共字段的问题,这样就可以统一赋值,更简化开发,比如说在新增用户需要指定创建时间、创建人等字段,修改用户时需要指定修改时间、修改人等字段,

增加拦截器

import com.datamiddle.common.utils.SecurityUtils;
import com.datamiddle.framework.security.LoginUser;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Date;

@Component
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class FieldFillInterceptor implements Interceptor {

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		Object[] args = invocation.getArgs();
		MappedStatement ms = (MappedStatement) args[0];
		SqlCommandType sqlCommandType = ms.getSqlCommandType();
		if (SqlCommandType.INSERT.equals(sqlCommandType)) {
			Object entity = args[1];
			Class<?> entityClass = entity.getClass();
      // 这里是获取父类的
			Class<?> superclass = entityClass.getSuperclass();
			LoginUser loginUser = SecurityUtils.getLoginUser();
//			System.out.println(loginUser);
			// 使用反射检查实体类是否包含指定的属性
			/**
			 * createTime 创建时间
			 * createId 创建人ID
			 */
			if (hasProperty(superclass, "createTime")) {
				superclass.getMethod("setCreateTime", LocalDateTime.class).invoke(entity, LocalDateTime.now());
			}
			if (hasProperty(superclass, "createBy")) {
				superclass.getMethod("setCreateBy", String.class).invoke(entity, loginUser.getUsername());
			}
		} else if (SqlCommandType.UPDATE.equals(sqlCommandType)) {
			Object entity = args[1];
			Class<?> entityClass = entity.getClass();
			Class<?> superclass = entityClass.getSuperclass();
			LoginUser loginUser = SecurityUtils.getLoginUser();
//			System.out.println(loginUser);
			// 使用反射检查实体类是否包含指定的属性
			/**
			 * updateTime 更新时间
			 * updateId 更新人ID
			 */
			if (hasProperty(superclass, "updateTime")) {
				superclass.getMethod("setUpdateTime", Date.class).invoke(entity, new Date());
			}
			if (hasProperty(superclass, "updateBy")) {
				superclass.getMethod("setUpdateBy", String.class).invoke(entity, loginUser.getUsername());
			}
		}

		return invocation.proceed();
	}

	private boolean hasProperty(Class<?> entityClass, String propertyName) {
		try {
			entityClass.getDeclaredField(propertyName);
			return true;
		} catch (NoSuchFieldException e) {
			return false;
		}
	}
}

在mybatis配置文件中增加配置

<configuration>
    <!-- 全局参数 -->
    <settings>
        <!-- 使全局的映射器启用或禁用缓存 -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 允许JDBC 支持自动生成主键 -->
        <setting name="useGeneratedKeys" value="true"/>
        <!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <!-- 指定 MyBatis 所用日志的具体实现 -->
        <setting name="logImpl" value="SLF4J"/>
        <!-- 使用驼峰命名法转换字段 -->
        <!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
    </settings>

    <plugins>
        <!-- 公共字段自动填充插件 -->
        <plugin interceptor="com.datamiddle.framework.interceptor.FieldFillInterceptor"/>
    </plugins>
</configuration>

;