10、SpringBoot-mybatis-plus-druid多源数据
系列导航
6、SpringBoot-mybatis分页实现pagehelper
9、SpringBoot-mybatis-druid多源数据多源数据
10、SpringBoot-mybatis-plus-druid多源数据
11、SpringBoot-mybatis-plus-druid多源数据事务
12、SpringBoot-mybatis-plus-ehcache
14、SpringBoot-easyexcel导出excle
完结
本文介绍如何在mybatis-plus上使用多源数据,本来以为mybatis-plus上多源数据和mybatis差不多实际操作后发现真还是不太一样。mybatis-plus的配置多源数据的大致思路就是,利用了切面的思想,访问那个mapper就把当前数据连接切换到对应的数据源上。
1数据库中创建表
zy数据库:
CREATE TABLE TEST_BLOCK_T
(
BLOCK_ID VARCHAR2(10 BYTE) PRIMARY KEY, --编码
BLOCK_NAME VARCHAR2(200 BYTE) --资源名称
);
Insert into TEST_BLOCK_T (BLOCK_ID, BLOCK_NAME) Values ('1', 'java');
COMMIT;
yc数据库:
CREATE TABLE TEST_USER_T
(
USER_ID VARCHAR2(10 BYTE) PRIMARY KEY,
NAME VARCHAR2(200 BYTE)
);
Insert into TEST_USER_T (USER_ID, NAME) Values ('1', '张三');
COMMIT;
2、pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.1.17.RELEASE</spring-boot.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <!-- oracle驱动 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency> <!-- 集成druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency> <!--集成mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>2.1.9</version>
</dependency> <!-- aop切面 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency> <!-- 省略get/set等方法 日志打印 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency> </dependencies> </project>
3、 application.properties配置
# 应用名称
spring.application.name=demo
# 应用服务 WEB 访问端口
server.port=8080 spring.aop.proxy-target-class=true
spring.aop.auto=true spring.datasource.druid.db1.url=jdbc:oracle:thin:@192.168.1.100:1521:orcl
spring.datasource.druid.db1.username=zy
spring.datasource.druid.db1.password=123
spring.datasource.druid.db1.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.druid.db1.initialSize=5
spring.datasource.druid.db1.minIdle=5
spring.datasource.druid.db1.maxActive=20 spring.datasource.druid.db2.url=jdbc:oracle:thin:@192.168.1.100:1521:orcl
spring.datasource.druid.db2.username=yc
spring.datasource.druid.db2.password=123
spring.datasource.druid.db2.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.druid.db2.initialSize=5
spring.datasource.druid.db2.minIdle=5
spring.datasource.druid.db2.maxActive=20 #开启sql打印
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
4、文件目录

