官方说明: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