Spring Batch如何将用户数据重组/聚合为单个对象

时间:2015-06-18 09:04:51

标签: spring spring-batch

我正在尝试将用户操作(如追踪)转换为用户摘要类(用户费用)。用户可以有多个操作但只有一个摘要。我无法在读者中总结追求,因为我需要一个处理器来拒绝某些操作,这取决于另一项服务。

所以有些代码:

class UserOperation {
  String userId;
  Integer price;
}

class UserSummary {
  String userId;
  Long sum;
}

@Bean
public Step retrieveOobClientStep1(StepBuilderFactory stepBuilderFactory, ItemReader<UserOperation> userInformationJdbcCursorItemReader, ItemProcessor<UserOperation, UserSummary> userInformationsProcessor, ItemWriter<UserSummary> flatFileWriter) {
    return stepBuilderFactory.get("Step1").<UserOperation, UserSummary>chunk(100) // chunck result that need to be aggregated... not good
        .reader(userInformationJdbcCursorItemReader) // read all user operations from DB
        .processor(userInformationsProcessor) // I need to reject or not some operations - but here 1 operation = 1 summary that is not good
        .writer(flatFileWriter) // write result into flat file
        .build();
}

我认为ItemReader / ItemProcessor / ItemWriter用于单项处理。 但是如何使用Spring Batch将多个记录重组为单个对象?只有Tasklet?

可能性但导致提交间隔时间小的问题

public class UserSummaryAggregatorItemStreamWriter implements ItemStreamWriter<UserSummary>, InitializingBean {

    private ItemStreamWriter<UserSummary> delegate;

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(delegate, "'delegate' may not be null.");
    }

    public void setDelegate(ItemStreamWriter<UserSummary> delegate) {
        this.delegate = delegate;
    }

    @Override
    public void write(List<? extends UserSummary> items) throws Exception {

        Map<String, UserSummary> userSummaryMap = new HashMap<String, UserSummary>();

        // Aggregate
        for (UserSummary item : items) {
            UserSummary savedUserSummary = userSummaryMap.get(item.getUserId());
            if (savedUserSummary != null) {
                savedUserSummary.incrementSum(item.getSum()); // sum
            } else {
                savedUserSummary = item;
            }
            userSummaryMap.put(item.getSubscriptionCode(), savedUserSummary);
        }

        Collection<UserSummary> values = userSummaryMap.values();
        if(values != null) {
            delegate.write(new ArrayList<UserSummary>(values));
        }
    }

    @Override
    public void open(ExecutionContext executionContext) throws ItemStreamException {
        delegate.open(executionContext);        
    }

    @Override
    public void update(ExecutionContext executionContext) throws ItemStreamException {
        delegate.update(executionContext);      
    }

    @Override
    public void close() throws ItemStreamException {
        delegate.close();       
    }

}

0 个答案:

没有答案