本文例程:https://files.cnblogs.com/files/heyang78/multiDataSource_211109.rar
本文基于SpringBoot 2.5.4 和Orcale19c,文中提到的双数据源将以两个不同账户来实现,其中luna账户用于供程序运转,system账户用于备份。
现在一个应用带多个数据源并不罕见,比如下文将要提到的一主一丛配置,第一数据源用于程序运作,第二数据源主要用于备份。
SpringBoot程序要实现双数据源以致多数据源并不难,主要分两步:在配置文件中定义及在配置类中声明。
首先看文件application-dev.yml中的定义部分:
server: port: 8080 myenv: name: '开发环境' spring: datasource: primary: jdbc-url: jdbc:oracle:thin:@127.0.0.1:1521:orclhy78 username: luna password: 1234 driver-class-name: oracle.jdbc.OracleDriver type: com.zaxxer.hikari.HikariDataSource secondary: jdbc-url: jdbc:oracle:thin:@127.0.0.1:1521:orclhy78 username: system password: 123456 driver-class-name: oracle.jdbc.OracleDriver type: com.zaxxer.hikari.HikariDataSource
上面粗体部分就是定义两个数据源,primary和secondary是我起的名字,您也可以选择自己的个性命名。但其它照着来就好。
再就是配置类:
import javax.sql.DataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import com.zaxxer.hikari.HikariDataSource; @Configuration public class DataSourceConfig { @ConfigurationProperties(prefix="spring.datasource.primary") @Bean("primaryOracleDs") @Primary public DataSource getPrimaryDs() { return DataSourceBuilder.create().type(HikariDataSource.class).build(); } @ConfigurationProperties(prefix="spring.datasource.secondary") @Bean("secondaryOracleDs") public DataSource getSecondaryDs() { return DataSourceBuilder.create().type(HikariDataSource.class).build(); } }
这个配了两个数据源,第一个加上Primary标识是告诉系统,你要的DataSource就是我,不是别的。系统装载默认数据源会去找所有DataSource的bean,@Primary就是告诉系统在发现多个时如何进行取舍的。
这两部完成了也就完事了,有些同学会问如何用备份数据源呢,别急,下面准备好了测试程序教你:
import java.sql.SQLException; import javax.sql.DataSource; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest class MyApplicationTests { @Value("${server.port}") private String serverPort; @Value("${myenv.name}") private String myenvName; // 因为有@primary标识,这个系统缺省数据源会载入spring.datasource.primary指代的数据源 @Autowired private DataSource systemDefaultDs; // 因为DataSource类已经被标识了@Primary的bean占据,备份数据源要注入seondary必须指定名字 // 也就是有@Bean("secondaryOracleDs")标识的那一个 @Autowired @Qualifier("secondaryOracleDs") private DataSource backupDs; @Test void test_systemDefaultDs() throws SQLException { System.out.println("系统缺省数据源的schema="+systemDefaultDs.getConnection().getSchema()); } @Test void test_backupDs() throws SQLException { System.out.println("备份数据源的schema="+backupDs.getConnection().getSchema()); } @Test void contextLoads() { } @Test void testEnvironment() { System.out.println("myenvName="+myenvName); System.out.println("serverPort="+serverPort); } }
上面的注入方法写得很清楚了,运行Junit测试一下看看:
备份数据源的schema=SYSTEM 2021-11-09 20:19:36.674 INFO 36464 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Starting... 2021-11-09 20:19:36.729 INFO 36464 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Start completed. 系统缺省数据源的schema=LUNA
这个结果说明两个数据源都能正常运转了。
如果需要把这些数据源注入到list中备用,可以这样做:
@Autowired private List<DataSource> dsList;
如果需要指定顺序,可以在添加@Order(2)标签,如:
@ConfigurationProperties(prefix="spring.datasource.primary") @Bean("primaryOracleDs") @Primary @Order(1) public DataSource getPrimaryDs() { return DataSourceBuilder.create().type(HikariDataSource.class).build(); } @ConfigurationProperties(prefix="spring.datasource.secondary") @Bean("secondaryOracleDs") @Order(2) public DataSource getSecondaryDs() { return DataSourceBuilder.create().type(HikariDataSource.class).build(); }
好了,就到这里,希望本文能帮助到有需要的同学。
END