Spring Batch 独自のItemReaderの実装

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【6/19開催】Kong Community Japan Meetup #4
本イベントでは、Kong Inc. のVP of ProductであるReza Shafii氏もプレゼンターとして参加。当社からはアーキテクト マネージャーの槌野の登壇が決定!参加無料です!!
https://column.api-ecosystem.sios.jp/connect/kong/1081/

【6/21開催】開発者目線でのSBOMとの向き合い方
SBOMの導入から開発者がSBOMの作成・管理を自動で行っていくための方法(デモ)を紹介します。SBOMを全く知らない人から、開発との統合までを紹介するので様々なレベルの方に学びがあるライブとなる予定です!
https://tech-lab.connpass.com/event/321422/

【7/19開催】現場で役立つAzure神小技10+α 〜生成AI,RAG,コスト削減など旬な技術満載のLT大会〜
Azureの最新技術や実用的な小技を紹介する特別なライトニングトーク大会を開催します!
https://tech-lab.connpass.com/event/319077/

【7/26開催】最適なIaCツールを選ぼう
プロジェクトでのツール選びに困らないための重要な観点をご説明します!
https://tech-lab.connpass.com/event/319532/

概要

Spring BatchではChankItemReaderを任意に入れ替えることができます。

CSVの読み込み

Spring BootのCSVファイルを読み込むライブラリを用いてItemReaderを作成します。

ItemReader

読み込むCSVファイルのデータ構造を作成します。
namevalueというふたつのフィールドを持った簡単なデータ構造を定義します。

  • SourceItemDto.java
    package com.sios.ex.springbatch;
    
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    public class SourceItemDto {
    
    	@Setter
    	@Getter
    	private String name;
    
    	@Setter
    	@Getter
    	private String value;
    
    	public SourceItemDto() {
    
    	}
    
    }
    

CSVファイルを読み込んでSourceItemDtoを生成するItemReaderを作成します。

  • SpringBatchSamp2e1Configuration.javaより抜粋
    @Bean
    @StepScope
    public FlatFileItemReader<SourceItemDto> sourceItemReader(
        @Value("#{jobParameters['filename']}") String filename) {
      FlatFileItemReader<SourceItemDto> reader = new FlatFileItemReader<SourceItemDto>();
      reader.setResource(new FileSystemResource(filename));
      reader.setLineMapper(new DefaultLineMapper<SourceItemDto>() {{
        setLineTokenizer(new DelimitedLineTokenizer() {{
          setNames(new String[] {"name", "value"});
        }});
        setFieldSetMapper(new BeanWrapperFieldSetMapper<SourceItemDto>() {{
          setTargetType(SourceItemDto.class);
        }});
      }});
      return reader;
    }
    

「@Value(“#{jobParameters[‘filename’]}”) String filename」はJobに指定したパラメータを受け取ります。
この場合@StepScodeアノテーションを指定する必要があります。

ItemProcessor

読み込んだCSVをデータベースに出力するためにデータベースのテーブルにエンティティを定義します。

  • TargetItemEntity.java
    package com.sios.ex.springbatch;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    import lombok.Data;
    import lombok.Getter;
    
    @Data
    @Entity
    @Table(name = "target_item")
    public class TargetItemEntity {
    
    	@Id
    	@Column(name = "name", nullable = false)
    	@Getter
    	private String name;
    
    	@Column(name = "value", nullable = false)
    	@Getter
    	private String value;
    
    	public TargetItemEntity() {
    
    	}
    
    	public TargetItemEntity(
    			String name,
    			String value) {
    		this.name = name;
    		this.value = value;
    	}
    }
    

ItemProcessorはCSVから読み込んだSourceItemDtoのオブジェクトを受け取りTargetItemEntityのオブジェクトを返します。

  • TargetItemProcessor.java
    package com.sios.ex.springbatch;
    
    import org.springframework.batch.item.ItemProcessor;
    
    public class TargetItemProcessor implements ItemProcessor<SourceItemDto, TargetItemEntity> {
    
    	@Override
    	public TargetItemEntity process(SourceItemDto item) throws Exception {
    		return new TargetItemEntity(item.getName(), item.getValue());
    	}
    
    }
    [/cdoe]
    
    ### ItemWriter
    
    **ItemWriter**はデータベースの**target_item**テーブルに出力するシンプルなものになります。
    
    [code]
      @Bean
      public ItemWriter<TargetItemEntity> targetItemWriter() {
        RepositoryItemWriter<TargetItemEntity> writer = new RepositoryItemWriter<>();
        writer.setRepository(targetItemRepository);
        writer.setMethodName("save");
        return writer;
      }
    

ItemReaderの作成

ItemReaderItemReader<T>を継承して作成することができます。
上記の例で使用したCSVファイルを読み込むItemReaderを実装する場合は次の通りです。

  • CsvSourceItemReader.java
    package com.sios.ex.springbatch;
    
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    import java.util.ArrayList;
    
    import org.springframework.batch.item.ItemReader;
    import org.springframework.batch.item.NonTransientResourceException;
    import org.springframework.batch.item.ParseException;
    import org.springframework.batch.item.UnexpectedInputException;
    
    public class CsvSourceItemReader implements ItemReader<SourceItemDto> {
    
    	private String filename;
    	private ArrayList<SourceItemDto> items = null;
    	private int nextIndex;
    
    	public CsvSourceItemReader(String filename) {
    		this.filename = filename;
    	}
    
    	private void readCsvFile() {
    		items = new ArrayList<SourceItemDto>();
    		try {
    			BufferedReader reader = new BufferedReader(new FileReader(filename));
    			try {
    				for (;;) {
    					String line = reader.readLine();
    					if (line == null) break;
    					String[] fields = line.split(",", 2);
    					SourceItemDto item = new SourceItemDto();
    					item.setName(fields[0]);
    					item.setValue(fields[1]);
    					items.add(item);
    				}
    			} finally {
    				reader.close();
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    
    	@Override
    	public SourceItemDto read()
    			throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
    		if (items == null) {
    			readCsvFile();
    			nextIndex = 0;
    		}
    		SourceItemDto item = null;
    		if (nextIndex < items.size()) {
    			item = items.get(nextIndex);
    			nextIndex++;
    		}
    		return item;
    	}
    
    }
    

read()メソッドが呼び出されるたびにSourceItemDtoのオブジェクトを返します。
返すSourceItemDtoのオブジェクトが終了したらnullを返します。

StepItemReaderの定義は次のようになります。

  • SpringBatchSamp2e1Configuration.javaより抜粋
    	@Bean
    	@StepScope
    	public CsvSourceItemReader sourceItemReader(
    			@Value("#{jobParameters['filename']}") String filename) {
    		return new CsvSourceItemReader(filename);
    	}
    

これらのように独自のItemReaderを作成することでさまざまな入力に対応したバッチ処理を実現することができます。

アバター画像
About サイオステクノロジーの中の人 5 Articles
サイオステクノロジーで働く中の人です。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる