美文网首页Spring mvcmysql开源框架-Mybatis系列
mybatis-plus真正批量新增和更新

mybatis-plus真正批量新增和更新

作者: 归来_仍是少年 | 来源:发表于2020-11-26 20:57 被阅读0次

    使用mybatis-plus来进行批量新增和更新时,你会发现其实是一条条sql执行,下面进行优化。

    1.添加InsertBatchMethod和UpdateBatchMethod类

    import com.baomidou.mybatisplus.core.injector.AbstractMethod;
    import com.baomidou.mybatisplus.core.metadata.TableInfo;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.executor.keygen.NoKeyGenerator;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.mapping.SqlSource;
    
    /**
     * 批量插入方法实现
     */
    @Slf4j
    public class InsertBatchMethod extends AbstractMethod {
        @Override
        public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
            final String sql = "<script>insert into %s %s values %s</script>";
            final String fieldSql = prepareFieldSql(tableInfo);
            final String valueSql = prepareValuesSql(tableInfo);
            final String sqlResult = String.format(sql, tableInfo.getTableName(), fieldSql, valueSql);
            //log.debug("sqlResult----->{}", sqlResult);
            SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
            return this.addInsertMappedStatement(mapperClass, modelClass, "insertBatch", sqlSource, new NoKeyGenerator(), null, null);
        }
    
        private String prepareFieldSql(TableInfo tableInfo) {
            StringBuilder fieldSql = new StringBuilder();
            fieldSql.append(tableInfo.getKeyColumn()).append(",");
            tableInfo.getFieldList().forEach(x -> fieldSql.append(x.getColumn()).append(","));
            fieldSql.delete(fieldSql.length() - 1, fieldSql.length());
            fieldSql.insert(0, "(");
            fieldSql.append(")");
            return fieldSql.toString();
        }
    
        private String prepareValuesSql(TableInfo tableInfo) {
            final StringBuilder valueSql = new StringBuilder();
            valueSql.append("<foreach collection=\"list\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
            valueSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},");
            tableInfo.getFieldList().forEach(x -> valueSql.append("#{item.").append(x.getProperty()).append("},"));
            valueSql.delete(valueSql.length() - 1, valueSql.length());
            valueSql.append("</foreach>");
            return valueSql.toString();
        }
    }
    
    
    import com.baomidou.mybatisplus.core.injector.AbstractMethod;
    import com.baomidou.mybatisplus.core.metadata.TableInfo;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.mapping.SqlSource;
    
    /**
     * 批量更新方法实现,条件为主键,选择性更新
     */
    @Slf4j
    public class UpdateBatchMethod extends AbstractMethod {
        @Override
        public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
            String sql = "<script>\n<foreach collection=\"list\" item=\"item\" separator=\";\">\nupdate %s %s where %s=#{%s} %s\n</foreach>\n</script>";
            String additional = tableInfo.isWithVersion() ? tableInfo.getVersionFieldInfo().getVersionOli("item", "item.") : "" + tableInfo.getLogicDeleteSql(true, true);
            String setSql = sqlSet(tableInfo.isWithLogicDelete(), false, tableInfo, false, "item", "item.");
            String sqlResult = String.format(sql, tableInfo.getTableName(), setSql, tableInfo.getKeyColumn(), "item." + tableInfo.getKeyProperty(), additional);
            //log.debug("sqlResult----->{}", sqlResult);
            SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
            // 第三个参数必须和RootMapper的自定义方法名一致
            return this.addUpdateMappedStatement(mapperClass, modelClass, "updateBatch", sqlSource);
        }
    
    }
    
    

    2.添加自定义方法SQL注入器

    import com.baomidou.mybatisplus.core.injector.AbstractMethod;
    import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
    
    import java.util.List;
    
    public class CustomizedSqlInjector extends DefaultSqlInjector {
        /**
         * 如果只需增加方法,保留mybatis plus自带方法,
         * 可以先获取super.getMethodList(),再添加add
         */
        @Override
        public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
            List<AbstractMethod> methodList = super.getMethodList(mapperClass);
            methodList.add(new InsertBatchMethod());
            methodList.add(new UpdateBatchMethod());
            return methodList;
        }
    }
    
    
    

    3.注入配置

    @MapperScan("com.xxx.mapper")
    @Configuration
    public class MyBatisPlusConfig {
        @Bean
        public CustomizedSqlInjector customizedSqlInjector() {
            return new CustomizedSqlInjector();
        }
    }
    
    

    4.添加通用mapper

    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import org.apache.ibatis.annotations.Param;
    
    import java.util.List;
    
    /**
     * 根Mapper,给表Mapper继承用的,可以自定义通用方法
     * {@link com.baomidou.mybatisplus.core.mapper.BaseMapper}
     * {@link com.baomidou.mybatisplus.extension.service.IService}
     * {@link com.baomidou.mybatisplus.extension.service.impl.ServiceImpl}
     */
    public interface RootMapper<T> extends BaseMapper<T> {
    
        /**
         * 自定义批量插入
         * 如果要自动填充,@Param(xx) xx参数名必须是 list/collection/array 3个的其中之一
         */
        int insertBatch(@Param("list") List<T> list);
    
        /**
         * 自定义批量更新,条件为主键
         * 如果要自动填充,@Param(xx) xx参数名必须是 list/collection/array 3个的其中之一
         */
        int updateBatch(@Param("list") List<T> list);
    }
    
    

    5.如何使用

    
    @Repository
    public interface UserInfoMapper extends RootMapper<UserInfo> {
    }
    
    
    
    public interface UserInfoService extends IService<UserInfo> {
    
        int saveAll();
    
        int updateAll();
    }
    
    
    
    @Service
    public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService{
    
        @Override
        public int saveAll() {
            List<UserInfo> list = new ArrayList<>();
            for (int i = 0; i < 20; i++) {
                UserInfo userInfo = new UserInfo();
                userInfo.setUserName("厉害" + i);
                userInfo.setSalt(RandomStringUtils.randomAlphabetic(6));
                userInfo.setPassword(SecureUtil.sha256("123456" + userInfo.getSalt()));
                userInfo.setSex(0);
                userInfo.setAvatar(LoginServiceImpl.AVATAR);
                list.add(userInfo);
            }
            return baseMapper.insertBatch(list);
        }
    
        @Override
        public int updateAll() {
            List<UserInfo> userInfos = baseMapper.selectList(Wrappers.<UserInfo>lambdaQuery().between(BaseEntity::getId, 43, 62));
            userInfos.forEach(userInfo -> {
                userInfo.setUserName("更新了" + IdUtil.simpleUUID());
            });
            return baseMapper.updateBatch(userInfos);
        }
    }
    
    
    

    相关文章

      网友评论

        本文标题:mybatis-plus真正批量新增和更新

        本文链接:https://www.haomeiwen.com/subject/fgiziktx.html