目前有个需求,需要使用不同的数据源,例如某业务要用A数据源,另一个业务要用B数据源。

如何在spring框架中解决多数据源的问题

使用springboot 整合多数据源 遇到的坑

1、添加依赖

<!-- 阿里的druid 依赖log4j -->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.0</version>
</dependency>
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.1</version>
</dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version>
</dependency><!-- 引入mybatis-spring -->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version>
</dependency>

2、application.properties配置文件

#主数据库
master:db:driverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://47.111.22.159:3306/xinyar_erp_uat?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=falseusername: erp_testpassword: erp_test@abc#从数据库
slave:db:driverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://47.111.22.159:3306/erp-test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=falseusername: erp_testpassword: erp_test@abcmybatis:mapper-locations: classpath*:com/xinyartech/erp/*/xml/*/*.xmltype-aliases-package: com.xinyartech.erp.*.model,com.xinyartech.erp.*.voconfiguration: map-underscore-to-camel-case: true

3、禁用springboot默认加载数据源配置

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {public static void main(String[] args) throws Exception {SpringApplication.run(Application.class, args);}
}

4、主数据源配置类

import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Configuration;import lombok.Data;
import org.springframework.beans.factory.annotation.Value;/*** 主数据源* * @author Lynch**/
@Configuration
@ConfigurationProperties(prefix = "master.db")
@Data
public class MasterDataSourceConfig {@Value("${master.db.url}")private String url;@Value("${master.db.username}")private String username;@Value("${master.db.password}")private String password;@Value("${master.db.driverClassName}")private String driverClassName;
}

5、从数据源配置类

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;import lombok.Data;/*** 从数据源* * @author Lynch**/
@Configuration
@ConfigurationProperties(prefix = "slave.db")
@Data
public class SlaveDataSourceConfig {@Value("${slave.db.url}")private String url;@Value("${slave.db.username}")private String username;@Value("${slave.db.password}")private String password;@Value("${slave.db.driverClassName}")private String driverClassName;
}

6、数据源配置类

import java.util.HashMap;
import java.util.Map;import javax.annotation.Resource;
import javax.sql.DataSource;import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;/*** 数据源配置类** @author Lynch*/
@Configuration
public class DataSourceComponent {@Resourceprivate MasterDataSourceConfig masterDataSourceConfig;@Resourceprivate SlaveDataSourceConfig slaveDataSourceConfig;@Bean(name = "master")public DataSource masterDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setUrl(masterDataSourceConfig.getUrl());dataSource.setUsername(masterDataSourceConfig.getUsername());dataSource.setPassword(masterDataSourceConfig.getPassword());dataSource.setDriverClassName(masterDataSourceConfig.getDriverClassName());return dataSource;}@Bean(name = "slave")public DataSource slaveDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setUrl(slaveDataSourceConfig.getUrl());dataSource.setUsername(slaveDataSourceConfig.getUsername());dataSource.setPassword(slaveDataSourceConfig.getPassword());dataSource.setDriverClassName(slaveDataSourceConfig.getDriverClassName());return dataSource;}@Primary//不加这个会报错。@DependsOn({ "master", "slave"}) //解决数据库循环依赖问题@Bean(name = "multiDataSource")public MultiRouteDataSource exampleRouteDataSource() {MultiRouteDataSource multiDataSource = new MultiRouteDataSource();Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("master", masterDataSource());targetDataSources.put("slave", slaveDataSource());multiDataSource.setTargetDataSources(targetDataSources);multiDataSource.setDefaultTargetDataSource(masterDataSource());return multiDataSource;}/*** 注册ServletRegistrationBean* * @return*/@Beanpublic ServletRegistrationBean druidServlet() {ServletRegistrationBean reg = new ServletRegistrationBean();reg.setServlet(new StatViewServlet());reg.addUrlMappings("/druid/*");reg.addInitParameter("allow", ""); // 白名单 return reg;reg.addInitParameter("loginUsername", "duan");reg.addInitParameter("loginPassword", "123456");reg.addInitParameter("resetEnable", "false");return reg;}/*** 注册FilterRegistrationBean* * @return*/@Beanpublic FilterRegistrationBean filterRegistrationBean() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setFilter(new WebStatFilter());filterRegistrationBean.addUrlPatterns("/*");filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");filterRegistrationBean.addInitParameter("profileEnable", "true");filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");filterRegistrationBean.addInitParameter("DruidWebStatFilter", "/*");return filterRegistrationBean;}
}

7、数据源上下文

/*** 数据源上下文** @author Lynch*/
public class DataSourceContext {private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();public static void setDataSource(String value) {contextHolder.set(value);}public static String getDataSource() {return contextHolder.get();}public static void clearDataSource() {contextHolder.remove();}
}

8、DataSource路由类

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;import com.xinyartech.erp.config.DataSourceContext;/*** DataSource路由类* * 重写的函数决定了最后选择的DataSource** @author Lynch*/
public class MultiRouteDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {// 通过绑定线程的数据源上下文实现多数据源的动态切换,有兴趣的可以去查阅资料或源码return DataSourceContext.getDataSource();}
}

9、修改上下文中的数据源就可以切换自己想要使用的数据源了 

public UserVO findUser(String username) {DataSourceContext.setDataSource("slave");UserVO userVO = userMapper.findByVO(username);System.out.println(userVO.getName());return null;
}

这种是在业务中使用代码设置数据源的方式,也可以使用AOP+注解的方式实现控制,还可以前端头部设置后端通过拦截器统一设置!

转载于:https://www.cnblogs.com/linjiqin/p/11597930.html

springboot+mybatis实现动态切换数据源相关推荐

  1. SpringBoot+AOP实现动态切换数据源

    首先描述下笔者的基本步骤: 1.yml配置文件中定义多数据源: 2.自定义一个注解类(@DataSource 可标注在类或方法上),定义String类型的变量value,value中存储数据源名称: ...

  2. springboot 中动态切换数据源(多数据源应用设计)

    目录 原理图 数据库 项目结构 启动类 entity controller service mapper 配置文件 线程上下文 (DataSourceHolder) 动态数据源 DynamicData ...

  3. mybatis手动切换数据库_在Spring项目中使用 Mybatis 如何实现动态切换数据源

    在Spring项目中使用 Mybatis 如何实现动态切换数据源 发布时间:2020-11-17 16:20:11 来源:亿速云 阅读:108 作者:Leah 这篇文章将为大家详细讲解有关在Sprin ...

  4. Springboot/MybatisPlus动态切换数据源

    1.1 简述 最近项目中有动态切换数据源需求,主要是要动态切换数据源进行数据的获取,现将项目中实现思路及代码提供出来,供大家参考.当然切换数据源还有其他的方式比如使用切面的方式,其实大体思路是一样的. ...

  5. Spring Boot多数据源配置并通过注解实现动态切换数据源

    文章目录 1. AbstractRoutingDataSource类介绍 2. ThreadLocal类介绍 3. 环境准备 3.1 数据库准备 3.2 项目创建 4. 具体实现 4.1 定义数据源枚 ...

  6. 动态切换数据源(spring+hibernate)

    起因:在当前我手上的一个项目中需要多个数据源,并且来自于不同类型的数据库... 因为很多历史原因.这个项目的住数据源是MySQL,整个系统的CURD都是操作的这个数据库. 但是还有另外两个用于数据采集 ...

  7. Spring学习总结(16)——Spring AOP实现执行数据库操作前根据业务来动态切换数据源

    深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...

  8. Java实现动态切换数据源

    在一般的Java项目中,如果使用Spring去管理数据库连接信息,一般只能连接一个数据库,可是会有部分情况我们需要连接多个数据库,甚至还会存在不同的请求需要根据配置信息连接不同的数据库,比如: 在很多 ...

  9. 通过切面动态切换数据源

    标题业务场景:大量的项目的数据库需要从db2迁移到oracle,为项目上线后出现不可预料的错误可及时回退,需要可以随时切换数据源 以控制层为切点,动态切换数据源,通过查询数据库查询当前应用的开关,来判 ...

最新文章

  1. 人脸识别引擎SeetaFaceEngine简介及在windows7 vs2013下的编译
  2. 经常玩电脑正确的坐姿_初级茶艺师工作技能培训:第一节礼仪(正确的坐姿)...
  3. centos系统中mysql密码_CentOS系统下强行重新修改MySQL密码
  4. .ajax 自定义headers,Ajax设置自定义请求头的两种方法
  5. 决策树的value是什么意思_从零开始的机器学习实用指南(六):决策树
  6. mysql分窗函数_频谱分析中如何选择合适的窗函数
  7. JSON数据格式----- JavaScript与JSON、JavaScript的JSON对象、构建JSON格式数据
  8. Chipmump文档
  9. win10系统下使用大漠插件后台截图卡住的解决方法
  10. Java、JSP毕业设计管理系统
  11. 定时任务task:annotation-driven配置
  12. 打通法律服务群众“最后一公里”,方正璞华劳动人事法律自助咨询服务平台频获“点赞”
  13. 信息系统项目管理基础
  14. VWware虚拟机如何设置固定的IP地址(详细步骤)
  15. Dataphin核心功能(四):安全——基于数据权限分类分级和敏感数据保护,保障企业数据安全
  16. 我和我目前的测试状态
  17. 客户端连接服务器,配置出错“连接超时”或者“无监听程序”解决方法
  18. Recent Trends in Deep Learning Based Natural Language Processing(arXiv)笔记
  19. ffmpeg源代码处理流程分析_FFmpeg源代码简单分析:内存的分配和释放
  20. com.intellij.execution.ExecutionException:at com.intellij.execution.rmi.RemoteProcessSupport.acqu报错

热门文章

  1. SQL:查询重复出现记录
  2. 20165322 第二周结队编程-四则运算
  3. 调试 Dockerfile - 每天5分钟玩转 Docker 容器技术(15)
  4. C#函数式编程之序列
  5. POJ-1904-King's Quest(强连通图)
  6. sql2005版本以上的分页存储过程
  7. 召唤AI大神与病毒作战!Kaggle发起CORD-19数据集文本挖掘竞赛
  8. 图片鉴黄大赛上线,请开始你的表演
  9. YOLOv3通道+层剪枝,参数压缩98%,砍掉48个层,提速2倍!
  10. 干点大事!“覆盖25万人的AI资源对接平台”发布,找人、找技术不再难!