主要源码:
MybatisPlusConfig.java
DataSourceSwitchAspect.java
5、源码
package com.example.demo.config; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; @Component
@Order(value = -100)
@Slf4j
@Aspect
public class DataSourceSwitchAspect { @Pointcut("execution(* com.example.demo.mapper.db1..*.*(..))")
private void db1Aspect() {
} @Pointcut("execution(* com.example.demo.mapper.db2..*.*(..))")
private void db2Aspect() {
} @Before("db1Aspect()")
public void db1() {
log.info("切换到db1 数据源...");
DbContextHolder.setDbType(DBTypeEnum.db1);
} @Before("db2Aspect()")
public void db2() {
log.info("切换到db2 数据源...");
DbContextHolder.setDbType(DBTypeEnum.db2);
} }
package com.example.demo.config;
public class DbContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal<>();
/**
* 设置数据源
* @param dbTypeEnum
*/
public static void setDbType(DBTypeEnum dbTypeEnum) {
contextHolder.set(dbTypeEnum.getValue());
}
/**
* 取得当前数据源
* @return
*/
public static String getDbType() {
return (String) contextHolder.get();
}
/**
* 清除上下文数据
*/
public static void clearDbType() {
contextHolder.remove();
}
}
package com.example.demo.config;
public enum DBTypeEnum {
db1("db1"), db2("db2") ;
private String value;
DBTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
package com.example.demo.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DbContextHolder.getDbType();
}
}
package com.example.demo.config; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.springframework.beans.factory.annotation.Qualifier;
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 org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map; @EnableTransactionManagement
@Configuration
public class MybatisPlusConfig { @Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setLocalPage(true);
return paginationInterceptor;
} @Bean(name = "db1")
@ConfigurationProperties(prefix = "spring.datasource.druid.db1")
public DataSource db1() {
return DruidDataSourceBuilder.create().build();
} @Bean(name = "db2")
@ConfigurationProperties(prefix = "spring.datasource.druid.db2")
public DataSource db2() {
return DruidDataSourceBuilder.create().build();
} /**
* 动态数据源配置
*
* @return
*/
@Bean
@Primary
public DataSource multipleDataSource(@Qualifier("db1") DataSource db1,
@Qualifier("db2") DataSource db2) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DBTypeEnum.db1.getValue(), db1);
targetDataSources.put(DBTypeEnum.db2.getValue(), db2);
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(db2);
return dynamicDataSource;
} @Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory() throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
sqlSessionFactory.setDataSource(multipleDataSource(db1(), db2())); MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setJdbcTypeForNull(JdbcType.NULL);
configuration.setMapUnderscoreToCamelCase(true);
configuration.setCacheEnabled(false);
sqlSessionFactory.setConfiguration(configuration);
//添加分页功能
sqlSessionFactory.setPlugins(new Interceptor[]{
paginationInterceptor()
});
return sqlSessionFactory.getObject();
} }
package com.example.demo.controller; import com.example.demo.service.ManySourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; @RestController
@RequestMapping("/hello")
public class ManySourceController { @Autowired
ManySourceService manySourceService; @GetMapping("/getZyBlock")
@ResponseBody
public String test1() {
return manySourceService.getZyBlock(); } @GetMapping("/getYcUser")
@ResponseBody
public String test2() {
return manySourceService.getYcUser(); } @PostMapping("/insertZyBlock")
@ResponseBody
public String test3() {
return manySourceService.insertZyBlock(); } @PostMapping("/insertYcUser")
@ResponseBody
public String test4() {
return manySourceService.insertYcUser(); } @PostMapping("/insertMany")
@ResponseBody
public String test5() {
return manySourceService.insertMany(); } }
package com.example.demo.domain.db1; import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName; @TableName(value = "TEST_BLOCK_T")
public class Block {
private static final long serialVersionUID = 1L; @TableId
private String blockId;
/**
* $field.comment。
*/
private String blockName; public String getBlockId() {
return blockId;
} public void setBlockId(String blockId) {
this.blockId = blockId;
} public String getBlockName() {
return blockName;
} public void setBlockName(String blockName) {
this.blockName = blockName;
} @Override
public String toString() {
return "TEST_BLOCK_T{" +
"blockId='" + blockId + '\'' +
", blockName='" + blockName + '\'' +
'}';
}
}
package com.example.demo.domain.db2; import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName; @TableName(value = "TEST_USER_T")
public class User {
private static final long serialVersionUID = 1L; @TableId
private String userId;
/**
* $field.comment。
*/
private String name; public String getUserId() {
return userId;
} public void setUserId(String userId) {
this.userId = userId;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "User{" +
"userId='" + userId + '\'' +
", name='" + name + '\'' +
'}';
}
}
package com.example.demo.mapper.db1; import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.example.demo.domain.db1.Block; public interface BlockMapper extends BaseMapper<Block> { }
package com.example.demo.mapper.db2; import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.example.demo.domain.db2.User; public interface UserMapper extends BaseMapper<User> { }
package com.example.demo.service; import com.example.demo.domain.db1.Block;
import com.example.demo.domain.db2.User;
import com.example.demo.mapper.db1.BlockMapper;
import com.example.demo.mapper.db2.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; @Service
public class ManySourceService { @Autowired
BlockMapper blockMapper; @Autowired
UserMapper userMapper; //获取zy库中的block中的数据
public String getZyBlock() {
return blockMapper.selectById("99999").toString(); } //获取yc库中的user中的数据
public String getYcUser() {
return userMapper.selectById("2").toString() ;
} public String insertZyBlock() {
Block block = new Block();
block.setBlockId("99999");
block.setBlockName("PHP");
return blockMapper.insert(block)+"";
} public String insertYcUser() {
User user = new User();
user.setUserId("2");
user.setName("李四");
return userMapper.insert(user)+"";
} //@Transactional 加了事务会报错
public String insertMany() {
Block block = new Block();
block.setBlockId("99999");
block.setBlockName("PHP");
blockMapper.insert(block) ; User user = new User();
user.setUserId("2");
user.setName("李四");
userMapper.insert(user) ;
return "1";
} }
package com.example.demo; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@MapperScan("com.example.demo.mapper.db*")
public class DemoApplication { public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
} }
6、启动项目访问项目
清空yc库里的表TEST_USER_T 和 zy库里的表TEST_BLOCK_T
(1)访问http://localhost:8080/hello/insertZyBlock 成功插入数据到TEST_BLOCK_T
(2)访问http://localhost:8080/hello/insertYcUser成功插入数据到TEST_USER_T
说明分别向不同数据源的数据库的插入没有问题。
(3)访问http://localhost:8080/hello/getZyBlock

