2022. 6. 26. 14:19ㆍSpring
Spring Batch에서 ItemWriter 중 JdbcBatchItemWriter와 MyBatisBatchItemWriter의 성능 비교를 다룹니다.
안녕하세요.
이번에는 JdbcBatchItemWriter와 MyBatisBatchItemWriter를 비교하는 테스트를 진행해보려 합니다.
Database
깃허브에 공유되어도 될만한 정보로 유저를 생성해주었습니다.
이 부분은 필수 사항은 아니었지만, 공유하고 싶어서 추후에 추가했습니다.
아이디는 'gngsn 이며, 비밀번호는 'Test1234!' 로 설정하고 권한은 대충,,ㅎㅎ 전부 줬습니다.
mysql> create user 'gngsn'@'localhost' identified by 'Test1234!';
mysql> grant all privileges on *.* to 'gngsn'@'localhost' with grant option;
mysql> create user 'gngsn'@'%' identified by 'Test1234!';
mysql> grant all privileges on *.* to 'gngsn'@'%' with grant option;
mysql> flush privileges;
그리고는 테스트할 테이블을 생성합니다.
CREATE TABLE `test`.`user_jdbc` (
`name` VARCHAR(50) NULL,
`email` VARCHAR(255) NULL,
`password` VARCHAR(255) NULL,
`timestamp` TIMESTAMP NULL DEFAULT now()
);
CREATE TABLE `test`.`user_mybatis` (
`name` VARCHAR(50) NULL,
`email` VARCHAR(255) NULL,
`password` VARCHAR(255) NULL,
`timestamp` TIMESTAMP NULL DEFAULT now()
);
Spring Project
Spring 프로젝트는 gradle을 통해 만들었는데, maven 보다 gradle이 더 편해서 선택했습니다.
본인한테 맞는 툴 쓰는게 좋겠죠.
사전 준비 내용으로는 데이터베이스에 연결할 Datasource와 SqlSessionFactory입니다.
Datasource
private DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("gngsn");
dataSource.setPassword("Test1234!");
return dataSource;
}
SqlSession
private SqlSessionFactory sqlSession() throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResource("classpath:/batchTest.xml"));
sessionFactoryBean.setDataSource(dataSource());
return sessionFactoryBean.getObject();
}
User Class
public class User {
private String name;
private String email;
private String password;
public User(String name, String email, String password) {
this.name = name;
this.email = email;
this.password = password;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public void setName(String name) {
this.name = name;
}
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
}
Test
JdbcBatchItemWriter
class BatchTestApplicationTests {
int INSERT_SIZE = 1_000;
@Test
void jdbcBatchItemWriter() throws Exception {
JdbcBatchItemWriter<User> jdbcBatchItemWriter = new JdbcBatchItemWriterBuilder<User>()
.dataSource(dataSource())
.sql("INSERT INTO user_jdbc(name, email, password) VALUES (:name, :email, :password)")
.beanMapped()
.build();
jdbcBatchItemWriter.afterPropertiesSet();
List<User> users = new ArrayList<>(INSERT_SIZE);
for (int i = 0; i < INSERT_SIZE; i++) {
users.add(new User("gngsn" + i, "gngsn" + i + "@email.com", "password~"));
}
jdbcBatchItemWriter.write(users);
}
// ...
}
MyBatisBatchItemWriter
class BatchTestApplicationTests {
int INSERT_SIZE = 1_000;
@Test
void mybatisBatchItemWriter() throws Exception {
MyBatisBatchItemWriter<User> myBatisBatchItemWriter = new MyBatisBatchItemWriterBuilder<User>()
.sqlSessionFactory(sqlSession())
.statementId("user.insertUser")
.assertUpdates(false)
.build();
myBatisBatchItemWriter.afterPropertiesSet();
List<User> users = new ArrayList<>(INSERT_SIZE);
for (int i = 0; i < INSERT_SIZE; i++) {
users.add(new User("gngsn" + i, "gngsn" + i + "@email.com", "password~"));
}
myBatisBatchItemWriter.write(users);
}
// ...
}
Mybatis 설정은 아래와 같습니다.
<?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="user">
<insert id="insertUser">
INSERT INTO user_mybatis (name, email, password)
VALUES (#{name}, #{email}, #{password})
</insert>
</mapper>
Result
결과는 아래와 같습니다.
Data Size : 1,000
JdbcBatchItemWriter : 2sec 350ms
MyBatisBatchItemWriter : 17sec 705ms
성능에서 차이가 크게 나네요.
간단한 구문으로 실행할 수 있는 SQL이면 최대한 JdbcBatchItemWriter을 사용하는 게 좋겠군요.
하지만, 저와 같은 경우에는 테이블 명을 데이터 하나마다 dynamic하게 변경되어야 해서 MyBatisBatchItemWriter를 선택했습니다.
JdbcBatchItemWriter로 시도는 했는데,,, 정말 어떻게 안되더라구요.
그럼 이상으로 두 ItemWriter를 비교해보았습니다.
'Spring' 카테고리의 다른 글
Spring Batch, SEQ ID 제대로 이해하기 (0) | 2022.08.21 |
---|---|
Spring Batch, 제대로 이해하기 (4) - 데이터 처리 활용 (2) | 2022.07.01 |
Spring Batch, Error Log (0) | 2022.06.23 |
Spring Batch, 제대로 이해하기 (3) - Meta Data (0) | 2022.06.22 |
Spring Batch, 제대로 이해하기 (2) - 동작원리 (4) | 2022.06.19 |
Backend Software Engineer
𝐒𝐮𝐧 · 𝙂𝙮𝙚𝙤𝙣𝙜𝙨𝙪𝙣 𝙋𝙖𝙧𝙠