Whiteship's Note


[스프링 배치 2.0] 걸음마 떼기

Spring Batch/etc : 2009. 8. 21. 00:26


1. 라이브러리 추가.

pom.xml에 스프링 번들 저장소에서 제공하는 스프링 배치 가장 최신 버전을 추가해줍니다

프로젝트가 세 개로 나눠져 있더군요. test 모듈은 테스트 용이니까 test scope으로 설정하는 것이 좋겠네요.

<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>org.springframework.batch.core</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.batch</groupId> <artifactId>org.springframework.batch.infrastructure</artifactId> <version>2.0.2.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.batch</groupId> <artifactId>org.springframework.batch.test</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>

2. 배치를 Job와 Step으로 표현합니다.

하나의 Job이 하나의 배치 작업이라고 생각하면 될 듯 하고, 배치 작업의 세세한 단계들을 여러 개의 Step으로 표현할 수 있습니다. 하나의 Step은 ItemReader, ItemProcessor, ItemWriter를 각각 가질 수 있는데, 이 것들 다 필요 없이 Tasklet을 구현해서 통짜로 Step을 구현할 수도 있습니다. 그러나 저는 최대한 IR, IP, IW 구조를 이용해 보려고 한 번 써봤습니다.

할 일은 DB에서 특정 데이터들을 읽어와서 이메일로 뿌려주고, 배치가 끝나면 그 결과를 로깅할 것.

2-1. XML 스키마 설정.

batch 네임스페이스를 기본 네임스페이스로 설정한 XML 스키마를 사용합니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/batch"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx">

// 여기에 job 설정.

</beans:beans>

job 하나 당 하나의 XML 설정 파일로 만드는걸 기본으로 하고, 공통으로 쓸 녀석들은 별도의 XML로 뺀 다음 각각의 job XML에서 import 해서 쓰는 것이 좋을 듯 합니다.

2-2. Job 설정.

본격적으로 job을 설정 파일로 만들어야 합니다. 배치 2.0에서는 개별 아이템들이 아니라 아이템 뭉탱이(chunk) 단위로 배치 작업을 설정할 수 있습니다.

    <job id="itemCouningJob" job-repository="jobRepository">
        <step id="itemCouningStep">
            <tasklet>
                <chunk reader="komaItemReader" writer="emailWriter"
                    commit-interval="100" />
                <listeners>
                    <listener ref="stepResultListener" />
                </listeners>
            </tasklet>
        </step>
        <listeners>
            <listener ref="jobResultListener"/>
        </listeners>
    </job>

이게 끝입니다. 하나의 job 내부에. 하나의 step이 있고, 하나의 listerner(jobResultListener)를 등록해 뒀습니다. job 내부에 여러 개의 step을 설정할 수 있고, 여러 개의 리스너도 등록할 수 있습니다.

하나의 step 에는 리더, 프로세서, 라이터를 등록할 수 있는데, 제가 개념 잡기 힘들었던 부분은 하나의 item을 읽어와서 처리하고 바로 쓴다고??? 였습니다. 그러나 그게 아니더군요. 뭉탱이던 개별 Item이던 읽어온 다음 개별적으로 처리를 하는 것 까진 맞는데, 그것들을 하나 하나 라이터가 처리하는게 아니라, 모든 프로세싱이 끝난 아이템 전체 목록을 라이터가 받아서 작업 합니다.

따라서, 제가 할 일이었던 모든 아이템 목록을 읽어오는 것은 리더에게 맡기면 되고, 별도의 프로세싱 작업이 필요 없는 듯 하니 프로세서는 설정하지 않고, 모든 목록을 읽어온 뒤 이메일로 보내야 하니까 emailWriter라는 걸 하나 등록했습니다.

그리고 Step에도 리스너 하나를 등록해 두었습니다. 이 녀석은 Job에 등록한 것과는 달리 한 Step의 결과, 이름, 시작 시간, 끝난 시간, 수행 시간 등을 알 수 있는 여긴한 녀석입니다.; Job에 등록한 리스너는 모든 Step..즉 Job에 대한 내용을 알 수 있지요.

만약, 정의해야 하는 작업이 step의 리더, 프로세서, 라이터 개념과 잘 맞지 않다면..  Tasklet 자체를 구현한 다음 <tasklet ref=""/> 에 등록해주면 됩니다.

