複数データベースを扱う方法
Spring BootとJPAで1つのデータベースを扱うのはサンプルも豊富なので簡単ですが、複数となると一気にサンプルが減り、なかなか実現するのが大変でした。なので、MySQLとPostgreSQLの2つに接続できる設定と実装方法を紹介します。
application.properties
application.propertiesに2つのデータベースへの接続設定を記載します。
spring: datasource: mysql: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/sample username: user password: pass postgres: driver-class-name: org.postgresql.Driver url: jdbc:postgresql://localhost:5432/sample username: user password: pass
接続処理
まずMySQLの接続処理を行うクラスです。
/** * MySQL Database Config */ @Component @ConfigurationProperties(prefix = "spring.datasource.mysql") @EnableJpaRepositories( basePackages=arrayOf("com.sample.repository.mysql"), entityManagerFactoryRef="mysqlEntityManagerFactory" ) class MySqlDatabaseConfig { var driverClassName: String = "" var url: String = "" var username: String = "" var password: String = "" @Primary @Bean("mysqlDataSource") fun dataSource(): DataSource { val dataSource: DriverManagerDataSource = DriverManagerDataSource() dataSource.setDriverClassName(driverClassName) dataSource.setUrl(url) dataSource.setUsername(username) dataSource.setPassword(password) return dataSource } @Primary @Bean("mysqlEntityManagerFactory") fun entityManagerFactory(@Qualifier("mysqlDataSource") dataSource: DataSource): EntityManagerFactory { val factory: LocalContainerEntityManagerFactoryBean = LocalContainerEntityManagerFactoryBean() factory.setDataSource(dataSource) factory.setPackagesToScan("com.sample.entity.mysql",) val vendorAdapter: HibernateJpaVendorAdapter = HibernateJpaVendorAdapter() factory.setJpaVendorAdapter(vendorAdapter) factory.afterPropertiesSet() return factory.getObject() } }
DriverManagerDataSourceはコネクションプールの機能がないので本番環境で使用しないようにしてください。コネクションプールの設定はHikariCPがオススメなので下記記事を参考にしてください。
関連記事:Spring BootでHikariCPを使ってコネクションプールを設定する方法
次にPostgreSQLです。
/** * PstgreSQL Database Config */ @Component @ConfigurationProperties(prefix = "spring.datasource.postgres") @EnableJpaRepositories( basePackages=arrayOf("com.sample.repository.postgres"), entityManagerFactoryRef="postgresEntityManagerFactory" ) class PostgresDatabaseConfig { var driverClassName: String = "" var url: String = "" var username: String = "" var password: String = "" @Bean("postgresDataSource") fun dataSource(): DataSource { val dataSource: DriverManagerDataSource = DriverManagerDataSource() dataSource.setDriverClassName(driverClassName) dataSource.setUrl(url) dataSource.setUsername(username) dataSource.setPassword(password) return dataSource } @Bean("postgresEntityManagerFactory") fun entityManagerFactory(@Qualifier("postgresDataSource") dataSource: DataSource): EntityManagerFactory { val factory: LocalContainerEntityManagerFactoryBean = LocalContainerEntityManagerFactoryBean() factory.setDataSource(dataSource) factory.setPackagesToScan("com.sample.entity.postgres") val properties: Properties = Properties() properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect") val vendorAdapter: HibernateJpaVendorAdapter = HibernateJpaVendorAdapter() factory.setJpaVendorAdapter(vendorAdapter) factory.setJpaProperties(properties) factory.afterPropertiesSet() return factory.getObject() } }
違いは2箇所で、MySQLの方に@Primaryをつけているのと、PostgreSQLの方はPropertiesを使ってdialectを指定しています。
@ConfigurationPropertiesにapplication.propertiesに設定した各データベース設定のルートパスを指定すると同名のメンバ変数に値を代入することができます。
@EnableJpaRepositoriesにはrepositoryのパッケージ名とEntityManagerFactoryのBean名を設定します。
MySQLとPostgreSQLのEntityとRepositoryは上記設定を行いやすくするためにも分けるようにしておいてください。
また、PostgreSQLのDriverを変更するだけでAWS Redshiftも扱えるようになります。下記リンクを参考にしてみてください。
GradleでRedshift JDBC Driverの取得と設定方法
使用方法
カスタムインターフェースを実装するときのみ変更が必要になります。カスタムインターフェースの実装方法は下記リンクを参照してください。
Spring Data JPAでカスタムRepositoryインターフェースを実装する方法
class SampleRepositoryImpl @Autowired constructor(@Qualifier("mysqlEntityManagerFactory") val emf: EntityManagerFactory) : SampleRepositoryCustom { /** * 期間を指定して取得 * * @param appIds ID * @return サンプルリスト */ override fun findById(id: Int): List<SampleEntity> { val sql: String = """ SELECT * FROM sample WHERE id :id """ val em: EntityManager = emf.createEntityManager() val query: Query = em.createNativeQuery(sql, "Sample") .setParameter("id", id) return query.getResultList() as List<SampleEntity> } }
設定箇所が少し多いですが上記を参考に実装していただければと思います。
最後にSpring Boot関連の記事を以下にまとめましたのでこちらも是非読んでください。
- Spring Bootでのテストコードの書き方
- Spring Bootで環境毎にapplication.propertiesを読み込む方法
- Spring BootでFlywayを使用したMySQLのマイグレーション
- KotlinでSpring BootのRESTful APIを実装
- EclipseでSpring BootとKotlinの環境構築
おすすめ書籍
JPAに関して体系的に学べる良い書籍だと思います。良くあるSpring系書籍ですとJPAは少ししか紹介がありませんが丸々一冊JPAに関してなので詳細な解説がされています。内容はJPAと他のORMとの比較から始まりセットアップ、実装の仕方まで幅広く網羅されています。これからJPAで開発を初めてみようかなと考えている方は一読することをオススメします!
Springの概要からインストール方法、各コア機能(Security, Sessionなど)の解説が体系的にまとめられています。2018年に出版されたばかりなので情報も新しいです。これからSpring Bootでアプリケーション開発をしたい方の最初に読む一冊としておすすめします。対象は初心者だけでなく上級者まで幅広く学べるので是非読んでみてください!
髙妻智一
最新記事 by 髙妻智一 (全て見る)
- Polkadot(Substrate)のアドレスとトランザクションについて - 2023-03-09
- 【無料公開】「Goで始めるBitcoin」3章 Bitcoinノードとの通信 技術書典8 - 2020-03-08
- エンジニアがゼロから技術ブログを書くための方法をまとめました - 2019-05-25
コメントを残す