SpringBoot项目连接多源MySQL数据库
说明(主要是实现的思路)
对于使用 SpringBoot 中使用 MySQL 的项目来说,可能会面临一个 SpringBoot 项目连接多个不同的 MySQL 数据库。这里针对普通的 SpringBoot 项目进行实现。关注点在查询前,数据库选择上进行定义。Demo 项目代码已经放到了我的 GitHub,是 SpringBoot + MyBatis 的测试项目。通过注解,选择不同的数据库。可能大家在参考的时候会出现各种奇奇怪怪的问题(细心能解决大部分问题哈)
1. 普通的 SpringBoot 项目

datasource 目录中的代码为主要实现代码。example 目录下的代码只是用作测试不同MySQL数据源的连接。
2. 实现思路
数据源连接信息实体类(getter、setter、constructer省略)
该实体类的字段信息,根据自己项目特定情况而定。不一定按照如此定义。
1  | package com.osys.dynamic.datasource;  | 
数据库连接构建类
对于上面的 DataSourceProperty 保存的是数据库连接信息,这里创建一个构建工具类,用于构建数据库连接。
1  | package com.osys.dynamic.datasource;  | 
多数据源连接信息实体类
上面的 DataSourceProperty 保存的时某个数据源的连接信息,由于是多数据源的,会存在多个 DataSourceProperty 对象,这里通过数据源 key 来获取对应的数据源连接信息,编写一个保存数据源信息的配置类:
1  | package com.osys.dynamic.datasource;  | 
多数据源的选择
AbstractRoutingDataSource 是 SpringBoot 基于查找 key 将 getConnection() 调用路由到各种目标 DataSource 之一的抽象 DataSource 实现。
选择数据源解决方案:编写一个类,继承 AbstractRoutingDataSource,实现它的 determineCurrentLookupKey() 方法和 determineTargetDataSource() 方法,来选择使用哪一个数据源。DynamicDataSourceConfig 中 Map 保存到创建的数据连接。
1  | package com.osys.dynamic.datasource;  | 
线程隔离的 key
上面的 DynamicDataSourceResolver#determineTargetDataSource() 方法中,确定的是 dataSource 的 key。SpringBoot 项目中,CRUD 操作是在不同线程中进行的,不同的需求,连接的MySQL数据库可能是不一样的,因此不同线程之间的 Key 是不能够被其它线程影响到的。使用 ThreadLocal 防止任务在共享资源上产生冲突
1  | package com.osys.dynamic.datasource;  | 
将数据源注册为 bean
前面一件基本实现了不同数据源的选择,在此还有一件比较重要的事情要完成,那就是将我们项目中的数据库连接注册为 bean。
1  | package com.osys.dynamic.datasource;  | 
对于不同的 SpringBoot 项目,数据库连接的方式大概率是不一样的,如果采用本思想实现连接不同MySQL的数据库,应该将主数据源的连接方式改为如此。
数据源连接信息
项目中会用到的多源MySQL数据库连接,在项目启动的时候需要将这些数据库的连接信息保存到前边创建的 DynamicDataSourceConfig 中,以便后续使用。在 SpringBoot 中可以通过继承 CommandLineRunner 接口,实现 run() 方法,在项目启动的时候,将多个数据库连接信息加载到程序中。
1  | package com.osys.dynamic.datasource.runner;  | 
例如:这里的数据库连接信息是保存在主数据源中的,那么 RegisterConnectService 的实现:
1  | package com.osys.dynamic.datasource.service;  | 
1  | package com.osys.dynamic.datasource.mapper;  | 
在前面多数据源的加载并创建功能已经基本实现,需要在 SpringApplication 中导入 DynamicDataSourceRegister 类。
1  | package com.osys.dynamic;  | 
到这里,项目连接不同数据源的数据库代码主体已经基本是实现了。下面需要实现数据源使用。
3. 项目连接不同数据源MySQL
创建注解
1  | package com.osys.dynamic.datasource.annotation;  | 
1  | package com.osys.dynamic.datasource.annotation;  | 
编写切面
虽然注解已经写好,不过对于这两个注解,还没关联到选择不同的数据源。
1  | package com.osys.dynamic.datasource.aspect;  | 
1  | package com.osys.dynamic.datasource.aspect;  | 
SpringApplication 添加切面代理支持
1  | package com.osys.dynamic;  | 
这里,对于项目使用多源数据库的实现思路已经基本定型(完成),下面编写几个测试接口,获取不同数据源下的信息。
4. 不同数据源连接测试
上面定义的 TargetDataSource 和 DynamicDataSource 注解,在 Repository 层/Service 层 的方法中使用即可。这里测试例子是在 Repository 中使用的。
创建实体类:getter、setter、constuctor等省略
1  | package com.osys.dynamic.example.dto;  | 
1  | package com.osys.dynamic.example.dto;  | 
1  | package com.osys.dynamic.example.dto;  | 
1  | package com.osys.dynamic.example.dto;  | 
1  | package com.osys.dynamic.example.dto;  | 
Repository
1  | package com.osys.dynamic.example.mapper;  | 
Service
1  | package com.osys.dynamic.example.service;  | 
Controller
1  | package com.osys.dynamic.example.controller;  | 
测试
项目启动成功:

先后调用接口:
- http://localhost:8888/user/select
 - http://localhost:8888/user/shopping
 - http://localhost:8888/user/qq
 - http://localhost:8888/user/game
 - http://localhost:8888/user/school
 
控制台查看使用的数据源:

使用的数据源都是不一样的。去不同的MySQL数据库查询数据。
附数据库信息
1  | USE mysql;  | 
SpringBoot项目连接多源MySQL数据库