2-3. Job 에서 필요한 빈 정의 및 설정.

이제 위에서 설정한 job에 필요한 빈들을 등록합니다. 우선 리파지토리를 등록합니다.

    <job-repository id="jobRepository" data-source="dataSource"
        transaction-manager="transactionManager" isolation-level-for-create="SERIALIZABLE"
        table-prefix="BATCH_" />

레퍼런스에 있는 것을 그대로 썼습니다. 실제 DB를 이용하도록 했습니다. 다음은 리더 입니다.

    <beans:bean id="komaItemReader"
        class="org.springframework.batch.item.database.HibernateCursorItemReader"
        p:queryString="from Item" p:sessionFactory-ref="sessionFactory" />

하이버네이트 커서 아이템 리더로.. 스프링 배치에서 기본으로 제공해주는 클래스입니다. HQL과 세션 팩토리만 설정하면 됩니다. 다음은 라이터 입니다. 이 녀석은 별도로 구현해 주었습니다.

    <beans:bean id="emailWriter" class="sandbox.batch.writer.EmailWriter"/>

public class EmailWriter implements ItemWriter {

    @Override
    public void write(List items) throws Exception {
        sendEmail(items);
    }

    private void sendEmail(List items) {
        System.out.println("Mailing : " + items);
    }

}

구현이라고 해봤자.. 그냥 저렇게 좀 허접하게 해뒀습니다. 주요 관심사는 아니기 때문에 저렇게 했습니다. 마지막으로 리스너 두개를 구현하는데 이 녀석들은 뭐 간단하니까 패스하죠.

3. 배치 실행하기.

배치 실행은 JobLauncher를 사용하는데 이 녀석은 jobRepository를 필요로 합니다. 따라서 이 녀석도 스프링 DI를 사용하도록 빈으로 등록해 줍니다.

    <beans:bean id="jobLauncher"
        class="org.springframework.batch.core.launch.support.SimpleJobLauncher" p:jobRepository-ref="jobRepository" />

자 이제 드디어 자바 코드로 Job을 실행해 줍니다.

jobLauncher.run(job, new JobParameters());

jobLauncher 이 녀석을 applicationContext에서 DL을 하건, Autowiring으로 가져오건 하고, job도 2번 작업에서 등록한 녀석을 가져옵니다. 그리고 JobParameter 객체를 넘겨주면 실행이 안 될 겁니다.

테이블이 없다는 에러가 나오죠. 다음 스키마 파일 중에 사용 중인 DB에 맞는 녀석을 골라서 테이블을 만들어 준 다음에 실행해 봅니다. 그럼 돌아갈 겁니다.


4. 앞으로 할 일

JobParameter가 이전에 사용한 것과 같다면 배치는 다시 돌지 않습니다. JobParameter를 다른 정보를 가지도록 매번 새로 만들어 줘야 하는데, 그 부분을 좀 살펴봐야겠습니다. Incrementer라는 것과 관련이 있어 보이던데 매번 실행할 때마다 자동으로 겹치지 않는 JobParameter를 만들어 주는게 있을 법도 한데 말이죠.

배치 테스트에 대하 알아봐야겠습니다. 어떻게 테스트 할 수 있는지. 스프링 배치가 제공해주는 테스트 방법은 어떤 것인지.

하이버네이트와 스프링 배치 기본 테이블 스키마를 맵핑해줄 자바빈 객체들은 없는지 살펴봐야겠습니다. 이것도 어딘가 있을 법도 한데 말이죠. 테이블 보고서 직접 자바빈 만들어서 맵핑 해주기는 좀 귀찮자나요. 누군가 해놨거나.. 하이버네이트 툴로 스키마에서 자바빈을 만들고 맵핑도 해주는 걸 찾아보던가 해야겠습니다. 하이버 맵핑만 끝나면.. 뭐 배치 정보 가져와서 화면에 뿌려주기만 하면 되니깐.. 식을 죽 먹기겠네요.

음.. 그리고 간간히 레퍼런스 보면서 이론 공부도 좀 해야겠네요. 여러 용어들이랑 개념들 기타 세부 기능들에는 뭐가 있는지 등등등.

'Spring Batch > etc' 카테고리의 다른 글

