From 244fa9a57a0178ec2b83e382d6cc4c6bb1327d14 Mon Sep 17 00:00:00 2001 From: scv1702 Date: Sun, 10 Nov 2024 20:52:20 +0900 Subject: [PATCH 1/4] =?UTF-8?q?GETP-324=20feat:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=EB=B0=B0=EC=B9=98=20=EC=82=BD=EC=9E=85=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- get-p-batch/build.gradle | 24 +++++ .../getp/batch/GetpBatchApplication.java | 31 +++++++ .../getp/batch/config/ExecutionTimer.java | 30 +++++++ .../config/ExtendsWithExecutionTimer.java | 11 +++ .../project/BatchInsertProjectService.java | 89 +++++++++++++++++++ .../batch/project/DropProjectService.java | 18 ++++ .../getp/batch/project/ProjectFactory.java | 29 ++++++ .../src/main/resources/application.yml | 4 + .../getp/fixture/project/ProjectFixture.java | 20 ++++- settings.gradle | 13 ++- 10 files changed, 258 insertions(+), 11 deletions(-) create mode 100644 get-p-batch/build.gradle create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/config/ExecutionTimer.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/config/ExtendsWithExecutionTimer.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/ProjectFactory.java create mode 100644 get-p-batch/src/main/resources/application.yml diff --git a/get-p-batch/build.gradle b/get-p-batch/build.gradle new file mode 100644 index 00000000..f011e57c --- /dev/null +++ b/get-p-batch/build.gradle @@ -0,0 +1,24 @@ +dependencies { + implementation(project(":get-p-domain")) + implementation(project(":get-p-persistence")) + implementation(testFixtures(project(":get-p-domain"))) + testImplementation(testFixtures(project(':get-p-domain'))) + + // Spring Data + implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.3.5' + + // Flyway + implementation 'org.flywaydb:flyway-core:9.16.3' + implementation 'org.flywaydb:flyway-mysql:9.16.3' + + // JDBC MySQL 드라이버 + runtimeOnly 'com.mysql:mysql-connector-j:9.0.0' +} + +bootJar { + enabled = true +} + +jar { + enabled = false +} \ No newline at end of file diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java b/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java new file mode 100644 index 00000000..3e68491b --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java @@ -0,0 +1,31 @@ +package es.princip.getp.batch; + +import es.princip.getp.batch.project.BatchInsertProjectService; +import es.princip.getp.batch.project.DropProjectService; +import es.princip.getp.batch.project.ProjectFactory; +import es.princip.getp.domain.project.commission.model.Project; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import java.util.List; + +@SpringBootApplication +public class GetpBatchApplication implements CommandLineRunner { + + @Autowired private DropProjectService dropProjectService; + @Autowired private ProjectFactory projectFactory; + @Autowired private BatchInsertProjectService batchInsertProjectService; + + public static void main(String[] args) { + SpringApplication.run(GetpBatchApplication.class, args); + } + + @Override + public void run(final String... args) { + dropProjectService.dropProject(); + final List projects = projectFactory.createProjects(100_000); + batchInsertProjectService.batchInsert(projects); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/config/ExecutionTimer.java b/get-p-batch/src/main/java/es/princip/getp/batch/config/ExecutionTimer.java new file mode 100644 index 00000000..c6962c33 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/config/ExecutionTimer.java @@ -0,0 +1,30 @@ +package es.princip.getp.batch.config; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +@Slf4j +@Aspect +@Component +public class ExecutionTimer { + + @Pointcut("@annotation(es.princip.getp.batch.config.ExtendsWithExecutionTimer)") + private void timer() {} + + @Around("timer()") + public Object AssumeExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { + final long start = System.currentTimeMillis(); + try { + return joinPoint.proceed(); + } finally { + final long finish = System.currentTimeMillis(); + final long executionTime = finish - start; + final String signature = joinPoint.getSignature().toShortString(); + log.info("execution time of {}: {}ms", signature, executionTime); + } + } +} \ No newline at end of file diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/config/ExtendsWithExecutionTimer.java b/get-p-batch/src/main/java/es/princip/getp/batch/config/ExtendsWithExecutionTimer.java new file mode 100644 index 00000000..bf601c80 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/config/ExtendsWithExecutionTimer.java @@ -0,0 +1,11 @@ +package es.princip.getp.batch.config; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExtendsWithExecutionTimer { +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java new file mode 100644 index 00000000..4846ebdd --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java @@ -0,0 +1,89 @@ +package es.princip.getp.batch.project; + +import es.princip.getp.batch.config.ExtendsWithExecutionTimer; +import es.princip.getp.domain.project.commission.model.Project; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.util.List; + +@Slf4j +@Service +@Transactional +@RequiredArgsConstructor +public class BatchInsertProjectService { + + private final JdbcTemplate jdbcTemplate; + private final int BATCH_SIZE = 1000; + + @ExtendsWithExecutionTimer + public void batchInsert(final List projects) { + final String sql = + """ + insert into project ( + project_id, + application_end_date, + application_start_date, + estimated_end_date, + estimated_start_date, + payment, + category, + description, + meeting_type, + status, + title, + client_id, + recruitment_count, + created_at, + updated_at + ) + values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + """; + final int batchSize = Math.min(BATCH_SIZE, projects.size()); + + for (int i = 0; i < projects.size(); i += batchSize) { + final int end = Math.min(i + batchSize, projects.size()); + final List batchList = projects.subList(i, end); + + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final Project project = batchList.get(i); + ps.setLong(1, project.getId().getValue()); + ps.setDate(2, Date.valueOf(project.getApplicationDuration().getEndDate())); + ps.setDate(3, Date.valueOf(project.getApplicationDuration().getStartDate())); + ps.setDate(4, Date.valueOf(project.getEstimatedDuration().getEndDate())); + ps.setDate(5, Date.valueOf(project.getEstimatedDuration().getStartDate())); + ps.setLong(6, project.getPayment()); + ps.setString(7, project.getCategory().toString()); + ps.setString(8, project.getDescription()); + ps.setString(9, project.getMeetingType().toString()); + ps.setString(10, project.getStatus().toString()); + ps.setString(11, project.getTitle()); + ps.setLong(12, project.getClientId().getValue()); + ps.setLong(13, project.getRecruitmentCount()); + ps.setString(14, String.valueOf(LocalDateTime.now())); + ps.setString(15, String.valueOf(LocalDateTime.now())); + } + + @Override + public int getBatchSize() { + return batchList.size(); + } + }); + + log.info("Batch inserted: {} to {}", i, end - 1); + log.info("Total gain: {}%", (i + batchSize) * 100D / projects.size()); + } + + log.info("Bach completed"); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java new file mode 100644 index 00000000..13e7874e --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java @@ -0,0 +1,18 @@ +package es.princip.getp.batch.project; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DropProjectService { + + private final JdbcTemplate jdbcTemplate; + + public void dropProject() { + jdbcTemplate.execute("delete from project"); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/ProjectFactory.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/ProjectFactory.java new file mode 100644 index 00000000..94cb7e86 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/ProjectFactory.java @@ -0,0 +1,29 @@ +package es.princip.getp.batch.project; + +import es.princip.getp.domain.client.model.ClientId; +import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.domain.project.commission.model.ProjectId; +import es.princip.getp.domain.project.commission.model.ProjectStatus; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +import static es.princip.getp.fixture.project.ProjectFixture.project; + +@Service +public class ProjectFactory { + + public List createProjects(final int size) { + final List projects = new ArrayList<>(); + for (int i = 1; i <= size; i++) { + final Long id = (long) i; + projects.add(project( + new ProjectId(id), + new ClientId(id), + ProjectStatus.APPLICATION_OPENED) + ); + } + return projects; + } +} diff --git a/get-p-batch/src/main/resources/application.yml b/get-p-batch/src/main/resources/application.yml new file mode 100644 index 00000000..e1c1d4f7 --- /dev/null +++ b/get-p-batch/src/main/resources/application.yml @@ -0,0 +1,4 @@ +spring: + config: + import: + - persistence-config.yml \ No newline at end of file diff --git a/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectFixture.java b/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectFixture.java index 780f3812..6929726c 100644 --- a/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectFixture.java +++ b/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectFixture.java @@ -2,10 +2,7 @@ import es.princip.getp.domain.client.model.ClientId; import es.princip.getp.domain.common.model.Duration; -import es.princip.getp.domain.project.commission.model.MeetingType; -import es.princip.getp.domain.project.commission.model.Project; -import es.princip.getp.domain.project.commission.model.ProjectCategory; -import es.princip.getp.domain.project.commission.model.ProjectStatus; +import es.princip.getp.domain.project.commission.model.*; import java.time.LocalDate; @@ -37,6 +34,21 @@ public class ProjectFixture { )) .hashtags(hashtags()); + public static Project project( + final ProjectId projectId, + final ClientId clientId, + final ProjectStatus status + ) { + return builder.id(projectId) + .clientId(clientId) + .status(status) + .applicationDuration(Duration.of( + APPLICATION_START_DATE, + APPLICATION_END_DATE + )) + .build(); + } + public static Project project(final ClientId clientId, final ProjectStatus status) { return builder.clientId(clientId) .status(status) diff --git a/settings.gradle b/settings.gradle index 172df1db..5dbd9429 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,9 +1,8 @@ rootProject.name = 'get-p-server' -include( - "get-p-api", - "get-p-domain", - "get-p-application", - "get-p-persistence", - "get-p-infrastructure" -) \ No newline at end of file +include 'get-p-api' +include 'get-p-domain' +include 'get-p-application' +include 'get-p-persistence' +include 'get-p-infrastructure' +include 'get-p-batch' \ No newline at end of file From 51fd0dbf39c2ca86a16730bdb14a4cd7a92e3535 Mon Sep 17 00:00:00 2001 From: scv1702 Date: Mon, 11 Nov 2024 02:11:29 +0900 Subject: [PATCH 2/4] =?UTF-8?q?GETP-324=20feat:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=EB=B0=B0=EC=B9=98=20=EC=82=BD=EC=9E=85=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=84=20ExecutorService=EC=9D=84=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=B4=20=EC=95=BD=203.17=EB=B0=B0=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../getp/batch/BatchInsertionException.java | 12 +++ .../getp/batch/GetpBatchApplication.java | 12 +-- .../parallel/ParallelBatchInsertService.java | 51 +++++++++++ .../batch/parallel/ParallelBatchInserter.java | 6 ++ .../BatchInsertProjectJdbcService.java | 70 +++++++++++++++ .../project/BatchInsertProjectService.java | 87 +------------------ .../batch/project/DropProjectService.java | 1 + .../ParallelBatchInsertProjectService.java | 40 +++++++++ .../getp/batch/project/ProjectFactory.java | 29 ------- .../SequentialBatchInsertProjectService.java | 36 ++++++++ .../getp/fixture/project/ProjectFixture.java | 37 ++++---- 11 files changed, 242 insertions(+), 139 deletions(-) create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/BatchInsertionException.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInsertService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInserter.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/ParallelBatchInsertProjectService.java delete mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/ProjectFactory.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/SequentialBatchInsertProjectService.java diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/BatchInsertionException.java b/get-p-batch/src/main/java/es/princip/getp/batch/BatchInsertionException.java new file mode 100644 index 00000000..41d0e2c3 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/BatchInsertionException.java @@ -0,0 +1,12 @@ +package es.princip.getp.batch; + +public class BatchInsertionException extends RuntimeException { + + public BatchInsertionException(final String message) { + super(message); + } + + public BatchInsertionException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java b/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java index 3e68491b..cb6ac582 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java @@ -1,22 +1,17 @@ package es.princip.getp.batch; -import es.princip.getp.batch.project.BatchInsertProjectService; import es.princip.getp.batch.project.DropProjectService; -import es.princip.getp.batch.project.ProjectFactory; -import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.batch.project.ParallelBatchInsertProjectService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import java.util.List; - @SpringBootApplication public class GetpBatchApplication implements CommandLineRunner { @Autowired private DropProjectService dropProjectService; - @Autowired private ProjectFactory projectFactory; - @Autowired private BatchInsertProjectService batchInsertProjectService; + @Autowired private ParallelBatchInsertProjectService batchInsertProjectService; public static void main(String[] args) { SpringApplication.run(GetpBatchApplication.class, args); @@ -25,7 +20,6 @@ public static void main(String[] args) { @Override public void run(final String... args) { dropProjectService.dropProject(); - final List projects = projectFactory.createProjects(100_000); - batchInsertProjectService.batchInsert(projects); + batchInsertProjectService.insert(100_000); } } diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInsertService.java b/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInsertService.java new file mode 100644 index 00000000..50339fa4 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInsertService.java @@ -0,0 +1,51 @@ +package es.princip.getp.batch.parallel; + +import es.princip.getp.batch.BatchInsertionException; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Slf4j +@Service +public class ParallelBatchInsertService { + + @Getter + private final int numThreads = Runtime.getRuntime().availableProcessors(); + private final ExecutorService executorService = Executors.newFixedThreadPool(numThreads); + + public void insert(final int size, final ParallelBatchInserter batchInserter) { + final List> futures = new ArrayList<>(); + final int batchSize = size / numThreads; + for (int i = 0; i < numThreads; i++) { + final int start = i * batchSize + 1; + final int end = (i == numThreads - 1) ? size : start + batchSize - 1; + final CompletableFuture future = CompletableFuture.runAsync(() -> { + final String threadName = Thread.currentThread().getName(); + log.info("Thread {} is inserting projects from {} to {}", threadName, start, end); + try { + batchInserter.insert(start, end); + } catch (final Exception exception) { + throw new BatchInsertionException( + String.format( + "Thread %s encountered an error during batch insert for range %d to %d: ", + threadName, + start, + end + ), + exception + ); + } + }, executorService); + futures.add(future); + } + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + executorService.shutdown(); + log.info("All threads completed. Executor service shutdown."); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInserter.java b/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInserter.java new file mode 100644 index 00000000..3f0fcf16 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInserter.java @@ -0,0 +1,6 @@ +package es.princip.getp.batch.parallel; + +@FunctionalInterface +public interface ParallelBatchInserter { + void insert(int start, int end); +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java new file mode 100644 index 00000000..0973abe0 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java @@ -0,0 +1,70 @@ +package es.princip.getp.batch.project; + +import es.princip.getp.domain.project.commission.model.Project; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.util.List; + +@Service +@RequiredArgsConstructor +class BatchInsertProjectJdbcService { + + private final JdbcTemplate jdbcTemplate; + private static final String sql = + """ + insert into project ( + project_id, + application_end_date, + application_start_date, + estimated_end_date, + estimated_start_date, + payment, + category, + description, + meeting_type, + status, + title, + client_id, + recruitment_count, + created_at, + updated_at + ) + values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + """; + + public void batchUpdate(final List projects) { + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final Project project = projects.get(i); + ps.setLong(1, project.getId().getValue()); + ps.setDate(2, Date.valueOf(project.getApplicationDuration().getEndDate())); + ps.setDate(3, Date.valueOf(project.getApplicationDuration().getStartDate())); + ps.setDate(4, Date.valueOf(project.getEstimatedDuration().getEndDate())); + ps.setDate(5, Date.valueOf(project.getEstimatedDuration().getStartDate())); + ps.setLong(6, project.getPayment()); + ps.setString(7, project.getCategory().toString()); + ps.setString(8, project.getDescription()); + ps.setString(9, project.getMeetingType().toString()); + ps.setString(10, project.getStatus().toString()); + ps.setString(11, project.getTitle()); + ps.setLong(12, project.getClientId().getValue()); + ps.setLong(13, project.getRecruitmentCount()); + ps.setString(14, String.valueOf(LocalDateTime.now())); + ps.setString(15, String.valueOf(LocalDateTime.now())); + } + + @Override + public int getBatchSize() { + return projects.size(); + } + }); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java index 4846ebdd..00ee8d8a 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java @@ -1,89 +1,6 @@ package es.princip.getp.batch.project; -import es.princip.getp.batch.config.ExtendsWithExecutionTimer; -import es.princip.getp.domain.project.commission.model.Project; -import jakarta.transaction.Transactional; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.jdbc.core.BatchPreparedStatementSetter; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Service; +public interface BatchInsertProjectService { -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.time.LocalDateTime; -import java.util.List; - -@Slf4j -@Service -@Transactional -@RequiredArgsConstructor -public class BatchInsertProjectService { - - private final JdbcTemplate jdbcTemplate; - private final int BATCH_SIZE = 1000; - - @ExtendsWithExecutionTimer - public void batchInsert(final List projects) { - final String sql = - """ - insert into project ( - project_id, - application_end_date, - application_start_date, - estimated_end_date, - estimated_start_date, - payment, - category, - description, - meeting_type, - status, - title, - client_id, - recruitment_count, - created_at, - updated_at - ) - values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - """; - final int batchSize = Math.min(BATCH_SIZE, projects.size()); - - for (int i = 0; i < projects.size(); i += batchSize) { - final int end = Math.min(i + batchSize, projects.size()); - final List batchList = projects.subList(i, end); - - jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { - @Override - public void setValues(final PreparedStatement ps, final int i) throws SQLException { - final Project project = batchList.get(i); - ps.setLong(1, project.getId().getValue()); - ps.setDate(2, Date.valueOf(project.getApplicationDuration().getEndDate())); - ps.setDate(3, Date.valueOf(project.getApplicationDuration().getStartDate())); - ps.setDate(4, Date.valueOf(project.getEstimatedDuration().getEndDate())); - ps.setDate(5, Date.valueOf(project.getEstimatedDuration().getStartDate())); - ps.setLong(6, project.getPayment()); - ps.setString(7, project.getCategory().toString()); - ps.setString(8, project.getDescription()); - ps.setString(9, project.getMeetingType().toString()); - ps.setString(10, project.getStatus().toString()); - ps.setString(11, project.getTitle()); - ps.setLong(12, project.getClientId().getValue()); - ps.setLong(13, project.getRecruitmentCount()); - ps.setString(14, String.valueOf(LocalDateTime.now())); - ps.setString(15, String.valueOf(LocalDateTime.now())); - } - - @Override - public int getBatchSize() { - return batchList.size(); - } - }); - - log.info("Batch inserted: {} to {}", i, end - 1); - log.info("Total gain: {}%", (i + batchSize) * 100D / projects.size()); - } - - log.info("Bach completed"); - } + void insert(int size); } diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java index 13e7874e..b7d76601 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java @@ -14,5 +14,6 @@ public class DropProjectService { public void dropProject() { jdbcTemplate.execute("delete from project"); + log.info("Table \"project\" is dropped"); } } diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/ParallelBatchInsertProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/ParallelBatchInsertProjectService.java new file mode 100644 index 00000000..4d8cd61a --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/ParallelBatchInsertProjectService.java @@ -0,0 +1,40 @@ +package es.princip.getp.batch.project; + +import es.princip.getp.batch.config.ExtendsWithExecutionTimer; +import es.princip.getp.batch.parallel.ParallelBatchInsertService; +import es.princip.getp.domain.client.model.ClientId; +import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.domain.project.commission.model.ProjectId; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.LongStream; + +import static es.princip.getp.domain.project.commission.model.ProjectStatus.APPLICATION_OPENED; +import static es.princip.getp.fixture.project.ProjectFixture.project; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ParallelBatchInsertProjectService implements BatchInsertProjectService { + + private final BatchInsertProjectJdbcService jdbcService; + private final ParallelBatchInsertService batchInsertService; + + @ExtendsWithExecutionTimer + public void insert(final int size) { + batchInsertService.insert(size, (start, end) -> { + final List projects = LongStream.rangeClosed(start, end) + .boxed() + .map(id -> project( + new ProjectId(id), + new ClientId(id), + APPLICATION_OPENED + )) + .toList(); + jdbcService.batchUpdate(projects); + }); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/ProjectFactory.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/ProjectFactory.java deleted file mode 100644 index 94cb7e86..00000000 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/ProjectFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -package es.princip.getp.batch.project; - -import es.princip.getp.domain.client.model.ClientId; -import es.princip.getp.domain.project.commission.model.Project; -import es.princip.getp.domain.project.commission.model.ProjectId; -import es.princip.getp.domain.project.commission.model.ProjectStatus; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.List; - -import static es.princip.getp.fixture.project.ProjectFixture.project; - -@Service -public class ProjectFactory { - - public List createProjects(final int size) { - final List projects = new ArrayList<>(); - for (int i = 1; i <= size; i++) { - final Long id = (long) i; - projects.add(project( - new ProjectId(id), - new ClientId(id), - ProjectStatus.APPLICATION_OPENED) - ); - } - return projects; - } -} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/SequentialBatchInsertProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/SequentialBatchInsertProjectService.java new file mode 100644 index 00000000..0c2fa485 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/SequentialBatchInsertProjectService.java @@ -0,0 +1,36 @@ +package es.princip.getp.batch.project; + +import es.princip.getp.batch.config.ExtendsWithExecutionTimer; +import es.princip.getp.domain.client.model.ClientId; +import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.domain.project.commission.model.ProjectId; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.LongStream; + +import static es.princip.getp.domain.project.commission.model.ProjectStatus.APPLICATION_OPENED; +import static es.princip.getp.fixture.project.ProjectFixture.project; + +@Slf4j +@Service +@RequiredArgsConstructor +public class SequentialBatchInsertProjectService implements BatchInsertProjectService { + + private final BatchInsertProjectJdbcService jdbcService; + + @ExtendsWithExecutionTimer + public void insert(final int size) { + final List projects = LongStream.rangeClosed(1, size) + .boxed() + .map(id -> project( + new ProjectId(id), + new ClientId(id), + APPLICATION_OPENED + )) + .toList(); + jdbcService.batchUpdate(projects); + } +} diff --git a/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectFixture.java b/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectFixture.java index 6929726c..257b81f8 100644 --- a/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectFixture.java +++ b/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectFixture.java @@ -20,26 +20,29 @@ public class ProjectFixture { public static final LocalDate ESTIMATED_START_DATE = LocalDate.of(2024, 8, 1); public static final LocalDate ESTIMATED_END_DATE = LocalDate.of(2024, 8, 31); - private static final Project.ProjectBuilder builder = Project.builder() - .category(ProjectCategory.BACKEND) - .attachmentFiles(attachmentFiles()) - .payment(PAYMENT) - .recruitmentCount(RECRUITMENT_COUNT) - .title(TITLE) - .description(DESCRIPTION) - .meetingType(MeetingType.IN_PERSON) - .estimatedDuration(Duration.of( - ESTIMATED_START_DATE, - ESTIMATED_END_DATE - )) - .hashtags(hashtags()); + public static Project.ProjectBuilder builder() { + return Project.builder() + .category(ProjectCategory.BACKEND) + .attachmentFiles(attachmentFiles()) + .payment(PAYMENT) + .recruitmentCount(RECRUITMENT_COUNT) + .title(TITLE) + .description(DESCRIPTION) + .meetingType(MeetingType.IN_PERSON) + .estimatedDuration(Duration.of( + ESTIMATED_START_DATE, + ESTIMATED_END_DATE + )) + .hashtags(hashtags()); + } public static Project project( final ProjectId projectId, final ClientId clientId, final ProjectStatus status ) { - return builder.id(projectId) + return builder() + .id(projectId) .clientId(clientId) .status(status) .applicationDuration(Duration.of( @@ -50,7 +53,8 @@ public static Project project( } public static Project project(final ClientId clientId, final ProjectStatus status) { - return builder.clientId(clientId) + return builder() + .clientId(clientId) .status(status) .applicationDuration(Duration.of( APPLICATION_START_DATE, @@ -64,7 +68,8 @@ public static Project project( final ProjectStatus status, final Duration applicationDuration ) { - return builder.clientId(clientId) + return builder() + .clientId(clientId) .status(status) .applicationDuration(applicationDuration) .build(); From 5efa2af6d5991afb534b02c4e1e942e82911e86f Mon Sep 17 00:00:00 2001 From: scv1702 Date: Mon, 11 Nov 2024 18:03:42 +0900 Subject: [PATCH 3/4] =?UTF-8?q?GETP-324=20feat:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=ED=95=B4=EC=8B=9C=ED=83=9C=EA=B7=B8,=20?= =?UTF-8?q?=EC=B2=A8=EB=B6=80=20=ED=8C=8C=EC=9D=BC=20=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=82=BD=EC=9E=85=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=B0=8F=20=EC=86=8D=EB=8F=84=20=EC=95=BD=2024.34=EB=B0=B0=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../getp/batch/GetpBatchApplication.java | 6 +-- ...ce.java => BatchDeleteProjectService.java} | 8 ++- ...nsertProjectAttachmentFileJdbcService.java | 53 +++++++++++++++++++ .../BatchInsertProjectHashtagJdbcService.java | 53 +++++++++++++++++++ .../BatchInsertProjectJdbcService.java | 4 ++ .../src/main/resources/application.yml | 34 ++++++++++-- 6 files changed, 150 insertions(+), 8 deletions(-) rename get-p-batch/src/main/java/es/princip/getp/batch/project/{DropProjectService.java => BatchDeleteProjectService.java} (56%) create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectAttachmentFileJdbcService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectHashtagJdbcService.java diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java b/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java index cb6ac582..a105fc73 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java @@ -1,6 +1,6 @@ package es.princip.getp.batch; -import es.princip.getp.batch.project.DropProjectService; +import es.princip.getp.batch.project.BatchDeleteProjectService; import es.princip.getp.batch.project.ParallelBatchInsertProjectService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; @@ -10,7 +10,7 @@ @SpringBootApplication public class GetpBatchApplication implements CommandLineRunner { - @Autowired private DropProjectService dropProjectService; + @Autowired private BatchDeleteProjectService batchDeleteProjectService; @Autowired private ParallelBatchInsertProjectService batchInsertProjectService; public static void main(String[] args) { @@ -19,7 +19,7 @@ public static void main(String[] args) { @Override public void run(final String... args) { - dropProjectService.dropProject(); + batchDeleteProjectService.delete(); batchInsertProjectService.insert(100_000); } } diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchDeleteProjectService.java similarity index 56% rename from get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java rename to get-p-batch/src/main/java/es/princip/getp/batch/project/BatchDeleteProjectService.java index b7d76601..d43406e8 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/DropProjectService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchDeleteProjectService.java @@ -8,12 +8,16 @@ @Slf4j @Service @RequiredArgsConstructor -public class DropProjectService { +public class BatchDeleteProjectService { private final JdbcTemplate jdbcTemplate; - public void dropProject() { + public void delete() { + jdbcTemplate.execute("delete from project_hashtag"); + jdbcTemplate.execute("delete from project_attachment_file"); jdbcTemplate.execute("delete from project"); + log.info("Table \"project_hashtag\" is dropped"); + log.info("Table \"project_attachment_file\" is dropped"); log.info("Table \"project\" is dropped"); } } diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectAttachmentFileJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectAttachmentFileJdbcService.java new file mode 100644 index 00000000..d59f95ed --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectAttachmentFileJdbcService.java @@ -0,0 +1,53 @@ +package es.princip.getp.batch.project; + +import es.princip.getp.domain.common.model.AttachmentFile; +import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.domain.project.commission.model.ProjectId; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; + +@Service +@RequiredArgsConstructor +class BatchInsertProjectAttachmentFileJdbcService { + + private record ProjectIdAttachmentFile( + ProjectId projectId, + AttachmentFile attachmentFile + ) { + } + + private final JdbcTemplate jdbcTemplate; + private static final String sql = + """ + insert into project_attachment_file (project_id, attachment_files) + values (?, ?); + """; + + public void batchUpdate(final List projects) { + final List attachmentFiles = projects.stream() + .flatMap(project -> project.getAttachmentFiles().stream() + .map(file -> new ProjectIdAttachmentFile(project.getId(), file))) + .toList(); + + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final Long projectId = attachmentFiles.get(i).projectId().getValue(); + final String attachmentFileUrl = attachmentFiles.get(i).attachmentFile().getUrl().getValue(); + ps.setLong(1, projectId); + ps.setString(2, attachmentFileUrl); + } + + @Override + public int getBatchSize() { + return attachmentFiles.size(); + } + }); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectHashtagJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectHashtagJdbcService.java new file mode 100644 index 00000000..713d8235 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectHashtagJdbcService.java @@ -0,0 +1,53 @@ +package es.princip.getp.batch.project; + +import es.princip.getp.domain.common.model.Hashtag; +import es.princip.getp.domain.project.commission.model.Project; +import es.princip.getp.domain.project.commission.model.ProjectId; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; + +@Service +@RequiredArgsConstructor +class BatchInsertProjectHashtagJdbcService { + + private record ProjectIdHashtag( + ProjectId projectId, + Hashtag hashtag + ) { + } + + private final JdbcTemplate jdbcTemplate; + private static final String sql = + """ + insert into project_hashtag (project_id, hashtags) + values (?, ?) + """; + + public void batchUpdate(final List projects) { + final List hashtags = projects.stream() + .flatMap(project -> project.getHashtags().stream() + .map(hashtag -> new ProjectIdHashtag(project.getId(), hashtag))) + .toList(); + + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final Long projectId = hashtags.get(i).projectId().getValue(); + final String hashtag = hashtags.get(i).hashtag().getValue(); + ps.setLong(1, projectId); + ps.setString(2, hashtag); + } + + @Override + public int getBatchSize() { + return hashtags.size(); + } + }); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java index 0973abe0..d501ec98 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java @@ -16,6 +16,8 @@ @RequiredArgsConstructor class BatchInsertProjectJdbcService { + private final BatchInsertProjectHashtagJdbcService hashtagJdbcService; + private final BatchInsertProjectAttachmentFileJdbcService attachmentFileJdbcService; private final JdbcTemplate jdbcTemplate; private static final String sql = """ @@ -66,5 +68,7 @@ public int getBatchSize() { return projects.size(); } }); + hashtagJdbcService.batchUpdate(projects); + attachmentFileJdbcService.batchUpdate(projects); } } diff --git a/get-p-batch/src/main/resources/application.yml b/get-p-batch/src/main/resources/application.yml index e1c1d4f7..fc2249b8 100644 --- a/get-p-batch/src/main/resources/application.yml +++ b/get-p-batch/src/main/resources/application.yml @@ -1,4 +1,32 @@ spring: - config: - import: - - persistence-config.yml \ No newline at end of file + datasource: + url: ${DB_URL}?&rewriteBatchedStatements=true&profileSQL=true&logger=Slf4JLogger + username: ${DB_USERNAME} + password: ${DB_PASSWORD} + + flyway: + enabled: true + baseline-on-migrate: true + + jpa: + hibernate: + ddl-auto: validate + properties: + hibernate: + show_sql: true + format_sql: true + highlight_sql: true + use_sql_comments: true + jdbc: + time_zone: Asia/Seoul + batch_size: 50 + default_batch_fetch_size: 20 + dialect: org.hibernate.dialect.MySQLDialect + +logging: + level: + org: + type: + descriptor: + sql: + BasicBinder: TRACE \ No newline at end of file From ccd520bea916d312cde5adf6cedd85b83c8af8a2 Mon Sep 17 00:00:00 2001 From: scv1702 Date: Mon, 11 Nov 2024 19:16:24 +0900 Subject: [PATCH 4/4] =?UTF-8?q?GETP-324=20feat:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=EC=A7=80=EC=9B=90=20=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=82=BD=EC=9E=85=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../getp/batch/GetpBatchApplication.java | 15 +++- .../getp/batch/UniqueLongGenerator.java | 11 +++ .../parallel/ParallelBatchInsertService.java | 2 +- .../BatchDeleteProjectApplicationService.java | 27 +++++++ ...dividualProjectApplicationJdbcService.java | 45 ++++++++++++ ...tApplicationAttachmentFileJdbcService.java | 58 +++++++++++++++ ...chInsertProjectApplicationJdbcService.java | 65 +++++++++++++++++ .../BatchInsertProjectApplicationService.java | 65 +++++++++++++++++ ...sertTeamProjectApplicationJdbcService.java | 48 ++++++++++++ ...ProjectApplicationTeammateJdbcService.java | 59 +++++++++++++++ .../BatchDeleteProjectService.java | 2 +- ...nsertProjectAttachmentFileJdbcService.java | 2 +- .../BatchInsertProjectHashtagJdbcService.java | 2 +- .../BatchInsertProjectJdbcService.java | 2 +- .../BatchInsertProjectService.java | 2 +- .../ParallelBatchInsertProjectService.java | 2 +- .../SequentialBatchInsertProjectService.java | 2 +- .../src/main/resources/application.yml | 1 - .../project/ProjectApplicationFixture.java | 73 ++++++++++++++++--- ...V8__drop_team_project_application_team.sql | 1 + 20 files changed, 461 insertions(+), 23 deletions(-) create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/UniqueLongGenerator.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchDeleteProjectApplicationService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertIndividualProjectApplicationJdbcService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationAttachmentFileJdbcService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationJdbcService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertTeamProjectApplicationJdbcService.java create mode 100644 get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertTeamProjectApplicationTeammateJdbcService.java rename get-p-batch/src/main/java/es/princip/getp/batch/project/{ => commission}/BatchDeleteProjectService.java (93%) rename get-p-batch/src/main/java/es/princip/getp/batch/project/{ => commission}/BatchInsertProjectAttachmentFileJdbcService.java (97%) rename get-p-batch/src/main/java/es/princip/getp/batch/project/{ => commission}/BatchInsertProjectHashtagJdbcService.java (97%) rename get-p-batch/src/main/java/es/princip/getp/batch/project/{ => commission}/BatchInsertProjectJdbcService.java (98%) rename get-p-batch/src/main/java/es/princip/getp/batch/project/{ => commission}/BatchInsertProjectService.java (60%) rename get-p-batch/src/main/java/es/princip/getp/batch/project/{ => commission}/ParallelBatchInsertProjectService.java (96%) rename get-p-batch/src/main/java/es/princip/getp/batch/project/{ => commission}/SequentialBatchInsertProjectService.java (95%) create mode 100644 get-p-persistence/src/main/resources/db/migration/V8__drop_team_project_application_team.sql diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java b/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java index a105fc73..0f55cdb2 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/GetpBatchApplication.java @@ -1,7 +1,9 @@ package es.princip.getp.batch; -import es.princip.getp.batch.project.BatchDeleteProjectService; -import es.princip.getp.batch.project.ParallelBatchInsertProjectService; +import es.princip.getp.batch.project.commission.BatchDeleteProjectService; +import es.princip.getp.batch.project.commission.ParallelBatchInsertProjectService; +import es.princip.getp.batch.project.apply.BatchDeleteProjectApplicationService; +import es.princip.getp.batch.project.apply.BatchInsertProjectApplicationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; @@ -10,16 +12,23 @@ @SpringBootApplication public class GetpBatchApplication implements CommandLineRunner { + @Autowired private BatchDeleteProjectApplicationService batchDeleteProjectApplicationService; @Autowired private BatchDeleteProjectService batchDeleteProjectService; + + @Autowired private BatchInsertProjectApplicationService batchInsertProjectApplicationService; @Autowired private ParallelBatchInsertProjectService batchInsertProjectService; public static void main(String[] args) { SpringApplication.run(GetpBatchApplication.class, args); } + private static final int PROJECT_SIZE = 100_000; @Override public void run(final String... args) { + batchDeleteProjectApplicationService.delete(); batchDeleteProjectService.delete(); - batchInsertProjectService.insert(100_000); + + batchInsertProjectService.insert(PROJECT_SIZE); + batchInsertProjectApplicationService.insert(PROJECT_SIZE); } } diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/UniqueLongGenerator.java b/get-p-batch/src/main/java/es/princip/getp/batch/UniqueLongGenerator.java new file mode 100644 index 00000000..86cfdcc2 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/UniqueLongGenerator.java @@ -0,0 +1,11 @@ +package es.princip.getp.batch; + +import java.util.concurrent.atomic.AtomicLong; + +public class UniqueLongGenerator { + private static final AtomicLong counter = new AtomicLong(); + + public static long generateUniqueLong() { + return counter.incrementAndGet(); + } +} \ No newline at end of file diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInsertService.java b/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInsertService.java index 50339fa4..e4bb801a 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInsertService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/parallel/ParallelBatchInsertService.java @@ -17,9 +17,9 @@ public class ParallelBatchInsertService { @Getter private final int numThreads = Runtime.getRuntime().availableProcessors(); - private final ExecutorService executorService = Executors.newFixedThreadPool(numThreads); public void insert(final int size, final ParallelBatchInserter batchInserter) { + final ExecutorService executorService = Executors.newFixedThreadPool(numThreads); final List> futures = new ArrayList<>(); final int batchSize = size / numThreads; for (int i = 0; i < numThreads; i++) { diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchDeleteProjectApplicationService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchDeleteProjectApplicationService.java new file mode 100644 index 00000000..91feb494 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchDeleteProjectApplicationService.java @@ -0,0 +1,27 @@ +package es.princip.getp.batch.project.apply; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class BatchDeleteProjectApplicationService { + + private final JdbcTemplate jdbcTemplate; + + public void delete() { + jdbcTemplate.execute("delete from team_project_application_teammate"); + jdbcTemplate.execute("delete from team_project_application"); + jdbcTemplate.execute("delete from individual_project_application"); + jdbcTemplate.execute("delete from project_application_attachment_file"); + jdbcTemplate.execute("delete from project_application"); + log.info("Table \"team_project_application_teammate\" is dropped"); + log.info("Table \"team_project_application\" is dropped"); + log.info("Table \"individual_project_application\" is dropped"); + log.info("Table \"project_application_attachment_file\" is dropped"); + log.info("Table \"project_application\" is dropped"); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertIndividualProjectApplicationJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertIndividualProjectApplicationJdbcService.java new file mode 100644 index 00000000..55f5e111 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertIndividualProjectApplicationJdbcService.java @@ -0,0 +1,45 @@ +package es.princip.getp.batch.project.apply; + +import es.princip.getp.domain.project.apply.model.IndividualProjectApplication; +import es.princip.getp.domain.project.apply.model.ProjectApplication; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; + +@Service +@RequiredArgsConstructor +class BatchInsertIndividualProjectApplicationJdbcService { + + private final JdbcTemplate jdbcTemplate; + private static final String sql = + """ + insert into individual_project_application ( + project_application_id + ) values (?); + """; + + public void batchUpdate(final List applications) { + final List individuals = applications.stream() + .filter(IndividualProjectApplication.class::isInstance) + .map(IndividualProjectApplication.class::cast) + .toList(); + + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final IndividualProjectApplication application = individuals.get(i); + ps.setLong(1, application.getId().getValue()); + } + + @Override + public int getBatchSize() { + return individuals.size(); + } + }); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationAttachmentFileJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationAttachmentFileJdbcService.java new file mode 100644 index 00000000..0c7dadd4 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationAttachmentFileJdbcService.java @@ -0,0 +1,58 @@ +package es.princip.getp.batch.project.apply; + +import es.princip.getp.domain.common.model.AttachmentFile; +import es.princip.getp.domain.project.apply.model.ProjectApplication; +import es.princip.getp.domain.project.apply.model.ProjectApplicationId; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; + +@Service +@RequiredArgsConstructor +class BatchInsertProjectApplicationAttachmentFileJdbcService { + + private record ProjectApplicationIdAttachmentFile( + ProjectApplicationId applicationId, + AttachmentFile attachmentFile + ) { + } + + private final JdbcTemplate jdbcTemplate; + private static final String sql = + """ + insert into project_application_attachment_file( + project_application_id, + attachment_files + ) values (?, ?); + """; + + public void batchUpdate(final List applications) { + final List attachmentFiles = applications.stream() + .flatMap(application -> application.getAttachmentFiles().stream() + .map(attachmentFile -> new ProjectApplicationIdAttachmentFile( + application.getId(), + attachmentFile + ))) + .toList(); + + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final ProjectApplicationId applicationId = attachmentFiles.get(i).applicationId(); + final AttachmentFile attachmentFile = attachmentFiles.get(i).attachmentFile(); + ps.setLong(1, applicationId.getValue()); + ps.setString(2, attachmentFile.getUrl().getValue()); + } + + @Override + public int getBatchSize() { + return attachmentFiles.size(); + } + }); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationJdbcService.java new file mode 100644 index 00000000..73ca614d --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationJdbcService.java @@ -0,0 +1,65 @@ +package es.princip.getp.batch.project.apply; + +import es.princip.getp.domain.project.apply.model.IndividualProjectApplication; +import es.princip.getp.domain.project.apply.model.ProjectApplication; +import es.princip.getp.domain.project.apply.model.TeamProjectApplication; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; + +@Service +@RequiredArgsConstructor +class BatchInsertProjectApplicationJdbcService { + + private final BatchInsertProjectApplicationAttachmentFileJdbcService attachmentFileJdbcService; + private final BatchInsertTeamProjectApplicationJdbcService teamJdbcService; + private final BatchInsertIndividualProjectApplicationJdbcService individualJdbcService; + private final JdbcTemplate jdbcTemplate; + private static final String sql = + """ + insert into project_application ( + project_application_id, + expected_end_date, + expected_start_date, + description, + status, + people_id, + project_id, + dtype + ) values (?, ?, ?, ?, ?, ?, ?, ?); + """; + + public void batchUpdate(final List applications) { + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final ProjectApplication application = applications.get(i); + final String dtype = (application instanceof TeamProjectApplication) ? + TeamProjectApplication.TYPE : IndividualProjectApplication.TYPE; + ps.setLong(1, application.getId().getValue()); + ps.setDate(2, Date.valueOf(application.getExpectedDuration().getEndDate())); + ps.setDate(3, Date.valueOf(application.getExpectedDuration().getStartDate())); + ps.setString(4, application.getDescription()); + ps.setString(5, application.getStatus().toString()); + ps.setLong(6, application.getApplicantId().getValue()); + ps.setLong(7, application.getProjectId().getValue()); + ps.setString(8,dtype); + } + + @Override + public int getBatchSize() { + return applications.size(); + } + }); + + attachmentFileJdbcService.batchUpdate(applications); + individualJdbcService.batchUpdate(applications); + teamJdbcService.batchUpdate(applications); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationService.java new file mode 100644 index 00000000..b392207e --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertProjectApplicationService.java @@ -0,0 +1,65 @@ +package es.princip.getp.batch.project.apply; + +import es.princip.getp.batch.UniqueLongGenerator; +import es.princip.getp.batch.config.ExtendsWithExecutionTimer; +import es.princip.getp.batch.parallel.ParallelBatchInsertService; +import es.princip.getp.domain.people.model.PeopleId; +import es.princip.getp.domain.project.apply.model.*; +import es.princip.getp.domain.project.commission.model.ProjectId; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static es.princip.getp.fixture.project.ProjectApplicationFixture.*; + +@Slf4j +@Service +@RequiredArgsConstructor +public class BatchInsertProjectApplicationService { + + private final BatchInsertProjectApplicationJdbcService jdbcService; + private final ParallelBatchInsertService batchInsertService; + + @ExtendsWithExecutionTimer + public void insert(final int projectSize) { + batchInsertService.insert(projectSize, (start, end) -> { + final List applications = new ArrayList<>(); + for (int i = start; i <= end; i++) { + final ProjectId projectId = new ProjectId((long) i); + applications.add(individualProjectApplication( + new ProjectApplicationId(UniqueLongGenerator.generateUniqueLong()), + new PeopleId(1L), + projectId + )); + applications.add(teamProjectApplication( + new ProjectApplicationId(UniqueLongGenerator.generateUniqueLong()), + new PeopleId(2L), + projectId, + ProjectApplicationStatus.COMPLETED, + Set.of( + teammate( + new TeammateId(UniqueLongGenerator.generateUniqueLong()), + new PeopleId(3L), + TeammateStatus.APPROVED + ), + teammate( + new TeammateId(UniqueLongGenerator.generateUniqueLong()), + new PeopleId(4L), + TeammateStatus.APPROVED + ), + teammate( + new TeammateId(UniqueLongGenerator.generateUniqueLong()), + new PeopleId(5L), + TeammateStatus.APPROVED + ) + ) + )); + } + jdbcService.batchUpdate(applications); + }); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertTeamProjectApplicationJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertTeamProjectApplicationJdbcService.java new file mode 100644 index 00000000..8893e091 --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertTeamProjectApplicationJdbcService.java @@ -0,0 +1,48 @@ +package es.princip.getp.batch.project.apply; + +import es.princip.getp.domain.project.apply.model.ProjectApplication; +import es.princip.getp.domain.project.apply.model.TeamProjectApplication; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; + +@Service +@RequiredArgsConstructor +class BatchInsertTeamProjectApplicationJdbcService { + + private final BatchInsertTeamProjectApplicationTeammateJdbcService teammateJdbcService; + private final JdbcTemplate jdbcTemplate; + private static final String sql = + """ + insert into team_project_application ( + project_application_id + ) values (?); + """; + + public void batchUpdate(final List applications) { + final List teams = applications.stream() + .filter(TeamProjectApplication.class::isInstance) + .map(TeamProjectApplication.class::cast) + .toList(); + + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final TeamProjectApplication application = teams.get(i); + ps.setLong(1, application.getId().getValue()); + } + + @Override + public int getBatchSize() { + return teams.size(); + } + }); + + teammateJdbcService.batchUpdate(teams); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertTeamProjectApplicationTeammateJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertTeamProjectApplicationTeammateJdbcService.java new file mode 100644 index 00000000..4e0c140c --- /dev/null +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/apply/BatchInsertTeamProjectApplicationTeammateJdbcService.java @@ -0,0 +1,59 @@ +package es.princip.getp.batch.project.apply; + +import es.princip.getp.domain.project.apply.model.ProjectApplicationId; +import es.princip.getp.domain.project.apply.model.TeamProjectApplication; +import es.princip.getp.domain.project.apply.model.Teammate; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; + +@Service +@RequiredArgsConstructor +class BatchInsertTeamProjectApplicationTeammateJdbcService { + + private record ProjectApplicationIdTeammate( + ProjectApplicationId applicationId, + Teammate teammate + ) { + } + + private final JdbcTemplate jdbcTemplate; + private static final String sql = + """ + insert into team_project_application_teammate ( + teammate_id, + people_id, + status, + project_application_id + ) values (?, ?, ?, ?) + """; + + public void batchUpdate(final List applications) { + final List teammates = applications.stream() + .flatMap(application -> application.getTeammates().stream() + .map(teammate -> new ProjectApplicationIdTeammate(application.getId(), teammate))) + .toList(); + + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final ProjectApplicationId applicationId = teammates.get(i).applicationId(); + final Teammate teammate = teammates.get(i).teammate(); + ps.setLong(1, teammate.getId().getValue()); + ps.setLong(2, teammate.getPeopleId().getValue()); + ps.setString(3, teammate.getStatus().toString()); + ps.setLong(4, applicationId.getValue()); + } + + @Override + public int getBatchSize() { + return teammates.size(); + } + }); + } +} diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchDeleteProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchDeleteProjectService.java similarity index 93% rename from get-p-batch/src/main/java/es/princip/getp/batch/project/BatchDeleteProjectService.java rename to get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchDeleteProjectService.java index d43406e8..60a0a8c2 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchDeleteProjectService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchDeleteProjectService.java @@ -1,4 +1,4 @@ -package es.princip.getp.batch.project; +package es.princip.getp.batch.project.commission; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectAttachmentFileJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectAttachmentFileJdbcService.java similarity index 97% rename from get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectAttachmentFileJdbcService.java rename to get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectAttachmentFileJdbcService.java index d59f95ed..d4c24504 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectAttachmentFileJdbcService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectAttachmentFileJdbcService.java @@ -1,4 +1,4 @@ -package es.princip.getp.batch.project; +package es.princip.getp.batch.project.commission; import es.princip.getp.domain.common.model.AttachmentFile; import es.princip.getp.domain.project.commission.model.Project; diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectHashtagJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectHashtagJdbcService.java similarity index 97% rename from get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectHashtagJdbcService.java rename to get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectHashtagJdbcService.java index 713d8235..54aac7c9 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectHashtagJdbcService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectHashtagJdbcService.java @@ -1,4 +1,4 @@ -package es.princip.getp.batch.project; +package es.princip.getp.batch.project.commission; import es.princip.getp.domain.common.model.Hashtag; import es.princip.getp.domain.project.commission.model.Project; diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectJdbcService.java similarity index 98% rename from get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java rename to get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectJdbcService.java index d501ec98..618b562d 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectJdbcService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectJdbcService.java @@ -1,4 +1,4 @@ -package es.princip.getp.batch.project; +package es.princip.getp.batch.project.commission; import es.princip.getp.domain.project.commission.model.Project; import lombok.RequiredArgsConstructor; diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectService.java similarity index 60% rename from get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java rename to get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectService.java index 00ee8d8a..24ee5230 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/BatchInsertProjectService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/BatchInsertProjectService.java @@ -1,4 +1,4 @@ -package es.princip.getp.batch.project; +package es.princip.getp.batch.project.commission; public interface BatchInsertProjectService { diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/ParallelBatchInsertProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/ParallelBatchInsertProjectService.java similarity index 96% rename from get-p-batch/src/main/java/es/princip/getp/batch/project/ParallelBatchInsertProjectService.java rename to get-p-batch/src/main/java/es/princip/getp/batch/project/commission/ParallelBatchInsertProjectService.java index 4d8cd61a..40ad36eb 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/ParallelBatchInsertProjectService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/ParallelBatchInsertProjectService.java @@ -1,4 +1,4 @@ -package es.princip.getp.batch.project; +package es.princip.getp.batch.project.commission; import es.princip.getp.batch.config.ExtendsWithExecutionTimer; import es.princip.getp.batch.parallel.ParallelBatchInsertService; diff --git a/get-p-batch/src/main/java/es/princip/getp/batch/project/SequentialBatchInsertProjectService.java b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/SequentialBatchInsertProjectService.java similarity index 95% rename from get-p-batch/src/main/java/es/princip/getp/batch/project/SequentialBatchInsertProjectService.java rename to get-p-batch/src/main/java/es/princip/getp/batch/project/commission/SequentialBatchInsertProjectService.java index 0c2fa485..892ebb8e 100644 --- a/get-p-batch/src/main/java/es/princip/getp/batch/project/SequentialBatchInsertProjectService.java +++ b/get-p-batch/src/main/java/es/princip/getp/batch/project/commission/SequentialBatchInsertProjectService.java @@ -1,4 +1,4 @@ -package es.princip.getp.batch.project; +package es.princip.getp.batch.project.commission; import es.princip.getp.batch.config.ExtendsWithExecutionTimer; import es.princip.getp.domain.client.model.ClientId; diff --git a/get-p-batch/src/main/resources/application.yml b/get-p-batch/src/main/resources/application.yml index fc2249b8..055dc92f 100644 --- a/get-p-batch/src/main/resources/application.yml +++ b/get-p-batch/src/main/resources/application.yml @@ -19,7 +19,6 @@ spring: use_sql_comments: true jdbc: time_zone: Asia/Seoul - batch_size: 50 default_batch_fetch_size: 20 dialect: org.hibernate.dialect.MySQLDialect diff --git a/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectApplicationFixture.java b/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectApplicationFixture.java index b9cd21d4..93d2a779 100644 --- a/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectApplicationFixture.java +++ b/get-p-domain/src/testFixtures/java/es/princip/getp/fixture/project/ProjectApplicationFixture.java @@ -22,17 +22,40 @@ public static Duration expectedDuration() { ); } + private static IndividualProjectApplication.IndividualProjectApplicationBuilder individualBuilder() { + return IndividualProjectApplication.builder() + .expectedDuration(expectedDuration()) + .status(ACCEPTED) + .description(DESCRIPTION) + .attachmentFiles(attachmentFiles()); + } + + private static TeamProjectApplication.TeamProjectApplicationBuilder teamBuilder() { + return TeamProjectApplication.builder() + .expectedDuration(expectedDuration()) + .description(DESCRIPTION) + .attachmentFiles(attachmentFiles()); + } + public static ProjectApplication individualProjectApplication( final PeopleId peopleId, final ProjectId projectId ) { - return IndividualProjectApplication.builder() + return individualBuilder() + .applicantId(peopleId) + .projectId(projectId) + .build(); + } + + public static ProjectApplication individualProjectApplication( + final ProjectApplicationId applicationId, + final PeopleId peopleId, + final ProjectId projectId + ) { + return individualBuilder() + .id(applicationId) .applicantId(peopleId) .projectId(projectId) - .expectedDuration(expectedDuration()) - .status(ACCEPTED) - .description(DESCRIPTION) - .attachmentFiles(attachmentFiles()) .build(); } @@ -41,20 +64,48 @@ public static TeamProjectApplication teamProjectApplication( final ProjectId projectId, final ProjectApplicationStatus status, final Set teammates - ) { - return TeamProjectApplication.builder() + ) { + return teamBuilder() .applicantId(peopleId) .projectId(projectId) - .expectedDuration(expectedDuration()) .status(status) - .description(DESCRIPTION) - .attachmentFiles(attachmentFiles()) .teammates(teammates) .build(); } - public static Teammate teammate(final PeopleId peopleId, final TeammateStatus status) { + public static TeamProjectApplication teamProjectApplication( + final ProjectApplicationId applicationId, + final PeopleId peopleId, + final ProjectId projectId, + final ProjectApplicationStatus status, + final Set teammates + ) { + return teamBuilder() + .id(applicationId) + .applicantId(peopleId) + .projectId(projectId) + .status(status) + .teammates(teammates) + .build(); + } + + public static Teammate teammate( + final PeopleId peopleId, + final TeammateStatus status + ) { + return Teammate.builder() + .peopleId(peopleId) + .status(status) + .build(); + } + + public static Teammate teammate( + final TeammateId teammateId, + final PeopleId peopleId, + final TeammateStatus status + ) { return Teammate.builder() + .id(teammateId) .peopleId(peopleId) .status(status) .build(); diff --git a/get-p-persistence/src/main/resources/db/migration/V8__drop_team_project_application_team.sql b/get-p-persistence/src/main/resources/db/migration/V8__drop_team_project_application_team.sql new file mode 100644 index 00000000..b78f62c0 --- /dev/null +++ b/get-p-persistence/src/main/resources/db/migration/V8__drop_team_project_application_team.sql @@ -0,0 +1 @@ +drop table team_project_application_team; \ No newline at end of file