我想创建一个批处理,使用Spring批处理从ini文件中读取数据并将数据保存在数据库中但是当我查询org.springframework.batch.item.file.FlatFileItemReader
类时,我没有找到从ini文件中解析数据的方法,我尝试将ini4j
API与spring批处理相结合,但没有结果
我的ini文件:
[Cat]
a=1
b= 2
c= 3
d= 4
e= 5
f= 6
[Cat2]
a=11
b= 21
c= 31
d= 41
e= 51
f= 61
答案 0 :(得分:1)
您可以做的是定义一个包含委托ItemStreamReader
的{{1}},这只是ItemStreamReader
使用FlatFileItemReader
作为行映射器。在PatternMatchingCompositeLineMapper
中,循环读取委托中的行,如果该行是ItemStreamReader
域对象的实例,则将其添加到Property
域对象的列表中。 Section
允许你做的是检查模式匹配的行,并将其传递给右边的tokenizer和fieldSetMapper。
这样做可以让您将多行读入一个包含PatternMatchingCompositeLineMapper
的{{1}}域对象。
Section
对于自定义List<Property>
,您可以这样做。您可以看到读数被委托给另一个读者,您将在稍后定义
public class Section {
private String name;
private List<Property> properties;
// getters and setters
@Override
public String toString() {
StringBuilder sb = new StringBuilder(name);
for (Property prop: properties) {
sb.append("," + prop.getKey() + "=" + prop.getValue());
}
return sb.toString();
}
}
public class Property {
private String key;
private String value;
// getters and setters
}
然后在您的配置中,使用ItemStreamReader
import java.util.ArrayList;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
public class IniFileItemReader implements ItemStreamReader<Object> {
private Object curItem = null;
private ItemStreamReader<Object> delegate;
@Override
public Object read() throws Exception, UnexpectedInputException,
ParseException, NonTransientResourceException {
if (curItem == null) {
curItem = (Section) delegate.read();
}
Section section = (Section) curItem;
curItem = null;
if (section != null) {
section.setProperties(new ArrayList<Property>());
while (peek() instanceof Property) {
section.getProperties().add((Property) curItem);
curItem = null;
}
}
return section;
}
private Object peek() throws Exception {
if (curItem == null) {
curItem = delegate.read();
}
return curItem;
}
public void setDelegate(ItemStreamReader<Object> delegate) {
this.delegate = delegate;
}
@Override
public void close() throws ItemStreamException {
delegate.close();
}
@Override
public void open(ExecutionContext arg0) throws ItemStreamException {
delegate.open(arg0);
}
@Override
public void update(ExecutionContext arg0) throws ItemStreamException {
delegate.update(arg0);
}
}
您看到我也使用了自定义PatternMatchingCompositeLineMapper
。我可能只能使用<bean id="inputFile" class="org.springframework.core.io.FileSystemResource"
scope="step">
<constructor-arg value="#{jobParameters[inputFile]}"></constructor-arg>
</bean>
<bean id="sectionFileReader"
class="com.underdogdevs.springbatch.reader.IniFileItemReader">
<property name="delegate" ref="trueSectionFileReader"></property>
</bean>
<bean id="trueSectionFileReader"
class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="lineMapper">
<bean
class="org.springframework.batch.item.file.mapping.PatternMatchingCompositeLineMapper">
<property name="tokenizers">
<map>
<entry key="[*" value-ref="sectionLineTokenizer">
</entry>
<entry key="*" value-ref="propertyLineTokenizer"></entry>
</map>
</property>
<property name="fieldSetMappers">
<map>
<entry key="[*" value-ref="sectionFieldSetMapper">
</entry>
<entry key="*" value-ref="propertyFieldSetMapper">
</entry>
</map>
</property>
</bean>
</property>
<property name="resource" ref="inputFile"></property>
</bean>
<bean id="sectionLineTokenizer"
class="com.underdogdevs.springbatch.tokenizer.SectionLineTokenizer">
</bean>
<bean id="sectionFieldSetMapper"
class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="section"></property>
</bean>
<bean id="section" class="com.underdogdevs.springbatch.domain.Section"
scope="prototype">
</bean>
<bean id="propertyLineTokenizer"
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value="="></property>
<property name="names" value="key,value"></property>
</bean>
<bean id="propertyFieldSetMapper"
class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="property"></property>
</bean>
<bean id="property" class="com.underdogdevs.springbatch.domain.Property"
scope="prototype">
</bean>
,但是当我意识到它时,我已经定义了这个类
LineTozenizer
使用以下作家和作业
DelimitedLineTokenizer
并使用此ini文件
import org.springframework.batch.item.file.transform.DefaultFieldSetFactory;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.batch.item.file.transform.FieldSetFactory;
import org.springframework.batch.item.file.transform.LineTokenizer;
public class SectionLineTokenizer implements LineTokenizer {
private final String nameField = "name";
private final FieldSetFactory fieldSetFactory = new DefaultFieldSetFactory();
@Override
public FieldSet tokenize(String line) {
String name = line.replaceAll("\\[", "").replaceAll("\\]", "").trim();
return fieldSetFactory.create(new String[] { name },
new String[] { nameField });
}
}
我得到以下输出,这是我<bean id="outputFile"
class="org.springframework.core.io.FileSystemResource" scope="step">
<constructor-arg value="#{jobParameters[outputFile]}"></constructor-arg>
</bean>
<bean id="outputFileWriter"
class="org.springframework.batch.item.file.FlatFileItemWriter">
<property name="resource" ref="outputFile"></property>
<property name="lineAggregator">
<bean
class="org.springframework.batch.item.file.transform.PassThroughLineAggregator">
</bean>
</property>
</bean>
<batch:step id="outputStep">
<batch:tasklet>
<batch:chunk commit-interval="10" reader="sectionFileReader"
writer="outputFileWriter">
<batch:streams>
<batch:stream ref="sectionFileReader" />
<batch:stream ref="trueSectionFileReader" />
</batch:streams>
</batch:chunk>
</batch:tasklet>
</batch:step>
<batch:job id="iniJob">
<batch:step id="step1" parent="outputStep"></batch:step>
</batch:job>
类[Cat]
a=1
b=2
c=3
d=4
e=5
f=6
[Cat2]
a=11
b=21
c=31
d=41
e=51
f=61
中的格式
toString()