[스프링 배치 2.0] 걸음마 떼기  (2) 2009.08.21
top

  1. Favicon of http://benelog.egloos.com BlogIcon benelog 2009.09.29 00:13 PERM. MOD/DEL REPLY

    쓰신지 좀 시간이 지난글이라서 이미 해결책을 찾으셨을 것 같은데요, 검색으로 찾아오셨을 분들을 위해서 추가로 정보를 남깁니다 ^^;

    1. 매번 실행할 때마다 겹치지 않는 JobParameters를 만드는건 JobParametersIncrementer를 통하라고 매뉴얼에 나와 있구요.
    http://static.springsource.org/spring-batch/reference/html/configureJob.html#JobParametersIncrementer

    2. "모든 프로세싱이 끝난 아이템 전체 목록을 라이터가 받아서 작업 합니다" 는 처음 스프링배치를 보시는 분들은 혹시나 모든 건들을 다 메모리에 올린다고 오해하실까봐 걱정스러운데, 정확히는 chunk단위, 즉 commit-size 만큼씩 읽어서 List로 만들어서 ItemWriter로 넘어가게 되어 있죠.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.09.29 09:42 신고 PERM MOD/DEL

    우와!! 보충설명 감사합니다. :)

    인크리멘터를 이용하는 것이었군요.

Write a comment.


ItemReader - Spring Batch Chapter 3

Spring Batch/Chapter 3 : 2008. 7. 29. 23:37


DB에서는 단일 레코드, 애플리케이션에서는 단일 도메인 객체, 배치 작업에서는 Item. 이 녀석을 읽어들일 때 사용하는 것이 바로 ItemReader.

public interface ItemReader {

  Object read() throws Exception;

  void mark() throws MarkFailedException;

  void reset() throws ResetFailedException;
}

아주 깔끔한 인터페이스 read()는 읽고, mark()는 표시해두고, reset()은 최근에 mark() 된 곳으로 이동. 마치 책갈피가 있는 Iterator 느낌이 납니다.

그리고 이 인터페이스를 구현한 녀석이 DB나 파일등에 연결이 필요한 경우 반드시 같이 구현하는 인터페이스가 있는데 그건 바로 ItemStream.

public interface ItemStream {

  void open(ExecutionContext executionContext) throws StreamException;

  void update(ExecutionContext executionContext);
 
  void close(ExecutionContext executionContext) throws StreamException;
}

ExecutionContext를 사용해서 처음 위치부터 시작하지 않고 이전에 멈췄던 곳에서 다시 시작 할 수 있는 방법을 제공합니다. open() 해서 연결하고, update()는 ExecutionContext에서 현재 상태 읽어옵니다. 따라서 커밋하기 전에 update()를 호출해서 현재상태가 DB에 보존되고 있는지 확인할 때 사용하고, close()는 open으로 읽어온 자원들 반납합니다. 작업 마친 담에 꼭 호출해주는게 좋겠네요.

DB에 있는 Item을 읽어올 때, 스프링의 JdbcTemplate에서는 RowMapper를 사용해서 반환된 ResultSet에 있는 데이터들을 모두. 왕창. 한방에. 객체로 맵핑해서 반환해줬습니다. 이게 이슈가 되기도 합니다. 왜냐면, 데이터가 너무 많으면 메모리가 모자라서 죽게 될테니까요. 그런데 배치에서도 역시 RowMapper를 사용하는데, 그런 일이 벌어지지 않게 하기 위해서 두 가지 방법을 마련했습니다. 하나는 커서Cursor, 하나는 드라이빙쿼리DrivingQuery.

Cursor 스타일이란?
맵핑을 한 번에 전부 하는게 아니라, 한 번에 한 줄씩 합니다. "스트리밍" 방식이라고 할 수 있습니다. 위에서 살펴본 ItemReader의 next()를 호출 할 때마다 한 줄(레코드)씩 이동합니다.

  HibernateCursorItemReader itemReader = new HibernateCursorItemReader();
  itemReader.setQueryString("from CustomerCredit");
  //For simplicity sake, assume sessionFactory already obtained.
  itemReader.setSessionFactory(sessionFactory);
  itemReader.setUseStatelessSession(true);
  int counter = 0;
  ExecutionContext executionContext = new ExecutionContext();
  itemReader.open(executionContext);
  Object customerCredit = new Object();
  while(customerCredit != null){
    customerCredit = itemReader.read();
    counter++;
  }
  itemReader.close(executionContext);

