Skip to content

Commit

Permalink
[feat] 추첨 이벤트 당첨 정보 bulk insert 기능 구현(#40)
Browse files Browse the repository at this point in the history
JPA로 추첨 이벤트 당첨 정보를 저장하기 위해서는 연관 객체인 EventUser를 객체로 가져와 연관 관계를 지정해야 하고, insertAll을 수행해도 단일 insert 여러번으로 처리된다. 이런 불필요한 작업을 제거하기 위해 JDBC Template 기반으로 bulk insert 기능을 구현한다.
  • Loading branch information
blaxsior committed Aug 9, 2024
1 parent 6788bb6 commit 6811ca0
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package hyundai.softeer.orange.event.draw.dto;

import lombok.Getter;

@Getter
public class DrawEventWinningInfoBulkInsertDto {
private long eventUserId;
private long ranking;
private long drawEventId;

public static DrawEventWinningInfoBulkInsertDto of(long eventUserId, long ranking, long drawEventId) {
var dto = new DrawEventWinningInfoBulkInsertDto();
dto.eventUserId = eventUserId;
dto.ranking = ranking;
dto.drawEventId = drawEventId;
return dto;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package hyundai.softeer.orange.event.draw.repository;

import hyundai.softeer.orange.event.draw.dto.DrawEventWinningInfoBulkInsertDto;

import java.util.List;

public interface CustomDrawEventWinningInfoRepository {
void insertMany(List<DrawEventWinningInfoBulkInsertDto> targets);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package hyundai.softeer.orange.event.draw.repository;

import hyundai.softeer.orange.event.draw.dto.DrawEventWinningInfoBulkInsertDto;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

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

@Repository
@RequiredArgsConstructor
public class CustomDrawEventWinningInfoRepositoryImpl implements CustomDrawEventWinningInfoRepository {
private final JdbcTemplate jdbcTemplate;

@Override
public void insertMany(List<DrawEventWinningInfoBulkInsertDto> targets) {
String sql = "insert into draw_event_winning_info (event_user_id, ranking, draw_event_id) VALUES (?, ?, ?)";

jdbcTemplate.batchUpdate(
sql,
new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
var target = targets.get(i);
ps.setLong(1, target.getEventUserId());
ps.setLong(2, target.getRanking());
ps.setLong(3, target.getDrawEventId());
}

@Override
public int getBatchSize() {
return targets.size();
}
}
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DrawEventWinningInfoRepository extends JpaRepository<DrawEventWinningInfo, Long> {
public interface DrawEventWinningInfoRepository extends JpaRepository<DrawEventWinningInfo, Long>, CustomDrawEventWinningInfoRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package hyundai.softeer.orange.event.draw.repository;

import hyundai.softeer.orange.event.common.entity.EventFrame;
import hyundai.softeer.orange.event.common.repository.EventFrameRepository;
import hyundai.softeer.orange.event.draw.dto.DrawEventWinningInfoBulkInsertDto;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.jdbc.DataJdbcTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.TestPropertySource;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;


@DataJpaTest(showSql = false)
@TestPropertySource(locations = "classpath:application-test.yml")
class CustomDrawEventWinningInfoRepositoryImplTest {
@Autowired // DrawEventWinningInfoRepository로 접근 가능해야 함
private DrawEventWinningInfoRepository repo;

@Autowired
JdbcTemplate jdbcTemplate;

@BeforeEach
void setUp() {
jdbcTemplate.execute("INSERT INTO event_frame(name) VALUES ('test')");
jdbcTemplate.execute("INSERT INTO event_metadata(event_type,event_frame_id,event_id) values (1, 1, 'HD_240808_001')");
jdbcTemplate.execute("INSERT INTO draw_event values ()");
jdbcTemplate.execute("INSERT INTO event_metadata(event_type,event_frame_id,event_id) values (1, 1, 'HD_240808_002')");
jdbcTemplate.execute("INSERT INTO draw_event values ()");
jdbcTemplate.execute("INSERT INTO event_user(score, event_frame_id, user_id) values ( 0, 1, 'user1')");
jdbcTemplate.execute("INSERT INTO event_user(score, event_frame_id, user_id) values ( 0, 1, 'user2')");
jdbcTemplate.execute("INSERT INTO event_user(score, event_frame_id, user_id) values ( 0, 1, 'user3')");
jdbcTemplate.execute("INSERT INTO event_user(score, event_frame_id, user_id) values ( 0, 1, 'user4')");
jdbcTemplate.execute("INSERT INTO event_user(score, event_frame_id, user_id) values ( 0, 1, 'user5')");
jdbcTemplate.execute("INSERT INTO event_user(score, event_frame_id, user_id) values ( 0, 1, 'user6')");
}


@DisplayName("제대로 데이터를 삽입하는지 확인")
@Test
void testBulkInsertWork() {
// Executing prepared SQL statement [insert into draw_event_winning_info (event_user_id, ranking, draw_event_id) VALUES (?, ?, ?)]

List<DrawEventWinningInfoBulkInsertDto> targets = List.of(
DrawEventWinningInfoBulkInsertDto.of(1, 1, 1),
DrawEventWinningInfoBulkInsertDto.of(2, 1, 1),
DrawEventWinningInfoBulkInsertDto.of(3, 2, 1),
DrawEventWinningInfoBulkInsertDto.of(4, 2, 1),
DrawEventWinningInfoBulkInsertDto.of(5, 2, 1),
DrawEventWinningInfoBulkInsertDto.of(6, 2, 1),
DrawEventWinningInfoBulkInsertDto.of(1, 1, 2),
DrawEventWinningInfoBulkInsertDto.of(2, 1, 2),
DrawEventWinningInfoBulkInsertDto.of(3, 2, 2),
DrawEventWinningInfoBulkInsertDto.of(4, 2, 2),
DrawEventWinningInfoBulkInsertDto.of(5, 2, 2),
DrawEventWinningInfoBulkInsertDto.of(6, 2, 2)
);
repo.insertMany(targets);
var events = repo.findAll();
assertThat(events).hasSize(12);
}
}

0 comments on commit 6811ca0

Please sign in to comment.