[Spring Batch] 2. ์คํ๋ง ๋ฐฐ์น ์์
1. ํ๋ก์ ํธ ๊ตฌ์ฑ ๋ฐ ์์กด์ฑ ์ค์
1) ์คํ๋ง๋ถํธ๊ธฐ๋ฐ ํ๋ก์ ํธ ์์ฑ
- maven ํ๋ก์ ํธ ์์ฑ
- docker๋ฅผ ํตํด mysql
- spring batch ์์กด์ฑ ์ถ๊ฐ
docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=test1234 -d -p 3306:3306 mysql:latest
์๋ฃ : https://github.com/onjsdnjs/spring-batch-lecture
2) ์คํ๋ง ๋ฐฐ์น ํ์ฑํ
- @EnableBatchProcessing
@SpringBootApplication
@EnableBatchProcessing
public class SpringbatchApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbatchApplication.class, args);
}
}
- ์ด 4๊ฐ์ ์ค์ ํด๋์ค ์คํ (์คํ๋ง ๋ฐฐ์น ๋ชจ๋ ์ด๊ธฐํ ๋ฐ ์คํ ๊ตฌ์ฑ ์คํ)
- ๋น์ผ๋ก ๋ฑ๋ก๋ ๋ชจ๋ Job์ ๋ฑ๋ก (๋ชจ๋ Job ๊ฒ์ ๋ฐ ์คํ ์ํด)
* ์คํ๋ง ๋ฐฐ์น ์ด๊ธฐํ ์ค์ ํด๋์ค
1) BatchAutoConfiguration
- ์คํ๋ง ๋ฐฐ์น๊ฐ ์ด๊ธฐํ ๋ ๋ ์๋์ผ๋ก ์คํ๋๋ ์ค์ ํด๋์ค
- Job์ ์ํํ๋ JobLauncherApplicationRunner ๋น์ ์์ฑ (์๋์ผ๋ก Job ์คํ๋๋ ๋น)
2) SimpleBatchConfiguration
- JobBuilderFactory์ StepBuilderFactory ์์ฑ (๋ ๊ฐ์ ํด๋์ค๋ฅผ ๊ฐ์ง๊ณ Job๊ณผ Step ์์ฑ)
- ์คํ๋ง ๋ฐฐ์น์ ์ฃผ์ ๊ตฌ์ฑ ์์ ์์ฑ - ํ๋ก์ ๊ฐ์ฒด๋ก ์์ฑ๋จ
3) BatchConfigurerConfiguration
a) BasicBatchConfigurer
- SimpleBatchConfiguration์์ ์์ฑํ ํ๋ก์ ๊ฐ์ฒด์ ์ค์ ๋์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์ค์ ํด๋์ค
- ๋น์ผ๋ก ์์กด์ฑ ์ฃผ์ ๋ฐ์์ ์ฃผ์ ๊ฐ์ฒด๋ค์ ์ฐธ์กฐํด์ ์ฌ์ฉํ ์ ์๋ค.
b) JpaBatchConfigurer
- JPA ๊ด๋ จ ๊ฐ์ฒด๋ค ์์ฑํ๋ ์ค์ ํด๋์ค
-> ๋๊ฐ์ ํด๋์ค๋ ์ฌ์ฉ์ ์ ์ BatchConfigurer ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ฌ ์ฌ์ฉํ ์ ์์
์์
2. Hello Spring Batch ์์ํ๊ธฐ
- ๊ธฐ๋ณธํ๊ฒฝ (ํ๋ก์ ํธ ์์ฑ / ์์กด์ฑ / ์ด๋ ธํ ์ด์ ) ์ค๋น๋จ
- ์ฉ์ด
1) @Configuration ์ ์ธ
- ํ๋์ ๋ฐฐ์น Job์ ์ ์ํ๊ณ ๋น ์ค์
- Job ์ ์ : Job ์คํ ๋จ์/๋ด์ฉ ์ค์ ํ๊ณ ๊ตฌ์ฑํ๋ค๋ ์๋ฏธ
------------------------
์คํ๋ง ๋ฐฐ์น๊ฐ ์ ๊ณตํ๋ Job ๊ตฌ์ฑํ ์ ์๋ ์ ํธ์ฑ ํด๋์ค ์ ๊ณต (์์กด์ฑ ์ฃผ์ ๋ฐ์์ ์ ์ธ)
2) JobBuilderFactory
- Job์ ์์ฑํ๋ ๋น๋ ํฉํ ๋ฆฌ
3) StepBuilderFactory
- Step์ ์์ฑํ๋ ๋น๋ ํฉํ ๋ฆฌ
------------------------
4) Job
- helloJob ์ด๋ฆ์ผ๋ก Job ์์ฑ (Step ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ๋๊ฒจ์ค)
5) Step
- helloStep ์ด๋ฆ์ผ๋ก Step ์์ฑ
6) Tasklet
- Step ์์์ ๋จ์ผ ํ ์คํฌ๋ก ์ํ๋๋ ๋ก์ง ๊ตฌํ
์์
[ Job ๊ตฌ๋ -> Step ์คํ -> Tasklet ์คํ ]
Job์ด ๊ตฌ๋๋๋ฉด Step์ ์คํํ๊ณ Step์ด ๊ตฌ๋๋๋ฉด Tasklet์ ์คํํ๋๋ก ์ค์
(๋น์ฆ๋์ค ๋ก์ง์ด Tasklet์ ์ ์ฅ๋ผ์์)
๊ตฌํ
@RequiredArgsConstructor
- ์์ฑ์๋ก ๊ฐ์ฒด ์ ์ธํ๋ฉด ์คํ๋ง์ด ์์กด์ฑ ์ฃผ์ ํด์ฃผ๋๋ก ํด์ค
- ์์ฑ์ ์ง์ ์๋ง๋ค์ด๋ ์์กด์ฑ ์ฃผ์ ๋ผ๋๋ก ํ๋ Annotation
* ์ง๊ธ ๊ฐ์์์ ์ฌ์ฉ๋ BuilderFactory ๊ฐ jobReposirtory๋ฅผ ๋ช ์ํ์ง ์์ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ๋ก Deprecated๊ฐ ๋จ
ํด๊ฒฐ) Builder์์ JobRepository๊ฐ ์์ฑ๋๊ณ ์ค์ ๋๋ค
spring batch v5
package io.springbatch.springbatch;
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
@RequiredArgsConstructor
@Configuration
public class HelloJobConfiguration {
@Bean
public Job helloJob(JobRepository jobRepository, Step step){
return new JobBuilder("helloJob", jobRepository)
.start(step)
.build();
}
@Bean
public Tasklet helloTasklet(){
return ((contribution, chunkContext) -> {
return RepeatStatus.FINISHED;
});
}
@Bean
public Step helloStep(JobRepository jobRepository, Tasklet helloTasklet, PlatformTransactionManager transactionManager) {
return new StepBuilder("helloStep", jobRepository)
.tasklet(helloTasklet, transactionManager)
.build();
}
}
3. DB ์คํค๋ง ์์ฑ ๋ฐ ์ดํด
1) ์คํ๋ง ๋ฐฐ์น ๋ฉํ ๋ฐ์ดํฐ
- ์คํ๋ง ๋ฐฐ์น์ ์คํ ๋ฐ ๊ด๋ฆฌ๋ฅผ ์ํ ๋ชฉ์ ์ผ๋ก ์ฌ๋ฌ ๋๋ฉ์ธ๋ค(Job, Step, JobParameters...)์ ์ ๋ณด๋ค์ ์ ์ฅ/์ ๋ฐ์ดํธ/์กฐํ ํ ์ ์๋ ์คํค๋ง ์ ๊ณต
- ๊ณผ๊ฑฐ, ํ์ฌ์ ์คํ์ ๋ํ ์ธ์ธํ ์ ๋ณด, ์คํ์ ๋ํ ์ฑ๊ณต๊ณผ ์คํจ ์ฌ๋ถ ๋ฑ์ ๊ด๋ฆฌํจ์ผ๋ก์จ ๋ฐฐ์น ์ด์ฉ์ ์์ด ๋ฆฌ์คํฌ ๋ฐ์ ์ ๋น ๋ฅธ ๋์ฒ ๊ฐ๋ฅ
- DB์ ์ฐ๋ํ ๊ฒฝ์ฐ ํ์์ ์ผ๋ก ๋ฉํ ํ ์ด๋ธ์ด ์์ฑ ๋์ด์ผํจ
2) DB ์คํค๋ง ์ ๊ณต
- ํ์ผ ์์น : /org/springframework/batch/core/schema-*.sql
- DB ์ ํ๋ณ๋ก ์ ๊ณต
3) ์คํค๋ง ์์ฑ ์ค์
- ์๋ ์์ฑ : ์ฟผ๋ฆฌ ๋ณต์ฌ ํ ์ง์ ์คํ
- ์๋ ์์ฑ : spring.batch.jdbc.initialize-schema ์ค์ (properties ํ์ผ์ ์ค์ )
ALWAYS : ์คํฌ๋ฆฝํธ ํญ์ ์คํ / RDBMS ์ค์ ์ด ๋์ด์์ ๊ฒฝ์ฐ ๋ด์ฅ DB๋ณด๋ค ์ฐ์ ์ ์ผ๋ก ์คํ EMBEDDED : ๋ด์ฅ DB์ผ ๋๋ง ์คํ๋๋ฉฐ ์คํค๋ง๊ฐ ์๋ ์์ฑ๋จ (๊ธฐ๋ณธ๊ฐ) NEVER : ์คํฌ๋ฆฝํธ ํญ์ ์คํ ์ํจ / ๋ด์ฅ DB์ผ ๊ฒฝ์ฐ ์คํฌ๋ฆฝํธ๊ฐ ์์ฑ์ด ์๋๊ธฐ ๋๋ฌธ์ ์ค๋ฅ ๋ฐ์ : ๋ด์ฅ DB์ผ ๊ฒฝ์ฐ ์คํฌ๋ฆฝํธ๊ฐ ์์ฑ์ด ์๋๊ธฐ ๋๋ฌธ์ ์ค๋ฅ ๋ฐ์ : ์ด์์์ ์๋์ผ๋ก ์คํฌ๋ฆฝํธ ์์ฑ ํ ์ค์ ํ๋ ๊ฒ์ ๊ถ์ฅ |
- batch core library -> db ๋ณ๋ก sql ์ค์ ๊ฐ๋ฅํ๋๋ก ์ ๊ณต
- ์ธํ ๋ฆฌ์ ์ด db ๊ด๋ฆฌ ํด ์ฌ์ฉํด์ ๊ด๋ฆฌ
- ๋น๋ฐ๋ฒํธ ๊ฐ์ ๊ทธ๋๋ก
- schema ํญ ์ฒดํฌ
- ์ฟผ๋ฆฌ์ฐฝ ์ด๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ณต์ฌํ sql ๋ณต๋ถํด์ ์คํ
- db ์์ฑ
mysql ์์กด์ฑ ์ถ๊ฐ
application.properties
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springbatch
spring.datasource.username=root
spring.datasource.password=
spring.profiles.active=dev
spring.batch.jdbc.initialize-schema=never
spring.batch.job.enabled=true
- initialize-schema ์์ ํ ์ด๋ธ ์์ฑ ์๋ ์ค์
DBJobConfiguration
package io.springbatch.springbatch;
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
@RequiredArgsConstructor
public class DBJobConfiguration {
@Bean
public Job newJob(JobRepository jobRepository, Step step1, Step step2){
return new JobBuilder("newJob", jobRepository)
.start(step1)
.next(step2)
.build();
}
@Bean
public Step step1(JobRepository jobRepository, Tasklet tasklet1, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.tasklet(tasklet1, transactionManager)
.allowStartIfComplete(true)
.build();
}
@Bean
public Step step2(JobRepository jobRepository, Tasklet tasklet2, PlatformTransactionManager transactionManager) {
return new StepBuilder("step2", jobRepository)
.tasklet(tasklet2, transactionManager)
.allowStartIfComplete(true)
.build();
}
@Bean
public Tasklet tasklet1(){
return ((contribution, chunkContext) -> {
System.out.println("step1 was executed");
return RepeatStatus.FINISHED;
});
}
@Bean
public Tasklet tasklet2(){
return ((contribution, chunkContext) -> {
System.out.println("step2 was executed");
return RepeatStatus.FINISHED;
});
}
}
* spring5 ์์๋ @EnableBatchProcessing ํ๋ฉด ์๋๋ ๊ฒ ๊ฐ๋ค... (๋ํดํธ ์ค์ ์ด ๋ผ์๋๋ฏ)
* annotation ๋ฐฉ์์ผ๋ก ๋ฐฐ์น profile ์ค์ ํ ์๋ ์๋๋ด
5) Job ๊ด๋ จ ํ ์ด๋ธ
[Job ๊ด๋ จ ํ ์ด๋ธ]
1. BATCH_JOB_INSTANCE ใด Job์ด ์คํ๋ ๋ JobInstance ์ ๋ณด๊ฐ ์ ์ฅ๋๋ฉฐ job_name๊ณผ job_key๋ฅผ ํค๋กํ์ฌ ํ๋์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ ใด ๋์ผํ job_name๊ณผ job_key๋ก ์ค๋ณต X 2. BATCH_JOB_EXECUTION ใด Job์ ์คํ์ ๋ณด๊ฐ ์ ์ฅ ใด ์์ฑ,์์,์ข ๋ฃ ์๊ฐ / ์คํ ์ํ / ๋ฉ์์ง ๋ฑ์ ๊ด๋ฆฌ 3. BATCH_JOB_EXECUTION_PARAMS ใด Job๊ณผ ํจ๊ป ์คํ๋๋ JobParameter ์ ๋ณด ์ ์ฅ 4. BATCH_JOB_EXECUTION_CONTEXT ใด Job์ ์คํ๋์ ์ฌ๋ฌ๊ฐ์ง ์ํ์ ๋ณด, ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ง๋ ฌํ (JSON ํ์) ํด์ ์ ์ฅ ใด Step ๊ฐ ์๋ก ๊ณต์ ๊ฐ๋ฅ |
[Step ๊ด๋ จ ํ ์ด๋ธ]
1. BATCH_STEP_EXECUTION ใด Step์ ์คํ์ ๋ณด๊ฐ ์ ์ฅ ใด ์์ฑ,์์,์ข ๋ฃ ์๊ฐ / ์คํ์ํ / ๋ฉ์์ง ๋ฑ์ ๊ด๋ฆฌ 2. BATCH_STEP_EXECUTION_CONTEXT ใด Step์ ์คํ๋์ ์ฌ๋ฌ๊ฐ์ง ์ํ์ ๋ณด, ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ง๋ ฌํ(JSONํ์)์์ ์ ์ฅ ใด Step ๋ณ๋ก ์ ์ฅ๋๋ฉฐ Step ๊ฐ ์๋ก ๊ณต์ ํ ์ ์์ |
[Job ๊ด๋ จ ํ ์ด๋ธ ์์ธ]
1. BATCH_JOB_INSTANCE - JOB_INSTANCE_ID : ๊ณ ์ ํ๊ฒ ์๋ณํ ์ ์๋ ๊ธฐ๋ณธํค - VERSION : ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค 1์ฉ ์ฆ๊ฐ - JOB_NAME : Job์ ๊ตฌ์ฑํ ๋ ๋ถ์ฌํ๋ Job์ ์ด๋ฆ - JOB_KEY : job_name๊ณผ jobParameter๋ฅผ ํฉ์ณ ํด์ฑํ ๊ฐ์ ์ ์ฅ 2. BATCH_JOB_EXECUTION - JOB_EXECUTION_ID : JobExecution์ ๊ณ ์ ํ๊ฒ ์๋ณํ ์ ์๋ ๊ธฐ๋ณธ ํค, JOB_INSTANCE์ ์ผ๋๋ค ๊ด๊ณ - VERSION : ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค 1์ฉ ์ฆ๊ฐ - JOB_INSTANCE_ID : JOB_INSTANCE์ ํค ์ ์ฅ - CREATE_TIME : ์คํ์ด ์์ฑ๋ ์์ ์ TimeStamp ํ์์ผ๋ก ๊ธฐ๋ก - START_TIME : ์คํ์ด ์์๋ ์์ ์ TimeStamp ํ์์ผ๋ก ๊ธฐ๋ก - END_TIME : ์คํ์ด ์ข ๋ฃ๋ ์์ ์ TimeStamp ํ์์ผ๋ก ๊ธฐ๋ก -์คํ ๋์ค ์ค๋ฅ ๋ฐ์ํด์ Job์ด ์ค๋จ๋ ๊ฒฝ์ฐ ๊ฐ์ด ์ ์ฅ๋์ง ์์ ์ ์์ (NULL) - STATUS : ์คํ ์ํ(BatchStatus)๋ฅผ ์ ์ฅ [COMPLETED / FAILED / STOPPED...] - EXIT_CODE : ์คํ ์ข ๋ฃ์ฝ๋(ExitStatus)๋ฅผ ์ ์ฅ[COMPLETED / FAILED...] - EXIT_MESSAGE : Status๊ฐ ์คํจ์ผ ๊ฒฝ์ฐ ์คํจ ์์ธ ๋ฑ์ ๋ด์ฉ์ ์ ์ฅ - LAST_UPDATED : ๋ง์ง๋ง ์คํ์์ ์ TimeStamp ํ์์ผ๋ก ๊ธฐ๋ก 3. BATCH_JOB_EXECUTION_PARAMS - JOB_EXECUTION_ID : JobExecution์ ๊ณ ์ ํ๊ฒ ์๋ณํ ์ ์๋ ๊ธฐ๋ณธ ํค, JOB_INSTANCE์ ์ผ๋๋ค ๊ด๊ณ - TYPE_CD : STRING, LONG, DATE, DOUBLE ํ์ ์ ๋ณด - KEY_NAME : ํ๋ผ๋ฏธํฐ ํค ๊ฐ - STRING_VAL : ํ๋ผ๋ฏธํฐ ๋ฌธ์ ๊ฐ - DATE_VAL : ํ๋ผ๋ฏธํฐ ๋ ์ง ๊ฐ - LONG_VAL : ํ๋ผ๋ฏธํฐ LONG ๊ฐ - DOUBLE_VAL : ํ๋ผ๋ฏธํฐ DOUBLE ๊ฐ - IDENTIFYING : ์๋ณ์ฌ๋ถ (TRUE, FALSE) 4. BATCH_JOB_EXECUTION_CONTEXT - JOB_EXECUTION_ID : JobExecution์ ๊ณ ์ ํ๊ฒ ์๋ณํ ์ ์๋ ๊ธฐ๋ณธ ํค, JOB_EXECUTION ๋ง๋ค ์์ฑ - SHORT_CONTEXT : Job์ ์คํ ์ํ์ ๋ณด, ๊ณต์ ๋ฐ์ดํฐ ๋ฑ์ ์ ๋ณด๋ฅผ ๋ฌธ์์ด๋ก ์ ์ฅ - SERIALIZED_CONTEXT: ์ง๋ ฌํ(serialized)๋ ์ ์ฒด ์ปจํ ์คํธ |
[Step ๊ด๋ จ ํ ์ด๋ธ ์์ธ]
1. BATCH_STEP_EXECUTION - STEP_EXECUTION_ID : Step์ ์คํ์ ๋ณด๋ฅผ ๊ณ ์ ํ๊ฒ ์๋ณํ ์ ์๋ ๊ธฐ๋ณธ ํค - VERSION : ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค 1์ฉ ์ฆ๊ฐ - STEP_NAME : Step์ ๊ตฌ์ฑํ ๋ ๋ถ์ฌํ๋ Step ์ด๋ฆ - JOB_EXECUTION_ID : JobExecution ๊ธฐ๋ณธํค, JobExecution๊ณผ๋ ์ผ๋ ๋ค ๊ด๊ณ - START_TIME : ์คํ์ด ์์๋ ์์ ์ TimeStamp ํ์์ผ๋ก ๊ธฐ๋ก - END_TIME : ์คํ์ด ์ข ๋ฃ๋ ์์ ์ TimeStamp ํ์์ผ๋ก ๊ธฐ๋ก - Job ์คํ ๋์ค ์ค๋ฅ๊ฐ ๋ฐ์ํด์ Job์ด ์ค๋จ๋ ๊ฒฝ์ฐ ๊ฐ์ด ์ง์ ๋์ง ์์ ์ ์์ - STATUS : ์คํ ์ํ(BatchStatus)๋ฅผ ์ ์ฅ [COMLETED / FAILED / STOPPED] - COMMIT_COUNT : ํธ๋์ญ์ ๋น ์ปค๋ฐ๋๋ ์๋ฅผ ๊ธฐ๋ก - READ_COUNT : ์คํ์์ ์ Readํ Item ์๋ฅผ ๊ธฐ๋ก - FILTER_COUNT : ์คํ๋์ค ํํฐ๋ง๋ Item ์๋ฅผ ๊ธฐ๋ก - WRITE_COUNT : ์คํ๋์ค ์ ์ฅ๋๊ณ ์ปค๋ฐ๋ Item ์๋ฅผ ๊ธฐ๋ก - PROCESS_SKIP_COUNT : ์คํ๋์ค Process๊ฐ Skip๋ Item ์๋ฅผ ๊ธฐ๋ก - ROLLBACK_COUNT : ์คํ๋์ค rollback์ด ์ผ์ด๋ ์๋ฅผ ๊ธฐ๋ก - EXIT_CODE : ์คํ ์ข ๋ฃ์ฝ๋(ExitStatus)๋ฅผ ์ ์ฅ [COMPLETED / FAILED] - EXIT_MESSAGE : Status๊ฐ ์คํจ์ผ ๊ฒฝ์ฐ ์คํจ ์์ธ ๋ฑ์ ๋ด์ฉ์ ์ ์ฅ - LAST_UPDATED : ๋ง์ง๋ง ์คํ(Execution) ์์ ์ TimeStamp ํ์์ผ๋ก ๊ธฐ๋ก 2. BATCH_STEP_EXECUTION_CONTEXT - STEP_EXECUTION_ID : StepExecution ์๋ณํค, STEP_EXECUTION๋ง๋ค ์์ฑ - SHORT_CONTEXT : STEP์ ์คํ ์ํ์ ๋ณด, ๊ณต์ ๋ฐ์ดํฐ๋ฑ์ ์ ๋ณด๋ฅผ ๋ฌธ์์ด๋ก ์ ์ฅ - SERIALIZED_CONTEXT : ์ง๋ ฌํ(serialized)๋ ์ ์ฒด ์ปจํ ์คํธ |
'๐จโ๐ป Web Development > Spring - Batch' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring Batch] 3. ์คํ๋ง ๋ฐฐ์น ๋๋ฉ์ธ ์ดํด (0) | 2024.01.16 |
---|---|
[Spring Batch] 0. ์๋ก & 1. ์คํ๋ง ๋ฐฐ์น ์๊ฐ (1) | 2023.11.13 |
์ต๊ทผ๋๊ธ