Spring Batch, Metadata Table DB Separation and Datasource Configuration

For clean DB configuration!


Goal

When using Spring Batch, tables that manage metadata such as when and how far the batch was completed are created.
I wanted to create these metadata tables in a different DB from the service, and configure the batch server to also access the service.

Summary

  1. Separate dataSource configuration into mybatis dataSource and batch dataSource
  2. Configure mybatis to use mybatis-specific dataSource

Content

1. dataSource Configuration

application.yml doesn't support multiple datasource configurations.
Therefore, datasource beans are directly injected through @Configuration.

# application.yml
spring:
  application:
    name: my-batch
  batch:
    jdbc:
      initialize-schema: never
    job:
      name: ${job.name:NONE}
  datasource:
    batch:
      jdbc-url: jdbc:mysql://{batch-database-uri}/batch
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: batch
      password: batch123
    service:
      jdbc-url: jdbc:mysql://{service-database-uri}/service
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: service
      password: service123
// com.dev.wichan.config.DataSourceConfig
@Configuration
public class DataSourceCOnfig {
 
  @Bean
  @Primary
  @ConfigurationProperties(prefix="spring.datasource.batch")
  public HikariConfig batchHikariConfig() {
      return new HikariConfig();
  }
 
  // Create batchDatasource to use as Spring's default datasource
  @Bean
  @Primary
  @Qualifier("batchDataSource")
  public DataSource batchDataSource() {
      return new HikariDataSource(batchHikariConfig());
  }
 
  @Bean
  @ConfigurationProperties(prefix="spring.datasource.service")
  public HikariConfig serviceHikariConfig() {
      return new HikariConfig();
  }
 
  // Create serviceDataSource bean for Mybatis to use
  @Bean
  @Qualifier("serviceDataSource")
  public DataSource serviceDataSource() {
      return new HikariDataSource(serviceHikariConfig());
  }
}

2. Mybatis Datasource Change

Specify the datasource for mybatis to use with Qualifier annotation

// com.dev.wichan.config.MyBatisConfig
@Configuration
public class MybatisConfig {
 
  @Primary
  @Bean
  public SqlSessionFactory sqlSessionFactory (
    @Qualifier("serviceDataSource") DataSource dataSource,
    ApplicationContext applicationContext
  ) throws Exception {
    SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
    sessionFactoryBean.setDataSource(dataSource);
    sessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:mapper/**/*.xml"));
 
    org.apache.ibatis.session.Configuration mybatisConfig = new org.apache.ibatis.session.Configuration();
    mybatisConfig.setMapUnderscoreToCamelCase(true);
    mybatisConfig.setDefaultExecutorType(ExecutorType.BATCH);
 
    sessionFactoryBean.setConfiguration(mybatisConfig);
    return sessionFactoryBean.getObject();
  }
 
}