-
[퍼옴] [Spring Batch] 스프링 배치 강좌 5. JDBC 로 디비 읽어서 CSV 파일에 쓰기spring 2021. 4. 14. 15:26728x90반응형
목적
성적 데이터를 저장하는Exam테이블 데이터를 읽어서 시험 점수0-100점스케일을A-F스케일로 변환하여CSV파일에 저장한다.
Inputsrc/test/resources에 com/fwantastic/example4 *폴더를 생성 후 *create-table.sql를 만든다.
Exam테이블을 생성 하고 테스트 데이터를 넣는다.Exam테이블에는 시험 점수가 0-100점 스케일로 저장되어있다.
create-table.sql
CREATE TABLE EXAM ( CLASS_NAME VARCHAR2(255) , STUDENT_NAME VARCHAR2(255) , SCORE INT , GRADE VARCHAR2(1) ) ; INSERT INTO EXAM (CLASS_NAME, STUDENT_NAME, SCORE) VALUES ('MATH' , 'Fwantastic', 64 ) ; INSERT INTO EXAM (CLASS_NAME, STUDENT_NAME, SCORE) VALUES ('MATH' , 'IU' , 95 ) ; INSERT INTO EXAM (CLASS_NAME , STUDENT_NAME, SCORE) VALUES ('COMPUTER SCIENCE', 'Fwantastic', 100 ) ; INSERT INTO EXAM (CLASS_NAME , STUDENT_NAME, SCORE) VALUES ('COMPUTER SCIENCE', 'IU' , 86 ) ; INSERT INTO EXAM (CLASS_NAME , STUDENT_NAME, SCORE) VALUES ('COMPUTER SCIENCE', '수지' , 77 ) ;
Exam.java
**Exam 테이블 데이터를 매핑 *할 *자바 클래스를 만든다. com.fwantastic.example4 패키지에 아래 클래스를 추가하자.
Exam.java**
package com.fwantastic.example4; import java.util.Arrays; import java.util.Comparator; import lombok.Getter; import lombok.Setter; @Getter @Setter public class Exam { private String className; private String studentName; // 시험 점수. 0-100점 private double score; // 시험 점수 스케일. A-F private String grade; @Getter public static enum Grade { A("A", 90), B("B", 80), C("C", 70), D("D", 60), F("F", 0); private final String grade; private final double score; private Grade(String grade, double score) { this.grade = grade; this.score = score; } public static String convertScore(double score) { return Arrays.stream(values()).filter(grade -> grade.score < score) .max(Comparator.comparing(grade -> grade.score)).get().getGrade(); } } }
****시험 점수 grade 스케일은 다음과 같다.
- A = 90점 이상
- B = 80점 이상
- C = 70점 이상
- D = 60점 이상
- F = 60점 이하
Getter/Setter는 lombok을 사용하여 처리했는데 셋업이 안되있다면 아래 포스트를 참고하자.
자바 lombok 설치와 Getter/Setter 간편하게 만들기
ExamProcessor.java
*시험 점수를 grade 스케일로 변환 한 값을 Exam 객체에 매핑 후 반환한다. *com.fwantastic.example4 패키지에 아래 클래스를 추가하자.
ExamProcessor.java****
package com.fwantastic.example4; import org.springframework.batch.item.ItemProcessor; /** * 시험 점수 0-100점 스케일을 A-F 스케일로 변환한다. */ public class ExamProcessor implements ItemProcessor<Exam, Exam> { public Exam process(Exam exam) throws Exception { exam.setGrade(Exam.Grade.convertScore(exam.getScore())); return exam; } }
job4.xml
****src/main/resources/com/fwantastic/example4에 아래의 **job4.xml을 만든다.
자세한 설명은 주석을 참고하자.
job4.xml**
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <import resource="classpath:/common-context.xml" /> <!-- job을 시작하기 전에 Exam 테이블과 테스트 데이터 생성. --> <jdbc:initialize-database data-source="dataSource"> <jdbc:script location="classpath:com/fwantastic/example4/create-table.sql" /> </jdbc:initialize-database> <job id="myJob4" xmlns="http://www.springframework.org/schema/batch"> <description> JDBC로 디비를 읽어서 CSV 파일로 저장하는 예제. </description> <step id="myStep1"> <tasklet> <chunk reader="examReader" processor="examProcessor" writer="examWriter" commit-interval="10" /> </tasklet> </step> </job> <bean id="examReader" class="org.springframework.batch.item.database.JdbcCursorItemReader"> <property name="dataSource" ref="dataSource" /> <property name="sql"> <value> <![CDATA[ SELECT CLASS_NAME, STUDENT_NAME, SCORE FROM EXAM ORDER BY CLASS_NAME, STUDENT_NAME, SCORE ]]> </value> </property> <property name="rowMapper" ref="examRowMapper" /> </bean> <!-- JDBC reader로 읽은 데이터를 자바 객체로 매핑 해준다. --> <bean id="examRowMapper" class="org.springframework.jdbc.core.BeanPropertyRowMapper" scope="step"> <property name="mappedClass" value="com.fwantastic.example4.Exam" /> </bean> <!-- Exam 데이터 가공 --> <bean id="examProcessor" class="com.fwantastic.example4.ExamProcessor" scope="step" /> <bean id="examWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step"> <!-- Aggregate이 모으다 라는 뜻인데, 한 라인을 어떻게 쓸지 설정한다. --> <!-- 여기선 콤마로 필드를 구분하고 className, studentName, grade 순서대로 값을 쓰라고 설정했다. --> <property name="lineAggregator"> <bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator"> <property name="delimiter" value="," /> <property name="fieldExtractor"> <bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor"> <property name="names" value="className, studentName, grade"></property> </bean> </property> </bean> </property> <!-- 쓸 파일 위치를 지정해준다. 배치가 종료되면 프로젝트 root 레벨 (pom.xml과 같은 위치) 에 output 폴더가 생성된다. --> <property name="resource"> <bean class="org.springframework.core.io.FileSystemResource"> <constructor-arg name="path" value="output/com/fwantastic/example4/output.csv" /> </bean> </property> <!-- 파일이 존재하면 삭제하고 새로 만든다. --> <property name="shouldDeleteIfExists" value="true" /> </bean> </beans>
테스트
**src/test/java에 **com.fwantastic.example4 패키지 만들고 아래 junit 클래스를 추가하자.
MyJobTest.java
package com.fwantastic.example4; import java.io.File; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.test.JobLauncherTestUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "/com/fwantastic/example4/job4.xml" }) public class MyJobTest { @Autowired private JobLauncherTestUtils jobLauncherTestUtils; @Autowired private JdbcTemplate jdbcTemplate; private static AtomicBoolean isLaunched = new AtomicBoolean(false); private JobExecution jobExecution; @Before public void setUp() throws Exception { if (!isLaunched.getAndSet(true)) { jobExecution = jobLauncherTestUtils.launchJob(); } } @Test public void testExitCode() { Assert.assertEquals(ExitStatus.COMPLETED.getExitCode(), jobExecution.getExitStatus().getExitCode()); } // output 파일이 생성되었는지 확인한다. 테스트는 더 디테일하면 할수록 더 좋다. @Test public void testOutputFileCreated() { File file = new File("output/com/fwantastic/example4/output.csv"); Assert.assertTrue(file.exists()); } }
****실행 결과****
프로젝트 root 레벨에 output/com/fwantastic/example4/output.csv 파일이 생성된 것을 확인 할 수 있다.
COMPUTER SCIENCE,Fwantastic,A COMPUTER SCIENCE,IU,B COMPUTER SCIENCE,수지,C MATH,Fwantastic,D MATH,IU,A
728x90반응형'spring' 카테고리의 다른 글
[퍼옴] 8. Spring Batch 가이드 - ItemWriter (0) 2021.04.20 전자정부프레임워크 - 배치 운영환경 (0) 2021.04.16 [퍼옴] [Spring Batch] 스프링 배치 강좌 4. CSV 파일 읽어서 JDBC로 디비에 저장하기 (0) 2021.04.14 [퍼옴] [Spring Batch] 스프링 배치 강좌 4. CSV 파일 읽어서 JDBC로 디비에 저장하기 (0) 2021.04.14 [퍼옴] [Spring Batch] 스프링 배치 강좌 3. JobExecutionContext를 활용하여 스텝간 데이터 공유하기 (0) 2021.04.14