How to process logically related rows after ItemReader in SpringBatch?

前端 未结 5 2137
忘掉有多难
忘掉有多难 2020-12-15 05:51

Scenario

To make it simple, let\'s suppose I have an ItemReader that returns me 25 rows.

  1. The first 10 rows belong to student A

  2. The

5条回答
  •  时光说笑
    2020-12-15 06:16

    because you changed your question i add a new answer

    if the students are ordered then there is no need for list/map, you could use exactly one studentObject on the processor to keep the "current" and aggregate on it until there is a new one (read: id change)

    if the students are not ordered you will never know when a specific student is "finished" and you'd have to keep all students in a map which can't be written until the end of the complete read sequence

    beware:

    • the processor needs to know when the reader is exhausted
    • its hard to get it working with any commit-rate and "id" concept if you aggregate items that are somehow identical the processor just can't know if the currently processed item is the last one
    • basically the usecase is either solved at reader level completely or at writer level (see other answer)
    private SimpleItem currentItem;
    private StepExecution stepExecution;
    
    @Override
    public SimpleItem process(SimpleItem newItem) throws Exception {
        SimpleItem returnItem = null;
    
        if (currentItem == null) {
            currentItem = new SimpleItem(newItem.getId(), newItem.getValue());
        } else if (currentItem.getId() == newItem.getId()) {
            // aggregate somehow
            String value = currentItem.getValue() + newItem.getValue();
            currentItem.setValue(value);
        } else {
            // "clone"/copy currentItem
            returnItem = new SimpleItem(currentItem.getId(), currentItem.getValue());
            // replace currentItem
            currentItem = newItem;
        }
    
        // reader exhausted?
        if(stepExecution.getExecutionContext().containsKey("readerExhausted")
                && (Boolean)stepExecution.getExecutionContext().get("readerExhausted")
                && currentItem.getId() == stepExecution.getExecutionContext().getInt("lastItemId")) {
            returnItem = new SimpleItem(currentItem.getId(), currentItem.getValue());
        }
    
        return returnItem;
    }
    

提交回复
热议问题