itemReader.read()를 할 때마다 RowMapper를 적용해서 객체를 던져주고, 다음 레코드로 넘어갑니다.

Driving Query 스타일이란?
레코드 전체를 가져오는게 아니라, 주키만 가져온 다음에 필요시에 애플리케이션의 DAO를 사용해서 객체를 DB에서 로딩하는 방법. 이 방법을 쓰는 이유는 DB2 처럼 Pessimistic Locking(읽는 롹킹)하는 경우에 Cursor 방법이 비효율적일 수 있기 때문입니다.

이 녀석의 구현체인 DrivingQueryItemReader가 의존하고 있는 인터페이스 KeyCollector.
 public interface KeyCollector {

    List retrieveKeys(ExecutionContext executionContext);

    void updateContext(Object key, ExecutionContext executionContext);
  }

첫번째 메소드야 뻔하고, updateContext는 현재 어디까지 읽었나, 책갈피를 끼워두는 겁니다.

KeyCollector 구현체
- SingleColumnJdbcKeyCollector : 주키가 컬럼 하나 일때 사용.
  SingleColumnJdbcKeyCollector keyCollector = new SingleColumnJdbcKeyCollector(getJdbcTemplate(),
  "SELECT ID from T_FOOS order by ID");

  keyCollector.setRestartSql("SELECT ID from T_FOOS where ID > ? order by ID");

  ExecutionContext executionContext = new ExecutionContext();

  List keys = keyStrategy.retrieveKeys(new ExecutionContext());

  for (int i = 0; i < keys.size(); i++) {
    System.out.println(keys.get(i));
  }
흠.. 이 예제 코드는 잘 이해가 안 가네요. ItemReader 인터페이스는 안 사용하나;;

복합키 일땐?? ExecutionContextRowMapper

'Spring Batch > Chapter 3' 카테고리의 다른 글

ItemReader - Spring Batch Chapter 3  (7) 2008.07.29
top

  1. Favicon of http://benelog.egloos.com BlogIcon benelog 2008.07.31 10:57 PERM. MOD/DEL REPLY

    DrivingQueryItemReader의 property로 keyCollector가 들어가서 동작하죠. 예제코드는 실전에서 저렇게 쓰라는 말보다는 해당 클래스의 동작을 보여주기 위한 성격이 강해 보이네요.

    그리고 ListItemReader처럼 ItemStream 이 아닌 ItemReader도 있기는해요 ^^;

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2008.07.31 11:22 PERM MOD/DEL

    그렇군요. 흠.. DrivingQuery를 볼 때 궁금한게 있었는데요. 왜 이 스타일 구현체는 iBatis만 있고 Hibernate는 없는걸까요? 또 반대로 Cursor 스타일의 구현체는 Hibernate가 있는데 iBatis용은 없네요. 무슨 이유가 있겠거니.. 하고 지나갔는데 마침 생각난김에 적어둡니다. ^^;;


    저 클래스는 보니까 테스트 용도인것 같구요. 사실상 ItemReader를 구현한 모든 (배치 로직 구현시에 필요한) 클래스들은 ItemStream을 구현했다고 봐도 괜찮을 것 같네요.

    Clients of an ItemReader that also implements ItemStream should call open before any calls to read, to open any resources such as files or obtain connections.

    레퍼런스에도 이렇게 나와있으니까요. :)

  2. Favicon of http://benelog.egloos.com BlogIcon benelog 2008.07.31 14:26 PERM. MOD/DEL REPLY

    일단 저의 생각은 hibernate로도 DrivingQuery는 가능할 것 같은데, iBatis로는 Cursor 스타일이 안 될 것만 같군요, hibernate의 ScrollableResults interface와 같은 것이 iBatis에 없는한 말이죠 ^^;

    그리고 매뉴얼에 영어해석이 다소 저와 다른 것 같은데, 저는 'ItemStream도 구현한 ItemReader를 사용하는 Client는 읽기 위한 호출 전에 open을 호출해야 한다..' 로 해석해서 ItemReader 중에서 ItemStream도 구현한 클래스들의 호출방식에 대한 설명이라고 생각했었습니다.

    뭐 실제 클래스들을 보면 DelegatingItemReader, ItemReaderAdapter, AggregateItemReader들도 ItemStream을 구현하지 않았는데, 어짜피 이 클래스들은 단독으로는 쓰이지 않는 것들이니 JMSItemReader 정도만이 구현 클래스중에 ItemStream이 아닌 것으로 보이기도 합니다.

    어쨓거나 대부분의 읽는 자원들이 file, DB등 열고 닫는 동작이 필요한 것들이고, Restarable한 장점을 살리기 위해서라도 ItemStream을 구현하지 않은 클래스는 별로 나오지 않을 것 같습니다. 아뭏든 저는 ItemReader와 ItemStream를 동시에 구현한 클래스는 그것이 반드시 붙어다니는 명세라기 보다는 그런 자원환경이 현실적으로 대부분이기 때문이라고 이해하고 있습니다. JMSItemReader 같은 예외도 있으니까요.

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2008.07.31 14:47 PERM MOD/DEL

    아.. 그렇군요. 제가 매뉴얼을 잘 못 이해한 것 같습니다. 감사합니다. 본문을 수정해야겠네요. ^^;;

    그럼 IbatisDrivingQueryItemReader의 read()를 호출하면, 이미 전부 키값들은 전부 읽어왔고, 그 상태에서 하나씩 순회하면서 키값을 던져주는 건가요?

    아.. 그렇게 되면 제가 포럼에 올린 질문 http://forum.ksug.org/viewtopic.php?f=6&t=157 에 대한 실마리를 찾을 수 있게 되는건데 말이죠.

    HibernateCursorItemReader의 read()를 호출하면, 그 때마다 한 row씩 가져와서 맵핑한 다음에 던져주는 것이고, 이런 게 커서 스타일 이란 거죠.

    ItemReader의 read()를 호출한다고 해서 무조건 커서 스타일이 아니라는 뜻이 되는데, 이렇게 되면 제가 포럼에 올렸던 궁금증 전부가 해결됩니다. 캬캬.

  3. Favicon of http://benelog.egloos.com BlogIcon benelog 2008.07.31 19:55 PERM. MOD/DEL REPLY

    네, Driving query에서는 미리 키값들은 read() 전에 다 읽어져 있는 상태입니다.

    open() 메서드에서 그 일을 하고 있죠. 포럼에 코드를 적어놓겠습니다~

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.07.31 21:25 신고 PERM MOD/DEL

    아 그랬었군요. 오호.. 포럼에 올렸던 궁금증이 해결됐네요. 감사합니다. :)

  4. Favicon of http://www.timberlandbaratas.com BlogIcon Mujer Timberland 2012.12.25 12:33 PERM. MOD/DEL REPLY

    Microsoft a annoncé lundi que son service de messagerie électronique Hotmail fonctionnait à nouveau normalement après une série de dysfonctionnements qui ont empêché certains de ses 360 millions d'utilisateurs à travers le monde de se connecter normalement à leurs comptes, http://www.timberlandbaratas.com zapatos timberland. De nombreux utilisateurs ont manifesté dimanche leur mécontentement via Twitter ou sur le site internet de Microsoft, http://www.timberlandbaratas.com outlet timberland. Microsoft a assuré "que l'accès aux courriels était complètement rétabli et que le contenu des bo, http://www.timberlandbaratas.com Timberland Online?tes de réception avait été récupéré", http://www.timberlandbaratas.com Timberland. Le géant informatique américain enquête toujours sur la cause de la panne et n'a pas donné le nombre précis d'usagersvictimes du "bug", http://www.timberlandbaratas.com timberland españa. High-Tech Facebook pèserait 50 milliards de dollars (presse) High-Tech Facebook pèserait 50 milliards de dollarsRelated articles:


    http://amitige.tistory.com/?page=1 La Bourse de Tokyo a fini en

    http://4think.tistory.com/category/?page=2 Des enseignants d'un collège du Plessis-Trévise (Val-de-Marne) qui s'étaient déjà mobilisés en

Write a comment.


The Domain Language of Batch - Spring Batch Chapter 2

Spring Batch/Chapter 2 : 2008. 7. 28. 23:26


배치 개념을 익히기 정말 좋은 챕터가 아닌가 생각됩니다. 스프링 배치의 도메인 언어인지, 일반적인 배치의 도메인 언어인지는 구분하기 힘들지만, 상당히 많이 정제되어 있다는 느낌을 받을 수 있었습니다. 분명, 수 많은 프로젝트의 배치 작업을 하면서 도출해낸 도메인 언어들이 아닐까 생각됩니다.

