關鍵詞:Spring Boot、多數據源配置、MySQL、SQL Server、Oracle、動態切換
? 摘要
在實際企業級開發中,一個 Spring Boot 項目可能需要連接多個數據庫,比如 MySQL、SQL Server 和 Oracle。不同的業務模塊可能依賴不同的數據源,這就要求我們掌握 如何在 Spring Boot 中靈活配置和管理多個數據源。
本文將圍繞以下內容進行詳細講解:
- Spring Boot 默認數據源配置方式
- 配置單個數據庫(MySQL、SQL Server、Oracle)
- 多數據源配置與使用(MySQL + SQL Server + Oracle)
- 使用
AbstractRoutingDataSource
實現動態數據源切換 - 常見問題與解決方案(驅動類、URL格式、連接失敗)
每部分都配有 完整的 application.yml 配置文件和 Java 配置類代碼示例。
📌 一、Spring Boot 數據源配置基礎
🔹 1. 默認數據源配置(以 MySQL 為例)
spring:datasource:url: jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTCusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
?? 注意:
url
要注意時區配置(serverTimezone)- 確保引入了正確的 JDBC 驅動包
📌 二、單個數據庫的配置方式
🔹 1. MySQL 數據源配置
Maven 依賴:
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
</dependency>
application.yml:
spring:datasource:mysql:url: jdbc:mysql://localhost:3306/mysql_db?useSSL=false&serverTimezone=UTCusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
🔹 2. SQL Server 數據源配置
Maven 依賴:
<dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>mssql-jdbc</artifactId><version>12.4.0.jre8</version>
</dependency>
application.yml:
spring:datasource:sqlserver:url: jdbc:sqlserver://localhost:1433;databaseName=SqlServerDB;encrypt=true;trustServerCertificate=false;loginTimeout=30;username: sapassword: yourStrongPassworddriver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
🔹 3. Oracle 數據源配置
Maven 依賴(需手動下載 ojdbc jar 并安裝到本地倉庫):
mvn install:install-file -Dfile=ojdbc8.jar -DgroupId=com.oracle.database.jdbc -DartifactId=ojdbc8 -Dversion=21.10.0.0 -Dpackaging=jar
pom.xml 添加依賴:
<dependency><groupId>com.oracle.database.jdbc</groupId><artifactId>ojdbc8</artifactId><version>21.10.0.0</version>
</dependency>
application.yml:
spring:datasource:oracle:url: jdbc:oracle:thin:@//localhost:1521/ORCLCDBusername: systempassword: oracledriver-class-name: oracle.jdbc.OracleDriver
📌 三、多數據源配置(MySQL + SQL Server + Oracle)
🔹 1. application.yml 多數據源配置
spring:datasource:mysql:url: jdbc:mysql://localhost:3306/mysql_db?useSSL=false&serverTimezone=UTCusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driversqlserver:url: jdbc:sqlserver://localhost:1433;databaseName=SqlServerDB;encrypt=true;trustServerCertificate=false;loginTimeout=30;username: sapassword: yourStrongPassworddriver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriveroracle:url: jdbc:oracle:thin:@//localhost:1521/ORCLCDBusername: systempassword: oracledriver-class-name: oracle.jdbc.OracleDriver
🔹 2. Java 配置類實現多數據源注入
第一步:定義配置屬性類
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
@Data
public class DataSourceProperties {private Map<String, DataSourceConfig> datasource;@Datapublic static class DataSourceConfig {private String url;private String username;private String password;private String driverClassName;}
}
第二步:創建多個數據源 Bean
@Configuration
@RequiredArgsConstructor
public class DataSourceConfig {private final DataSourceProperties dataSourceProperties;@Bean("mysqlDataSource")@ConfigurationProperties(prefix = "spring.datasource.mysql")public DataSource mysqlDataSource() {return DataSourceBuilder.create().url(dataSourceProperties.getDatasource().get("mysql").getUrl()).username(dataSourceProperties.getDatasource().get("mysql").getUsername()).password(dataSourceProperties.getDatasource().get("mysql").getPassword()).driverClassName(dataSourceProperties.getDatasource().get("mysql").getDriverClassName()).build();}@Bean("sqlServerDataSource")public DataSource sqlServerDataSource() {return DataSourceBuilder.create().url(dataSourceProperties.getDatasource().get("sqlserver").getUrl()).username(dataSourceProperties.getDatasource().get("sqlserver").getUsername()).password(dataSourceProperties.getDatasource().get("sqlserver").getPassword()).driverClassName(dataSourceProperties.getDatasource().get("sqlserver").getDriverClassName()).build();}@Bean("oracleDataSource")public DataSource oracleDataSource() {return DataSourceBuilder.create().url(dataSourceProperties.getDatasource().get("oracle").getUrl()).username(dataSourceProperties.getDatasource().get("oracle").getUsername()).password(dataSourceProperties.getDatasource().get("oracle").getPassword()).driverClassName(dataSourceProperties.getDatasource().get("oracle").getDriverClassName()).build();}
}
📌 四、動態切換數據源(基于 AbstractRoutingDataSource)
🔹 1. 定義當前線程使用的數據源標識
public class DynamicDataSourceContextHolder {private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();public static void setDataSourceKey(String key) {CONTEXT_HOLDER.set(key);}public static String getDataSourceKey() {return CONTEXT_HOLDER.get();}public static void clearDataSourceKey() {CONTEXT_HOLDER.remove();}
}
🔹 2. 自定義 AbstractRoutingDataSource
@Component
@RequiredArgsConstructor
public class DynamicDataSource extends AbstractRoutingDataSource {private final DataSource mysqlDataSource;private final DataSource sqlServerDataSource;private final DataSource oracleDataSource;@PostConstructpublic void init() {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("mysql", mysqlDataSource);targetDataSources.put("sqlserver", sqlServerDataSource);targetDataSources.put("oracle", oracleDataSource);this.setTargetDataSources(targetDataSources);this.setDefaultTargetDataSource(mysqlDataSource); // 設置默認數據源this.afterPropertiesSet();}@Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSourceKey();}
}
🔹 3. 配置為事務管理器的數據源
@Bean
public PlatformTransactionManager transactionManager(DynamicDataSource dynamicDataSource) {return new DataSourceTransactionManager(dynamicDataSource);
}
🔹 4. 在 Service 層使用動態數據源
@Service
@RequiredArgsConstructor
public class UserService {private final JdbcTemplate jdbcTemplate;public void queryFromMysql() {DynamicDataSourceContextHolder.setDataSourceKey("mysql");List<Map<String, Object>> result = jdbcTemplate.queryForList("SELECT * FROM user");System.out.println("MySQL 查詢結果:" + result);}public void queryFromSqlServer() {DynamicDataSourceContextHolder.setDataSourceKey("sqlserver");List<Map<String, Object>> result = jdbcTemplate.queryForList("SELECT * FROM Users");System.out.println("SQL Server 查詢結果:" + result);}public void queryFromOracle() {DynamicDataSourceContextHolder.setDataSourceKey("oracle");List<Map<String, Object>> result = jdbcTemplate.queryForList("SELECT * FROM employees");System.out.println("Oracle 查詢結果:" + result);}
}
? 總結
以下幾點為本文重點:
模塊 | 技能點 |
---|---|
單數據源配置 | MySQL、SQL Server、Oracle 的基本配置方法 |
多數據源配置 | 如何在一個 Spring Boot 項目中配置多個數據源 |
動態數據源切換 | 使用 AbstractRoutingDataSource 實現運行時切換 |
實戰能力 | 結合 JdbcTemplate、事務管理器使用多數據源 |
這些技能是你構建復雜微服務系統、支持多數據庫架構的重要基礎。
📚 參考資料
- Spring Boot 官方文檔
- Spring Data Access 文檔