2017-03-01 13 views
0

通常、csvファイルから読み込んでデータベースに書き込むと、すべての行がPOJO(ドメインオブジェクト)にマップされます。しかし、csvファイルが変更されたときにこれを行う方法は?つまり、フォーマットが異なる多くのcsvファイルがあり、それぞれにPOJOを書きたくないということです。ドメインオブジェクトにラインをマッピングせずにspringbatchを使用する方法

私はそれを扱う2つの方法を考えることができます。最初にPOJOクラスを動的に生成しますが、どうすればよいでしょうか?次に、PassThroughFieldSetMapperPassThroughItemProcessorを使用しますが、SQLのパラメータをJdbcBatchItemWriterに設定する方法はありますか?

答えて

0

これは相対的に設定可能ですが、最終的にファイルのフィールドをデータベースのどこかのの列にマップする必要があります。

このようなものから始めて、次にfieldMap beanを動的に定義する方法を理解することができます。さらに進んで、データベースの各列のデータ型を含めることもできます。

public class FieldSetItemSqlParameterSourceProvider 
        implements ItemSqlParameterSourceProvider<FieldSet> { 
    @Override 
    public SqlParameterSource createSqlParameterSource(FieldSet item) { 
     Map<String, Object> map = new HashMap<>(); 
     for (Entry<Object, Object> entry : item.getProperties().entrySet()) { 
      map.put((String) entry.getKey(), entry.getValue()); 
     } 
     return new MapSqlParameterSource(map); 
    } 
} 
ItemSqlParameterSourceProvider

<bean id="csvReader" class="org.springframework.batch.item.file.FlatFileItemReader"> 
    <property name="resource" value="#{jobParameters['FILENAME']}" /> 
    <property name="lineMapper"> 
     <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"> 
      <property name="lineTokenizer"> 
       <bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"> 
        <property name="names" value="#{fieldMap.keySet()}" /> 
       </bean> 
      </property> 
      <property name="fieldSetMapper"> 
       <bean class="org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper" /> 
      </property> 
     </bean> 
    </property> 
</bean> 

<bean id="jdbcWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="sql" ref="sqlString" /> 
    <property name="itemSqlParameterSourceProvider"> 
     <bean class="org.sample.sql.FieldSetItemSqlParameterSourceProvider" /> 
    </property> 
</bean> 

<bean id="sqlString" class="org.sample.factory.SqlFactoryBean"> 
    <property name="table" value="MY_TABLE" /> 
    <property name="schema" value="${my.schema}" /> 
    <property name="fieldMap" ref="fieldMap" /> 
</bean> 

<util:map id="fieldMap"> 
    <entry key="firstName" value="FIRST_NAME" /> 
    <entry key="lastName" value="LAST_NAME" /> 
    <entry key="email" value="EMAIL" /> 
    <entry key="birthDate" value="BIRTH_DATE" /> 
</util:map> 

FactoryBeanの

public class SqlFactoryBean implements FactoryBean<String> { 

    private String table; 
    private String schema; 
    private Map<String, String> fieldMap; 

    @Override 
    public String getObject() throws Exception { 
     Assert.isTrue((fieldMap != null) && (fieldMap.size() > 0)); 
     final StringBuilder sb = new StringBuilder("INSERT INTO " + schema + "." + table + " "); 

     final Iterator<Entry<String, String>> iterator = fieldMap.entrySet().iterator(); 
     Entry<String, String> entry = iterator.next(); 
     final StringBuilder columnBuilder = new StringBuilder("(" + entry.getValue()); 
     final StringBuilder paramBuilder = new StringBuilder("(" + entry.getKey()); 
     while (iterator.hasNext()) { 
      entry = iterator.next(); 
      columnBuilder.append("," + entry.getValue()); 
      paramBuilder.append("," + entry.getKey()); 
     } 
     columnBuilder.append(")"); 
     paramBuilder.append(")"); 

     sb.append(columnBuilder.toString()); 
     sb.append(" values "); 
     sb.append(paramBuilder.toString()); 

     return sb.toString(); 
    } 
} 

関連する問題