MyBatis | Batch Updates
By default, each time SQL is executed, a PreparedStatement is created and the SQL is sent to the database.
When there are many updates, this is very inefficient.
Depending on the configuration, MyBatis can reuse PreparedStatement instances and perform batch updates.
Default Behavior
Source Code
sample_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="sample.mybatis">
<insert id="insertTest">
insert into test_table (value) values (#{value})
</insert>
</mapper>
Main.java
package sample.mybatis;
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class Main {
public static void main(String[] args) throws Exception {
try (InputStream in = Main.class.getResourceAsStream("/mybatis-config.xml")) {
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
try (SqlSession session = factory.openSession()) {
for (int i=0; i<3; i++) {
TestTable t = new TestTable("value-" + i);
int updateCount = session.insert("sample.mybatis.insertTest", t);
System.out.println("updateCount = " + updateCount);
}
session.commit();
}
}
}
}
- This implementation repeats INSERT three times.
Execution Result
[DEBUG] s.m.insertTest - ==> Preparing: insert into test_table (value) values (?)
[DEBUG] s.m.insertTest - ==> Parameters: value-0(String)
[DEBUG] s.m.insertTest - <== Updates: 1
updateCount = 1
[DEBUG] s.m.insertTest - ==> Preparing: insert into test_table (value) values (?)
[DEBUG] s.m.insertTest - ==> Parameters: value-1(String)
[DEBUG] s.m.insertTest - <== Updates: 1
updateCount = 1
[DEBUG] s.m.insertTest - ==> Preparing: insert into test_table (value) values (?)
[DEBUG] s.m.insertTest - ==> Parameters: value-2(String)
[DEBUG] s.m.insertTest - <== Updates: 1
updateCount = 1
Description
- A PreparedStatement is created and SQL is sent every time.
Reuse PreparedStatement
Source Code
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="defaultExecutorType" value="REUSE"/>
</settings>
...
</configuration>
Execution Result
[DEBUG] s.m.insertTest - ==> Preparing: insert into test_table (value) values (?)
[DEBUG] s.m.insertTest - ==> Parameters: value-0(String)
[DEBUG] s.m.insertTest - <== Updates: 1
updateCount = 1
[DEBUG] s.m.insertTest - ==> Parameters: value-1(String)
[DEBUG] s.m.insertTest - <== Updates: 1
updateCount = 1
[DEBUG] s.m.insertTest - ==> Parameters: value-2(String)
[DEBUG] s.m.insertTest - <== Updates: 1
updateCount = 1
Description
- Set
defaultExecutorTypetoREUSEin the configuration file. - The PreparedStatement is created only once.
- SQL is still sent every time.
Batch Execution
Source Code
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="defaultExecutorType" value="BATCH"/>
</settings>
...
</configuration>
Execution Result
[DEBUG] s.m.insertTest - ==> Preparing: insert into test_table (value) values (?)
[DEBUG] s.m.insertTest - ==> Parameters: value-0(String)
updateCount = -2147482646
[DEBUG] s.m.insertTest - ==> Parameters: value-1(String)
updateCount = -2147482646
[DEBUG] s.m.insertTest - ==> Parameters: value-2(String)
updateCount = -2147482646
Description
- Setting
defaultExecutorTypetoBATCHperforms batch updates. - SQL is sent together at the end.
- As a result, the update count cannot be obtained.
Specify It When Obtaining SqlSession
The setting that determines whether to use batch updates can be specified as an argument when obtaining a SqlSession.
import org.apache.ibatis.session.ExecutorType;
...
SqlSession session = factory.openSession(ExecutorType.BATCH);
You can specify it by passing ExecutorType to the argument of openSession().
The condition specified here takes precedence over the configuration file.