Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat/CK-236] JdbcTemplate을 이용하여 bulk insert를 적용한다 #198

Merged
merged 2 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package co.kirikiri.persistence.goalroom;

import co.kirikiri.domain.goalroom.GoalRoomMember;
import java.util.List;

public interface GoalRoomMemberJdbcRepository {

void saveAllInBatch(final List<GoalRoomMember> goalRoomMembers);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package co.kirikiri.persistence.goalroom;

import co.kirikiri.domain.goalroom.GoalRoomMember;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class GoalRoomMemberJdbcRepositoryImpl implements GoalRoomMemberJdbcRepository {

private final JdbcTemplate jdbcTemplate;

public GoalRoomMemberJdbcRepositoryImpl(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

@Override
public void saveAllInBatch(final List<GoalRoomMember> goalRoomMembers) {
final String sql = "INSERT INTO goal_room_member "
+ "(goal_room_id, member_id, role, joined_at, accomplishment_rate) "
+ "VALUES (?, ?, ?, ?, ?)";
jdbcTemplate.batchUpdate(sql, goalRoomMembers, goalRoomMembers.size(), ((ps, goalRoomMember) -> {
ps.setLong(1, goalRoomMember.getGoalRoom().getId());
ps.setLong(2, goalRoomMember.getMember().getId());
ps.setString(3, goalRoomMember.getRole().name());
ps.setObject(4, goalRoomMember.getJoinedAt());
ps.setDouble(5, goalRoomMember.getAccomplishmentRate());
}));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
import co.kirikiri.domain.goalroom.GoalRoom;
import co.kirikiri.domain.goalroom.GoalRoomMember;
import co.kirikiri.domain.member.vo.Identifier;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;

public interface GoalRoomMemberRepository extends JpaRepository<GoalRoomMember, Long>, GoalRoomMemberQueryRepository {
public interface GoalRoomMemberRepository extends JpaRepository<GoalRoomMember, Long>,
GoalRoomMemberQueryRepository, GoalRoomMemberJdbcRepository {

@Query("select gm from GoalRoomMember gm "
+ "inner join fetch gm.goalRoom g "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import co.kirikiri.domain.goalroom.GoalRoom;
import co.kirikiri.domain.goalroom.GoalRoomPendingMember;
import co.kirikiri.domain.member.vo.Identifier;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;

public interface GoalRoomPendingMemberRepository extends JpaRepository<GoalRoomPendingMember, Long>,
GoalRoomPendingMemberQueryRepository {
Expand All @@ -28,4 +29,8 @@ Optional<GoalRoomPendingMember> findByGoalRoomAndMemberIdentifier(
+ "where g=:goalRoom "
+ "and gp.member = m")
List<GoalRoomPendingMember> findAllByGoalRoom(@Param("goalRoom") final GoalRoom goalRoom);

@Modifying
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Modifying을 붙여야 하는 이유가 JPA에서 동작을 추론가능한 메서드명일 경우라서 그런건가요?

@Query("DELETE FROM GoalRoomPendingMember gp WHERE gp.id IN :ids")
void deleteAllByIdIn(@Param("ids") final List<Long> ids);
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ public List<GoalRoom> findByRoadmap(final Roadmap roadmap) {
@Override
public List<GoalRoom> findAllRecruitingGoalRoomsByStartDateEarlierThan(final LocalDate date) {
return selectFrom(goalRoom)
.innerJoin(goalRoom.goalRoomPendingMembers.values, goalRoomPendingMember)
.fetchJoin()
Comment on lines +119 to +120
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

join이 안되어있었네요..👍

.where(statusCond(GoalRoomStatus.RECRUITING))
.where(equalOrEarlierStartDateThan(date))
.fetch();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package co.kirikiri.persistence.goalroom;

import co.kirikiri.domain.goalroom.GoalRoom;
import org.springframework.data.jpa.repository.JpaRepository;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface GoalRoomRepository extends JpaRepository<GoalRoom, Long>, GoalRoomQueryRepository {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package co.kirikiri.service.scheduler;

import co.kirikiri.domain.BaseEntity;
import co.kirikiri.domain.goalroom.GoalRoom;
import co.kirikiri.domain.goalroom.GoalRoomMember;
import co.kirikiri.domain.goalroom.GoalRoomPendingMember;
import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository;
import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository;
import co.kirikiri.persistence.goalroom.GoalRoomRepository;
import co.kirikiri.service.aop.ExceptionConvert;
import java.time.LocalDate;
Expand All @@ -19,23 +22,25 @@
public class GoalRoomScheduler {

private final GoalRoomRepository goalRoomRepository;
private final GoalRoomPendingMemberRepository goalRoomPendingMemberRepository;
private final GoalRoomMemberRepository goalRoomMemberRepository;

@Scheduled(cron = "0 0 0 * * *")
public void startGoalRooms() {
final List<GoalRoom> goalRoomsToStart = goalRoomRepository.findAllRecruitingGoalRoomsByStartDateEarlierThan(
LocalDate.now());
for (final GoalRoom goalRoom : goalRoomsToStart) {
final List<GoalRoomPendingMember> goalRoomPendingMembers = goalRoom.getGoalRoomPendingMembers().getValues();
saveGoalRoomMemberFromPendingMembers(goalRoomPendingMembers, goalRoom);
saveGoalRoomMemberFromPendingMembers(goalRoomPendingMembers);
goalRoom.start();
}
}

private void saveGoalRoomMemberFromPendingMembers(final List<GoalRoomPendingMember> goalRoomPendingMembers,
final GoalRoom goalRoom) {
private void saveGoalRoomMemberFromPendingMembers(final List<GoalRoomPendingMember> goalRoomPendingMembers) {
final List<GoalRoomMember> goalRoomMembers = makeGoalRoomMembers(goalRoomPendingMembers);
goalRoom.addAllGoalRoomMembers(goalRoomMembers);
goalRoom.deleteAllPendingMembers();
goalRoomMemberRepository.saveAllInBatch(goalRoomMembers);
final List<Long> ids = makeGoalRoomPendingMemberIds(goalRoomPendingMembers);
goalRoomPendingMemberRepository.deleteAllByIdIn(ids);
}

private List<GoalRoomMember> makeGoalRoomMembers(final List<GoalRoomPendingMember> goalRoomPendingMembers) {
Expand All @@ -45,9 +50,14 @@ private List<GoalRoomMember> makeGoalRoomMembers(final List<GoalRoomPendingMembe
}

private GoalRoomMember makeGoalRoomMember(final GoalRoomPendingMember goalRoomPendingMember) {
return new GoalRoomMember(goalRoomPendingMember.getRole(),
goalRoomPendingMember.getJoinedAt(), goalRoomPendingMember.getGoalRoom(),
goalRoomPendingMember.getMember());
return new GoalRoomMember(goalRoomPendingMember.getRole(), goalRoomPendingMember.getJoinedAt(),
goalRoomPendingMember.getGoalRoom(), goalRoomPendingMember.getMember());
}

private List<Long> makeGoalRoomPendingMemberIds(final List<GoalRoomPendingMember> goalRoomPendingMembers) {
return goalRoomPendingMembers.stream()
.map(BaseEntity::getId)
.toList();
}

@Scheduled(cron = "0 0 4 * * *")
Expand Down
2 changes: 1 addition & 1 deletion backend/kirikiri/src/main/resources/properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@
import co.kirikiri.integration.helper.InitIntegrationTest;
import co.kirikiri.persistence.goalroom.GoalRoomMemberRepository;
import co.kirikiri.persistence.goalroom.GoalRoomPendingMemberRepository;
import co.kirikiri.service.scheduler.GoalRoomScheduler;
import co.kirikiri.service.dto.auth.request.LoginRequest;
import co.kirikiri.service.dto.goalroom.request.GoalRoomCreateRequest;
import co.kirikiri.service.dto.goalroom.request.GoalRoomRoadmapNodeRequest;
import co.kirikiri.service.dto.member.request.GenderType;
import co.kirikiri.service.dto.member.request.MemberJoinRequest;
import co.kirikiri.service.dto.member.response.MemberGoalRoomResponse;
import co.kirikiri.service.dto.roadmap.response.RoadmapResponse;
import org.junit.jupiter.api.Test;
import co.kirikiri.service.scheduler.GoalRoomScheduler;
import java.io.IOException;
import java.util.List;
import org.junit.jupiter.api.Test;

class GoalRoomSchedulerIntegrationTest extends InitIntegrationTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public TestTransactionService(final GoalRoomRepository goalRoomRepository,
}

public void 골룸_멤버를_저장한다(final List<GoalRoomMember> 골룸_멤버_리스트) {
goalRoomMemberRepository.saveAll(골룸_멤버_리스트);
goalRoomMemberRepository.saveAllInBatch(골룸_멤버_리스트);
}

public void 골룸의_상태와_종료날짜를_변경한다(final Long 골룸_아이디, final GoalRoomStatus 골룸_상태, final LocalDate 변경할_종료날짜) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
import co.kirikiri.persistence.member.MemberRepository;
import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository;
import co.kirikiri.persistence.roadmap.RoadmapRepository;
import org.junit.jupiter.api.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import org.junit.jupiter.api.Test;

@RepositoryTest
class CheckFeedRepositoryTest {
Expand Down Expand Up @@ -86,7 +86,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository,
final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator);
final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom,
member);
goalRoomMemberRepository.saveAll(List.of(leader, joinedMember));
goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember));

final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0);
인증_피드를_저장한다(goalRoomRoadmapNode, joinedMember);
Expand Down Expand Up @@ -120,7 +120,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository,
final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator);
final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom,
member);
goalRoomMemberRepository.saveAll(List.of(leader, joinedMember));
goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember));

final GoalRoomRoadmapNode goalRoomRoadmapNode = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0);
인증_피드를_저장한다(goalRoomRoadmapNode, joinedMember);
Expand Down Expand Up @@ -151,7 +151,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository,
final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator);
final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom,
member);
goalRoomMemberRepository.saveAll(List.of(leader, joinedMember));
goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember));

final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0);
final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1);
Expand Down Expand Up @@ -188,7 +188,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository,
member);
final GoalRoomMember otherLeader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom2,
creator);
goalRoomMemberRepository.saveAll(List.of(leader, joinedMember));
goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember));

