官方說明:Spring Boot 2.X 版本不再支持配置繼承,多數據源的話每個數據源的所有配置都需要單獨配置,否則配置不會生效。所以需要單獨配置多個數據源的配置項。這裏需要注意的是多個數據源的配置區分是要在druid後面。
下面以一個項目中連接兩個不同數據庫實例中來演示MyBatis 配置多數據源。
11.1 POM文件配置
添加POM依賴。
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gavinbj</groupId>
<artifactId>gavinbj-mp</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>gavinbj-psbigdata</artifactId>
<name>gavinbj-psbigdata</name>
<url>http://maven.apache.org</url>
<!-- 添加打包jar的打包方式 -->
<packaging>jar</packaging>
<!-- 可以繼承父模塊中的配置,此處可以刪除,也可以進行單獨模塊的設置 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加對gavinbj-common的依賴-->
<dependency>
<groupId>com.gavinbj</groupId>
<artifactId>gavinbj-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--導入配置文件處理器,配置文件進行綁定就會有提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 導入使用JDBC訪問數據庫的依賴包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- MySQL依賴 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
</dependencies>
<!-- 添加編譯選項 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.png</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
11.2 在application.properties 中配置數據庫連接信息
server.servlet.context-path=/gavin
server.port=9001
# 數據源primary
spring.datasource.druid.primary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.primary.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.primary.url=jdbc:mysql://119.3.155.128:3306/psbigdata?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
spring.datasource.druid.primary.username=root
spring.datasource.druid.primary.password=HaoXXX80
# 省略其他配置
# Secondary
spring.datasource.druid.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.secondary.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.secondary.url=jdbc:mysql://119.3.155.129:3306/conf_mng?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
spring.datasource.druid.secondary.username=root
spring.datasource.druid.secondary.password=HaoXXX80
# 省略其他配置
11.3 配置自定義數據源
創建DataSourceConfig 配置數據源,根據application.properties中的配置創建兩個數據源。
- DataSourceConfig中提供了兩個數據源實例:dsPrimary 和 dsSecondary
- @ConfigurationProperties註解使用配置文件中不同前綴來創建不同的DataSource實例
package com.gavinbj.psbigdata.config;
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.druid.primary")
@Primary
DataSource dsPrimary() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.secondary")
DataSource dsSecondary() {
return DruidDataSourceBuilder.create().build();
}
}
11.4 配置MyBatis用數據庫配置類
MyBatis配置類,主要提供SqlSessionFactory 實例和 SqlSessionTemplate 實例。
- 在 @MapperScan 註解中指定 Mapper 接口所在的位置,同時指定 SqlSessionFactory 的實例名,則該位置下的所有 Mapper將使用 SqlSessionFactory 實例。
- 提供SqlSessionFactory的實例,同時將 DataSource 的實例設置給 SqlSessionFactory,這裏創建的 SqlSessionFactory 實例也就是 @MapperScan 註解中 sqlSessionFactoryRef 參數指定的實例。
- 提供一個SqlSessionTemplate 實例,主要用來管理 MyBatis 中的 SqlSession 操作。
MyBatisPrimaryConfig代碼示例:
package com.gavinbj.psbigdata.config;
import javax.sql.DataSource;
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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan(value="com.gavinbj.psbigdata.primary.persistence.mapper", sqlSessionFactoryRef = "sqlSessionFactoryPrimary")
public class MyBatisPrimaryConfig {
@Autowired
@Qualifier("dsPrimary")
DataSource dsPrimary;
@Bean
SqlSessionFactory sqlSessionFactoryPrimary() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dsPrimary);
return factoryBean.getObject();
}
@Bean
SqlSessionTemplate sqlSessionTemplatePrimary() throws Exception {
return new SqlSessionTemplate(sqlSessionFactoryPrimary());
}
}
MyBatisSecondaryConfig代碼示例:
package com.gavinbj.psbigdata.config;
import javax.sql.DataSource;
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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan(value="com.gavinbj.psbigdata.secondary.persistence.mapper", sqlSessionFactoryRef = "sqlSessionFactorySecondary")
public class MyBatisSecondaryConfig {
@Autowired
@Qualifier("dsSecondary")
DataSource dsSecondary;
@Bean
SqlSessionFactory sqlSessionFactorySecondary() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dsSecondary);
return factoryBean.getObject();
}
@Bean
SqlSessionTemplate sqlSessionTemplateSecondary() throws Exception {
return new SqlSessionTemplate(sqlSessionFactorySecondary());
}
}
11.5 自動生成Mapper文件
生成的不同數據源代碼結構如下:primary和secondary是使用工具自動生成。
├─src
│ ├─main
│ │ ├─java
│ │ │ ├─com
│ │ │ │ └─gavinbj
│ │ │ │ └─psbigdata
│ │ │ │ │ PSBigDataApplication.java
│ │ │ │ │
│ │ │ │ ├─config
│ │ │ │ │ DataSourceConfig.java
│ │ │ │ │ MyBatisBaseDao.java
│ │ │ │ │ MyBatisPrimaryConfig.java
│ │ │ │ │ MyBatisSecondaryConfig.java
│ │ │ │ │
│ │ │ │ ├─controller
│ │ │ │ │ HelloController.java
│ │ │ │ │ UserController.java
│ │ │ │ │
│ │ │ │ ├─primary
│ │ │ │ │ └─persistence
│ │ │ │ │ │ UecHotspots.java
│ │ │ │ │ │ UecHotspotsExample.java
│ │ │ │ │ │
│ │ │ │ │ └─mapper
│ │ │ │ │ UecHotspotsMapper.java
│ │ │ │ │ UecHotspotsMapper.xml
│ │ │ │ │
│ │ │ │ ├─secondary
│ │ │ │ │ └─persistence
│ │ │ │ │ │ UserInfo.java
│ │ │ │ │ │ UserInfoExample.java
│ │ │ │ │ │
│ │ │ │ │ └─mapper
│ │ │ │ │ UserInfoMapper.java
│ │ │ │ │ UserInfoMapper.xml
│ │ │ │ │
│ │ │ │ └─service
│ │ │ │ │ UserInfoService.java
│ │ │ │ │
│ │ │ │ └─impl
│ │ │ └─META-INF
│ │ │ additional-spring-configuration-metadata.json
│ │ │
│ │ └─resources
application.properties
logback-spring.xml
11.6 創建測試用Controller
這裏直接將Mapper 注入到了Controller中,然後分別查詢兩個數據庫中的數據。
package com.gavinbj.psbigdata.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.gavinbj.common.bean.BaseResult;
import com.gavinbj.common.bean.ResponseUtils;
import com.gavinbj.psbigdata.primary.persistence.UecHotspots;
import com.gavinbj.psbigdata.primary.persistence.mapper.UecHotspotsMapper;
import com.gavinbj.psbigdata.secondary.persistence.UserInfo;
import com.gavinbj.psbigdata.secondary.persistence.mapper.UserInfoMapper;
@RestController
@RequestMapping("/api")
public class HelloController {
@Autowired
UecHotspotsMapper uecHotspotsMapper;
@Autowired
UserInfoMapper userInfoMapper;
@GetMapping("/mult")
public BaseResult<Map<String, Object>> hello() {
UserInfo userInfo = userInfoMapper.selectByPrimaryKey("gavin");
UecHotspots hotspots = this.uecHotspotsMapper.selectByPrimaryKey(137318);
Map<String, Object> mapResult = new HashMap<String, Object>();
mapResult.put("UserInfo", userInfo);
mapResult.put("Hotspot", hotspots);
return ResponseUtils.makeOKRsp(mapResult);
}
}
數據庫表構成
檢索結果:
{
"status":0,
"code":1003,
"msg":"處理成功!",
"data":{
"UserInfo":{
"userId":"gavin",
"userName":"蓋文",
"introduce":"大學教授",
"mobilephone":"13940981276",
"email":"[email protected]",
"birthday":"2019-10-07T00:00:00.000+0000",
"gender":"男"
},
"Hotspot":{
"id":137318,
"type":"3959",
"extCity":"",
"irAbstract":"整場節目很精彩,一些年輕的相聲演員初露鋒芒,有混搭比如都沒有帶原配去的,都是捧哏的閻鶴祥楊九郎組合,他倆演的是對口相聲雙簧。 節目有新創意,也耐看,另外還看到了相聲演員們的新才藝,能唱歌能跳舞,德雲舞王除了孟鶴堂又來新人。 第柒個節目是德雲五子才藝秀,表演者是張九南,秦霄賢,張九齡,王九龍,尚九熙。 才藝秀沒出來之前,一霄對四九,很多觀衆以爲,他們五個人要說的是羣口相聲,張九齡王九龍一對組合,剩下的是三個耍單的逗哏,王九龍一個人捧不過來。 有顏值有才藝的五個人,在生活中特別受小女生們的喜歡,劉老根交換生尚九熙在現場沒唱二人轉,也沒帶把腿都磨平了的小企鵝出場,而是解鎖了新技能跳舞。",
"irAccountUid":"",
"irAuthors":"",
"irChannel":"軍事_娛樂頻道",
"irCount1":"0",
"irCount2":null,
"irCount3":null,
"irGroupflag":"0",
"irPagepdf":"",
"irPagepic":"",
"irPextag1":null,
"irSitename":"東方網",
"irSrcname":"",
"irTableflag":null,
"irUrlname":"http://mini.eastday.com/a/200125043918896.html",
"irUrltime":"2020-01-25 04:39:00",
"irUrltitle":"德雲弟子南祥北郎演雙簧,五子才藝秀,郭老師的筐不夠用了",
"irVia":null,
"rid":"8223521218",
"syBbCommon":"正面",
"syCommonTags":null,
"syInfotype":"1",
"syKeywords":"才藝;雙簧;德雲;老師;南祥北郎;弟子;師父;夠用;張九齡;節目;",
"syLoc":"九龍;電視臺;天津;京城",
"syMd5tag":null,
"syOrg":"德雲社;天津衛視",
"syPeople":"張九齡;閻鶴祥;張九南;秦霄賢;德雲舞;郎演;周九良;孟鶴堂;郭德綱;楊九郎",
"mediaArea":null,
"sySimCount":null,
"irContent":"晚會一場接一場,有着熱熱鬧鬧的新春佳節氣氛,追晚會比追劇還要上心,每一場春節晚會都整得挺好。
天津衛視的德雲社相聲晚會,是喜歡德雲社的觀衆最期待,也是最愛看的,郭德綱老師領着大夥兒回家鄉,迴天津開開心心過大年。
<img src=https://00imgmini.eastday.com/mobile/20200125/20200125043918_9764750bf9c69d165a70b7adf137951e_1.jpeg>
整場節目很精彩,一些年輕的相聲演員初露鋒芒,有混搭比如都沒有帶原配去的,都是捧哏的閻鶴祥楊九郎組合,他倆演的是對口相聲雙簧。
互粉的父子檔南有閻鶴祥,北有楊九郎,嶄新的南祥北郎,一個睡南邊炕一個睡北邊炕,他倆綜合小孩子,評書,老話劇演雙簧,出色的展示了他們過硬的表演功底。
<img src=https://00imgmini.eastday.com/mobile/20200125/20200125043918_9764750bf9c69d165a70b7adf137951e_2.jpeg>
壯壯說話算話,他說過只給姓郭的捧哏說到做到,和九郎合作時,他變成了逗哏,站到桌子外面去了。
--------------------------------------------------------------------------------------------------
京城九爺變成九萌萌,天真無邪的小孩子模仿得惟妙惟肖,閻鶴祥的我不讓你走更是如餘音繞樑,他們表演得是越來越上道,越來越精品。
節目有新創意,也耐看,另外還看到了相聲演員們的新才藝,能唱歌能跳舞,德雲舞王除了孟鶴堂又來新人。
<img src=https://00imgmini.eastday.com/mobile/20200125/20200125043918_9764750bf9c69d165a70b7adf137951e_3.jpeg>
第柒個節目是德雲五子才藝秀,表演者是張九南,秦霄賢,張九齡,王九龍,尚九熙。
才藝秀沒出來之前,一霄對四九,很多觀衆以爲,他們五個人要說的是羣口相聲,張九齡王九龍一對組合,剩下的是三個耍單的逗哏,王九龍一個人捧不過來。
<img src=https://00imgmini.eastday.com/mobile/20200125/20200125043918_9764750bf9c69d165a70b7adf137951e_4.jpeg>
節目出來後不是羣口相聲,是唱歌跳舞於一體的才藝展示,師父挨個給介紹,都是他徒弟,讓他們在觀衆面前亮個相。
--------------------------------------------------------------------------------------------------
有顏值有才藝的五個人,在生活中特別受小女生們的喜歡,劉老根交換生尚九熙在現場沒唱二人轉,也沒帶把腿都磨平了的小企鵝出場,而是解鎖了新技能跳舞。
<img src=https://00imgmini.eastday.com/mobile/20200125/20200125043918_9764750bf9c69d165a70b7adf137951e_5.jpeg>
尚九熙圍着師父盡情搖擺,魔性舞蹈帥炸了,卻把師父折磨得夠嗆,看郭老師一臉嫌棄的樣子。
師父準備的筐不夠用了,不僅大封箱上過於活躍的周九良需要用筐扣起來,這個尚九熙也需要用筐扣起來。
師父調侃尚九熙,孩子恢復得不錯,還問他這跳得都是什麼呀,是請神請仙的嗎?
<img src=https://00imgmini.eastday.com/mobile/20200125/20200125043918_9764750bf9c69d165a70b7adf137951e_6.jpeg>
沒有筐扣,師父有了新招數,現場給他念緊箍咒,郭老師心裏想這都教出來一些什麼怪徒兒,快快收了。
--------------------------------------------------------------------------------------------------
尚九熙迷人的舞蹈過後,是低音炮秦霄賢和張九南合演的《聲聲慢》,張九南彈吉他,老秦唱得深情好聽。
<img src=https://00imgmini.eastday.com/mobile/20200125/20200125043918_9764750bf9c69d165a70b7adf137951e_7.jpeg>
張九齡王九龍唱了自己的新單曲。他們五個精心準備的野狼迪斯科,被節目組無情的剪輯沒了。
德雲社相聲演員們,他們錄製天津衛視春節晚會的時間,是一下午加晚上到夜裏凌晨四點鐘,有的節目錄三四遍,不能夠都播,因爲節目播出的時長沒那麼久。
<img src=https://00imgmini.eastday.com/mobile/20200125/20200125043918_9764750bf9c69d165a70b7adf137951e_8.jpeg>
演員們真的很辛苦,包括燒餅唱歌現場是真唱,錄了四遍,不是對嘴型,電視臺給後期配的原音,可能是爲了更好的播出效果。
節目效果很好,他一張嘴出來張九齡的聲音,像演雙簧,讓人笑得不行。過年了,開開心心的,春節快樂。"
}
}
}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.1.RELEASE)
2020-01-25 20:15:37.024 INFO 3876 --- [ main] c.g.psbigdata.PSBigDataApplication : Starting PSBigDataApplication on 20190823-032019 with PID 3876 (C:\StsEclipse4.3.2\workspace\gavinbj-mp\gavinbj-psbigdata\target\classes started by Administrator in C:\StsEclipse4.3.2\workspace\gavinbj-mp\gavinbj-psbigdata)
2020-01-25 20:15:37.026 INFO 3876 --- [ main] c.g.psbigdata.PSBigDataApplication : No active profile set, falling back to default profiles: default
2020-01-25 20:15:38.551 INFO 3876 --- [ main] o.a.coyote.http11.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-9001"]
2020-01-25 20:15:38.552 INFO 3876 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-01-25 20:15:38.553 INFO 3876 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.27]
2020-01-25 20:15:38.673 INFO 3876 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/gavin] : Initializing Spring embedded WebApplicationContext
2020-01-25 20:15:39.601 INFO 3876 --- [ main] o.a.coyote.http11.Http11NioProtocol : Starting ProtocolHandler ["http-nio-9001"]
2020-01-25 20:15:39.630 INFO 3876 --- [ main] c.g.psbigdata.PSBigDataApplication : Started PSBigDataApplication in 3.065 seconds (JVM running for 3.416)
2020-01-25 20:15:57.548 INFO 3876 --- [nio-9001-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/gavin] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-01-25 20:16:09.432 INFO 3876 --- [nio-9001-exec-4] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
2020-01-25 20:16:10.244 INFO 3876 --- [nio-9001-exec-4] com.alibaba.druid.pool.DruidDataSource : {dataSource-2} inited