2017-05-08 10 views
2

私はさまざまなCSVファイルをSQLデータベースに変換する必要があるアプリケーションで作業しています。異なるCSVファイルには可変数の列が含まれていますが、最初の3つは常にファイル間で一貫しています。Springバッチを使用して、フィールド値に基づいて異なるSQLテーブルにCSVレコードを書き込む

ファイルは読み込み中です。新しいデータベーステーブルは、可能な値の組み合わせを知っているので、CSVを取得する前に作成されています。しかし、Writer(私はJdbcBatchItemWriterを使用しています)に関しては、これらの列の値に基づいて新しく作成されたテーブル名を参照して、データが対応するテーブルを判断する必要があります。私は各列を見るまでテーブルに。

この例証するためにいくつかのコード:

public JdbcBatchItemWriter<Form> writer(@Value("#{jobParameters}") Map<String,Object> jobParameters) { 
    JdbcBatchItemWriter<Form> writer = new JdbcBatchItemWriter<Form>(); 
    ... 
    String parameters = getParameters(); 
    writer.setSql(String.format("INSERT INTO tableName VALUES (%s)", parameters.toString())); 

を基本的には、 'tableNameの' が処理される行ごとに更新する必要があります。

ItemSqlParameterSourceProviderとItemPreparedStatementSetterはSQLクエリ文字列に値を設定するように設計されているようですが、パラメータとしてテーブル名を取得するための検索結果はありません。私はライターの定義のレベルで各項目にアクセスすることができないので、準備されたステートメントを組み立てる前に値を置き換えることはできません。

私はそこに着く前にフィルタリング項目を検討しましたが、CSVから入力する必要がある不明な数の表についてはあまりにも面倒です。何か案は?

+0

カスタム分類子で結合されたClassifierCompositeItemWriterべきフィットをあなたの必要性 –

+0

ありがとう - これを使用し、より良い結果を得るのを選んだ! – MattSteel

答えて

0

あなた自身の作家を書くと、作家の地図が残っています。新しいtablenameが現れるたびに、新しいライターをインスタンス化してこのマップに格納することができます。

JdbcBatchItemWriterを即座にインスタンス化することは大したことではありません(Spring Beanである必要はありません)。

public static <T> ItemWriter<T> createDbItemWriter(DataSource ds, String sql, ItemPreparedStatementSetter<T> psSetter) { 
    JdbcBatchItemWriter<T> writer = new JdbcBatchItemWriter<>(); 

    writer.setDataSource(ds); 
    writer.setSql(sql); 
    writer.setItemPreparedStatementSetter(psSetter); 

    writer.afterPropertiesSet(); 
    return writer; 
} 

あなたの作家がローク何とかこの(注:このコードはテストされていない、それはあなたのアイデアを与えるためだけにここにある)を見なければならないでしょう

public class MyWriter extends ItemWriter<MyDto> { 

    private Map<String, JdbcBatchItemWriter<MyDto>> writersMaps = new HashMap<>(); 

    private JdbcBatchItemWriter<MyDto> getDbWriter(String tableName) throws Exception { 
     return writersMaps.putIfAbsent(tableName, createJdbcWriter(tableName)); 

    } 

    private JdbcBatchItemWriter<MyDto> createJdbcWriter(String tableName) { 
      JdbcBatchItemWriter<T> writer = new JdbcBatchItemWriter<>(); 

      // do your configuration 

      writer.afterPropertiesSet(); 
      return writer; 
    } 

    public void write(List<MyDto> items) throws Exception { 
     Map<String, List<MyDto>> groupedItems = 
       --> build a list for every targetTableName, put in a Map 


     for (Map.Entry<String, List<MyDto>> entry : groupedItems) { 
      getDbWriter(entry.getKey()).write(entry.getValue); 
     } 
    } 
} 
+0

アドバイスをいただきありがとうございます。私はClassifierCompositeItemWriterを拡張しました。これは、あなたが記述した行に沿って何かをしているようです。 – MattSteel

関連する問題