歡迎您光臨本站 註冊首頁

spring中使用mybatis實現批量插入的示例代碼

←手機掃碼閱讀     hongdian2012 @ 2020-06-04 , reply:0

有3種實現方式:foreach,spring事務,以及ExecutorType.BATCH.

1. foreach方式

這種方式實際是對SQL語句進行拼接,生成一個長長的SQL,對很多變量進行綁定。如果數據量不大(1000個以內),可以用這種方式。如果數據量太大,可能數據庫會報錯。

定義接口

 public interface StudentMapper05 { public void insertStudent(ListstudentList); }


定義mapper

適用於Oracle數據庫

 BEGININSERT 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(ListstudentList) { 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) { ListstudentList = 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(Liststudents) { 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


[hongdian2012 ] spring中使用mybatis實現批量插入的示例代碼已經有244次圍觀

http://coctec.com/docs/java/show-post-236972.html