2017-05-16 2 views
1
내가 일괄 봄에 새로 온 사람

로 작성하고 스프링 배치는 다른 데이터베이스에 작성하고 CSV

  • 쓰기 내가

    1. MySQL 데이터베이스에서 읽기 일괄 작업을 구현하기 위해 노력하고, 한 번에 데이터베이스에서 읽기 결과는 CSV 파일로
    2. MySQL 결과 집합을 처리하고 다른 데이터베이스에 씁니다.

    나는 this question on StackOverflow를 통해 검토 한 결과,하지만 메인 허용 대답은 데이터베이스에서 두 번 읽고 두 단계를 구현하기 위해 기본적으로했다 :

    <job id="myJob"> 
        <step id="step1" next="step2"> 
         <tasklet> 
          <chunk reader="reader" writer="typeAwriter"/> 
         </tasklet> 
        </step> 
        <step id="step2"> 
         <tasklet> 
          <chunk reader="reader" processor="processor" writer="typeBwriter"/> 
         </tasklet> 
        </step> 
    </job> 
    

    보다이 일을 더 효율적인 방법이되지 않습니다 MySQL 데이터베이스에서 두 번 읽는 중입니까? 예를 들어 쿼리가 상당히 커서 시스템 성능을 끌어 올리는 경우 어떻게해야합니까?

  • 답변

    0

    나는 내 자신의 질문에 답할 것이다. 이를 수행하는 방법은 여러 가지가 있지만 속성과 개체를 먼저 StepExecutionContext에 저장 한 다음 단계 완료 후 JobExecutionContext으로 승격하는 것이 좋습니다. 당신의 작가에

    가/리더 개인 StepExecution 선언 : 또한 매우 철저하게 here.

    1 단계 설명되어 있습니다. 그런 다음, 읽기/쓰기 방법 내부의 단계 컨텍스트를 만들고, 키/값 쌍으로에 데이터를 입력 :

    ExecutionContext stepContext = this.stepExecution.getExecutionContext(); 
    stepContext.put("someKey", someObject); 
    

    2 단계 : 당신의 단계의 빈 설정에 ExecutionContextPromotionListener를 추가합니다. ExecutionContextPromotionListener 당신이 LinkedIn article에서이 구현과 유사한 당신의 단계를 넘어 작업 범위를 촉진하고자하는 키를 포함 키라는 String[] 특성이 포함되어야합니다

    @Bean 
    public ExecutionContextPromotionListener promotionListener() { 
        ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener(); 
        listener.setKeys(new String[] { "entityRef" }); 
        return listener; 
    } 
    

    단계 3 : 당신은 또한 추가 할 필요가 당신의 단계 전에 작가에 StepExecution가 실행됩니다 :

    @BeforeStep 
    public void saveStepExecution(StepExecution stepExecution) { 
        this.stepExecution = stepExecution; 
    } 
    

    4 단계 : 이 당신의을 줄 것이다stepExecution 인스턴스에 대한 메소드 액세스. 여기에서 stepContext에 액세스하여 데이터를 저장할 수 있습니다.예를 들어,이 예는 Spring Batch documentation에서 직접 오는 (

    write() { 
        ... // write logic 
    
        ExecutionContext stepContext = this.stepExecution.getExecutionContext(); 
        stepContext.put("keyYouWantToPutIn", theCorrespondingDataObject); 
    } 
    

    마지막으로, 다음 단계에서,이 데이터를 검색 할 수 있습니다 작성할 수 있습니다

    @BeforeStep 
    public void retrieveInterstepData(StepExecution stepExecution) { 
        JobExecution jobExecution = stepExecution.getJobExecution(); 
        ExecutionContext jobContext = jobExecution.getExecutionContext(); 
        this.someObject = jobContext.get("someKey"); 
    } 
    

    이 시간을, 그러나 액세스하고있어 것을 알 수 jobContext과 대조적으로 stepContext - 승진 됨

    2

    필요한 것은 태스크 릿 대신 청크 전략입니다. ItemReader가 데이터베이스에서 청크를 읽으면 프로세서가 데이터를 처리 한 다음 각 항목에 대해 데이터베이스 및 파일에 쓸 수있는 ItemWriter로 보낼 수 있습니다. 이것은 여러 가지 가능한 전략 중 하나입니다. 비즈니스 논리에 대한 세부 사항을 모르지만, 이것이 자신 만의 아이디어를 얻는 데 충분한 정보라고 생각합니다.

    <?xml version="1.0" encoding="UTF-8"?> 
    <job id="customerJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd" 
    version="1.0"> 
    
        <step id="step1"> 
         <chunk item-count="5"> 
          <reader ref="itemReader"/> 
          <processor ref="itemProcessor"/> 
          <writer ref="itemWriter"/> 
         </chunk> 
        </step> 
    </job> 
    

    이것은 스프링에 대해 JSR-352 XML 유형이며 이에 상응하는 접근법을 가지고 있습니다.

    +0

    감사합니다.하지만이 질문에 대한 답변을 완전히 모르겠습니다. itemWriter에 CSV와 데이터베이스에 동시에 쓸 수있는 논리가 포함되어 있다고 제안하고 있습니까? ? 그렇다면 어떻게 구현 되나요? 나는 좀 더 파고 들어보기 좋은 해결책을 찾았다. 내 자신의 대답을하고 나에게 네가 생각하는 바를 알려줘! –

    +1

    ItemWriter의 구현은 비즈니스 로직의 세부 사항에 달려 있습니다. 물론 한 줄에 한 줄씩 처리하고 다음 줄에서 엔티티를 처리하여 파일 (또는 부르사)에 쓸 수 있습니다. –

    관련 문제