springboot数据库主从方案
2019-09-18 11:25
本篇分享数据库主从方案,案例采用springboot+mysql+mybatis演示;要想在代码中做主从选择,通常需要明白什么时候切换数据源,怎么切换数据源,下面以代码示例来做阐述;
搭建测试环境(1个master库2个slave库)
DataSource多数据源配置
设置mybatis数据源
拦截器+注解设置master和slave库选择
选出当前请求要使用的slave从库
测试用例
搭建测试环境(1个master库2个slave库)
由于测试资源优先在本地模拟创建3个数据库,分别是1个master库2个slave库,里面分别都有一个tblArticle表,内容也大致相同(为了演示主从效果,我把从库中表的title列值增加了slave字样):
再来创建一个db.properties,分别配置3个数据源,格式如下:
复制代码
1 spring.datasource0.jdbc-url=jdbc:mysql://localhost:3306/db0?useUnicode=true&characterEncoding=utf-8&useSSL=false
2 spring.datasource0.username=root
3 spring.datasource0.password=123456
4 spring.datasource0.driver-class-name=com.mysql.jdbc.Driver
5
6 spring.datasource1.jdbc-url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8&useSSL=false
7 spring.datasource1.username=root
8 spring.datasource1.password=123456
9 spring.datasource1.driver-class-name=com.mysql.jdbc.Driver
10
11 spring.datasource2.jdbc-url=jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf-8&useSSL=false
12 spring.datasource2.username=root
13 spring.datasource2.password=123456
14 spring.datasource2.driver-class-name=com.mysql.jdbc.Driver
复制代码
同时我们创建具有对应关系的DbType枚举,帮助我们使代码更已读:
复制代码
1 public class DbEmHelper {
2 public enum DbTypeEm {
3 db0(0, "db0(默认master)", -1),
4 db1(1, "db1", 0),
5 db2(2, "db2", 1);
6
7 /**
8 * 用于筛选从库
9 *
10 * @param slaveNum 从库顺序编号 0开始
11 * @return
12 */
13 public static Optional getDbTypeBySlaveNum(int slaveNum) {
14 return Arrays.stream(DbTypeEm.values()).filter(b -> b.getSlaveNum() == slaveNum).findFirst();
15 }
16
17 DbTypeEm(int code, String des, int slaveNum) {
18 this.code = code;
19 this.des = des;
20 this.slaveNum = slaveNum;
21 }
22
23 private int code;
24 private String des;
25 private int slaveNum;
26
27 //get,set省略
28 }
29 }
复制代码
DataSource多数据源配置
使用上面3个库连接串信息,配置3个不同的DataSource实例,达到多个DataSource目的;由于在代码中库的实例需要动态选择,因此我们利用AbstractRoutingDataSource来聚合多个数据源;下面是生成多个DataSource代码:
复制代码
1 @Configuration
2 public class DbConfig {
3
4 @Bean(name = "dbRouting")
5 public DataSource dbRouting() throws IOException {
6 //加载db配置文件
7 InputStream in = this.getClass().getClassLoader().getResourceAsStream("db.properties");
8 Properties pp = new Properties();
9 pp.load(in);
10
11 //创建每个库的datasource
12 Map