2 min read

Bulk Insert

JPA Bulk Insert-1674903588761.jpeg

๊ต๋‚ด ํ•™์ƒ๋“ค์ด ํ‘ผ ๋ฐฑ์ค€ ๋ฌธ์ œ๋ฅผ ๋ชจ๋‘ DB์— ๋„ฃ๋Š” ๋ฐฐ์น˜ ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ ์†๋„๊ฐ€ ๋„ˆ๋ฌด ๋А๋ฆฌ๋‹ค. ์ด๋ฅผ ๊ฐœ์„ ํ•ด๋ณด์ž.

์šฐ์„  PK ์ƒ์„ฑ ์ „๋žต์ด TABLE์œผ๋กœ ๋˜์–ด ์žˆ์–ด์„œ, IDENTITY๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค. ํ‚ค ์ƒ์„ฑ ์ „์šฉ ํ…Œ์ด๋ธ”์„ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹œํ€ธ์Šค๋ฅผ ํ‰๋‚ด๋‚ด๋Š” ์ „๋žต์ธ๋ฐ, ์ตœ์ ํ™” ๋˜์–ด์žˆ์ง€ ์•Š์€ ํ…Œ์ด๋ธ”์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ด ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค. IDENTITY ์ „๋žต์€ ๊ธฐ๋ณธ ํ‚ค ์ƒ์„ฑ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์œ„์ž„ํ•˜๋Š” ์ „๋žต์ด๋‹ค. (DDL๋กœ ๊ธฐ๋ณธํ‚ค์— AUTO_INCREMENT ๊ฑธ๊ธฐ)

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด JPA๋กœ BATCH INSERT๋ฅผ ํ•  ์ˆ˜์—†๋‹ค. ์ž ์‹œ JPA๋ฅผ ๋†“์•„์ฃผ๊ณ  JDBC๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์ž.

package skku.skkujoon.repository;

import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import skku.skkujoon.domain.Problem;
import skku.skkujoon.domain.User;

import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;

/**
 * Only for batch insert
 * @author ks1ksi
 */

@Repository
@RequiredArgsConstructor
public class JdbcRepository {
    private final JdbcTemplate jdbcTemplate;

    public void insertUsers(List<User> users) {
        String sql = "insert into user (handle, bio, solved_count, tier, rating, ranking, global_rank) values (?, ?, ?, ?, ?, ?, ?)";
        jdbcTemplate.batchUpdate(sql,
                users,
                users.size(),
                (ps, u) -> {
                    ps.setString(1, u.getHandle());
                    ps.setString(2, u.getBio());
                    ps.setInt(3, u.getSolvedCount());
                    ps.setInt(4, u.getTier());
                    ps.setInt(5, u.getRating());
                    ps.setInt(6, u.getRanking());
                    ps.setInt(7, u.getGlobalRank());
                });
    }

    public void insertProblems(List<Problem> problems) {
        String sql = "insert into problem (problem_number, title_ko, level, solved_by_skku, solvable, partial) values (?, ?, ?, ?, ?, ?)";
        jdbcTemplate.batchUpdate(sql,
                problems,
                problems.size(),
                (ps, p) -> {
                    ps.setLong(1, p.getProblemNumber());
                    ps.setString(2, p.getTitleKo());
                    ps.setInt(3, p.getLevel());
                    ps.setInt(4, p.getSolvedBySkku());
                    ps.setBoolean(5, p.isSolvable());
                    ps.setBoolean(6, p.isPartial());
                });
    }

    public void insertUserProblems(User user, List<Problem> problems) {
        String sql = "insert into user_problem (user_id, problem_id) values (?, ?)";
        jdbcTemplate.batchUpdate(sql,
                problems,
                problems.size(),
                (ps, p) -> {
                    ps.setLong(1, user.getId());
                    ps.setLong(2, p.getId());
                });
    }

    public void updateProblems(List<Problem> problems) {
        String sql = "update problem set solved_by_skku = solved_by_skku + 1 where problem_id = ?";
        jdbcTemplate.batchUpdate(sql,
                problems,
                problems.size(),
                (ps, p) -> {
                    ps.setLong(1, p.getId());
                });
    }

}

Bulk Insert-1674963763722.jpeg

7์‹œ๊ฐ„ ๋„˜๊ฒŒ ๊ฑธ๋ฆฌ๋˜๊ฑธ 1์‹œ๊ฐ„์œผ๋กœ ์ค„์˜€๋‹ค. solved.ac api ํ˜ธ์ถœ ์ œํ•œ์ด ์žˆ์–ด์„œ ์‹œ๊ฐ„์„ ๋” ์ค„์ด๊ธฐ๋Š” ํž˜๋“ค ๊ฒƒ ๊ฐ™๋‹ค.