(4)访问http://localhost:8080/hello/getYcUser

说明分别从不同数据源的数据库的查询没有问题。
再次清空yc库里的表TEST_USER_T 和 zy库里的表TEST_BLOCK_T
(5)访问http://localhost:8080/hello/insertMany
一个方法中向TEST_USER_T 和TEST_BLOCK_T插入数据插入成功数据库里的数据生成了。

日志中看到同一个方法中向不同的数据库中插入数据程序会自动的切换数据源。
注:下面就不能加事务Transactional了,这里估计是我没有用对,如果有能解决的道友可以反馈一下。
//@Transactional 加了事务会报错
public String insertMany()
10、SpringBoot-mybatis-plus-druid多源数据的更多相关文章
- spring boot 学习(五)SpringBoot+MyBatis(XML)+Druid
SpringBoot+MyBatis(xml)+Druid 前言 springboot集成了springJDBC与JPA,但是没有集成mybatis,所以想要使用mybatis就要自己去集成. 主要是 ...
- 12.SpringBoot+MyBatis(XML)+Druid
转自:https://www.cnblogs.com/MaxElephant/p/8108342.html 主要是在Spring Boot中集成MyBatis,可以选用基于注解的方式,也可以选择xml ...
- 搭建Springboot+mybatis+redis+druid
2019独角兽企业重金招聘Python工程师标准>>> 准备工作 JDK:1.8 使用技术:SpringBoot.Dubbo.Mybatis.Druid 开发工具:Intelj ID ...
- shardingsphere多数据源(springboot + mybatis+shardingsphere+druid)
org.springframeword.boot:spring-boot-starer-web: 2.0.4release io.shardingsphere:sharding-jdbc-spring ...
- 基于Maven的Springboot+Mybatis+Druid+Swagger2+mybatis-generator框架环境搭建
基于Maven的Springboot+Mybatis+Druid+Swagger2+mybatis-generator框架环境搭建 前言 最近做回后台开发,重新抓起以前学过的SSM(Spring+Sp ...
- SpringBoot+Mybatis+ Druid+PageHelper 实现多数据源并分页
前言 本篇文章主要讲述的是SpringBoot整合Mybatis.Druid和PageHelper 并实现多数据源和分页.其中SpringBoot整合Mybatis这块,在之前的的一篇文章中已经讲述了 ...
- 3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务
文章来自: https://blog.csdn.net/qq_29242877/article/details/79033287 在一些复杂的应用开发中,一个应用可能会涉及到连接多个数据源,所谓多数据 ...
- springboot+mybatis+druid+atomikos框架搭建及测试
前言 因为最近公司项目升级,需要将外网数据库的信息导入到内网数据库内.于是找了一些springboot多数据源的文章来看,同时也亲自动手实践.可是过程中也踩了不少的坑,主要原因是我看的文章大部分都是s ...
- 【优雅写代码系统】springboot+mybatis+pagehelper+mybatisplus+druid教你如何优雅写代码
目录 spring基本搭建 整合mybatis pom配置 mybatis配置 设置数据源 设置sqlsessionfactory 设置扫描 设置开启事务 资源放行 测试 结果 思考&& ...
- SpringBoot 使用yml配置 mybatis+pagehelper+druid+freemarker实例
SpringBoot 使用yml配置 mybatis+pagehelper+druid+freemarker实例 这是一个简单的SpringBoot整合实例 这里是项目的结构目录 首先是pom.xml ...
随机推荐
- 使用Druid解析SQL实现血缘关系计算
import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLStatement; import com.ali ...
- 【总结】MySQL使用优化
一.表设计 1.避免使用null 占用额外空间.索引无效.检索麻烦 2.能用int 不用varchaer,能用varchaer 不用text 3.int 最好给默认值 0 .varchar empt ...
- springcloud+nacos项目启动后,登陆连接服务器时超时:Connection timed out no further information
问题现象:项目启动后,登陆连接服务器时超时:Connection timed out no further information 192.168.42.190:4004 原因:我的配置有问题,在na ...
- 【纯手工打造】时间戳转换工具(python)
1.背景 最近发现一个事情,如果日志中的时间戳,需要我们转换成时间,增加可读性.或者将时间转换成时间戳,来配置时间.相信大多人和我一样,都是打开网页,搜索在线时间戳转换工具,然后复制粘贴进去.个人认为 ...
- Android阅读器之文本、图片和表格测量
文章摘要 本文将介绍如何在Android开发中实现文本.图片和表格的测量.我们将使用Android Studio和Java语言,并利用Android SDK中的相关类库. 正文 文本测量 在Andro ...
- 换热站数字孪生 | 图扑智慧供热 3D 可视化
前言 换热站作为供热系统不可或缺的一部分,其能源消耗对城市环保至关重要.在双碳目标下,供热企业可通过搭建智慧供热系统,实现供热方式的低碳.高效.智能化,从而减少碳排放和能源浪费.通过应用物联网.大数据 ...
- 深入理解 Docker 核心原理:Namespace、Cgroups 和 Rootfs
通过这篇文章你可以了解到 Docker 容器的核心实现原理,包括 Namespace.Cgroups.Rootfs 等三个核心功能. 如果你对云原生技术充满好奇,想要深入了解更多相关的文章和资讯,欢迎 ...
- MySQL 数据目录
MySQL 的数据目录 1. MySQL 的主要目录结构 方式1:通过命令搜索 find / -name mysql 方式2(推荐):通过查看配置文件获取目录结构 vim /etc/my.cnf (重 ...
- 【云原生 | Kubernetes 系列】— Kubernetes存储方案
目录 [云原生 | Kubernetes 系列]- Kubernetes存储方案 一.基本存储 EmptyDir HostPath NFS 搭建nfs服务器 二.高级存储 PV和PVC pv pvc ...
- 使用openfrp搭建网站[无公网ip]
使用openfrp搭建网站的理由 免费/低成本 安全 可扩展 使用条件 有一台低功耗准系统/服务器[无公网ip] u盘 网线/waif网卡 屏幕 使用方法 第1步准备服务 低功耗准系统 / 服务器 推 ...