요즘은 귀찮아서 그림을 안 그렸었는데, 오랜만에 그려봐야겠습니다. 레퍼런스에 나와있는 그림에 표현하지 않은 도메인(JobParameters, ExecutionContext, Persistence 여부)도 있어서요.

사용자 삽입 이미지

후광이 있는 녀석들은 Persistent Domain입니다. 즉 (DB를 사용한다는 가정하에) Step이라는 테이블이 없다고 (즉, Step 정보를 유지하지 않는다고) 봐도 됩니다. 그래서 StepExecution 테이블에는 JobExecution의 주키를 참조하는 외례키 컬럼만 있고 Step_ID와 같은 컬럼은 없습니다.

연한색 박스는 인터페이스, 진한 색은 클래스입니다.

ExcutionContext는 StepExcuion 당 하나씩 생성됩니다.

재미있는 건 저 도메인들을 저장하는 책임을 지닌 JobRepository라는 인터페이스인데, 이 녀석의 구현이 어떻게 되어 있을까 궁금했는데, 구현체는 없었습니다. 어떻게 구현해야 할런지... JDBC 말고 애노테이션 기반 하이버네이트를 써서 구현하는 방법이 궁금해집니다. JobRepositoryHibernate 야.. 뭐 SessionFactory만 있으면 알아서 넣어줄테니 걱정되지 않는데, 저들 도메인의 맵핑 정보를 넘겨줘야 하는데 말이죠. 그걸 어떻게 애노테이션으로 할 방법은 없을까요. 흠... XML로만 해야 할까요. XML 로 해야 한다면, 맵핑 정보는 어떻게 만들면 될까요? 어느정도 고정적인 도메인이니까, 하나 만들어 두는게 좋을 것 같습니다.

흠.. Spring Batch + 하이버네이트를 기반으로 한 어떤 프레임워크가 되겠군요.

자세한 설명은 http://static.springframework.org/spring-batch/spring-batch-docs/reference/html/core.html 를 참조하세요.


'Spring Batch > Chapter 2' 카테고리의 다른 글

The Domain Language of Batch - Spring Batch Chapter 2  (4) 2008.07.28
top

  1. Favicon of http://benelog.egloos.com BlogIcon benelog 2008.07.29 08:15 PERM. MOD/DEL REPLY

    그리고 배치의 도메인 언어는 웹의 MVC만큼은 통일되지는 않은 것 같은데, 대체로 Job,Step, Transformation 같은 용어는 여기저기서 많이 보이더군요(Pentaho Data Integratino이나 Websphere XD computer Grid 같은 솔류션에서도 본듯..) 그런데 영어 단어 뜻을 생각하면 그 정도 용어의 유사성은 당연한 것 같기도 하군요 ^^;

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.07.29 08:28 신고 PERM MOD/DEL

    네. 좋은 정보 감사합니다. :)

  2. Favicon of http://benelog.egloos.com BlogIcon benelog 2008.07.29 08:18 PERM. MOD/DEL REPLY

    SimpleJobRepository가 JobRepository를 implements 하고 있죠. 여기에 JobInstanceDao, JobExecutionDao, StepExecutionDao가 속성으로 들어가 있고, JobInstanceDao를 구현하는 클래스로는 메모리를 사용하는 MapJobInstanceDao와 JDBC를 사용하는 JdbcJobInstanceDao가 있습니다. Hiberate를 사용하려면 이런 DAO클래스부터 만들어주면 될 것 같네요. JdbcJobInstanceDao같은 것대신 hibernate로 재작성한다면 어떤 장점이 있을지는 생각해봐야 할 것 같네요 ^^;

    Springbatch에서는 HibernateCursorItemReader나
    HibernateAwareItemWriter 클래스로 Hibernate사용자를 위한 연결점을 제공하기는 하는데, JobRepository에서는 별도로 사용자가 코드를 짤 일이 ItemReader나 Writer보다는 적을 것이라고 예측했던 것 같습니다.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.07.29 08:25 신고 PERM MOD/DEL

    우와.. 기본 구현체가 있었군요;; 보통 스프링 API에는 인터페이스 밑에 그걸 구현한 클래스들 목록도 보여주는데, 아무것도 없길래 기본 구현체가 없는 줄 알았는데 있었네요.

    와.. 감사합니다.

Write a comment.