final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom1.getGoalRoomRoadmapNodes().getValues().get(0);
final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom1.getGoalRoomRoadmapNodes().getValues().get(1);
Expand Down Expand Up @@ -226,7 +226,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository,
final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator);
final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom,
member);
goalRoomMemberRepository.saveAll(List.of(leader, joinedMember));
goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember));

final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0);
final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1);
Expand Down Expand Up @@ -269,7 +269,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository,
final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator);
final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom,
member);
goalRoomMemberRepository.saveAll(List.of(leader, joinedMember));
goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember));

final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0);
final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1);
Expand Down Expand Up @@ -303,7 +303,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository,
final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator);
final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom,
member);
goalRoomMemberRepository.saveAll(List.of(leader, joinedMember));
goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember));

final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0);
final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1);
Expand Down Expand Up @@ -348,7 +348,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository,
final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator);
final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom,
member);
goalRoomMemberRepository.saveAll(List.of(leader, joinedMember));
goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember));

final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0);
final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1);
Expand Down Expand Up @@ -407,7 +407,7 @@ public CheckFeedRepositoryTest(final MemberRepository memberRepository,
final GoalRoomMember leader = new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), goalRoom, creator);
final GoalRoomMember joinedMember = new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), goalRoom,
member);
goalRoomMemberRepository.saveAll(List.of(leader, joinedMember));
goalRoomMemberRepository.saveAllInBatch(List.of(leader, joinedMember));

final GoalRoomRoadmapNode goalRoomRoadmapNode1 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(0);
final GoalRoomRoadmapNode goalRoomRoadmapNode2 = goalRoom.getGoalRoomRoadmapNodes().getValues().get(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
import co.kirikiri.persistence.member.MemberRepository;
import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository;
import co.kirikiri.persistence.roadmap.RoadmapRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

@RepositoryTest
class GoalRoomMemberRepositoryTest {
Expand Down Expand Up @@ -296,11 +296,13 @@ public GoalRoomMemberRepositoryTest(final MemberRepository memberRepository,
private Member 크리에이터를_저장한다() {
final MemberImage memberImage = new MemberImage("originalFileName", "serverFilePath", ImageContentType.JPG);
final MemberProfile memberProfile = new MemberProfile(Gender.MALE, "kirikiri1@email.com");
final Member creator = new Member(1L, new Identifier("cokirikiri"), null, new EncryptedPassword(new Password("password1!")), new Nickname("코끼리"), memberImage, memberProfile);
final Member creator = new Member(1L, new Identifier("cokirikiri"), null,
new EncryptedPassword(new Password("password1!")), new Nickname("코끼리"), memberImage, memberProfile);
return memberRepository.save(creator);
}

private Member 사용자를_생성한다(final String identifier, final String password, final String nickname, final String email) {
private Member 사용자를_생성한다(final String identifier, final String password, final String nickname,
final String email) {
final MemberProfile memberProfile = new MemberProfile(Gender.MALE, email);
final Member member = new Member(new Identifier(identifier),
new EncryptedPassword(new Password(password)), new Nickname(nickname),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
import co.kirikiri.persistence.member.MemberRepository;
import co.kirikiri.persistence.roadmap.RoadmapCategoryRepository;
import co.kirikiri.persistence.roadmap.RoadmapRepository;
import org.junit.jupiter.api.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import org.junit.jupiter.api.Test;

@RepositoryTest
class GoalRoomToDoCheckRepositoryTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@
import co.kirikiri.persistence.goalroom.GoalRoomRepository;
import co.kirikiri.persistence.helper.RepositoryTest;
import co.kirikiri.persistence.member.MemberRepository;
import org.junit.jupiter.api.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.Test;

@RepositoryTest
class RoadmapRepositoryTest {
Expand Down Expand Up @@ -249,13 +249,13 @@ public RoadmapRepositoryTest(final MemberRepository memberRepository,
// gameRoadmap2 : 참가인원 1명
final List<GoalRoomMember> gameRoadmap2GoalRoomMembers = List.of(
new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), gameRoadmap2GoalRoom, creator));
goalRoomMemberRepository.saveAll(gameRoadmap2GoalRoomMembers);
goalRoomMemberRepository.saveAllInBatch(gameRoadmap2GoalRoomMembers);

// travelRoadmap : 참가인원 2명
final List<GoalRoomMember> travelRoadmapGoalRoomMembers = List.of(
new GoalRoomMember(GoalRoomRole.LEADER, LocalDateTime.now(), travelRoadmapGoalRoom, creator),
new GoalRoomMember(GoalRoomRole.FOLLOWER, LocalDateTime.now(), travelRoadmapGoalRoom, follower));
goalRoomMemberRepository.saveAll(travelRoadmapGoalRoomMembers);
goalRoomMemberRepository.saveAllInBatch(travelRoadmapGoalRoomMembers);

final RoadmapCategory category = null;
final RoadmapOrderType orderType = RoadmapOrderType.PARTICIPANT_COUNT;
Expand Down
Loading