在 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;
}
}
我有一个 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;
}
}