# database-separation
**Repository Path**: Gene_orange/database-separation
## Basic Information
- **Project Name**: database-separation
- **Description**: 记录学习数据库读写分离(SpringBoot + Mybatis + Spring Aop + MySQL)
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2021-05-07
- **Last Updated**: 2021-09-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
```
一、MySQL数据库主从搭建
本人是以window的数据库作为主(写)库,然后虚拟机的数据库作为从(读)库;
这里先简单记录下虚拟机安装MySQL的命令以及搭建数据库主从备份:
# 查看有没有安装MySQL:
dpkg -l | grep mysql
# 安装MySQL:
apt install mysql-server
# 安装完成之后可以使用如下命令来检查是否安装成功:
netstat -tap | grep mysql
# 检查mysql服务状态:
systemctl status mysql
# 配置mysql允许远程访问,编辑mysqld.cnf
vim /etc/mysql/mysql.conf.d/mysqld.cnf
# 忘记密码,则在mysqld.cnf文件skip-external-locking下添加
skip-grant-tables
# 重启数据库
sudo service mysql restart
mysql> CREATE USER 'orange'@'%' IDENTIFIED BY 'XXXXXX'; # 创建用户
mysql> GRANT REPLICATION SLAVE ON *.* TO 'orange'@'%'; # 分配权限
mysql> flush privileges; # 刷新权限
```
```
# 主库配置(my.ini)
[mysqld]
# Server Id.
server-id=1
log-bin=master-bin
log-bin-index=master-bin.index
重启之后,执行查询语句 show master status;
```

```
# 从库配置 (/etc/mysql/mysql.conf.d/mysqld.cnf)
[mysqld]
server-id=2
relay-log-index=slave-relay-bin.index
relay-log=slave-relay-bin
# 重启数据库,执行连接主库数据库语句
CHANGE MASTER TO
MASTER_HOST='192.168.25.5',
MASTER_USER='orange',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='master-bin.000004',
MASTER_LOG_POS=154;
# 开启备份
mysql> start slave;
```

```
# 不同步哪些数据库
binlog-ignore-db = mysql
binlog-ignore-db = test
binlog-ignore-db = information_schema
# 只同步哪些数据库,除此之外,其他不同步
binlog-do-db = game
```
二、pom.xml
```
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
com.alibaba
druid-spring-boot-starter
1.1.10
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
mysql
mysql-connector-java
5.1.47
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.0.0
tk.mybatis
mapper-spring-boot-starter
2.0.2
commons-io
commons-io
2.6
org.apache.commons
commons-lang3
3.5
org.springframework.boot
spring-boot-starter-aop
```
二、application.yml
```
spring:
datasource:
num: 1 # 读库数目
type-aliases-package: com.gdkm.database.mapper
mapper-locations: classpath*:mapper/*Mapper.xml
# config-location: classpath:/mybatis-config.xml
master:
url: jdbc:mysql://192.168.25.5:3306/db_user?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
username: orange
password: XXXXX
driver-class-name: com.mysql.jdbc.Driver
slave:
url: jdbc:mysql://192.168.25.6:3306/db_user?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
username: root
password: XXXXX
driver-class-name: com.mysql.jdbc.Driver
```
三、代码实现

```
- DataSourceConfig : 主要是配置主从库的数据源,以及事务管理等,不再使用SpringBoot默认的配置
- DataSourceContextHolder:利用ThreadLocal封装的保存数据源上线的上下文context;
- DataSourceRouter extend AbstractRoutingDataSource: 最终的determineCurrentLookupKey返回的是从DataSourceContextHolder中拿到的,因此在动态切换数据源的时候注解应该给DataSourceContextHolder设值;
- DataSourceSwitcher: 自定义注解,用于动态切换数据源;
- DataSourceContextAop:切面类,用于拦截自定义注解从而设置DataSourceContextHolder的值来实现动态切换数据源;
- DataSourceAspect:切面类,用于拦截service包特定方法的前缀判断从而设置DataSourceContextHolder的值来实现动态切换数据源;
```