1. 程式人生 > >SpringBoot如何整合多個數據源,看這篇就夠了

SpringBoot如何整合多個數據源,看這篇就夠了

SpringBoot現在是很多很多公司應用的後端框架,因為它搭建快,能更好、更快速的整合其他第三方。那麼隨著業務的不斷擴充套件,業務量的增加,這時候就會牽扯到分庫分表,雖然這個詞聽起來很熟悉,作為程式設計師也很容易理解,但是我想應該也有不少讀者沒接觸過分庫分表,今天我們不聊如何分庫分表,而是聊SpringBoot如何整合多個數據源的事情。也就是如何接入不同的(多個)資料庫。

 

我們直接開始,我們直接建立一個乾淨的SpringBoot應用。

<parent>    <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --></parent>

 

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version></dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.8</version></dependency>

引入需要的maven座標,那麼我們這個工程就算搭建起來了,接下來就是配置,如何讓SpringBoot整合兩個Mysql資料來源。首先我們在本地建立兩個資料庫test1和test2,同時在裡面建立兩個結構一樣的表。

CREATE TABLE `user` (  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '使用者ID',  `username` varchar(100) CHARACTER SET utf8 NOT NULL COMMENT '使用者名稱',  `password` varchar(100) NOT NULL COMMENT '密碼',  `create_time` datetime DEFAULT NULL COMMENT '建立時間',  PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

在我們的工程中配置application.yml檔案,將資料庫的資訊配置進去

spring:  datasource:    test1:      driver-class-name: com.mysql.cj.jdbc.Driver      jdbc-url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC      username: root      password: 1234    test2:      driver-class-name: com.mysql.cj.jdbc.Driver      jdbc-url: jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC      username: root      password: 1234

接下來就是寫我們的配置類了,這也是整合多個數據源最為關鍵的部分。

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;/** * @ClassName DataSource2Config * @Description TODO * @Auther lbt * @Date 2019/6/28/028 10:07 * @Version 1.0 */@Configuration@MapperScan(basePackages = "com.example.mapper.test1", sqlSessionFactoryRef = "test1SqlSessionFactory")public class DataSource1Config {    @Bean(name = "test1DataSource")    @ConfigurationProperties(prefix = "spring.datasource.test1")    @Primary    public DataSource test1DataSource() {        return DataSourceBuilder.create().build();    }    @Bean(name = "test1SqlSessionFactory")    @Primary    public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();        bean.setDataSource(dataSource);        return bean.getObject();    }    @Bean(name = "test1TransactionManager")    @Primary    public DataSourceTransactionManager test1TransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {        return new DataSourceTransactionManager(dataSource);    }    @Bean(name = "test1SqlSessionTemplate")    @Primary    public SqlSessionTemplate test1SqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {        return new SqlSessionTemplate(sqlSessionFactory);    }}

第二個資料來源的配置

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.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;@Configuration@MapperScan(basePackages = "com.example.mapper.test2", sqlSessionFactoryRef = "test2SqlSessionFactory")public class DataSource2Config {    @Bean(name = "test2DataSource")    @ConfigurationProperties(prefix = "spring.datasource.test2")    public DataSource test2DataSource() {        return DataSourceBuilder.create().build();    }    @Bean(name = "test2SqlSessionFactory")    public SqlSessionFactory test2SqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();        bean.setDataSource(dataSource);        return bean.getObject();    }    @Bean(name = "test2TransactionManager")    public DataSourceTransactionManager test2TransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {        return new DataSourceTransactionManager(dataSource);    }    @Bean(name = "test2SqlSessionTemplate")    public SqlSessionTemplate test2SqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {        return new SqlSessionTemplate(sqlSessionFactory);    }}

這樣我們整個的配置其實就算好了,我們接下來寫一個Controller類來測試一下,我們整合的資料來源是不是真的可以用呢?

@RestControllerpublic class TestController {    @Autowired    private User1Service user1Service;    @Autowired    private User2Service user2Service;    @RequestMapping("/user1")    public Object user1Controller() {        List<UserPo> all = user1Service.findAll();        return all;    }    @RequestMapping("/user2")    public Object user2Controller() {        List<UserPo> all = user2Service.findAll();        return all;    }}

我寫了個兩個Controller方法,分別訪問不同的介面,我們來看下訪問結果。

當我們訪問user1的時候返回如下:

 

當我們訪問user2的時候訪問如下

看到這裡其實我們的整個整合也就完成了, 雖然看起來很簡單,但是你如果沒寫過確實會走很多坑,我剛整合的時候就遇到了很多坑,為了幫助大家重複採坑,分享出來供大家參考,另外我已經上傳GitHub,大家可以直接拉下來跑。

 

下篇給大家分享一下,這幾天在對接微信支付時,遇到的坑,已經微信支付的業務流程。

 

GitHub地址:

相關推薦

SpringBoot如何整合個數

SpringBoot現在是很多很多公司應用的後端框架,因為它搭建快,能更好、更快速的整合其他第三方。那麼隨著業務的不斷擴充套件,業

SpringBoot整合ActiveMQ

ActiveMQ是Apache提供的一個開源的訊息系統,完全採用Java來實現,因此它能很好地支援JMS(Java Message Service,即Java訊息服務)規範;本文將詳細介紹下ActiveMq的安裝、與SpringBoot整合傳送佇列訊息、傳送主題訊息的的過程。 本文目錄 一、L

學習Java JDBC

