복붙노트

[SPRING] 값을 집계하고 단일 값을 쓰는 스프링 배치

SPRING

값을 집계하고 단일 값을 쓰는 스프링 배치

나는 스프링 배치를 사용하고 있으며 다음을 달성해야합니다.

나는 과거에 일괄 처리를 사용했고 다음과 같은 접근 방식을 생각했습니다. 2 단계로 배치를 작성하십시오.

1 단계:

2 단계:

1 단계에서지도를 채웠습니다. 이 맵은 @JobScope로 선언되었습니다.

나는 단지 값 목록을 읽어야하는 step2 독자를 어떻게 만듭니 까? ListItemReader를 시도했지만 ListItemReader에서 Map에 액세스 할 수 없습니다.

해결책을 조언하거나이 문제를 해결할 더 나은 방법이 있다면

감사

해결법

  1. ==============================

    1.옵션 1: cvs가 이미 날짜순으로 정렬되어 있다면 키 값이 변경 될 때까지 행을 읽는 그룹 리더를 구현할 수 있습니다. 그런 다음 전체 그룹을 하나의 항목으로 프로세서에 전달할 수 있습니다.

    옵션 1: cvs가 이미 날짜순으로 정렬되어 있다면 키 값이 변경 될 때까지 행을 읽는 그룹 리더를 구현할 수 있습니다. 그런 다음 전체 그룹을 하나의 항목으로 프로세서에 전달할 수 있습니다.

    이러한 그룹 리더는 다음과 같이 보일 수 있습니다.

      private SingleItemPeekableItemReader<I> reader;
      private ItemReader<I> peekReaderDelegate;
    
      @Override
      public void afterPropertiesSet() throws Exception {
        Assert.notNull(peekReaderDelegate, "The 'itemReader' may not be null");
        this.reader= new SingleItemPeekableItemReader<I>();
        this.reader.setDelegate(peekReaderDelegate);
      }
    
      @Override
      // GroupDTO is just a simple container. It is also possible to use
      // List<I> instead of GroupDTO<I>
      public GroupDTO<I> read() throws Exception {
        State state = State.NEW; // a simple enum with the states NEW, READING, and COMPLETE
        GroupDTO<I> group = null;
        I item = null;
    
        while (state != State.COMPLETE) {
          item = reader.read();
    
          switch (state) {
            case NEW: {
              if (item == null) {
                // end reached
                state = State.COMPLETE;
                break;
              }
    
              group = new GroupDTO<I>();
              group.addItem(item);
              state = State.READING;
              I nextItem = reader.peek();
              // isGroupBreak returns true, if 'item' and 'nextItem' do NOT belong to the same group
              if (nextItem == null || getGroupBreakStrategy.isGroupBreak(item, nextItem)) {
                state = State.COMPLETE;
              }
              break;
            }
            case READING: {
              group.addItem(item);
    
              // peek and check if there the peeked entry has a new date
              I nextItem = peekEntry();
              // isGroupBreak returns true, if 'item' and 'nextItem' do NOT belong to the same group
              if (nextItem == null || getGroupBreakStrategy.isGroupBreak(item, nextItem)) {
                state = State.COMPLETE;
              }
              break;
            }
            default: {
              throw new org.springframework.expression.ParseException(groupCounter, "ParsingError: Reader is in an invalid state");
            }
          }
        }
    
        return group;
      }
    

    다음 요소를 미리 읽으려면 SingleItemPeekableItemReader가 필요합니다. 이것은 정상적인 독자를 감싸줍니다.

    옵션 2 : 1 단계는 제안한대로이지만 2 단계의 작업 릿을 작성하기 만하면됩니다. 리더 프로세스 라이저 접근 방식을 사용할 필요가 없으며 맵의 내용을 파일에 쓰는 간단한 태스크 렛을 사용할 수 있습니다.

    옵션 3 : 2 단계에서 리더 - 프로세서 - 작가 접근 방식을 사용하고 싶다면지도를 반복하는 독자를 작성하십시오.

    (나는 그 코드를 테스트하지 않았다.)

    public class MapReader implements ItemReader {
    
         private MapContainer container;
         private Iterator<Map.Entry<Date, Integer> mapIterator;
    
         @PostConstruct
         public void afterPropertiesSet() {
            Assert.notNull(container);
            iterator = container.getMap().entry().iterator;
         }
    
         public void setMapContainer(MapContainer container) {
             this.container = container;
         }
    
         public Map.Entry<Date, Integer> read() {
            if (iterator.hasNext()) {
               return iterator.next();
            }
            return null;
          }
    }
    
    @Component
    public class MapContainer {
        private Map<Date, Integer> data = new Hashmap<>();
    
        public Map<Date, Integer> getMap() {
            return data;
        }
    
        // add modifier method as needed for step 1
    
    }
    

    그래서 컨테이너에 대한 단일 스프링 - 빈 인스턴스를 생성하고, 2 단계의 프로세서에 그것을 삽입하고, 거기에 채우고, 위의 판독기에 삽입하십시오.

  2. from https://stackoverflow.com/questions/31558470/spring-batch-to-aggregate-values-and-write-single-value by cc-by-sa and MIT license