mybatis 批量插入

发布时间 2023-10-07 18:06:42作者: Marydon

1.情景展示

在实际开发过程中,我们有时候会遇到前端批量提交的数据。

诚然,如果我们使用for循环一次一次插入,也是可以的。

但这会涉及到对数据库频繁操作的问题,有没有更好的办法呢?

2.具体分析

我们可以通过mybatis的批量插入功能来解决这个问题。

只需要操作一次数据库,就能完成多条数据的插入操作。

3.解决方案

XML

<!--批量插入-->
<insert id="addFlinkDataFieldBatch" parameterType="java.util.List">
    insert into flink_data_field
        (pipelineid, DATABASEID_SOURCE, TABLENAME_SOURCE, FIELDNAME_SOURCE, status, createtime, TABLESTATUS_TARGET)
    values
    <foreach collection="fieldList" separator="," item="row">
        (#{row.pipelineid},#{row.databaseidSource},#{row.tablenameSource},#{row.fieldnameSource}, #{row.status} ,now(), #{row.tablestatusTarget})
    </foreach>
</insert>

说明:

这里是mysql数据库,表主键使用的是自增属性,所以插入的时候,可以不用管主键列。

映射层(dao层、mapper层)

Boolean addFlinkDataFieldBatch(List<FlinkDataField> fieldList);

说明:

插入成功,返回:true;插入失败,返回:false。

方法入参的参数名称:fileldList,与foreach标签的collection的属性值相对应。

如果不对应的话,也可以,只不过,需要我们使用注解@Param。

Boolean addFlinkDataFieldBatch(@Param("fieldList") List<FlinkDataField> list);

说明:

当方法入参的参数名称与foreach标签的collection的属性值不一致时,我们有两种解决办法。

第1种:修改方法入参的参数名称,使其与foreach标签的collection的属性值保持一致。

第2种:在方法入参的变量类型前面增加@Param注解,使该注解的值与foreach标签的collection的属性值保持一致。

业务层(Bo层)

/**
 * 插入管道信息及字段映射信息
 * @param pipelineFieldVo
 * @return
 */
@Override
public Boolean addPipelineAndField(PipelineFieldVo pipelineFieldVo) {
    // 获取管道信息
    FlinkDataPipeline pipeline = pipelineFieldVo.getPipeline();
    if (null == pipeline) {
        // 抛出运行时异常,触发提交事务进行回滚
        throw new RuntimeException("管道信息不能为空");
    }
    // 插入flink_data_pipeline表
    Boolean isSuccess = pipelineMapper.addFlinkDataPipeline(pipeline);

    // 获取插入的管道主键
    Long pipelineid = pipeline.getPipelineid();
    if (!isSuccess || pipelineid == null) {// 插入失败
        throw new RuntimeException("管道信息保存失败");
    }

    // 获取表信息
    List<TableVo> tables = pipelineFieldVo.getTables();
    if (null == tables || tables.isEmpty()) {
        throw new IllegalArgumentException("保存失败:字段映射不能为空");
    }

    List<FlinkDataField> fieldList = new ArrayList<>();
    // 遍历取出每个table里面包含的字段映射信息
    tables.forEach(tableVo -> {
        ColumnVo columnVo = tableVo.getTable();
        if (null == columnVo) {
            throw new IllegalArgumentException("保存失败:字段映射不能为空");
        }

        List<FlinkDataFieldVo> columns = columnVo.getColumns();
        if (null == columns || columns.isEmpty()) {
            throw new IllegalArgumentException("保存失败:字段映射不能为空");
        }

        columns.forEach(flinkDataFieldVo -> {
            FlinkDataField flinkDataField = FlinkDataField.builder().build();
            flinkDataField.setPipelineid(pipelineid)// 管道主键
                .setDatabaseidSource(columnVo.getDatabaseidSource())
                .setDatabaseidTarget(columnVo.getDatabaseidTarget())
                .setTablenameSource(columnVo.getTablenameSource())
                .setTablenameTarget(columnVo.getTablenameTarget())
                .setTablestatusTarget(columnVo.getTablestatusTarget())
                ;

            flinkDataField.setFieldnameSource(flinkDataFieldVo.getFieldnameSource())
                .setFieldtypeSource(flinkDataFieldVo.getFieldtypeSource())
                .setFieldisnullSource(flinkDataFieldVo.getFieldisnullSource())
                .setFieldiskeySource(flinkDataFieldVo.getFieldiskeySource())
                .setFieldnameTarget(flinkDataFieldVo.getFieldnameTarget())
                .setFieldtypeTarget(flinkDataFieldVo.getFieldtypeTarget())
                .setFieldisnullTarget(flinkDataFieldVo.getFieldisnullTarget())
                .setFieldiskeyTarget(flinkDataFieldVo.getFieldiskeyTarget())
                .setStatus(flinkDataFieldVo.getStatus())
                ;

            // 将表的字段映射关系放到List当中
            fieldList.add(flinkDataField);
        });
    });

    return flinkDataFieldMapper.addFlinkDataFieldBatch(fieldList);
}

控制层(Controller层) 

@ApiOperation(value = "添加管道信息", notes = "添加管道信息", httpMethod = "POST")
@PostMapping(value = "/add", produces = {"application/json;charset=UTF-8"})
public Boolean addPipelineAndField(@RequestBody @Valid PipelineFieldVo pipelineFieldVo){
    return pipelineService.addPipelineAndField(pipelineFieldVo);
}

 

写在最后

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

 相关推荐: