欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

扩展 MyBatis Plus 全字段更新,优化批量插入

最编程 2024-03-09 10:35:19
...
【直播预告】程序员逆袭 CEO 分几步?

一、场景

  • Myabtis Plus默认没有集成全字段更新,不满足将字段值设置为null的需求
  • 单条SQL批量插入,内置saveBatch方法是多条insert语句,批量提交,效率低

二、优化

2.1 扩展mapper层

mybatis plus官方有三个选装插件

文档

public interface CommonMapper<T> extends BaseMapper<T> {

    /**
     * 全量插入,等价于insert
     * {@link InsertBatchSomeColumn}
     *
     * @param entityList
     * @return
     */
    int insertBatchSomeColumn(List<T> entityList);

    /**
     * 全量更新,不忽略null字段,等价于update
     * 解决mybatis-plus会自动忽略null字段不更新
     * {@link com.baomidou.mybatisplus.extension.injector.methods.additional.AlwaysUpdateSomeColumnById}
     *
     * @param entity
     * @return
     */
    int alwaysUpdateSomeColumnById(@Param(Constants.ENTITY) T entity);

    /**
     * 根据 id 逻辑删除数据,并带字段填充功能
     * <p>注意入参是 entity !!! ,如果字段没有自动填充,就只是单纯的逻辑删除</p>
     * {@link LogicDeleteByIdWithFill}
     *
     * @param entity
     * @return
     */
    int deleteByIdWithFill(T entity);

}

2.2 扩展service层

public class BaseServiceImpl<M extends CommonMapper<T>, T> extends ServiceImpl<M, T> {

    private static final int BATCH_SIZE = 1000;

    @Transactional(rollbackFor = Exception.class)
    public boolean fastSaveBatch(List<T> list, int batchSize) {
        if(CollectionUtils.isEmpty(list)) {
            return true;
        }

        batchSize = batchSize < 1 ? BATCH_SIZE : batchSize;

        if(list.size() <= batchSize) {
            return retBool(baseMapper.insertBatchSomeColumn(list));
        }

        for (int fromIdx = 0 , endIdx = batchSize ; ; fromIdx += batchSize, endIdx += batchSize) {
            if(endIdx > list.size()) {
                endIdx = list.size();
            }
            baseMapper.insertBatchSomeColumn(list.subList(fromIdx, endIdx));
            if(endIdx == list.size()) {
                return true;
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean fastSaveBatch(List<T> list) {
        return fastSaveBatch(list, BATCH_SIZE);
    }

    public boolean updateAllColById(T t) {
        return retBool(baseMapper.alwaysUpdateSomeColumnById(t));
    }

}

搞定收工!