我正在开发一个Spring批处理项目,我必须将数据从CSV文件推送到数据库中。管理实现批处理和其余部分,目前数据正在被推送,但我想知道是否有任何方法要跳过CSV文件中的某些列,因为其中一些列是无关紧要的。
我做了一些研究但是我找不到答案,除非我错过了什么。
我的代码示例如下。
<bean id="mysqlItemWriter"
class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
insert into WEBREPORT.RAWREPORT(CLIENT,CLIENTUSER,GPS,EXTENSION) values (:client, :clientuser, :gps, :extension)
]]>
</value>
</property>
答案 0 :(得分:0)
如果检查跳过很简单并且不需要数据库往返,则可以使用简单的itemProcessor,它为跳过的项返回null
真正简单的伪代码
Dim dir2 As New DirectoryInfo("d:\input")
Dim sw2 As New StreamWriter("d:\input\reportCond.txt")
For Each fi2 As FileInfo In dir2.GetFiles("report.txt")
Dim sr2 As New StreamReader(fi2.FullName)
While Not sr2.EndOfStream
Dim sLine As String = sr2.ReadLine
Dim myPath As String = sLine
Dim fileName As String =System.IO.Path.GetFileNameWithoutExtension(myPath)
' Build string
Dim sb As New System.Text.StringBuilder()
For Each c As Char In fileName
If Char.IsLetter(c) Then
sb.Append(c)
End If
Next
Dim comp As String = sLine.Substring(28)
' Here's the string you built
Dim letters As String = sb.ToString()
sw2.WriteLine(letters)
End While
Next
如果跳过检查更复杂并且需要数据库往返,则可以使用项目处理器,但性能(如果需要)将受到影响
如果性能至关重要......那么它取决于设置,要求和你的可能性,我会尝试两步,一步加载cvs到数据库(没有任何检查),第二步从数据库读取数据,和跳过检查是在SQL的itemReader
中使用聪明的SQL JOIN完成的答案 1 :(得分:0)
您可以实施FieldSetMapper
,它会将结构从一行映射到您在阅读器中的POJO。
让我们说:
name, surname, email
Mike, Evans, test@test.com
您的模型Person
仅包含name
和email
。你对surname
不感兴趣。这是reader
示例:
@Component
@StepScope
public class PersonReader extends FlatFileItemReader<Person> {
@Override
public void afterPropertiesSet() throws Exception {
//load file in csvResource variable
setResource(csvResource);
setLineMapper(new DefaultLineMapper<Person>() {
{
setLineTokenizer(new DelimitedLineTokenizer());
setFieldSetMapper(new PersonFieldSetMapper());
}
});
super.afterPropertiesSet();
}
}
您可以定义PersonFieldSetMapper
:
@Component
@JobScope
public class PersonFieldSetMapper implements FieldSetMapper<Person> {
@Override
public Person mapFieldSet(final FieldSet fieldSet) throws BindExceptio
{
final Person person = new Person();
person.setName(fieldSet.readString(0)); // columns are zero based
person.setEmail(fieldSet.readString(2));
return person;
}
}
这是为了跳过列,如果我理解这是你想要的。如果你想跳过行,也可以这样做,我在this question中解释了如何跳过空白行。