상세 컨텐츠

본문 제목

7. 예제4: Spring Batch - Read from DB and write to flat file

Spring/SpringBatch

by husks 2016. 3. 31. 15:26

본문

반응형

이번 예제에서는 Spring Batch의 ItemReader, ItemWriter를 사용하여 데이터베이스의 데이터를 읽어 파일에 저장하는 방법을 알아보도록 하겠습니다.

 

6.예제3: Spring Batch - Read from flat file and write to DB 에서 데이터베이스에 저장된 Player 정보를 다시 읽어 파일에 저장하는 예제입니다.

 

소스 코드는 첨부파일을 참조하세요.

 

예제의 각 파일에 대한 기본적인 설명은 다음과 같습니다.


1. spring-context.xml: Spring Batch Infrastructure 설정.

 

2. com.hjh,batch.bean package

 

  •  PlayerBean: 데이터베이스의 Player 정보를 매핑할 오브젝트.

 

3. com.hjh.batch.itemReader package

 

  • PlayerRowMapper: 데이터베이스의 Player정보를 PlayerBean 오브젝트로 매핑하는 로직이 있는 클래스
4. com.hjh.batch.Launcher - Job을 실행하는 main() 메소드가 있는 클래스.

5. resource 폴터
  • create_table.sql: Player 테이블 생성.
  • insert_player.sql: Player 정보 생성.
  • spring_batch_table_creation.sql: 데이터베이스 repository에 필요한 테이블 및 시퀀스 생성 sql 

 

 

1. spring-context.xml 설정


 <?xml version="1.0" encoding="UTF-8"?>

 

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx

xmlns:batch="http://www.springframework.org/schema/batch"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="

    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd    

    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd

    http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd

    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd

    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xs">

       

    <!-- 1. Define MySQL DataSource  -->

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

     <property name="driverClassName" value="com.mysql.jdbc.Driver" />

     <property name="url" value="jdbc:mysql://127.0.0.1:3306/test" />

     <property name="username" value="root" />

     <property name="password" value="will" />    

    </bean>

    

    <!-- 2. Define DataSource TransactionManager -->

    <bean id="transactionManager"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

</bean>

    <!-- 3. Job Repository - MySQL Database Repository with MySQL DataSource-->

    <bean id="jobRepository"

class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">

<property name="transactionManager" ref="transactionManager" />

<property name="dataSource" ref="dataSource" />

<property name="tablePrefix" value="BATCH_" />

<property name="isolationLevelForCreate" value="ISOLATION_SERIALIZABLE"/>

<property name="databaseType" value="MySql" />

</bean>

    

    <!-- 4. Launch Job from a Repository -->

    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">

     <property name="jobRepository" ref="jobRepository" />

    </bean>

        

    <!-- 5. Define JdbcCursorItemReader -->

 <bean id="dbPagingReader" class="org.springframework.batch.item.database.JdbcPagingItemReader">

     <property name="dataSource" ref="dataSource" />

     <property name="queryProvider">

     <bean class="org.springframework.batch.item.database.support.MySqlPagingQueryProvider">

     <property name="selectClause" value="select player_id, first_name, last_name, position, birth_year, debut_year" />

     <property name="fromClause" value="from player" />

     <property name="sortKey" value="player_id" />

     </bean>

     </property>

     <property name="pageSize" value="2" />    

    <property name="rowMapper" ref="playerRowMapper" />

    </bean>

    

    <bean id="playerRowMapper" class="com.hjh.batch.itemreader.PlayerRowMapper" />

 

       

    <!-- 6. Define FlatFileItemWriter -->

  <bean id="delimitedFileWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">

     <property name="resource" value="file:c:/temp/player.txt" />

     <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="id, firstName, lastName, position, birthYear, debutYear" />

     </bean>

     </property>

     </bean>

     </property>

    </bean>

         

    <!-- 7. Finally Job Defined -->

    <batch:job id="simpleJob">    

     <batch:step id="dbToDelimitedFileStep">

     <batch:tasklet>

     <batch:chunk reader="dbPagingReader" writer="delimitedFileWriter" commit-interval="2"/>

     </batch:tasklet>

     </batch:step>

    </batch:job>       

    

</beans>


1. 데이터베이스에 CRUD 작업을 위한 'DriverManagerDataSource'를 설정합니다. 예제에서는 MySql 데이터베이스를 사용하였습니다.

 

2. DatasourceTransactionManager를 설정합니다.

 

3. Spring Batch JobRepsitory를 설정합니다. 예제에서는 비즈니스 데이터(PlayerBean, OrderBean) CRUD 수행을 위한 DataSource와 TransactionManager를 사용하고 있습니다.

JobRepsitory를 위한 별도의 DataSource와 TransactionManager를 사용할 수도 있습니다.

 

4. 실제로 Job을 실행하기 위한 JobLauncher를 설정합니다. Job을 실행하기 위해 유효한 JobExecution 정보을 업데이트하기 위한 JobRepository를 셋팅합니다.

 

5. 이번 예제에서 핵심내용인 데이터베이스의 정보를 읽기 위한 ItemReader (JdbcPagingItemReader)를 설정합니다. 

 

