728x90
Spring Batch와 MyBatis를 활용하여 CSV 파일 데이터를 읽고, 가공 후 데이터베이스에 저장하는 배치 처리 예제입니다.
https://github.com/Raconer/SpringBatch
📁 프로젝트 구성
com.example.batch
├── config
│ └── BatchConfig.java # 배치 Job/Step 설정
├── entity
│ └── Person.java # 도메인 엔티티
├── listener
│ └── JobCompletionNotificationListener.java # Job 실행 리스너
├── processor
│ └── PersonItemProcessor.java # ItemProcessor 구현체
├── mappers
│ └── PersonMapper.java # MyBatis Mapper 인터페이스
├── log
│ └── CustomMyBatisLoggerImpl.java # MyBatis SQL 로그 커스터마이징
├── resources
│ ├── application.yml # 환경 설정
│ ├── schema-all.sql # 테이블 생성 SQL
│ ├── sample-data.csv # CSV 입력 데이터
│ └── mybatis/mappers/PersonMapper.xml # MyBatis SQL 매퍼
└── BatchApplication.java # 실행 메인 클래스
🔧 실행 환경
- Java: 17
- Spring Boot: 2.7.13
- 빌드 도구: Gradle
📦 주요 의존성
// Batch
implementation("org.springframework.boot:spring-boot-starter-batch")
// DB - MySQL
runtimeOnly("com.mysql:mysql-connector-j")
// MyBatis
implementation("org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.2")
// H2 (Test용)
runtimeOnly("com.h2database:h2")
// Lombok
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
// Test
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.batch:spring-batch-test")
🌐 환경 프로파일별 DB 설정
Spring Boot의 spring.profiles.active에 따라 다른 DB를 사용하도록 구성:
- local → MySQL
- test → H2 (In-Memory)
각 환경은 application.yml 또는 application-{profile}.yml로 분기 관리합니다.
💬 구성 요약
- FlatFileItemReader: CSV → Person 객체 변환
- ItemProcessor: 이름 필드 대문자 변환
- MyBatisBatchItemWriter: XML Mapper를 통한 DB 저장
- JobListener: 실행 로그 및 상태 추적
- Custom Logger: SQL 가독성 향상
Spring Batch
💡 Spring Batch란?
개발자가 정의한 작업을 일괄 처리하는 데 최적화된 스프링 기반 프레임워크입니다.
📚 참고 자료
✅ 대표 사용 사례
- 일매출 집계, 정산 처리
- 보험급여 계산
- 외부 시스템 수신 데이터 적재
📌 배치 애플리케이션이 필요한 경우
- 스케줄 기반 주기적 작업이 필요할 때
- 대량 데이터의 비동기 처리 필요할 때
단일 서버에서 모든 것을 처리하지 않고, 별도 배치 애플리케이션에서 분리 운영함으로써 성능 향상
🔒 배치 시스템이 갖춰야 할 조건
- 대용량 처리 능력: 파일, DB 등 다양한 대량 데이터 처리
- 자동화: 사용자 개입 없이 실행 가능
- 견고성: 오류 발생 시에도 중단 없이 진행
- 신뢰성: 실패 로그, 알림 제공
- 성능: 병렬 처리, 스케줄링 고려
⚙️ 실행 순서 정리
Spring Batch 실행 순서는 다음과 같습니다:
0. 청크 처리
- ex) 1500개 단위로 처리 → 병렬 처리 핵심 단위
1. Job
- 하나의 배치 작업 단위
- 내부에 여러 개의 Step 포함
2. Step
- 작업 단위
- Reader: 입력 (파일/DB 등)
- Processor: 데이터 가공 (선택)
- Writer: 출력 (DB 등 저장)
3. JobLauncher
- 배치 실행 트리거 역할 (스케줄러, REST 등에서 호출)
4. JobRepository
- 실행 이력 관리, 실패 복구를 위한 상태 저장소
5. JobExecution
- 실행 결과 요약, 성공/실패 여부 추적 가능
💡 핵심 코드 요약 (자세히 설명)
✅ BatchConfig.java
@Configuration
@EnableBatchProcessing
public class BatchConfig {
// Job: 배치 작업 단위 구성
@Bean
public Job importUserJob(...) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer()) // 실행마다 다른 JobInstance로 처리
.listener(listener) // 실행 전/후 리스너 등록
.flow(step(writer)) // 실행할 Step 연결
.end()
.build();
}
// Step: Reader → Processor → Writer 실행 흐름 정의
@Bean
public Step step(MyBatisBatchItemWriter<Person> writer) {
return stepBuilderFactory.get("Person Insertion Step")
.<Person, Person>chunk(10) // 10개 단위 청크 처리
.reader(reader())
.processor(processor())
.writer(writer)
.build();
}
}
✅ FlatFileItemReader
@Bean
public FlatFileItemReader<Person> reader() {
return new FlatFileItemReaderBuilder<Person>()
.name("personItemReader")
.resource(new ClassPathResource("sample-data.csv"))
.delimited() // 구분자 기반 파싱
.names("firstName", "lastName") // CSV 컬럼 이름 지정
.fieldSetMapper(new BeanWrapperFieldSetMapper<>() {{
setTargetType(Person.class); // 매핑할 객체 타입 지정
}})
.build();
}
✅ PersonItemProcessor.java
public class PersonItemProcessor implements ItemProcessor<Person, Person> {
public Person process(Person person) {
return new Person(
person.getFirstName().toUpperCase(), // 이름 대문자 변환
person.getLastName().toUpperCase()
);
}
}
✅ PersonMapper.xml
<mapper namespace="com.example.batch.mappers.PersonMapper">
<insert id="insert" parameterType="com.example.batch.entity.Person">
INSERT INTO PEOPLE (first_name, last_name)
VALUES (#{firstName}, #{lastName})
</insert>
</mapper>
728x90
'BackEnd > Spring Batch' 카테고리의 다른 글
Spring Batch 실행 순서 정리 (0) | 2025.06.24 |
---|---|
Spring Batch 실행 이력 테이블 분석 가이드 (0) | 2025.06.02 |
Spring Batch Chunk Size에 따른 성능 비교 실험 (Bulk Insert 포함) (0) | 2025.06.02 |