通过Mybatis执行拼接的SQL批量插入数据并返回数据库自增ID
Posted Neo Yang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过Mybatis执行拼接的SQL批量插入数据并返回数据库自增ID相关的知识,希望对你有一定的参考价值。
背景
开发项目引入元数据管理,表和字段都允许用户自己定义。操作数据库的SQL就不能在mybatis 的xml文件里面写具体的表名和子段名。
解决这个问题有两种思路,一种是用PreparedStatement组装SQL语句通过JDBC连接执行;另一种是将表名,字段名称作为参数传递到mybatis执行。
这里描述第二种方案中比较复杂的批量插入数据怎么实现。
首先在mysql中创建一个简单的t_user表。其DDL如下所示:
CREATE TABLE `t_user` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT '',
`age` int DEFAULT '20',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8mb3 COMMENT='用户表'
定义DAO层接口
1. 访问数据库的mapper接口
package com.elon.mapper;
import com.elon.model.InsertValueModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 动态数据查询接口
*
* @author elon
* @since 2022-02-19
*/
@Mapper
public interface DataMapper
/**
* 批量插入数据
*
* @param fieldNameList 数据库字段名称列表
* @param tableName 数据库表名
* @param bulkDataList 数据库多行数据
* @author elon
*/
void batchInsertData(@Param("fieldNameList") List<String> fieldNameList,
@Param("tableName") String tableName,
@Param("list") List<InsertValueModel> bulkDataList);
注意:bulkDataList参数注解固定写为:@Param(“list”) 。
2. 定义插入数据的模型
InsertValueModel模型每个实例代表数据库的一行记录。为了接收回填的自增ID,增加一个id成员。
package com.elon.model;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 单条插入数据库的数据
*
* @author elon
* @since 2022-02-19
*/
@Getter
@Setter
public class InsertValueModel
/**
* 用于接收回填的自增ID
*/
private int id = -1;
/**
* 数据列表
*/
private List<Object> dataList = new ArrayList<>();
public static InsertValueModel create(Object... values)
InsertValueModel valueModel = new InsertValueModel();
valueModel.dataList = Arrays.asList(values);
return valueModel;
增加Mybatis的XML文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.elon.mapper.DataMapper">
<!--批量插入数据-->
<insert id="batchInsertData" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO $tableName
<foreach item = "field" collection="fieldNameList" open="(" separator="," close=")">
$field
</foreach>
VALUES
<foreach item="record" collection="list" separator=",">
<foreach item="data" collection="record.dataList" open="(" separator="," close=")">
#data
</foreach>
</foreach>
</insert>
</mapper>
这里要注意两点:
1. 配置用于回填自增ID属性: keyProperty="id"。
2. 用于拼接insert语句的数据集合指定为list: collection="list"。
测试接口,打印回填的自增ID
1. 测试接口代码
@RestController
@RequestMapping("/v1/user")
@Api(tags = "测试接口")
public class UserController
private static Logger LOGGER = LoggerFactory.getLogger(UserController.class);
@Resource
private DataMapper dataMapper;
@PostMapping("bulk-insert-user-data")
@ApiOperation(value = "批量插入用户数据")
public List<Integer> bulkInsertUserData()
// 初始化拼接SQL用的表名和字段名
List<String> fieldNameList = Arrays.asList("name", "age");
String tableName = "t_user";
// 初始化批量数据
List<InsertValueModel> bulkDataList = new ArrayList<>();
bulkDataList.add(InsertValueModel.create("张三", 12));
bulkDataList.add(InsertValueModel.create("李四", 15));
bulkDataList.add(InsertValueModel.create("王五", 19));
dataMapper.batchInsertData(fieldNameList, tableName, bulkDataList);
List<Integer> ids = bulkDataList.stream().map(InsertValueModel::getId).collect(Collectors.toList());
LOGGER.info("打印自增ID:", ids);
return ids;
2. 用swagger调用一下上面的测试接口,可以看到打印的结果
2022-02-19 16:13:57,932 INFO c.z.h.HikariDataSource [http-nio-10001-exec-5] HikariPool-1 - Start completed.
2022-02-19 16:13:58,363 INFO c.e.r.UserController [http-nio-10001-exec-5] 打印自增ID:[25, 26, 27]
测试代码github路径: https://github.com/ylforever/elon-mybatisxml.git
以上是关于通过Mybatis执行拼接的SQL批量插入数据并返回数据库自增ID的主要内容,如果未能解决你的问题,请参考以下文章
通过Mybatis执行拼接的SQL批量插入数据并返回数据库自增ID