JSON-OBJECT Software Engineering Blog

Professional Senior Backend Engineer. Specializing in high volume traffic and distributed processing with Kotlin and Spring Boot as core technologies.

View on GitHub
22 June 2022

Spring Boot, MySQL, 엔티티 스키마 변경 없이 Bulk Insert로 속도 개선하기

by Taehyeong Lee

개요

MySQL 커넥션 스트링 추가

val config = HikariConfig().apply {
    ...
    addDataSourceProperty("rewriteBatchedStatements", true)
}
val datasource = HikariDataSource(config)

FooRepository#saveAll 작성

import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Repository
import org.springframework.transaction.annotation.Isolation
import org.springframework.transaction.annotation.Transactional
import java.math.BigDecimal
import java.sql.Timestamp

@Repository
@Transactional(readOnly = true, isolation = Isolation.READ_COMMITTED)
class FooRepositorySupport(
    private val jdbcTemplate: JdbcTemplate
) {
    @Transactional(isolation = Isolation.READ_COMMITTED)
    fun saveAll(foos: List<Foo>) {
        jdbcTemplate.batchUpdate(
            "INSERT INTO foo (string, long, double, boolean, instant) VALUES (?, ?, ?, ?, ?)",
            foos,
            4096
        ) { ps, foo ->
            foo.string?.let { ps.setString(1, it) } ?: ps.setNull(1, java.sql.Types.NULL)
            foo.long?.let { ps.setLong(2, it) } ?: ps.setNull(2, java.sql.Types.NULL)
            foo.double?.let { ps.setBigDecimal(3, BigDecimal.valueOf(it)) } ?: ps.setNull(3, java.sql.Types.NULL)
            foo.boolean?.let { ps.setBoolean(4, it) } ?: ps.setNull(4, java.sql.Types.NULL)
            foo.instant?.let { ps.setTimestamp(5, Timestamp.from(it)) } ?: ps.setNull(5, java.sql.Types.NULL)
        }
    }
}

적용 후기

참고 글

tags: MySQL - Spring Boot