spring中使用mybatis实现批量插入的示例代码

网友投稿 289 2022-12-05


spring中使用mybatis实现批量插入的示例代码

有3种实现方式:foreach,spring事务,以及ExecutorType.BATCH.

1. foreach方式

这种方式实际是对SQL语句进行拼接,生成一个长长的SQL,对很多变量进行绑定。如果数据量不大(1000个以内),可以用这种方式。如果数据量太大,可能数据库会报错。

定义接口

public interface StudentMapper05 {

public void insertStudent(List studentList);

}

定义mapper

适用于Oracle数据库

BEGIN

INSERT INTO test_student(ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL)

VALUES

(SEQ_ID.nextval, #{student.name}, #{student.branch}, #{student.percentage}, #{student.phone}, #{student.email});

END;

这个mapper的含义,就是把上送的studentList拼接成一个长SQL,拼成的SQL类似:

BEGIN

INSERT INTO test_student(ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL) VALUES (SEQ_ID.nextval, ?, ?, ?, ?, ?);

INSERT INTO test_student(ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL) VALUES (SEQ_ID.nextval, ?, ?, ?, ?, ?);

INSERT INTO test_student(ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL) VALUES (SEQ_ID.nextval, ?, ?, ?, ?, ?);

...

END;

studentList有几个,就会生成多少个insert语句拼接到一起,每个?都会进行变量绑定,所以当studentList中数据量较多时,生成的SQL会很长,导致数据库执行报错。

dao

public class StudentDao05 {

private StudentMapper05 studentMapper; // 省略getter和setter

public void insertStudentList(List studentList) {

studentMapper.insertStudent(studentList);

}

}

beans

mybatis-spring-05.xml:

main函数

public static void main(String[] args) {

String[] configFiles = new String[]{"spring-beans-config.xml", "mybatis/mybatis-spring-05.xml"}; // 分别配置datasource和mybatis相关bean

ApplicationContext context = new ClassPathXmlApplicationContext(configFiles);

StudentDao05 studentDao = (StudentDao05)context.getBean("studentDao05");

int counts[] = new int[]{10, 50, 100, 200, 500, 1000, 2000, 3000, 5000, 8000};

for (int count : counts) {

List studentList = new ArrayList<>();

for (int i = 0; i < count; i++) {

Student st = new Student();

st.setName("name");

st.setBranch("");

st.setEmail("");

st.setPercentage(0);

st.setPhone(0);

studentList.add(st);

}

long startTime = System.currentTimeMillis();

studentDao.insertStudentList(studentList);

long endTime = System.currentTimeMillis();

System.out.println("插入" + count + "笔数据耗时: " + (endTime - startTime) +" ms");

}

}

测试结果

插入100笔数据耗时: 197 ms

插入200笔数据耗时: 232 ms

插入500笔数据耗时: 421 ms

插入1000笔数据耗时: 650 ms

插入2000笔数据耗时: 1140 ms

插入3000笔数据耗时: 27113 ms

插入5000笔数据耗时: 98213 ms

插入8000笔数据耗时: 301101 ms

2. 借助spring事务

借助spring事务,插入一组数据

开启spring事务

定义接口

public interface StudentMapper06 {

public void insertStudent(@Param("student") Student student);

}

mapper

INSERT INTO test_student(ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL)

VALUES

(SEQ_ID.nextval, #{student.name}, #{student.branch}, #{student.percentage}, #{student.phone}, #{student.email})

dao

public class StudentDao06 {

private StudentMapper06 studentMapper; // 省略getter和setter

@Transactional // spring事务控制

public void insertStudentList(List students) {

for (Student student : students) {

studentMapper.insertStudent(student);

}

}

}

beans

main

测试结果

batchInsert001插入10笔数据耗时: 602 ms

batchInsert001插入50笔数据耗时: 196 ms

batchInsert001插入100笔数据耗时: 284 ms

batchInsert001插入200笔数据耗时: 438 ms

batchInsert001插入500笔数据耗时: 944 ms

batchInsert001插入1000笔数据耗时: 1689 ms

batchInsert001插入2000笔数据耗时: 3138 ms

batchInsert001插入3000笔数据耗时: 4427 ms

batchInsert001插入5000笔数据耗时: 7368 ms

batchInsert001插入8000笔数据耗时: 11832 ms

3. 使用ExecutorType.BATCH

基本原理是SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);,设置BATCH方式的sqlSession

有三种设置方式:

3.1 在mybatis的config文件中设置

SqlSessionFactoryBean中可以配置配置文件:

这个mybatis配置文件中,设置BATCH方式:

这样,默认打开的sqlSession就都是BATCH方式的。再与spring的事务结合(参看上一节中的spring事务设置),就可以实现批量插入。

测试结果:

batchInsert001插入10笔数据耗时: 565 ms

batchInsert001插入50笔数据耗时: 117 ms

batchInsert001插入100笔数据耗时: 98 ms

batchInsert001插入200笔数据耗时: 106 ms

batchInsert001插入500笔数据耗时: 145 ms

batchInsert001插入1000笔数据耗时: 132 ms

batchInsert001插入2000笔数据耗时: 154 ms

batchInsert001插入3000笔数据耗时: 163 ms

batchInsert001插入5000笔数据耗时: 200 ms

batchInsert001插入8000笔数据耗时: 250 ms

3.2 自己创建sqlSession,手工commit

SqlSessionFactory sqlSessionFactory = (SqlSessionFactory)context.getBean("sqlSessionFactory");

SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);

StudentMapper06 studentMapper = sqlSession.getMapper(StudentMapper06.class);

for (int i = 0; i < count; i++) {

Student st = new Student();

st.setName("name");

...

studentMapper.insertStudent(st);

}

sqlSession.commit();

sqlSession.clearCache();

sqlSession.close();

测试结果:

batchInsert002插入10笔数据耗时: 568 ms

batchInsert002插入50笔数据耗时: 157 ms

batchInsert002插入100笔数据耗时: 132 ms

batchInsert002插入200笔数据耗时: 135 ms

batchInsert002插入500笔数据耗时: 148 ms

batchInsert002插入1000笔数据耗时: 139 ms

batchInsert002插入2000笔数据耗时: 151 ms

batchInsert002插入3000笔数据耗时: 139 ms

batchInsert002插入5000笔数据耗时: 207 ms

batchInsert002插入8000笔数据耗时: 299 ms

3.3 使用sqlSessionTemplate在XML文件中创建bean

创建一个SqlSessionTemplate,然后注入到MapperFactoryBean中,生成对应的mapper:

与spring的事务结合后(参看上一节中的spring事务设置),就可以实现批量插入

测试结果

batchInsert003插入10笔数据耗时: 651 ms

batchInsert003插入50笔数据耗时: 133 ms

batchInsert003插入100笔数据耗时: 124 ms

batchInsert003插入200笔数据耗时: 129 ms

batchInsert003插入500笔数据耗时: 144 ms

batchInsert003插入1000笔数据耗时: 179 ms

batchInsert003插入2000笔数据耗时: 229 ms

batchInsert003插入3000笔数据耗时: 241 ms

batchInsert003插入5000笔数据耗时: 216 ms

batchInsert003插入8000笔数据耗时: 259 ms


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java并发统计变量值偏差原因及解决方案
下一篇:springboot中@Async默认线程池导致OOM问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~