Mybatis批量插入的三種實現(xiàn)方法
在日常開發(fā)中,如果要操作數(shù)據(jù)庫的話,或多或少都會遇到批量數(shù)據(jù)的處理,我們公司使用的mybaits-plus作為持久層的框架,今天就簡單介紹一下mybaits批量操作數(shù)據(jù)庫的幾種方式。
1.循環(huán)插入
其實這種方式并不是批量插入,只是在日常開發(fā)中,使用這種方式的還是比較多的。
@RunWith(SpringRunner.class) @SpringBootTest public class BatchTest { @Resource private StudentMapper studentMapper; @Test public void test(){ List<Student> students = generateStudentData(100); long start = System.currentTimeMillis(); students.forEach(studentMapper::insert); System.out.println("循環(huán)插入: " + students.size() + " 條數(shù)據(jù),共計耗時:" + (System.currentTimeMillis() - start) + " 毫秒"); } public static List<Student> generateStudentData(int size){ List<Student> list = new ArrayList<>(size); Random random = new Random(); for (int i = 0; i < size; i++) { Student student = new Student(); student.setName("zhangsan-" + i); student.setAge(random.nextInt(40)); student.setPhone("15077828899"); student.setBirthday(LocalDateTime.now()); list.add(student); } return list; } }
2.foreach方式插入
@RunWith(SpringRunner.class) @SpringBootTest public class BatchTest { @Resource private StudentMapper studentMapper; @Test public void test3(){ List<Student> students = generateStudentData(100); long foreachStart = System.currentTimeMillis(); studentMapper.insertBatch(students); System.out.println("foreach插入: " + students.size() + " 條數(shù)據(jù),共計耗時:" + (System.currentTimeMillis() - foreachStart) + " 毫秒"); } public static List<Student> generateStudentData(int size){ List<Student> list = new ArrayList<>(size); Random random = new Random(); for (int i = 0; i < size; i++) { Student student = new Student(); student.setName("zhangsan-" + i); student.setAge(random.nextInt(40)); student.setPhone("15077828899"); student.setBirthday(LocalDateTime.now()); list.add(student); } return list; } }
StudentMapper 接口如下:
public interface StudentMapper extends BaseMapper<Student> { /** * 批量插入 */ int insertBatch(@Param("entities") List<Student> entities); /** * 批量更新或者插入 */ int insertOrUpdateBatch(@Param("entities") List<Student> entities); }
StudentMapper.xml內(nèi)容如下:
<?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.efreight.oss.transfer.dao.StudentMapper"> <resultMap type="com.efreight.oss.transfer.entity.Student" id="StudentMap"> <result property="id" column="id" jdbcType="INTEGER"/> <result property="name" column="name" jdbcType="VARCHAR"/> <result property="age" column="age" jdbcType="INTEGER"/> <result property="birthday" column="birthday" jdbcType="TIMESTAMP"/> <result property="phone" column="phone" jdbcType="VARCHAR"/> </resultMap> <!-- 批量插入 --> <insert id="insertBatch" keyProperty="id" useGeneratedKeys="true"> insert into cargo.student(name, age, birthday, phone) values <foreach collection="entities" item="entity" separator=","> (#{entity.name}, #{entity.age}, #{entity.birthday}, #{entity.phone}) </foreach> </insert> <!-- 批量插入或按主鍵更新 --> <insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true"> insert into cargo.student(name, age, birthday, phone) values <foreach collection="entities" item="entity" separator=","> (#{entity.name}, #{entity.age}, #{entity.birthday}, #{entity.phone}) </foreach> on duplicate key update name = values(name) , age = values(age) , birthday = values(birthday) , phone = values(phone) </insert> </mapper>
搭配 useGeneratedKeys="true" 和 keyProperty="id" 屬性(這個id是javaBean的屬性),可以獲取自增主鍵,有時候這個主鍵我們是非常需要的。
3.批處理方式插入
通過 ExecutorType.BATCH來構(gòu)建一個可以完成批處理工作的執(zhí)行器
@RunWith(SpringRunner.class) @SpringBootTest public class BatchTest { @Resource private StudentMapper studentMapper; @Resource private SqlSessionTemplate sqlSessionTemplate; @Test public void test2(){ List<Student> students = generateStudentData(100); long batchStart = System.currentTimeMillis(); try(SqlSession sqlSession = this.sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false)) { StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); for (int i = 0; i < students.size(); i++) { studentMapper.insert(students.get(i)); if (i % 1000 == 0 || i == students.size() - 1) { sqlSession.flushStatements(); } } sqlSession.commit(); } System.out.println("mybatis批處理插入: " + students.size() + " 條數(shù)據(jù),共計耗時:" + (System.currentTimeMillis() - batchStart) + " 毫秒"); } public static List<Student> generateStudentData(int size){ List<Student> list = new ArrayList<>(size); Random random = new Random(); for (int i = 0; i < size; i++) { Student student = new Student(); student.setName("zhangsan-" + i); student.setAge(random.nextInt(40)); student.setPhone("15077828899"); student.setBirthday(LocalDateTime.now()); list.add(student); } return list; } }
注意:批處理方式是無法獲取自增主鍵的。
順便說一下,現(xiàn)在使用mybatis-plus的也非常多,他也提供了批量插入的功能,它內(nèi)部使用的就是ExecutorType.BATCH 來構(gòu)建的。
關(guān)于三者性能的比較大家可以跑下看看,循環(huán)插入的方式性能最差,能不用就盡量不用,在foreach和批處理中,我測試發(fā)現(xiàn)foreach的性能最好(我用的MySQL是5.7),所以項目中我們批處理使用的都是foreach, 因為一般我們一般批量插入最多也就2000條左右的數(shù)據(jù),但是大家可以根據(jù)自己機器的實際情況,去跑一下看看。
插入方式 | 100條 | 1000條 | 10000條 | 10萬條 |
---|---|---|---|---|
循環(huán)插入 | 1599 毫秒 | 14336 毫秒 | 140793 毫秒 | * |
foreach | 62 毫秒 | 364 毫秒 | 3249 毫秒 | 23940 毫秒 |
批處理 | 321 毫秒 | 6868 毫秒 | 72851 毫秒 | 457005 毫秒 |
到此這篇關(guān)于Mybatis批量插入的三種實現(xiàn)方法的文章就介紹到這了,更多相關(guān)Mybatis批量插入 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mybatis中批量插入的兩種方式(高效插入)
- MyBatis批量插入(insert)數(shù)據(jù)操作
- Mybatis三種批量插入數(shù)據(jù)的方式
- MyBatis-Plus 批量插入數(shù)據(jù)的操作方法
- MyBatis批量插入大量數(shù)據(jù)(1w以上)
- MyBatis批量插入數(shù)據(jù)的三種方法實例
- 給你的MyBatis-Plus裝上批量插入的翅膀(推薦)
- MyBatis批量插入數(shù)據(jù)到Oracle數(shù)據(jù)庫中的兩種方式(實例代碼)
- Mybatis-plus 批量插入太慢的問題解決(提升插入性能)
- mybatis插入與批量插入返回ID的原理詳解
相關(guān)文章
Java基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換詳解
這篇文章主要講解Java中基本數(shù)據(jù)類型的轉(zhuǎn)換,數(shù)據(jù)之間相互轉(zhuǎn)換是經(jīng)常會用到的基礎(chǔ)操作,文中講的很清晰,希望能給大家做一個參考。2022-05-05springboot關(guān)閉druid監(jiān)控 druid2改配置文件無效的解決
這篇文章主要介紹了springboot關(guān)閉druid監(jiān)控 druid2改配置文件無效的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05Java 利用枚舉實現(xiàn)接口進(jìn)行統(tǒng)一管理
這篇文章主要介紹了Java 利用枚舉實現(xiàn)接口進(jìn)行統(tǒng)一管理,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02深入探究TimSort對歸并排序算法的優(yōu)化及Java實現(xiàn)
這篇文章主要介紹了TimSort歸并排序的優(yōu)化及Java實現(xiàn),TimSort 是一個歸并排序做了大量優(yōu)化的版本,需要的朋友可以參考下2016-05-05idea項目打開后出現(xiàn)橙色的時鐘圖標(biāo)的解決
本文主要介紹了idea項目打開后出現(xiàn)橙色的時鐘圖標(biāo)的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06