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数据库