批量新增

表结构

CREATE TABLE `customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(250) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

实体类

public class Customer implements Serializable {

	private static final long serialVersionUID = -1545195873576249731L;

	private Integer id;
	
	private String name;
	
	private Integer age;
	
	// get、set 和 toString 方法省略
}

DAO层

public interface CustomerDao {

	int insertBatch(@Param("customers") Collection<? extends Serializable> customers);
}

XML

<insert id="insertBatch" parameterType="java.util.Collection">
     	<selectKey resultType ="java.lang.Integer" keyProperty= "id" order= "AFTER">
			SELECT LAST_INSERT_ID()
		</selectKey >
     	INSERT INTO customer
     		(name,age)
     	VALUES
     	<foreach collection="customers" item="customer" separator=",">
     		(#{customer.name},#{customer.age})
     	</foreach>
</insert>

foreach中的属性

  • collection

该属性是必须指定的,有以下几种情况

  1. 如果传入的是单参数且使用@Param注解的时候,collection属性值为@Param里的值,例如这里是 customers
  2. 如果传入的是单参数且参数类型是一个List且不使用@Param注解的时候,collection属性值为list
  3. 如果传入的是单参数且参数类型是一个array数组且不使用@Param注解的时候,collection属性值为array
  4. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map,这个时候collection属性值就是传入的List或array对象在自己封装的map 里面的key
  • item

该属性表示集合中每一个元素进行迭代时的别名

  • separator

表示在每次进行迭代之间以什么符号作为分隔符

  • index

该属性指定一个名字,用于表示在迭代过程中,每次迭代到的位置,在list和数组中,index是元素的下标,在map中,index是元素的key

  • open

表示该语句以什么开始

  • close

表示以什么结束

自增主键的获取

原来的自增主键获取是这样的

<insert id="insertBatch" parameterType="java.util.Collection" keyProperty="id" useGeneratedKeys="true">
     	INSERT INTO customer
     		(name,age)
     	VALUES
     	<foreach collection="customers" item="customer" separator=",">
     		(#{customer.name},#{customer.age})
     	</foreach>
</insert>

当使用进行批量操作时,这种写法会报错:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [customers, param1]

需使用以下方式获取自增主键:

<insert id="insertBatch" parameterType="java.util.Collection">
     	<selectKey resultType ="java.lang.Integer" keyProperty= "id" order= "AFTER">
			SELECT LAST_INSERT_ID()
		</selectKey >
     	INSERT INTO customer
     		(name,age)
     	VALUES
     	<foreach collection="customers" item="customer" separator=",">
     		(#{customer.name},#{customer.age})
     	</foreach>
</insert>

测试

	@Autowired
	private CustomerDao customerDao;
	
	@Test
	public void insertBatchTest() {
		List<Customer> list = new ArrayList<>();
		for(int i = 0;i < 10;i++) {
			Customer customer = new Customer();
			customer.setName("张三");
			customer.setAge(i);
			list.add(customer);
		}
		int insertBatch = customerDao.insertBatch(list);
		System.out.println(insertBatch);
	}

控制台打印:10

数据库:

image

原文链接:https://miansen.wang/2019/02/28/1/