dataSource 프로퍼티: 데이터베이스에 접속하기 위해 DataSource를 설정합니다.

 

queryProvider 프로퍼티: 쿼리를 생성하기 위해 데이터베이스 유형에 맞는 PagingQueryProvider를 설정합니다. 예제에서는 MySql 데이터베이스를 사용함으로 MySqlPagingQueryProvider를 설정하였습니다.

 

그외에 Db2PaingQueryProvidier, OraclePagingProvider, HsqlPagingQueryProvider... 가 있습니다. 보다 많은 유형을 확인하기 위해서 PagingQueryProvider 인터페이스를 확인해 보세요.

 

pageSize 프로퍼티: 한번의 쿼리에서 읽어 올 열의 사이즈를 설정합니다.

pageSize의 설정값과 Job설정의 commit-interval 설정값이 같을때 최적의 성능을 제공합니다.

 

rowMapper 프로퍼티: 데이터베이스에서 읽어온 Player 정보를 PlayerBean 오브젝트로 매핑할 RowMapper를 설정합니다.

 

 

 <bean id="dbPagingReader" class="org.springframework.batch.item.database.JdbcPagingItemReader">

     <property name="dataSource" ref="dataSource" />

     <property name="queryProvider">

           <bean class="org.springframework.batch.item.database.support.MySqlPagingQueryProvider">

       <property name="selectClause" value="select player_id, first_name, last_name, position, birth_year, debut_year" />

        <property name="fromClause" value="from player" />

        <property name="sortKey" value="player_id" />

         </bean>

     </property>

     <property name="pageSize" value="2" />    

 <property name="rowMapper" ref="playerRowMapper" />

    </bean>

 

다음은 PlayerRowMapper 클래스입니다. 

mapRow에 전달된 ResultSet과 데이터베이스 컬럼 명으로 데이터를 매핑합니다.

 package com.hjh.batch.itemreader;

 

import java.sql.ResultSet;

import java.sql.SQLException;

 

import org.springframework.jdbc.core.RowMapper;

 

import com.hjh.batch.bean.PlayerBean;

 

public class PlayerRowMapper implements RowMapper<PlayerBean>{

 

@Override

public PlayerBean mapRow(ResultSet rs, int rowNum) throws SQLException {

 

PlayerBean player = new PlayerBean();

player.setId(rs.getString("player_id"));

player.setFirstName(rs.getString("first_name"));

player.setLastName(rs.getString("last_name"));

player.setPosition(rs.getString("position"));

player.setBirthYear(rs.getInt("birth_year"));

player.setDebutYear(rs.getInt("debut_year"));

return player;

}

 

}

 

6. 데이터베이스에서 읽어온 정보를 파일에 저장하기 위해 다음과 같이 FlatFileItemWriter를 설정합니다.

 

resource 프로퍼티: 데이터를 저장할 디렉토리 및 파일 명을 지정합니다. 디렉토리 및 파일이 없는 경우 자동 생성됩니다.

 

lineAggregator 프로퍼티: PlayerBean의 각 필드 정보를 한 줄의 라인으로 생성하여 파일에 쓰기하는 역할을 할 클래스를 설정합니다.

 

BeanWrapperFieldExtraxctor: JdbcPagingItemReader의 PlayerRowMapper에 의해 리턴된 PlayerBean의 필드 정보를 Reflection을 이용해 읽는 역할을 합니다. FieldExtractor의 names 프로퍼티에 설정된 값은 PlayerBean의 변수 이름입니다.

 

 <bean id="delimitedFileWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">

     <property name="resource" value="file:c:/temp/player.txt" />

     <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="id, firstName, lastName, position, birthYear, debutYear" />

     </bean>

     </property>

     </bean>

     </property>

 </bean>

 

2. PlayerBean 작성


 package com.hjh.batch.bean;

 

import java.io.Serializable;

 

public class PlayerBean implements Serializable{

/**

 * 

 */

private static final long serialVersionUID = -5330794101303450135L;

 

private String id;

private String lastName;

private String firstName;

private String position;

private int birthYear;

private int debutYear;

 

// setter/getter 메소드



3. 실행


 package com.hjh.batch;

 

import org.springframework.batch.core.launch.support.CommandLineJobRunner;

 

public class Launcher {

 

public static void main(String[] agrs){

try{

CommandLineJobRunner.main(new String[]{"spring-context.xml", "simpleJob"}); 

}catch(Exception e){

 System.out.print("Launcher has failed: " + e.getMessage());

         System.exit(-1);

}

}

}



4. 결과


다음과 같이 player.txt 가 생성되었는지 확인해 보세요.


 AbduKa00,Karim,Abdul-Jabbar,rb,1974,1996

AbduRa00,Rabih,Abdullah,rb,1975,1999

AberWa00,Walter,Abercrombie,rb,1959,1982

AbraDa00,Danny,Abramowicz,wr,1945,1967

AdamBo00,Bob,Adams,te,1946,1969

AdamCh00,Charlie,Adams,wr,1979,2003




반응형

관련글 더보기

댓글 영역