Mybatis多数据源读写分离(注解实现)
#### Mybatis多数据源读写分离(注解实现)
------
首先需要建立两个库进行测试,我这里使用的是master_test和slave_test两个库,两张库都有一张同样的表(偷懒,喜喜),表结构
表名 t_user
| 字段名 | 类型 | 备注 |
| :------: | :------: | :------: |
| id | int | 主键自增ID |
| name | varchar | 名称 |

表中分别添加两条不同数据,方便测试
主数据库记录name为xiaobin,从库为xiaoliu
开始使用Springboot 整合mybatis,首先引入pom文件
```
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.4.RELEASE
com.xiaobin
mysql_master_slave
1.0-SNAPSHOT
1.8
1.18.6
1.3.2
1.18.6
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
${lombok.version}
org.springframework.boot
spring-boot-starter-test
org.projectlombok
lombok
${lombox.version}
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.version}
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-jdbc
com.alibaba
druid-spring-boot-starter
1.1.10
org.springframework.boot
spring-boot-starter-aop
```
#### 动态数据源配置
这里使用的数据源为druid,实现数据源之间的切换用@DataSource自定义注解,配置Aop进行切换
application.yml 配置文件
```
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
xiaobin-master: # 主数据源
driverClassName: com.mysql.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/master_test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8
xiaobin-slave: # 从数据源
driverClassName: com.mysql.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/slave_test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8
mybatis:
mapper-locations: classpath:mapper/*.xml
```
#### 多数据源配置类
```
package com.xiaobin.config;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
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.stereotype.Component;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 创建时间: 2019/9/22 11:42
* 备注:多数据源配置信息
* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事
**/
@Configuration
@Component
public class DynamicDataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.druid.xiaobin-master")
public DataSource xiaobinMasterDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.xiaobin-slave")
public DataSource xiaobinSlaveDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@Primary
public DynamicDataSource dataSource(DataSource xiaobinMasterDataSource, DataSource xiaobinSlaveDataSource) {
Map targetDataSources = new HashMap();
targetDataSources.put("xiaobin-master",xiaobinMasterDataSource);
targetDataSources.put("xiaobin-slave", xiaobinSlaveDataSource);
return new DynamicDataSource(xiaobinMasterDataSource, targetDataSources);
}
}
```
#### 动态数据源切换类
```
package com.xiaobin.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.lang.Nullable;
import javax.sql.DataSource;
import java.util.Map;
/**
* 创建时间: 2019/9/22 11:51
* 备注:动态数据源
* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事
**/
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal contextHolder = new ThreadLocal();
public DynamicDataSource(DataSource defaultTargetDataSource, Map targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
```
#### 自定义@DataSource注解
在需要切换数据的Dao添加此注解
```
package com.xiaobin.annotation;
import java.lang.annotation.*;
/**
* 创建时间: 2019/9/22 11:53
* 备注:自定义数据源选择注解
* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事
**/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
String name() default "";
}
```
#### Aop切面类配置
```
package com.xiaobin.aspect;
import com.xiaobin.annotation.DataSource;
import com.xiaobin.config.DynamicDataSource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 创建时间: 2019/9/22 11:54
* 备注:
* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事
**/
@Aspect
@Component
public class DataSourceAspect {
@Pointcut("@annotation(com.xiaobin.annotation.DataSource)")
public void dataSourcePointCut() {
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSource dataSource = method.getAnnotation(DataSource.class);
if(dataSource == null){
DynamicDataSource.setDataSource("xiaobin-master");
}else {
DynamicDataSource.setDataSource(dataSource.name());
}
try {
return point.proceed();
} finally {
DynamicDataSource.clearDataSource();
}
}
}
```
#### 启动配置注解信息,重要(不然运行会报错)
```
package com.xiaobin;
import com.xiaobin.config.DynamicDataSourceConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Import;
/**
* 创建时间: 2019/9/22 11:17
* 备注:
* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事
**/
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@MapperScan(basePackages = "com.xiaobin.mapper")
@Import({DynamicDataSourceConfig.class})
public class StartApp {
public static void main(String[] args) {
SpringApplication.run(StartApp.class);
}
}
```
#### 测试controller
```
package com.xiaobin.api;
import com.xiaobin.Entity.TUser;
import com.xiaobin.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 创建时间: 2019/9/22 12:08
* 备注:
* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事
**/
@RestController
@RequestMapping
public class UserController {
@Autowired
private UserMapper userMapper;
@GetMapping("/{name}/list")
public List list(@PathVariable("name")String name){
if(name.equals("master")){
return userMapper.queryAllWithMaster();
}else{
return userMapper.queryAllWithSlave();
}
}
}
```
#### 效果图
更具路径传值,进行主从数据源切换


#### 目录结构

源码地址(数据库需要自己创建)https://gitee.com/MyXiaoXiaoBin/learning-to-share/tree/master/mysql_master_slave
###### 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事
Mybatis多数据源读写分离(注解实现)的更多相关文章
- spring集成mybatis实现mysql读写分离
前言 在网站的用户达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈.幸运的是目前大部分的主流数据库都提供主从热备功能,通过配置两台数据库主从关系,可以将一台数据库的数据更新同步到另一台服务器上. ...
- Spring+MyBatis实现数据库读写分离方案
推荐第四种:https://github.com/shawntime/shawn-rwdb 方案1 通过MyBatis配置文件创建读写分离两个DataSource,每个SqlSessionFactor ...
- Spring配置动态数据源-读写分离和多数据源
在现在互联网系统中,随着用户量的增长,单数据源通常无法满足系统的负载要求.因此为了解决用户量增长带来的压力,在数据库层面会采用读写分离技术和数据库拆分等技术.读写分离就是就是一个Master数据库,多 ...
- spring结合mybatis实现数据库读写分离
随着系统用户访问量的不断增加,数据库的频繁访问将成为我们系统的一大瓶颈之一.由于项目前期用户量不大,我们实现单一的数据库就能完成.但是后期单一的数据库根本无法支撑庞大的项目去访问数据库,那么如何解决这 ...
- spring项目配置双数据源读写分离
我们最早做新项目的时候一直想做数据库的读写分离与主从同步,由于一些原因一直没有去做这个事情,这次我们需要配置双数据源的起因是因为我们做了一个新项目用了另一个数据库,需要把这个数据库的数据显示到原来的后 ...
- Spring Boot + MyBatis + MySQL 实现读写分离
读写分离要做的事情就是对于一条SQL该选择哪个数据库去执行,至于谁来做选择数据库这件事儿,无非两个,要么中间件帮我们做,要么程序自己做. 读写分离有两种实现方式: 第一种是依靠中间件(比如:MyCat ...
- mysql+spring+mybatis实现数据库读写分离[代码配置] .
场景:一个读数据源一个读写数据源. 原理:借助spring的[org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource] ...
- 【Spring】Spring如何实现多数据源读写分离?这是我看过最详细的一篇!!
写在前面 很多小伙伴私聊我说:最近他们公司的业务涉及到多个数据源的问题,问我Spring如何实现多数据源的问题.回答这个问题之前,首先需要弄懂什么是多数据源:多数据源就是在同一个项目中,会连接两个甚至 ...
- 2.配置Spring+SpringMvc+Mybatis(分库or读写分离)--Intellij IDAE 2016.3.5
建立好maven多模块项目后,开始使用ssm传统的框架: 1.打开总工程下的pom.xml文件:添加如下代码: <!--全局的所有版本号定义--> <properties> & ...
随机推荐
- 车载多传感器融合定位方案:GPS +IMU+MM
导读 高德定位业务包括云上定位和端上定位两大模块.其中,云上定位主要解决Wifi指纹库.AGPS定位.轨迹挖掘和聚类等问题:端上定位解决手机端和车机端的实时定位问题.近年来,随着定位业务的发展,用户对 ...
- django前后端分离部署
部署静态文件: 静态文件有两种方式1:通过django路由访问2:通过nginx直接访问 方式1: 需要在根目录的URL文件中增加,作为入口 url(r'^$', TemplateView.as_vi ...
- springboot中的springSession的存储和获取
利用redis进行springSession的存储: 存储: // 在session中保存用户信息 HttpSession session = httpRequest.getSession(true) ...
- js中的数据类型,以及如何检测数据类型
基本数据类型:string,number,boolean,null,undefined,symbol 引用数据类型:object(array,function...) 常用的检测数据类型的方法一般有以 ...
- java学习之- 线程继承Thread类
标签(空格分隔): 线程 在java.lang包中有个Thread子类,大家可以自行查阅文档,及范例: 如何在自定义的代码中,自定义一个线程呢? 1.通过对api的查找,java已经提供了对线程这类事 ...
- ECMAScript---object对象类型详解
普通对象:由大括号包裹起来的,由零到多个属性名和属性值(键值对)组成的 那什么是属性呢? 属性:描述当前对象特征的,属性名是当前具备这个特征,属性值是这个特征的描述(专业语法,属性名称为键[key], ...
- centos安装oracle11g
1.1 安装依赖,创建用户和目录 参考http://www.cnblogs.com/gaojun/archive/2012/11/22/2783257.html yum -y install binu ...
- 【管理学】PDCA
- POJ 1797-Heavy Transportation-dijkstra小变形和POJ2253类似
传送门:http://poj.org/problem?id=1797 题意: 在起点和终点间找到一条路,使得经过的边的最小值是最大的: 和POJ2253类似,传送门:http://www.cnblog ...
- POJ 2643 Election map
POJ 2643 Election 第一次写博客,想通过写博客记录自己的ACM历程,也想解释下英文题目,写些自己的理解.也可以让自己以后找题目更加方便点嘛.ElectionTime Limit: 10 ...