在 spring 批次中通过列顺序解析 csv

Parsing csv via column order in spring batch

我有一个 CSV 格式...

Kitten URL,Kitten Name,# of Reviews,Rating,Categories,,,,,,,,,,,,,
www.happykitten.com,happykittem.com,111746,7.8,Clothes & Fashion,Fashion Accessories,Ladies wear,Menswear,,,,,,,,,,
animedkitten.co.uk,Animed Kitten,33918,9.6,Pets,,,,,,,,,,,,,

所以第一列是 Kitten URL,Kitten Name,# of Reviews,Rating,然后是作为额外属性列出的可能类别。

我正在尝试使用 Spring 批处理,所以我指定了哑 object 来表示此 CSV。我遇到的第一个问题是(使用 the example from Spring documentation 我不知道如何解析标题中带有空格的 CSV。是否可以像这样使用 Spring 批处理?我可以注释每个喜欢在 Hibernate 中使用 csv 列的标题吗?

我的笨蛋 object 会变成...

public class ImportDataObject {
    private String kittenUrl;
    private String kittenName;
    private int numOfReviews;
    public String getKittenUrl() {
        return kittenUrl;
    }
    public void setKittenUrl(String kittenUrl) {
        this.kittenUrl = kittenUrl;
    }
    public String getKittenName() {
        return kittenName;
    }
    public void setKittenName(String kittenName) {
        this.kittenName = kittenName;
    }
    public int getNumOfReviews() {
        return numOfReviews;
    }
    public void setNumOfReviews(int numOfReviews) {
        this.numOfReviews = numOfReviews;
    }

}

我真的只想阅读前 2 列,附加一些字符串,然后保留 CSV 的其余部分。

我也在考虑之后使用这些多个逗号的最佳方法。不幸的是,这就是我获取数据的方式,我无法更改。

您可以为您的对象实现 FieldSetMapper,然后将其设置为您的 DefaultLineMapper。您的 FieldSetMapper 实现可以处理位置,您可以仅解析前几个位置并将其设置为您的 bean。

这是根据您发布的 URL 中的代码提出的建议:

reader.setLineMapper(new DefaultLineMapper<ImportDataObject>());
            setFieldSetMapper(new ImportDataObjectFieldSetMapper());
            }});
            setLinesToSkip(1); //skip header since read int will throw exception and I assume you do not need header info
        }});

然后更改为 POJO 对象以保存类别列表:

public class ImportDataObject {
    private String kittenUrl;
    private String kittenName;
    private int numOfReviews;
    private int rating; //add getters and setters
    private List<String> categories; //add getters and setters
    public String getKittenUrl() {
        return kittenUrl;
    }
    public void setKittenUrl(String kittenUrl) {
        this.kittenUrl = kittenUrl;
    }
    public String getKittenName() {
        return kittenName;
    }
    public void setKittenName(String kittenName) {
        this.kittenName = kittenName;
    }
    public int getNumOfReviews() {
        return numOfReviews;
    }
    public void setNumOfReviews(int numOfReviews) {
        this.numOfReviews = numOfReviews;
    }

}

这里是 FieldSetMapper:

public class ImportDataObjectFieldSetMapper implements FieldSetMapper<ImportDataObject> {

    @Override
    public ImportDataObject mapFieldSet(final FieldSet fieldSet) throws BindException {
        final ImportDataObject importDataObject = new ImportDataObject();

        importDataObject.setKittenUrl(fieldSet.readString(0));
        importDataObject.setKittenName(fieldSet.readString(1));
        importDataObject.setNumOfReviews(fieldSet.readInt(2));
        importDataObject.setRating(fieldSet.readInt(3));

        importDataObject.setCategories(new ArrayList<String>());
        for (int i = 4; i < fieldSet.getFieldCount(); i++) {
            importDataObject.getCategories().add(fieldSet.readString(i));
        }


        return importDataObject;
    }
}