使用MyBatis批量插入数据,MyBatis拦截器失效?

作者站长头像
站长
· 阅读数 17

使用MyBatis批量插入数据,MyBatis拦截器失效?问题描述:我在项目中写了一个MyBatis的拦截器(插件),作用是在插入或更新数据时自动填充id、create_by、create_time等基础字段的值,代码如下:

@Component
@Intercepts({
        @Signature(type = Executor.class,method = "update",args = {MappedStatement.class, Object.class})
})
public class MyBatisAutoFillPlugin implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 被代理的对象
        Object target = invocation.getTarget();
        // 被代理的方法
        Method method = invocation.getMethod();
        // 被代理的方法执行参数
        Object[] args = invocation.getArgs();

        if (!(args.length > 1)){
            return invocation.proceed();
        }

        MappedStatement mappedStatement = (MappedStatement) args[0];
        Object paramObj = args[1];
        if (paramObj instanceof BaseEntity){
            // 获取登录用户
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            SysLoginUser sysLoginUser = (SysLoginUser) authentication.getPrincipal();

            BaseEntity entity = (BaseEntity) paramObj;
            Date now = new Date();
            // 判断sql语句
            if (Objects.equals(SqlCommandType.INSERT,sqlCommandType)){
                entity.setId(IdGenerator.getId());
                entity.setStatus(CommonStatusEnum.NORMAL.getCode());
                entity.setCreateBy(sysLoginUser.getId());
                entity.setCreateTime(now);
            }else if (Objects.equals(SqlCommandType.UPDATE,sqlCommandType)){
                entity.setUpdateBy(sysLoginUser.getId());
                entity.setUpdateTime(now);
            }
        }
        // 调用实际业务方法
        Object result = invocation.proceed();
        return result;
    }
}

当我在Mapper中写了一个批量插入的方法,执行后拦截器却失效了,导致我的基础字段无法赋值,这是什么原因?

<!-- 批量插入 -->
<insert id="insertBatch">
        insert into sys_user_role
        ( id,user_id,role_id
        ,status,create_time,create_by
        ,update_time,update_by) values
        <foreach collection="list" separator="," item="item">
            (#{item.id},#{item.userId},
             #{item.roleId},
             #{item.status}, #{item.createTime},#{item.createBy},
             #{item.updateTime},#{item.updateBy})
        </foreach>
    </insert>

我尝试使用单个插入的方法,这是可以的。

<!-- 单个记录插入 -->
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.ss.sys.modular.role.entity.UserRole" useGeneratedKeys="true">
        insert into sys_user_role
        ( id,user_id,role_id
        ,status,create_time,create_by
        ,update_time,update_by)
        values (#{id,jdbcType=BIGINT},#{userId,jdbcType=BIGINT},#{roleId,jdbcType=BIGINT}
        ,#{status,jdbcType=TINYINT},#{createTime,jdbcType=TIMESTAMP},#{createBy,jdbcType=BIGINT}
        ,#{updateTime,jdbcType=TIMESTAMP},#{updateBy,jdbcType=BIGINT})
    </insert>
回复
1个回答
avatar
test
2024-06-23

找到原因了,在@Intercepts注解添加要拦截的StatementHandler方法即可

@Intercepts({
        @Signature(type = Executor.class,method = "update",args = {MappedStatement.class, Object.class}),
        @Signature(type = StatementHandler.class,method = "update",args = {Statement.class})
})
public class MyBatisAutoFillPlugin implements Interceptor {
    // some code...
}
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容