影響 數據庫中間件 project prepare 管理系 lba 分布 為我 vax JDBC (Java DB Connection)---Java數據庫連接 JDBC是一種可用於運行SQL語句的JAVA API(ApplicationProgramming

入門Webpack

ref ebp shu 走了 pack webp body 入門 ble 原文地址:https://www.jianshu.com/p/42e11515c10f一直以前對webpack不是很了解,通過看了原文,自己動手走了一邊,算是對webpack有了個入門。我把自己做了的

Map總結

java map 概要 學完了Map的全部內容,我們再回頭開開Map的框架圖。 第1部分 Map概括 (01) Map 是“鍵值對”映射的抽象接口。(02) AbstractMap 實現了Map中的絕大部分函數接口。它減少了“Map的實現類”的重復編碼。(03) SortedMap 有序的“鍵值對”映

入門 Webpack

通過 位置 post 進行 參考 sets 想要 避免 pat 轉:https://segmentfault.com/a/1190000006178770 2018年8月25日更新,目前 webpack 已經更新值 4.17.1 ,本文所用到的各種庫或多或少有些過時,跟著代

Elasticsearch Query DSL 整理總結(二)—— 要搞懂 Match Query

目錄 引言 構建示例 match operator 引數 analyzer lenient 引數 Fuzziness fuzzniess 引數 什麼是模糊搜尋? Levenshtein Edit Dist

Python Web怎麼學

Python目前應用領域實在太多,這也是他這麼火的原因吧。我認為目前Python作為應用領域來說幾個方向是值得肯定的:人工智慧、大資料分析、DevOps、Web、自動化測試、爬蟲。 在Python基礎方向,我認為必須掌握的技能有: 基本資料型別、內建資料結構 函式、高階函式、裝飾器 迭代器、

Python Web怎麽學

哪些 都是 這一 djang quest int 數據類型 簡單 dev Python目前應用領域實在太多,這也是他這麽火的原因吧。我認為目前Python作為應用領域來說幾個方向是值得肯定的:人工智能、大數據分析、DevOps、Web、自動化測試、爬蟲。 在Python基礎

繼萬字諫言後Python Web 怎麼學

  1. 之前那篇「萬字諫言,給那些想學Python的人,建議收藏後細看!」得到很多後臺讀者的留言,表示想再來點,甚至說萬字系?你知道萬字有多少麼?不要槓我根本沒有萬字!不叫萬字你能看到這篇良心嘛! 那憋了3天了,今天放個web好了,相信很多讀者都有關注web開發,那我們

Python 中的 orand 運算

問題出現: Python 中的 or,and 運算,可以寫出非常複雜的演算表示式; 看了一些大神的演算規則解釋,覺得不是很好理解,有些人甚至理解錯了規則。 這篇部落格聊一下自己的理解。 其他人是怎麼做的: 先看兩個例子熱下身: return 1 or 2 return

Python 中的 or and 運算

可能 參考答案 大神 cto 51cto 是不是 拆分 並且 情況 問題出現: Python 中的 or,and 運算,可以寫出非常復雜的演算表達式; 看了一些大神的演算規則解釋,覺得不是很好理解,有些人甚至理解錯了規則。 這裏聊一下自己的理解。 其他人是怎麽做的:

10大經典排序演算法動圖演示!(配相應程式碼)

排序演算法是《資料結構與演算法》中最基本的演算法之一。 排序演算法可以分為內部排序和外部排序。 內部排序是資料記錄在記憶體中進行排序。 而外部排序是因排序的資料很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。 常見的內部排序演算法有:插入排序、希爾排序、選擇排序、氣泡排序、歸併排序、快速排

Java 動態代理

這篇文章需要用到 Java 的反射知識,如果對反射還不清楚的小夥伴,可以先移步到這裡 《Java進階-反射》。 程式設計思想都是來自於生活的,“代理” 在生活中很常見。比如我們買一個東西時,一般都不會是直接從工廠裡買的,而是去商店或者其他的商家買,這些商家做的事情就是代理。

mybatis 快取的使用

快取的重要性是不言而喻的。 使用快取, 我們可以避免頻繁的與資料庫進行互動, 尤其是在查詢越多、快取命中率越高的情況下, 使用快取對效能的提高更明顯。 mybatis 也提供了對快取的支援, 分為一級快取和二級快取。 但是在預設的情況下, 只開啟一級快取(一級快

搞定計算機網路面試

文章目錄結構:  一 OSI與TCP/IP各層的結構與功能,都有哪些協議 運輸層主要使用以下兩種協議: UDP的主要特點: TCP的主要特點: 域名系統(Domain Name System縮寫DNS,Doma

Elasticsearch Query DSL 整理總結(二)—— 要搞懂 Match Query

目錄 引言 昨天是感恩節,上幼兒園的女兒在老師的叮囑下,晚上為我和老婆洗了腳(形式上的^_^),還給我們每人端了一杯水。看著孩子一天天的長大,懂事,感覺很開心,話說咱們程式設計師這麼辛苦是為了什麼?不就是為了老婆,孩子,熱炕頭,有一個溫暖幸福的家庭,再捎帶著用程式碼改變一下世界嗎?想到這裡,頓時覺得學習,創

jdk安裝與環境變數配置

文章目錄 - 場景 - jdk 下載安裝 - 如何環境變數的配置 - 總結 場景 在做 java 開發或者 android 開發,經常會碰到 jdk 安裝與環境變數的配置,每次配置的時候,經常需要去檢視一下,而且偶爾還會

Java執行緒池詳解

構造一個執行緒池為什麼需要幾個引數?如果避免執行緒池出現OOM?Runnable和Callable的區別是什麼?本文將對這些問題一一解答,同時還將給出使用執行緒池的常見場景和程式碼片段。 基礎知識 Executors建立執行緒池 Java中建立執行緒池很簡單,只需要呼叫Execu

Python 3 入門

簡介 Python 是一種高層次的結合瞭解釋性、編譯性、互動性和麵向物件的指令碼語言。Python 由 Guido van Rossum 於 1989 年底在荷蘭國家數學和電腦科學研究所發明,第一個公開發行版發行於 1991 年。 特點 易於學習:Pyt