やること
内部DBだけでなく、外部DBにも接続したいよーってときありますよね
SpringBootとDoma2で複数データソースに接続していきます
環境
Java 11
Spring Boot 2.6.1
Doma 2.50.0
MySQL 8.0.25
Gradle 2.24
実装
データベース接続設定
# DB1
datasource.one.jdbcUrl=jdbc:mysql://sample1.com:3306/sample1?autoReconnect=true&useSSL=false
datasource.one.username=sample
datasource.one.password=sample
# DB2
datasource.two.jdbcUrl=jdbc:mysql://sample2.com:3306/sample2?autoReconnect=true&useSSL=false
datasource.two.username=sample
datasource.two.password=sample
データベースへの接続はHikariCPを利用します。
接続するURLは、jdbcUrl
または、jdbc-url
で設定する必要があります。
url
で設定すると、下記エラーで怒られます。
Caused by: java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
Applicationクラス
Spring Bootでは、単一データソースを前提とする動作になるため、
exclude = {DataSourceAutoConfiguration.class}
で自動設定を無効にします。
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
}
Configクラス
Doma2を利用するため、Configクラスを実装します
設定ファイルから取得した接続情報を保持するため、HikariConfigクラスを継承しています
また、同じタイプのBeanが複数作成されるため、片方のConfigクラスに@Primary
を付与することで、SpringにBeanの優先度を伝えてあげます
@Configuration("dataSourceOneConfig")
@ConfigurationProperties("datasource.one")
@Primary
public class DataSourceOneConfig extends HikariConfig implements Config {
private DataSource dataSource;
@PostConstruct
public void postConstruct() {
this.dataSource = new TransactionAwareDataSourceProxy(new HikariDataSource(this));
}
@Override
public Dialect getDialect() {
return new MysqlDialect();
}
@Override
public DataSource getDataSource() {
return this.dataSource;
}
}
@Configuration("dataSourceTwoConfig")
@ConfigurationProperties("datasource.two")
public class DataSourceTwoConfig extends HikariConfig implements Config {
private DataSource dataSource;
@PostConstruct
public void postConstruct() {
this.dataSource = new TransactionAwareDataSourceProxy(new HikariDataSource(this));
}
@Override
public Dialect getDialect() {
return new MysqlDialect();
}
@Override
public DataSource getDataSource() {
return this.dataSource;
}
}
Daoを作成
@AnnotateWith
でDaoインターフェースの実装クラスにアノテーションを付与していきます
@ConfigAutowireable
で@Repository
と@Autowired
を付与しようとすると怒られます
@Dao
@AnnotateWith(annotations = {
@Annotation(target = AnnotationTarget.CLASS, type = Repository.class),
@Annotation(target = AnnotationTarget.CLASS, type = Component.class),
@Annotation(target = AnnotationTarget.CONSTRUCTOR, type = Autowired.class),
@Annotation(target = AnnotationTarget.CONSTRUCTOR_PARAMETER, type = Qualifier.class, elements = "\"dataSourceOneConfig\"")
})
public interface SampleOneDao {
}
@Dao
@AnnotateWith(annotations = {
@Annotation(target = AnnotationTarget.CLASS, type = Repository.class),
@Annotation(target = AnnotationTarget.CLASS, type = Component.class),
@Annotation(target = AnnotationTarget.CONSTRUCTOR, type = Autowired.class),
@Annotation(target = AnnotationTarget.CONSTRUCTOR_PARAMETER, type = Qualifier.class, elements = "\"dataSourceTwoConfig\"")
})
public interface SampleTwoDao {
}
最後に
今後とも愉快なDaoライフを満喫しましょう
参考