1. 循環(huán)插入
mapper.xml:
<?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.buhe.demo.mapper.StudentMapper">
<insert id="insert" parameterType="Student">
INSERT INTO tb_student (name, age, phone, address, class_id) VALUES (#{name},#{age},#{phone},#{address},#{classId})
</insert>
</mapper>
mapper接口:
public interface StudentMapper {
int insert(Student student);
}
測試代碼:
@SpringBootTest
class DemoApplicationTests {
@Resource
private StudentMapper studentMapper;
@Test
public void testInsert(){
//數(shù)據(jù)生成
List<Student> studentList = createData(100);
//循環(huán)插入
long start = System.currentTimeMillis();
studentList.stream().forEach(student -> studentMapper.insert(student));
System.out.println(System.currentTimeMillis() - start);
}
private List<Student> createData(int size){
List<Student> studentList = new ArrayList<>();
Student student;
for(int i = 0; i < size; i++){
student = new Student();
student.setName("小王" + i);
student.setAge(18);
student.setClassId(1);
student.setPhone("1585xxxx669");
student.setAddress("未知");
studentList.add(student);
}
return studentList;
}
}
2. foreach標簽
mapper.xml:
<?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.buhe.demo.mapper.StudentMapper">
<insert id="insert" parameterType="Student">
INSERT INTO tb_student (name, age, phone, address, class_id) VALUES (#{name},#{age},#{phone},#{address},#{classId})
</insert>
<insert id="insertBatch">
INSERT INTO tb_student (name, age, phone, address, class_id) VALUES
<foreach collection="list" separator="," item="item">
(#{item.name},#{item.age},#{item.phone},#{item.address},#{item.classId})
</foreach>
</insert>
</mapper>
mapper接口:
public interface StudentMapper {
int insert(Student student);
int insertBatch(List<Student> studentList);
}
測試代碼:
@SpringBootTest
class DemoApplicationTests {
@Resource
private StudentMapper studentMapper;
@Test
public void testInsertByForeachTag(){
//數(shù)據(jù)生成
List<Student> studentList = createData(100);
//使用foreach標簽,拼接SQL插入
long start = System.currentTimeMillis();
studentMapper.insertBatch(studentList);
System.out.println(System.currentTimeMillis() - start);
}
private List<Student> createData(int size){
List<Student> studentList = new ArrayList<>();
Student student;
for(int i = 0; i < size; i++){
student = new Student();
student.setName("小王" + i);
student.setAge(18);
student.setClassId(1);
student.setPhone("1585xxxx669");
student.setAddress("未知");
studentList.add(student);
}
return studentList;
}
}
3. 批處理
測試代碼:
@SpringBootTest
class DemoApplicationTests {
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Test
public void testInsertBatch(){
//數(shù)據(jù)生成
List<Student> studentList = createData(100);
//使用批處理
long start = System.currentTimeMillis();
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
StudentMapper studentMapperNew = sqlSession.getMapper(StudentMapper.class);
studentList.stream().forEach(student -> studentMapperNew.insert(student));
sqlSession.commit();
sqlSession.clearCache();
System.out.println(System.currentTimeMillis() - start);
}
private List<Student> createData(int size){
List<Student> studentList = new ArrayList<>();
Student student;
for(int i = 0; i < size; i++){
student = new Student();
student.setName("小王" + i);
student.setAge(18);
student.setClassId(1);
student.setPhone("1585xxxx669");
student.setAddress("未知");
studentList.add(student);
}
return studentList;
}
}
三種方式的對比
MySQL服務器版本:5.6.4
其他依賴版本如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.buhe</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
三種插入方式在不同數(shù)據(jù)量下的表現(xiàn),測試結(jié)果:
插入方式 | 10條 | 100條 | 500條 | 1000條 |
---|---|---|---|---|
循環(huán)插入 | 496ms | 3330ms | 15584ms | 33755ms |
foreach標簽 | 268ms | 366ms | 392ms | 684ms |
批處理 | 222ms | 244ms | 364ms | 426ms |
三種方式中,批處理的方式效率是最高的,尤其是在數(shù)據(jù)量大的情況下尤為明顯。
其次是foreach標簽,foreach標簽是通過拼接SQL語句的方式完成批量操作的。但是當拼接的SQL過多,導致SQL大小超過了MySQL服務器中max_allowed_packet變量的值時,會導致操作失敗,拋出PacketTooBigException異常。
最后是循環(huán)插入的方式,這種方式在數(shù)據(jù)量小的時候可以使用,在數(shù)據(jù)量大的情況下效率要低很多。
以上就是關(guān)于Mybatis批量導入數(shù)據(jù)三種方法的詳細內(nèi)容,想要了解更多關(guān)于Mybatis 批量導入數(shù)據(jù)的資料,請關(guān)注W3Cschool其它相關(guān)文章!