LoginSignup
1
0

More than 1 year has passed since last update.

Spring Batchでtsvファイルをバッチ処理でDBに取り込む

Last updated at Posted at 2022-04-05

#はじめに

tsvファイルをresouse配下に置き、SpringBootのバッチ処理でPostgresのテーブルに取り込みを行う機能を作成したい。

#環境

  • macOS Big Sur 11.2.3
  • Java8
  • SpringBoot Maven
  • PostgreSQL

#pom.xml
Spring Batchを依存性に追加する

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-batch</artifactId>
</dependency>

#テーブル作成

src/main/resources/schema-all.sql

DROP TABLE if EXISTS items;

create table items (
  id serial not null
, name character varying(255)
, condition integer
, category integer
, brand character varying(255)
, price double PRECISION
, shipping integer
, description text
, constraint items_PKC primary key (id)
);

Spring Bootでは、src/main/resources直下にschema.sqlやdata.sqlを配備することで、起動時にDDLやDMLを自動で実行してくれます。

 また、-allをつけることでどのプラットフォームでも(OracleやMySQLなど)実行されるようになります。

#ビジネスクラスの作成
TSVファイルの1レコードに対応するクラスを作成します。

public class Item {
    private Integer id;
    private String name;
    private Integer condition;
    private Integer category;
    private String brand;
    private Integer price;
    private Integer shipping;
    private String description;

#バッジジョブをまとめる
@EnableBatchProcessingアノテーションをつけることで、Bean(Springが管理しているインスタンス)が使えるようになります。

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
	
    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;
    
    // tag::readerwriterprocessor[]
    @Bean
    public FlatFileItemReader<Item> reader() {
    	//ItemReaderを生成します。
    	//demo.tsvを探し出し、CSVファイル内の1行ずつをItemオブジェクトに変換します。
        return new FlatFileItemReaderBuilder<Item>()
            .name("ItemReader")
            .resource(new ClassPathResource("demo.tsv"))
            .linesToSkip(1) //ヘッダーをスキップ
            .delimited()
            .delimiter("\t") //タブ区切りを指定)
            .names(new String[]{"id","name","condition","category","brand","price","shipping","description"})
            .fieldSetMapper(new BeanWrapperFieldSetMapper<Item>() {{
            	setTargetType(Item.class);
            }})
            .build();
    }

    @Bean
    public JdbcBatchItemWriter<Item> writer(DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<Item>()
            .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
            .sql("INSERT INTO items (id,name,condition,category,brand,price,shipping,description) "
            		+ " VALUES (:id, :name, :condition, :category, :brand, :price, :shipping, :description )")
            .dataSource(dataSource)
            .build();
    }
 // tag::jobstep[]
    @Bean
    public Job importItemJob(Step step1) {
        return jobBuilderFactory.get("importItemJob") //Job名を指定
            .incrementer(new RunIdIncrementer())
            .flow(step1)	//実行するStepを指定
            .end()
            .build();
    }

    @Bean
    public Step step1(JdbcBatchItemWriter<Item> writer) {
    	//inputはItemReader<Item>で、outputがItemWriter<Item>
    	//10レコードずつ書き込む
        return stepBuilderFactory.get("step1") //Step名を指定
            .<Item, Item> chunk(10)
            .reader(reader())
            .writer(writer)
            .build();
    }
    // end::jobstep[]

readerはItemReaderを生成します。これは、demo.tsvを探し出し、TSVファイル内の1行ずつをItemオブジェクトに変換します。

writerはItemWriterを生成します。データベース内のテーブルに出力内容を書き込んでいます。

#バッチの起動設定

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/DB名
    username: user
    password: pass
    driver-class-name: org.postgresql.Driver
  batch:
    initialize-schema: always
    job:
      enabled: false

"initialize-schema: always"
SpringBatchが使用するテーブルのDDLを実行するための設定。デフォルトではembeddedで、PostgreSQLを使用する場合はDDLが実行されないので、明示的に変更しておく。

"enabled: false "
デフォルトではtrueでSpring起動時にJobが実行されるが、起動時はJobParametersがないため起動時には実行できない。そのため明示的に変更しておく。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0