0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Spring Batchのメタテーブルは使いたくないけどJdbcTemplateが使いたい

Posted at

概要

・メインDBにメタテーブルを生成したくない
・Repositoryを利用していない
・でもJdbcTemplateを利用して簡単にテーブルの操作がしたい

環境

Contents Version
Java 1.8
Spring Boot 2.7.16
H2 2.1.214

実装方法

メタテーブル用とメインテーブル用でそれぞれDataSourceとJdbcTemplateを生成する

DataSourceConfiguration.java
@Configuration
public class DataSourceConfiguration {

    //メタテーブル用DataSource
    @Bean("metaDataSource") //metaDataSourceという名前でBean登録
    @BatchDataSource //メタテーブルの接続先に指定
    @ConfigurationProperties(prefix = "spring.datasource.meta") //プロパティファイルのspring.datasource.meta.*を設定
    public DataSource createMetaDataSource(){
        return DataSourceBuilder.create().build();
    }

    //メインテーブル用DataSource
    @Bean("mainDataSource") //mainDataSourceという名前でBean登録
    @Primary //メインテーブルの接続先に指定
    @ConfigurationProperties(prefix = "spring.datasource.main") //プロパティファイルのspring.datasource.main.*を設定
    public DataSource createMainDataSource(){
        return DataSourceBuilder.create().build();
    }

    //メタテーブル用JdbcTemplate
    @Bean("metaJdbcTemplate") //metaJdbcTempalteという名前でBean登録
    JdbcTemplate createMetaJdbcTemplate(@Qualifier("metaDataSource") DataSource ds){ //metaDataSourceを指定して引数として呼び出す
        return new JdbcTemplate(ds);
    }

    //メインテーブル用JdbcTemplate
    @Bean("mainJdbcTemplate") //mainJdbcTempalteという名前でBean登録
    JdbcTemplate createMainJdbcTemplate(@Qualifier("mainDataSource") DataSource ds){ //mainDataSourceを指定して引数として呼び出す
        return new JdbcTemplate(ds);
    }
}
application.properties
#SpringBatchの起動のたびにメタテーブルをインメモリDBに生成する必要があるためalwaysに設定
spring.batch.jdbc.initialize-schema=always
#メタテーブルの接続先情報
#※今回はメタテーブルを保持したくないのでインメモリDBのH2に生成し、メモリの解放とともに消えてもらう
spring.datasource.meta.username=sa
spring.datasource.meta.password=
spring.datasource.meta.jdbcUrl=jdbc:h2:mem:batch
#メインテーブルの接続先情報
spring.datasource.main.username=root
spring.datasource.main.password=root
spring.datasource.main.jdbcUrl=jdbc:mysql~~~

詳細

上記のソースでは、メタテーブルとメインテーブルのDataSourceをそれぞれ用意しています。それらを設定したJdbcTemplateをBean登録することで、メタテーブル用とメインテーブル用で使い分けられるようにしています。
@BatchDataSourceを付与したDataSourceはメタテーブルの管理に利用されるようになりますのでBean登録さえしておけば、spring.datasource.metaに定義した接続先で勝手にメタテーブルを管理してくれます。
そして、メインテーブルを操作したいときはmainJdbcTemplateのほうを@Qualifierで指定して呼び出してあげればOKです。

SampleTasklet.java
@Component
public class SampleTasklet implements Tasklet {

    @Autowired
    @Qualifier("mainJdbcTemplate")
    JdbcTemplate jdbcTemplate;

    @Override 
    public RepeatStatus execute(StepContribution contribution, ChunkContext context){
        jdbcTemplate.execute("INSERT INTO sample VALUES (1).... ");
    }
}

トランザクション

DBにメタテーブルを保持せずにJdbcTemplateが利用できるようになりました!!
ただし、これではstepのトランザクション管理がメタテーブルのDBに貼られてしまいます。
メインテーブルのトランザクション管理をしたい場合は、transactionManagerを用意してあげましょう。

DataSourceConfiguration.java
@Configuration
public class DataSourceConfiguration {

    //~~~JdbcTemplateのコードの続き

    @Bean("mainTransactionManager")
    public PlatformTransactionManager mainTransactionManager(@Qualifier("mainJdbcTemplate") JdbcTemplate jdbcTemplate){
        return new DataSourceTransactionManager(jdbcTemplate.getDataSource);
    }
}

transactionManagerを作成したらトランザクション管理をしたい場所に設定することをお忘れなく

JobConfiguration.java
@Configuration
public class JobConfiguration {

    @Autowired
    @Qualifier("mainTransactionManager")
    public PlatformTransactionManager mainTransactionManager;

    @Bean("step1")
    public Step step1(JobRepository jobRep){
        return new StepBuilder("step1").repository(jobRep).transactionManager(mainTransactionManager)
        .tasklet(sampleTasklet).build;
    }
}

例外が発生したらメインDBをロールバックしてくれるようになりました!
これでメタテーブルは利用せず、管理せず、Springの便利機能を享受できるようになりました。
もっと美しく書くこともできそうではありますが、まずは機能を満たすことを優先ということで...

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?