gpt4 book ai didi

java - 在 Spring Batch 中读取 CSV 数据(创建自定义 LineMapper)

转载 作者:行者123 更新时间:2023-12-04 08:05:37 24 4
gpt4 key购买 nike

我一直在做一些工作,在 CSV 数据上编写一些批处理代码。我在网上找到了一个教程,到目前为止一直在使用它,但并没有真正理解它的工作原理或原因,这意味着我无法解决我目前面临的问题。
我正在使用的代码如下:

 @Bean
public LineMapper<Employee> lineMapper() {
DefaultLineMapper<Employee> lineMapper = new DefaultLineMapper<Employee>();
DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
lineTokenizer.setNames(new String[] { "id", "firstName", "lastName" });
lineTokenizer.setIncludedFields(new int[] { 0, 1, 2 });
BeanWrapperFieldSetMapper<Employee> fieldSetMapper = new BeanWrapperFieldSetMapper<Employee>();
fieldSetMapper.setTargetType(Employee.class);
lineMapper.setLineTokenizer(lineTokenizer);
lineMapper.setFieldSetMapper(fieldSetMapper);
return lineMapper;
}
我不完全清楚 setNames 是什么或 setIncludedFields真的在做。我浏览了文档,但仍然不知道引擎盖下发生了什么。为什么我们需要给 lineTokenizer 命名?为什么不能告诉它会有多少列数据?它的唯一目的是让 fieldSetMapper知道哪些字段映射到哪些数据对象(它们是否都需要与 POJO 中的字段命名相同?)?
我有一个新问题,我的 CSV 包含需要处理的大量列(大约 25-35)。有没有办法在 setNames 中生成列?以编程方式使用 POJO 的变量名称,而不是手动编辑它们?
编辑:
示例输入文件可能类似于:
test.csv:
field1, field2, field3,
a,b,c
d,e,f
g,h,j
DTO:
public class Test {

private String field1;
private String field2;
private String field3;

//setters and getters and constructor

最佳答案

我看到了困惑,所以我将尝试澄清关键接口(interface)如何协同工作。一个 LineMapper负责将输入文件中的一行映射到域类型的实例。 Spring Batch 提供的默认实现是 DefaultLineMapper ,它将工作委托(delegate)给两个合作者:

  • LineTokenizer : 它接受一个字符串并将其标记为 FieldSet (类似于 JDBC 世界中的 ResultSet,您可以通过索引或名称获取字段)
  • FieldSetMapper : 映射FieldSet到您的域类型的实例

  • 所以流程是: String -> FieldSet -> Object :
    enter image description here
    每个接口(interface)都有一个默认实现,但如果需要,您可以提供自己的实现。
    定界线标记器 names DelimitedLineTokenizer 中的属性用于在 FieldSet 中创建命名字段.这允许您从 FieldSet 中按名称获取字段。 (再次,类似于 ResultSet 方法,您可以通过名称获取字段)。 includedFields允许从输入文件中选择字段子集,就像在您有 25 个字段并且只需要提取字段子集的用例中一样。
    BeanWrapperFieldSetMapper
    这个 FieldSetMapper实现需要一个类型,并使用 getter/setter 的 JavaBean 命名约定来设置来自 FieldSet 的目标对象的字段。 .

    Is there a way to generate the columns in setNames programmatically with the variable names of the POJOs, rather than editing them in by hand?


    这就是 BeanWrapperFieldSetMapper会做。如果您在 FieldSet 中提供字段名称,映射器将调用具有相同名称的每个字段的 setter 。名称匹配是模糊的,因为它允许紧密匹配,这里是 Javadoc 的摘录:
    Property name matching is "fuzzy" in the sense that it tolerates close matches,
    as long as the match is unique. For instance:

    * Quantity = quantity (field names can be capitalised)
    * ISIN = isin (acronyms can be lower case bean property names, as per Java Beans recommendations)
    * DuckPate = duckPate (capitalisation including camel casing)
    * ITEM_ID = itemId (capitalisation and replacing word boundary with underscore)
    * ORDER.CUSTOMER_ID = order.customerId (nested paths are recursively checked)
    此映射器也可以使用自定义 ConversionService 进行配置如果需要的话。如果这仍然不能涵盖您的用例,您需要提供自定义映射器。

    关于java - 在 Spring Batch 中读取 CSV 数据(创建自定义 LineMapper),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66234905/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com