├── .gitignore ├── README.md ├── pom.xml └── src ├── main ├── java │ └── org │ │ └── test │ │ ├── SpringMultiDatasourceTest.java │ │ ├── SpringMultipleDatasourcesApplication.java │ │ └── SpringMultipleDatasourcesApplicationConfig.java └── resources │ ├── application.yml │ └── db │ └── changelog │ ├── cee.database.sql │ └── db.changelog-master.xml └── test └── java └── org └── test └── SpringMultipleDatasourcesApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion 2 | 3 | *.iml 4 | 5 | ## Directory-based project format: 6 | .idea/ 7 | # if you remove the above rule, at least ignore the following: 8 | 9 | # User-specific stuff: 10 | # .idea/workspace.xml 11 | # .idea/tasks.xml 12 | # .idea/dictionaries 13 | 14 | # Sensitive or high-churn files: 15 | # .idea/dataSources.ids 16 | # .idea/dataSources.xml 17 | # .idea/sqlDataSources.xml 18 | # .idea/dynamic.xml 19 | # .idea/uiDesigner.xml 20 | 21 | # Gradle: 22 | # .idea/gradle.xml 23 | # .idea/libraries 24 | 25 | # Mongo Explorer plugin: 26 | # .idea/mongoSettings.xml 27 | 28 | ## File-based project format: 29 | *.ipr 30 | *.iws 31 | 32 | ## Plugin-specific files: 33 | 34 | # IntelliJ 35 | /out/ 36 | 37 | # mpeltonen/sbt-idea plugin 38 | .idea_modules/ 39 | 40 | # JIRA plugin 41 | atlassian-ide-plugin.xml 42 | 43 | # Crashlytics plugin (for Android Studio and IntelliJ) 44 | com_crashlytics_export_strings.xml 45 | crashlytics.properties 46 | crashlytics-build.properties 47 | 48 | # maven ignore 49 | target/ 50 | **/target/ 51 | pom.xml.tag 52 | pom.xml.releaseBackup 53 | pom.xml.versionsBackup 54 | pom.xml.next 55 | release.properties 56 | dependency-reduced-pom.xml 57 | buildNumber.properties 58 | .mvn/timing.properties 59 | 60 | # Windows image file caches 61 | Thumbs.db 62 | ehthumbs.db 63 | 64 | # Folder config file 65 | Desktop.ini 66 | 67 | # Recycle Bin used on file shares 68 | $RECYCLE.BIN/ 69 | 70 | # Windows Installer files 71 | *.cab 72 | *.msi 73 | *.msm 74 | *.msp 75 | 76 | # Windows shortcuts 77 | *.lnk 78 | 79 | .DS_Store 80 | .AppleDouble 81 | .LSOverride 82 | 83 | # Icon must end with two \r 84 | Icon 85 | 86 | 87 | # Thumbnails 88 | ._* 89 | 90 | # Files that might appear in the root of a volume 91 | .DocumentRevisions-V100 92 | .fseventsd 93 | .Spotlight-V100 94 | .TemporaryItems 95 | .Trashes 96 | .VolumeIcon.icns 97 | 98 | # Directories potentially created on remote AFP share 99 | .AppleDB 100 | .AppleDesktop 101 | Network Trash Folder 102 | Temporary Items 103 | .apdisk 104 | *.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot Multiple Datasource with Liquibase 2 | ## Multiple Datasource 3 | You need to add a couple of datasource definitions to your yaml configuration file. 4 | 5 | datasource: 6 | primary: 7 | url: jdbc:mysql://localhost/primary 8 | username: root 9 | driver-class-name: com.mysql.jdbc.Driver 10 | validation-query: select 1 11 | secondary: 12 | url: jdbc:mysql://localhost/secondary 13 | username: root 14 | driver-class-name: com.mysql.jdbc.Driver 15 | validation-query: select 1 16 | 17 | Make sure to disable the *DataSourceAutoConfiguration* in you configuration 18 | 19 | @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) 20 | 21 | You then need to manual configure each datasource and remember to set one as primary for any other auto configuration to work. 22 | 23 | @Bean(name = "primaryDataSource") 24 | @Primary 25 | @ConfigurationProperties(prefix="datasource.primary") 26 | public DataSource primaryDataSource() { 27 | return DataSourceBuilder.create().build(); 28 | } 29 | 30 | @Bean(name = "jdbcPrimaryTemplate") 31 | public JdbcTemplate jdbcPrimaryTemplate(@Qualifier(value = "primaryDataSource") DataSource primaryDataSource) { 32 | return new JdbcTemplate(primaryDataSource); 33 | } 34 | 35 | 36 | ## Liquibase 37 | ### Running Liquibase 38 | All you need to do in a Spring Boot project to get Liquibase to run for you is to simply add a dependency to the project pom. You can read more in the documents. 39 | [Liquibase Database Initialization](http://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html) 40 | 41 | ### Liquibase Properties 42 | Looking at the spring documentation you can find the additional properties used for Liquibase. 43 | In this example I am explicitly stating the connection properties rather than attempt to use the default datasource. 44 | [Spring Ref Appendix A. ](http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html) -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.test 7 | spring-multiple-datasource 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | spring-multiple-datasources 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.2.4.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | 1.7 24 | 1.7 25 | 1.7 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-jdbc 32 | 33 | 34 | org.liquibase 35 | liquibase-core 36 | 3.4.0 37 | 38 | 39 | 40 | mysql 41 | mysql-connector-java 42 | runtime 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-maven-plugin 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/main/java/org/test/SpringMultiDatasourceTest.java: -------------------------------------------------------------------------------- 1 | package org.test; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Qualifier; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.scheduling.annotation.Scheduled; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Component 12 | public class SpringMultiDatasourceTest { 13 | 14 | private static Logger logger = LoggerFactory.getLogger(SpringMultiDatasourceTest.class); 15 | 16 | @Autowired 17 | @Qualifier("jdbcPrimaryTemplate") 18 | private JdbcTemplate jdbcPrinaryTemplate; 19 | 20 | @Autowired 21 | @Qualifier("jdbcSecondaryTemplate") 22 | private JdbcTemplate jdbcSecondaryTemplate; 23 | 24 | @Scheduled(fixedRate = 5000) 25 | public void testQuery(){ 26 | 27 | Integer primaryCount = jdbcPrinaryTemplate.queryForObject("SELECT count(*) FROM cee.fe_prod_claims_postprocess", 28 | Integer.class); 29 | 30 | Integer secondaryCount = jdbcSecondaryTemplate.queryForObject("SELECT count(*) FROM cee.fe_prod_claims_postprocess", 31 | Integer.class); 32 | 33 | logger.debug("PrinaryCount {}, SecondaryCount {}", primaryCount, secondaryCount); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/test/SpringMultipleDatasourcesApplication.java: -------------------------------------------------------------------------------- 1 | package org.test; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 7 | import org.springframework.scheduling.annotation.EnableScheduling; 8 | 9 | @SpringBootApplication 10 | @EnableScheduling 11 | @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) 12 | public class SpringMultipleDatasourcesApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(SpringMultipleDatasourcesApplication.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/test/SpringMultipleDatasourcesApplicationConfig.java: -------------------------------------------------------------------------------- 1 | package org.test; 2 | 3 | import org.springframework.beans.factory.annotation.Qualifier; 4 | import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; 5 | 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.annotation.Primary; 10 | import org.springframework.jdbc.core.JdbcTemplate; 11 | 12 | import javax.sql.DataSource; 13 | 14 | @Configuration 15 | public class SpringMultipleDatasourcesApplicationConfig { 16 | 17 | @Bean(name = "jdbcPrimaryTemplate") 18 | public JdbcTemplate jdbcPrimaryTemplate(@Qualifier(value = "primaryDataSource") DataSource primaryDataSource) { 19 | return new JdbcTemplate(primaryDataSource); 20 | } 21 | 22 | @Bean(name = "jdbcSecondaryTemplate") 23 | public JdbcTemplate jdbcSecondaryTemplate(@Qualifier(value = "secondaryDataSource") DataSource secondaryDataSource) { 24 | return new JdbcTemplate(secondaryDataSource); 25 | } 26 | 27 | @Bean(name = "primaryDataSource") 28 | @Primary 29 | @ConfigurationProperties(prefix="datasource.primary") 30 | public DataSource primaryDataSource() { 31 | return DataSourceBuilder.create().build(); 32 | } 33 | 34 | @Bean(name = "secondaryDataSource") 35 | @ConfigurationProperties(prefix="datasource.secondary") 36 | public DataSource secondaryDataSource() { 37 | return DataSourceBuilder.create().build(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | datasource: 2 | primary: 3 | url: jdbc:mysql://localhost/primary 4 | username: root 5 | driver-class-name: com.mysql.jdbc.Driver 6 | validation-query: select 1 7 | secondary: 8 | url: jdbc:mysql://localhost/secondary 9 | username: root 10 | driver-class-name: com.mysql.jdbc.Driver 11 | validation-query: select 1 12 | 13 | logging: 14 | level: 15 | org.springframework: INFO 16 | org.test: DEBUG 17 | com.liquibase: DEBUG 18 | 19 | liquibase: 20 | change-log: classpath:/db/changelog/db.changelog-master.xml 21 | enabled: true 22 | url: jdbc:mysql://localhost/test 23 | user: root 24 | 25 | -------------------------------------------------------------------------------- /src/main/resources/db/changelog/cee.database.sql: -------------------------------------------------------------------------------- 1 | -- liquibase formatted sql 2 | -- changeset jwilliams:CreateCeeDatabase 3 | CREATE DATABASE `cee` /*!40100 DEFAULT CHARACTER SET utf8 */; 4 | 5 | -- changeset jwilliams:Createfe_prod_claims_postprocess 6 | CREATE TABLE `cee`.`fe_prod_claims_postprocess` ( 7 | `id` int(11) NOT NULL AUTO_INCREMENT, 8 | `fe_prod_id` int(11) DEFAULT NULL, 9 | `claim` varchar(10000) DEFAULT NULL, 10 | `date_entered` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 11 | `suspect` tinyint(4) DEFAULT '0', 12 | `claim_id` int(11) DEFAULT '0', 13 | `level` int(11) DEFAULT '0', 14 | `sameas_id` int(11) DEFAULT '0', 15 | PRIMARY KEY (`id`), 16 | KEY `ind_fe_prod_id` (`fe_prod_id`), 17 | KEY `ind_claim` (`claim`(255)), 18 | KEY `ind_claim_id` (`claim_id`), 19 | KEY `ind_suspect` (`suspect`) 20 | ) ENGINE=InnoDB AUTO_INCREMENT=5112521 DEFAULT CHARSET=utf8; 21 | -------------------------------------------------------------------------------- /src/main/resources/db/changelog/db.changelog-master.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/test/java/org/test/SpringMultipleDatasourcesApplicationTests.java: -------------------------------------------------------------------------------- 1 | package org.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.SpringApplicationConfiguration; 6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 7 | 8 | @RunWith(SpringJUnit4ClassRunner.class) 9 | @SpringApplicationConfiguration(classes = SpringMultipleDatasourcesApplication.class) 10 | public class SpringMultipleDatasourcesApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------