之前介紹了Spring Boot 整合mybatis 使用注解方式配置的方式實作增删改查以及一些複雜自定義的sql 語句 。想必大家對spring boot 項目中,如何使用mybatis 有了一定的了解。但在很多業務場景下,我們需要在一個項目中配置多個資料源來實作業務邏輯,例如:現有電商業務,商品和庫存資料分别放在不同的資料庫中,這就要求我們的系統架構支援同時配置多個資料源實作相關業務操作。那麼Spring Boot 如何應對這種多資料源的場景呢?其實,在 Spring Boot 項目中配置多資料源十分便捷。接下來就聊一聊 Spring Boot 整合mybatis 實作多資料源的相關配置。
一、配置資料庫
首先在系統配置檔案中,需要配置多個資料源,即在application.properties 檔案中增加如下配置:
# mybatis 多資料源配置
# 資料庫1的配置
spring.datasource.test1.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.test1.jdbc-url = jdbc:mysql://localhost:3306/zwz_test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.test1.username = root
spring.datasource.test1.password = root
# 資料庫2的配置
spring.datasource.test2.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.test2.jdbc-url = jdbc:mysql://localhost:3306/zwz_test2?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.test2.username = root
spring.datasource.test2.password = root
注意:
1、這裡配置的是兩個一樣的資料庫zwz_test 和zwz_test2。
2、資料庫連接配接的配置使用jdbc-url , 不是之前的url ,這點需要注意。
二、資料源配置類
1、主資料源配置類
在config 包中,建立 DataSource1Config 類。此類配置主資料源。
package com.weiz.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.weiz.mapper.test1", sqlSessionFactoryRef = "test1SqlSessionFactory")
public class DataSource1Config {
@Bean(name = "test1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test1")
@Primary
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
2、配置其他資料源
在config 包中,建立DataSource2Config 類。此類配置其他普通資料源。
package com.weiz.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.weiz.mapper.test2", sqlSessionFactoryRef = "test2SqlSessionFactory")
public class DataSource2Config {
@Bean(name = "test2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "test2SqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "test2TransactionManager")
public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test2SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
說明, DataSource1Config 和 DataSource2Config 即是相關的主資料源配置類和普通資料源配置類。
com.weiz.mapper.test1 為 掃描的mapper的路徑。
可以看到兩個資料源都配置的各自的DataSource、SqlSessionFactory、TransactionManager和SqlSessionTemplate 。
雖然兩個類看着差不多,但是需要特别注意以下幾點:
1、主資料源配置需要加@Primary 注解,其他普通資料源不能加這個注解,否則會報錯,複制的時候小心。
2、各個資料源配置的 basePackages 掃描路徑需要配置正确。配置錯了不會出異常,但是運作的時候,會找錯資料庫。
3、如何調用
首先,建立com.weiz.mapper.test1 和 com.weiz.mapper.test2 包,将之前的UserMapper ,重名命為User1Mapper 和User2Mapper 複制到相應的包中。
然後,UserServiceImpl 分别注入兩個不同的 Mapper,想操作哪個資料源就使用哪個資料源的 Mapper 進行操作處理。
package com.weiz.service.impl;
import com.weiz.mapper.test1.User1Mapper;
import com.weiz.mapper.test2.User2Mapper;
import com.weiz.pojo.User;
import com.weiz.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private User1Mapper user1Mapper;
@Autowired
private User2Mapper user2Mapper;
@Override
public int saveUser(User user) {
user1Mapper.insert(user);
return user2Mapper.insert(user);
}
@Override
public int updateUser(User user) {
user1Mapper.updateByPrimaryKey(user);
return user2Mapper.updateByPrimaryKey(user);
}
@Override
public int deleteUser(String userId) {
user1Mapper.deleteByPrimaryKey(userId);
return user2Mapper.deleteByPrimaryKey(userId);
}
@Override
public User queryUserById(String userId) {
user1Mapper.selectByPrimaryKey(userId);
return user2Mapper.selectByPrimaryKey(userId);
}
}
這裡是一個簡單的測試程式,實際項目中是根據實際的業務,調用不同的mapper 實作的,或者通過注解配置,動态切換資料源。
三、驗證測試
啟動項目,浏覽器中輸入如下位址: http://localhost:8088/mybatis/saveuser ,可以看到兩個資料庫中,都增加了一條使用者資訊。
資料庫 zwz_test 中 使用者表sys_user 增加了一條記錄。

資料庫 zwz_test2 中 使用者表sys_user 也增加了一條同樣的記錄。
四、可能會遇到的坑
1、資料庫連接配接的配置使用jdbc-url , 不是之前的url 。這點需要注意。
2、主資料源配置需要加@Primary 注解,其他普通資料源不能加這個注解,否則會報錯,複制的時候小心。
3、各個資料源配置的 basePackages 掃描路徑需要配置正确。配置錯了不會出異常,但是運作的時候,會找錯資料庫。
4、如果Mybatis使用的是xml 配置版,xml位置需要在每個config顯示置頂位置。
最後
以上,就把Spring Boot整合Mybatis,實作多資料源配置的功能介紹完了。操作看似簡單,其實還是得小心仔細。不然很容易出錯。
此外配置多資料源之後,還涉及到資料源切換的問題,網上有很多種方法,比較流行的就是druid架構實作多資料源切換。這個後面再講吧。
還有,這裡沒有使用事務,如果采用事務需要分别配置每個資料源的事務,并采用事務性注解進行統一管理。這裡不細說大家自己研究吧。
這個系列課程的完整源碼,也會提供給大家。大家關注我的微信公衆号(架構師精進),回複:springboot源碼。擷取這個系列課程的完整源碼。
推薦閱讀:
SpringBoot從入門到精通(二十二)使用Swagger2優雅建構 RESTful API文檔 SpringBoot從入門到精通(二十一)如何優雅的設計 RESTful API 接口版本号,實作 API 版本控制! SpringBoot從入門到精通(二十)快速建構RESTful Web API 服務 SpringBoot從入門到精通(十九)使用注解實作動态Sql、參數傳遞 SpringBoot從入門到精通(十八)Mybatis系列之——使用注解的方式實作背景管理功能 SpringBoot從入門到精通(十七)MyBatis系列之——建立自定義mapper 實作多表關聯查詢! SpringBoot從小白到精通(十六)使用pagehelper實作分頁查詢功能 SpringBoot從小白到精通(十五)實作開發環境熱部署 SpringBoot從小白到精通(十四)使用JdbcTemplate操作資料庫,配置多資料源! SpringBoot從小白到精通(十三)如何實作事務儲存 SpringBoot從小白到精通(十二)logback日志配置 SpringBoot從小白到精通(十一)統一異常處理 SpringBoot從小白到精通(十)使用Interceptor攔截器,一學就會! SpringBoot從小白到精通(九)使用@Async實作異步執行任務 SpringBoot從小白到精通(八)熟悉@EnableScheduling,一秒搞定定時任務 SpringBoot從小白到精通(七)使用Redis實作高速緩存架構 SpringBoot從小白到精通(六)使用Mybatis實作增删改查【附詳細步驟】 SpringBoot從小白到精通(五)Thymeleaf的文法及常用标簽 SpringBoot從小白到精通(四)Thymeleaf頁面模闆引擎 SpringBoot從小白到精通(三)系統配置及自定義配置 SpringBoot從小白到精通(二)如何傳回統一的資料格式 SpringBoot從小白到精通(一)如何快速建立SpringBoot項目