Oracle数据库批量插入
对于Oracle数据库,批量插入的写法如下。
首先,先对要批量插入的对象设置ID的值,一般是通过序列获取。这样我们自然也就拿到了插入后的主键id。
1 2
| @Select(" SELECT SEQ_TEST.NEXTVAL AS ID FROM DUAL") long getSeqID();
|
然后在XML文件中写 insert 语句。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <insert id="batchInsert" parameterType="com.lzumetal.database.employee"> INSERT INTO EMPLOYEE ( ID, NAME, PHONE, EMAIL, GENDER ) <foreach collection="list" item="item" separator="UNION ALL"> (SELECT #{item.id, jdbcType=BIGINT}, #{item.name, jdbcType=VARCHAR}, #{item.phone, jdbcType=VARCHAR}, #{item.email, jdbcType=VARCHAR}, #{item.gender, jdbcType=INTEGER} FROM DUAL ) </foreach> </insert>
|
MySQL数据库批量插入
MySQL数据库的批量插入写法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <insert id="batchInsert" parameterType="java.util.List"> INSERT INTO EMPLOYEE ( ID, NAME, PHONE, EMAIL, GENDER ) VALUES <foreach collection="list" item="item" separator=","> ( #{item.id, jdbcType=BIGINT}, #{item.name, jdbcType=VARCHAR}, #{item.phone, jdbcType=VARCHAR}, #{item.email, jdbcType=VARCHAR}, #{item.gender, jdbcType=INTEGER} ) </foreach> </insert>
|
Mapper.java文件中代码是这样写的:
1 2 3 4 5
| @Mapper public interface EmployeeMapper { void batchInsert(@Param("list") List<Employee> list); }
|
注意,对于Oracle数据库,批量插入或者查询都可能导致参数变量过多而报错。查看oracle11 的官方文档,明确说明变量的数量不能超过64k(64k=64*1024B=65536B)。16位的2进制最大的数字,即1111111111111111,换算成10进制就是65536,那么我们计算可以插入的条数 n=65536/变量数。
因此需要在Serivce层中对传参数量做下限制,比如批量插入可以写成这样,一次最多只插入200条记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import com.google.common.collect.Lists;
public void batchAdd1(List<Book> books) { int toIndex; int capacity = 200; List<Book> tempHolder; for (int i = 0; i <= books.size() / capacity; i++) { toIndex = (i + 1) * capacity; tempHolder = books.subList(i * capacity, Math.min(toIndex, books.size())); bookMapper.batchInsert(tempHolder); } }
public void batchAdd2(List<Book> books) { List<List<Book>> partition = Lists.partition(books, 200); for (List<Book> partionBooks:partition) { bookMapper.batchInsert(partionBooks); } }
|