java - 使用Spring批处理读取文件并写入Map

标签 java spring hashmap spring-batch

背景

我对 Spring Batch 相当陌生,并且有以下要求:

  1. 读取至少包含百万条记录的文件(CSV、管道分隔符等)
  2. 将文件中的每一行加载到映射中,其中键作为第一列,值作为域对象/POJO。

据我了解,Spring 批处理具有所谓的面向 block 的处理,其中配置读取器、处理器和写入器来处理由提交间隔控制的一定数量的记录。这可以使用读者的任务执行器或通过分区添加另一层多线程来进一步扩展。

问题

如上面第 2 点所述,我想将文件加载到 map 中。为了便于讨论,假设我实现了以下 ItemWriter,它将 block 聚合到 Map 中。

public class MapItemWriter implements ItemWriter<SomePOJO> {

    private Map<String, SomePOJO> somePojoMap; 

    public MapItemWriter() {
        System.out.println("Writer created ");
        somePojoMap= new ConcurrentHashMap<String, SomePOJO>();
    }

    public void write(List<? extends SomePOJO> item) throws Exception {
        if (item != null && item.size() > 0) {
            for (SomePOJO data : item) {
                String uniqueId = data.Id();
                somePojoMap.put(uniqueId, data);
             }
        }
    }

    public Map<String, SomePojo> getSomePojoMap() {
        return somePojoMap;
    }
}

由于我可以访问 ItemWriter bean,因此我可以稍后调用 getSomePojoMap 来获取文件中记录的聚合 Map;然而,在 ItemWriter 中保存这样的 Map 感觉并不是解决此问题的最佳方法。另一个问题是,使用 ConcurrentHashMap 可能会降低性能,但我没有看到任何其他方法可以以线程安全的方式将文件聚合到 Map 中。

是否有更好的方法将我的文件聚合到 Map 中,而不是在编写器中保存 Map 并使用 ConcurrentHashMap?

最佳答案

差不多就是这样。您可以进行一些小的改进,例如将映射放入单独的 bean 中,这将使写入器 bean 和映射具有不同的生命周期,并将映射的读取器与写入器分离。例如,您可以将映射放入作业范围的 bean 中,并且仍然让编写器保持单例。

如果您的作业被划分为多个线程,您只需要一个 ConcurrentHashMap(我假设您不希望在作业之间共享映射)。

关于java - 使用Spring批处理读取文件并写入Map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35571796/

相关文章:

java - 打印通用类列表

java - 相同的对象用作 Map 中两个条目的键

java - 将两个 HashMap 的值相乘

java - Stax处理指令

java - 应用程序无故崩溃

java - Spring MVC,将@ExceptionHandler 迁移到 HandlerExceptionResolver 以获得 RESTful 服务

java - 如何根据方法忽略字段?

java - 考虑在您的配置中定义类型为 'com.gisapp.gisapp.dao.IUserDAO' 的 bean

android - 获取 HashMap 以按顺序打印出来

java - hystrix java.lang.NoSuchMethodError : rx. 主题.BehaviorSubject.hasValue()Z