使用mybatis拦截器实现公共字段自动注入——第一版

需求

拦截器第二版

如题,用Mybatis拦截器做公共字段的自动注入,这是我第一次使用Mybatis拦截器。之前做过一次自动注入,是用的自定义注解,然后用AOP拦截注入的。

  • 注意:这一版是我写的第一版。都是写死的字段,很废物,下一遍会写一个注解版,稍微能通用一点…
  • 需要注入的字段:
字段备注
created_by创建人
created_time创建时间
updated_by修改人
updated_time修改时间

思路

  • 因为是公共字段,所以抽一个基类,将这些公共字段放到基类中
  • 在拦截器中,通过反射机制递归获取对象及其基类的所有字段,遍历获取到的字段数组,判断字段名,如果跟我们的字段一致则注入。
  • 前端提交请求时传一个updatedBy。新增时拦截器将updatedBy注入到createdBy中

实现

  • 反射工具类
public class ReflectUtil {

    public static Field[] getAllFields(Object object){
        Class clazz = object.getClass();
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null){
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }

    public static Field[] getAllFields(Class clazz){
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null){
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }
}
  • 拦截器
@Intercepts({@Signature(type = Executor.class, method = "update"
        , args = {MappedStatement.class, Object.class})})
public class StuffInterceptorFirst implements Interceptor {


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        if (invocation.getTarget() instanceof Executor && invocation.getArgs().length == 2) {
            final Executor executor = (Executor) invocation.getTarget();
            // 获取第一个参数
            final MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
            final Object paramObj = invocation.getArgs()[1];
            if (ms.getSqlCommandType() == SqlCommandType.INSERT) {
                return this.executeInsert(executor, ms, paramObj);
            } else if (ms.getSqlCommandType() == SqlCommandType.UPDATE) {
                return this.executeUpdate(executor, ms, paramObj);
            }
        }
        return invocation.proceed();
    }

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

    @Override
    public void setProperties(Properties properties) {

    }

    /**
     * 新增操作
     *
     * @param executor executor
     * @param ms       ms
     * @param paramObj 参数
     * @return 返回执行结果
     */
    private Object executeInsert(final Executor executor, final MappedStatement ms, final Object paramObj) throws Exception {
        final BaseEntity baseEntity = (BaseEntity)paramObj;
        // 获取对象的所有字段
        final Field[] fields = ReflectUtil.getAllFields(paramObj);
        // 遍历获取到的字段,根据字段名判断注入
        for (final Field field : fields) {
            field.setAccessible(true);
            final String fieldName = field.getName();
            switch (fieldName) {
                case "createdBy":
                    field.set(paramObj, baseEntity.getUpdatedBy());
                    break;
                case "createdTime":
                    field.set(paramObj, new Date());
                    break;
                case "updatedBy":
                    field.set(paramObj, baseEntity.getUpdatedBy());
                    break;
                case "updatedTime":
                    field.set(paramObj, new Date());
                    break;
                default:
                    break;
            }
        }
        return executor.update(ms, paramObj);
    }

    /**
     * 修改操作
     *
     * @param executor executor
     * @param ms       ms
     * @param paramObj 参数
     * @return 返回执行结果
     */
    private Object executeUpdate(final Executor executor, final MappedStatement ms, final Object paramObj) throws Exception {
        final BaseEntity baseEntity = (BaseEntity)paramObj;
        final Field[] fields = ReflectUtil.getAllFields(paramObj);
        for (final Field field : fields) {
            field.setAccessible(true);
            final String fieldName = field.getName();
            switch (fieldName) {
                case "updatedBy":
                    field.set(paramObj, baseEntity.getUpdatedBy());
                    break;
                case "updatedTime":
                    field.set(paramObj, new Date());
                    break;
                default:
                    break;
            }
        }
        return executor.update(ms, paramObj);
    }
}
  • 配置类
@Configuration
public class InterceptorConfig {

    @Bean
    public Interceptor interceptor() {
        return new StuffInterceptor();
    }
    
}

缺点

  • 字段名都写死了,换一个项目或者项目修改一下就要跟着修改了。
  • 要注入的内容还得让前端传,老奇怪了…

收获

主要是稍微了解了一下mybatis拦截器的使用吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值