springboot数据源切换
需求:对不同的数据库进行操作,如读写分离
思想:在对数据库进行操作时,程序会默认去找数据源,从数据源获取一个连接connection,要做的点是在程序调用之前把数据源换了(例如本身默认是写,换成读的数据源),spring boot提供了一个AbstractRoutingDataSource类,翻译过来是抽象路由数据源,这个类可以指定使用的数据源,继承这个抽象类之后需要实现两个方法,一个方法是用来添加数据源的(读写分离就两个数据源,有其他的也可以添加进去),设置默认数据源的,还有一个是指定使用的数据源的。方法添加数据源的时候是以键值对的形式添加到map中,当指定数据源的方法返回的值在map中存在时,就是用这个key对应的数据源,如果不存在,就会使用设置的默认数据源
这里使用aop的方式来进行数据源的动态切换,先看数据源配置(这里两个数据源是读写分离,写在本机上,读在虚拟机上)
application.xml:
server:
port: 9222
spring:
datasource:
localmysql:
username: root
password: root
url: jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf8
driverClassName: com.mysql.cj.jdbc.Driver
remomysql:
username: root
password: root
url: jdbc:mysql://172.21.4.130:3306/mytest?useUnicode=true&characterEncoding=utf8
driverClassName: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
数据源配置为bean,加入ioc,供后面切换:
DatabaseResourceConfig
package com.gzt.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
/**
* @Description:
* @Author: guozhengtao
* @Date: 2022/1/29 11:48
*/
数据源key枚举:DatabaseSelectEnum
package com.gzt.config;
/**
* @Description: 定义一个枚举变量,当枚举变量的值为write是,选择写入的数据库连接,当枚举变量的值为read时,返回读取的数据库连接
* @Author: guozhengtao
* @Date: 2022/1/29 13:30
*/
public enum DatabaseSelectEnum {
/**
* 选择写枚举
* */
Write("write"),
/**
* 选择读枚举
* */
Read("read");
private final String select;
DatabaseSelectEnum(String select) {
this.select = select;
}
public String getSelect() {
return select;
}
}
数据源切换适配:DatabaseAdapt
package com.gzt.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* @Description:
* @Author: guozhengtao
* @Date: 2022/1/29 13:19
*/
到现在为止,数据源相关操作设置完毕,下面切换数据源的两种方式,因为在DatabaseAdapt类中定义了一个变量flag,这个flag是数据源对应的key,有两种方式来进行设置:
-
在方法中调用mapper之前先使用
DatabaseAdapt.flag=DatabaseSelectEnum.Write.getSelect();
-
使用aop的方式在执行方法或者类之前进行切换,主要介绍:
注解:DatabaseResourcedefine
package com.gzt.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Description:
* @Author: guozhengtao
* @Date: 2022/1/29 14:37
*/
Aop:DatabaseResourceToggle
package com.gzt.aspect;
import com.gzt.annotation.DatabaseResourcedefine;
import com.gzt.config.DatabaseAdapt;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @Description:
* @Author: guozhengtao
* @Date: 2022/1/29 15:01
*/目录结构如下:
主要代码部分:
package com.gzt.service;
import com.gzt.annotation.DatabaseResourcedefine;
import com.gzt.entity.User;
import com.gzt.mapper.TestMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description:
* @Author: guozhengtao
* @Date: 2022/1/30 13:03
*/
看这江湖浊酒,请共饮之
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构