![](/img/trans.png)
[英]How to create a stream.parallel ItemReader in spring-batch?
[英]How to skip lines with ItemReader in Spring-Batch?
我有一个自定义项目阅读器,可以将文本文件中的行转换为我的实体:
public class EntityItemReader extends AbstractItemStreamItemReader<MyEntity> {
@Override
public MyEntity read() {
String line = delegate.read();
//analyze line and skip by condition
//line.split
//create entity with line values
}
}
这类似于FlatFileItemReader
。
然后读取的MyEntity
将通过JdbcItemReader
持久化到数据库。
问题:有时我的行包含应该跳过的值。
但是,当我在read()
器的read()
方法中只return null
时,不仅会跳过此项目,还会完全终止阅读,并且会跳过所有其他行。 因为null
元素是所有 spring-readers 的“信号”,即要读取的文件已完成。
那么:如果我不能返回 null,我该怎么做才能根据阅读器中的条件跳过特定的行? 因为根据读者的性质,我被迫在这里返回一个对象。
我认为过滤某些行的好做法是不使用阅读器,而是使用处理器(当您想过滤该行时,您可以在其中返回 null)。
请参阅http://docs.spring.io/spring-batch/trunk/reference/html/readersAndWriters.html :
6.3.2 过滤记录
项目处理器的一个典型用途是在将记录传递给 ItemWriter 之前过滤掉记录。 过滤是一种不同于跳过的动作; 跳过表示记录无效,而过滤仅表示不应写入记录。
例如,考虑读取包含三种不同类型记录的文件的批处理作业:要插入的记录、要更新的记录和要删除的记录。 如果系统不支持记录删除,那么我们不希望向 ItemWriter 发送任何“删除”记录。 但是,由于这些记录实际上并不是坏记录,我们希望将它们过滤掉,而不是跳过。 因此,ItemWriter 将只接收“插入”和“更新”记录。
要过滤记录,只需从 ItemProcessor 返回“null”。 框架将检测结果为“null”并避免将该项目添加到传递给 ItemWriter 的记录列表中。 像往常一样,从 ItemProcessor 抛出的异常将导致跳过。
对于我使用自定义阅读器的更一般情况,我遇到了类似的问题。 这由对象类型上的迭代器支持,并为每个读取的对象返回一个新项目(不同类型)。 问题是其中一些对象没有映射到任何东西,所以我想返回一些标记它的东西。
最终我决定定义一个 INVALID_ITEM 并返回它。 另一种方法可能是在 read() 方法中推进迭代器,直到下一个有效项,如果 .hasNext() 变为 false,则返回 null,但这更麻烦。
最初我也尝试返回一个自定义的 ecxeption 并告诉 Spring 跳过它上面的项目,但它似乎被忽略了,所以我放弃了(如果有太多无效的无论如何都没有性能)。
在这种情况下(以及阅读所有评论后),我认为您不能吃蛋糕并吃掉它。 最好的意见是(按照建议)抛出自定义异常并跳过“在它上面”。 您可以在其他地方优化您的实体创建或流程,这样您就不会失去太多的性能。 祝你好运。
我们可以通过自定义的虚拟对象来处理它。
private final MyClass DUMMYMyClassObject ;
private MyClass(){
// create blank Object .
}
public static final MyClass getDummyyClassObject(){
if(null == DUMMYMyClassObject){
DUMMYMyClassObject = new MyClass();
}
return DUMMYMyClassObject ;
}
当需要跳过阅读器中的记录时,只需使用以下内容:
return MyClass.getDummyyClassObject();
同样可以在处理器中忽略,检查对象是否为空或按照私有默认构造函数中编写的逻辑。
对于跳过行,当您想跳过某些行时可以抛出异常,如下所示。
我的春季批次步骤
@Bean
Step processStep() {
return stepBuilderFactory.get("job step")
.<String, String>chunk(1000)
.reader(ItemReader)
.writer(DataWriter)
.faultTolerant() //allowing spring batch to skip line
.skipLimit(1000) //skip line limit
.skip(CustomException.class) //skip lines when this exception is thrown
.build();
}
我的物品阅读器
@Bean(name = "reader")
public FlatFileItemReader<String> fileItemReader() throws Exception {
FlatFileItemReader<String> reader = new FlatFileItemReader<String>();
reader.setResource(resourceLoader.getResource("c://file_location/file.txt"));
CustomLineMapper lineMapper = new CustomLineMapper();
reader.setLineMapper(lineMapper);
return reader;
}
我的自定义线映射器
public class CustomLineMapper implements LineMapper<String> {
@Override
public String mapLine(String s, int i) throws Exception {
if(Condition) //put your condition here when you want to skip lines
throw new CustomException();
return s;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.