SpringBoot项目实现多数据源的三种方式
在开发过程中,我们经常被要求在一个项目中使用多数据源下面是总结下,使用多数据源的几种方式:
方式一:在同一实例下的不同数据库(在写SQL的时候用(数据库名称+"."+表名))
方式二:AOP+注解实多数据源
方式三:使用dynamic-datasource-spring-boot-starter实现多数据源
方式一:不用对程序做任何更改,只是写SQL时加上表名称
上面是在同一实例下面的不同数据库(citex_guess,citex_fusion),我先在一个项目中同时操作这两个数据库怎么半办啦!
select * from citex_fusion.fusion_invitee limit 10
select * from citex_guess.guess_account limit 10
不论是增删改查,只要是对数据库表进行操作,都需要加上表名
方式二、三、四通用实体类,mapper,service、web层
@Data
public class GuessAccount {private Long id;private Integer userId;private Integer currencyId;private String currency;private BigDecimal availableQty;private BigDecimal frozenQty;private Date createTime;private Date updateTime;
}
@Data
public class FusionInvite {private Integer userId;private Integer inviteeId;private String code;private Date createTime;private Date updateTime;}
Mapper代码
@Mapper
public interface FusionMapper {@DS("master")@Select("select * from fusion_invitee limit 10 ")List<FusionInvite> getFusionInviteList();}
@Mapper
public interface GuessMapper {@DS("slaveOne")@Select("select * from guess_account limit 10")List<GuessAccount> getGuessAccountList();}
service层
@Service
public class TestService {@Autowiredprivate FusionMapper fusionMapper;@Autowiredprivate GuessMapper guessMapper;public Object testDynamic() {List<FusionInvite> fusionInviteList = getFusionInviteList();List<GuessAccount> guessAccountList = getGuessAccountList();ResultVos resultVos = new ResultVos();resultVos.setFusionList(fusionInviteList);resultVos.setGuessList(guessAccountList);return resultVos; }public List<FusionInvite> getFusionInviteList(){List<FusionInvite> fusionList= fusionMapper.getFusionInviteList();return fusionList;}public List<GuessAccount> getGuessAccountList(){List<GuessAccount> guessList=guessMapper.getGuessAccountList();return guessList;}
web层
@RestController
public class TestController {@Autowiredprivate TestService testService;@PostMapping("getList")public Object getTestList() {return testService.testDynamic();}
}
方式二:
Maven依赖:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.0.BUILD-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>study_demo2</artifactId><version>0.0.1-SNAPSHOT</version><name>study_demo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.8</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId></dependency></dependencies>
配置文件YML
server:port: 8025spring:application:name: study_demo2datasource:master:username: jackpassword: jack987driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/citex_fusion?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE&serverTimezone=UTCslave1:username: jackpassword: jack987driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/citex_guess?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE&serverTimezone=UTCdruid:initial-size: 5max-active: 20min-idle: 5test-on-borrow: truemax-wait: -1min-evictable-idle-time-millis: 30000max-evictable-idle-time-millis: 30000time-between-eviction-runs-millis: 0
mybatis:configuration:map-underscore-to-camel-case: true
多数据源配置类:
数据源切换注解类:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface DS {String value() default "master";}
动态数据源配置类:
@Configuration
public class DynamicDataSourceConfiguration {@Primary@Bean(name = "master")@ConfigurationProperties(prefix = "spring.datasource.master")public DataSource masterDataSource() {DataSource ds = DataSourceBuilder.create().build();return ds;}@Bean(name = "slaveOne")@ConfigurationProperties(prefix = "spring.datasource.slave1")public DataSource slave_1_DataSource() {DataSource ds = DataSourceBuilder.create().build();return ds;}/*** 动态数据源: 通过AOP在不同数据源之间动态切换** @return*/@Bean(name = "dynamicDataSource")public DataSource dataSource(@Autowired @Qualifier("master") DataSource primery, @Autowired @Qualifier("slaveOne") DataSource coocon) {DynamicDataSource dynamicDataSource = new DynamicDataSource();// 默认数据源dynamicDataSource.setDefaultTargetDataSource(primery);// 配置多数据源Map<Object, Object> dsMap = new HashMap<Object, Object>(2);dsMap.put("master", primery);dsMap.put("slaveOne", coocon);dynamicDataSource.setTargetDataSources(dsMap);return dynamicDataSource;}@Beanpublic PlatformTransactionManager txManager(DataSource dynamicDataSource) {return new DataSourceTransactionManager(dynamicDataSource);}@Bean@ConfigurationProperties(prefix = "mybatis")public SqlSessionFactoryBean sqlSessionFactoryBean(@Autowired @Qualifier("dynamicDataSource") DataSource dynamicDataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dynamicDataSource);return sqlSessionFactoryBean;}}
实现多数据源的核心类(可动态路由的数据源类型)
public class DynamicDataSource extends AbstractRoutingDataSource {public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {super.setDefaultTargetDataSource(defaultTargetDataSource);super.setTargetDataSources(targetDataSources);super.afterPropertiesSet();}@Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDateSoureType();}public DynamicDataSource() {// TODO Auto-generated constructor stub}
}
使用ThreadLocal维护数据源类
@Slf4j
public class DynamicDataSourceContextHolder { /*** 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。*/private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();/*** 设置数据源的变量*/public static void setDateSoureType(String dsType) {log.info("切换到{}数据源", dsType);CONTEXT_HOLDER.set(dsType);}/*** 获得数据源的变量*/public static String getDateSoureType() {return CONTEXT_HOLDER.get();}/*** 清空数据源变量*/public static void clearDateSoureType() {CONTEXT_HOLDER.remove();}}
切面拦截注解实现多数据源切换
@Aspect
@Component
@Slf4j
public class DataSourceAspect {@Pointcut("@annotation(com.example.study.config.DS)")public void dataSourcePointCut() {}@Around("dataSourcePointCut()")public Object around(ProceedingJoinPoint point) throws Throwable {MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();DS annotation = method.getAnnotation(DS.class);DynamicDataSourceContextHolder.setDateSoureType(annotation.value());try {return point.proceed();} finally {// 销毁数据源 在执行方法之后log.info("销毁数据源{}", annotation.value());DynamicDataSourceContextHolder.clearDateSoureType();}}}
以上是通过AOP切换数据源的配置类:
使用通用以上通用的实体类,Mapper、Service、web层便可以实现多数据源的使用。
方式三:使用dynamic-datasource-spring-boot-starter实现多数据源
maven依赖:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.0.BUILD-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository -->
</parent><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>2.3.2</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.8</version></dependency>
配置文件(yml)
spring:application:name: study_demodatasource:dynamic:druid:initial-size: 5max-active: 20min-idle: 5test-on-borrow: truemax-wait: -1min-evictable-idle-time-millis: 30000max-evictable-idle-time-millis: 30000time-between-eviction-runs-millis: 0primary: master #设置默认的数据源或者数据源组,默认值即为masterdatasource:master:username: jackpassword: jack987driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/citex_fusion?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE&serverTimezone=UTCslaveOne:username: jackpassword: jack987driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/citex_guess?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE&serverTimezone=UTC
mybatis:configuration:map-underscore-to-camel-case: true
测试地址:localhost:8080/getList
结果:
SpringBoot项目实现多数据源的三种方式相关推荐
- 在Tomcat配置JNDI数据源的三种方式
转载自 在Tomcat配置JNDI数据源的三种方式 在我过去工作的过程中,开发用服务器一般都是Tomcat,数据源的配置往往都是在applicationContext.xml中配置一个dataSo ...
- XtraReport绑定数据源的三种方式
一 .report.datasource直接放一个dataset或datatable 此种方法在代码里实现,直接为report赋数据源 特点: -无须生成xml -生成模板文件.repx中不包含表结构 ...
- 第二周项目1函数参数传递的三种方式
/* .*Copyright (c) 2014,烟台大学计算机学院 *All right reserved. *文件名称:函数参数传递的三种方式.cpp *作者:彭子竹 *完成日期:2015年9月11 ...
- springboot项目解决跨域的几种方式
跨域资源共享(CORS):通过修改Http协议header的方式,实现跨域.说的简单点就是,通过设置HTTP的响应头信息,告知浏览器哪些情况在不符合同源策略的条件下也可以跨域访问,浏览器通过解析Htt ...
- springboot配置多个数据源(两种方式)
在我们的实际业务中可能会遇到:在一个项目里面读取多个数据库的数据来进行展示,spring对同时配置多个数据源是支持的. 本文中将展示两种方法来实现这个功能. springboot+mybatis 第一 ...
- quartz mysql数据源_配置quartz数据源的三种方式
如果是使用了JDBC JobStore或JobStoreCMT获得持久的Job时,就要配置相关的数据源了. 方式一:使用quartz.properties文件,这时只需要在property文件中增加如 ...
- SpringBoot中注入ApplicationContext对象的三种方式
在项目中,我们可能需要手动获取spring中的bean对象,这时就需要通过 ApplicationContext 去操作一波了! 1.直接注入(Autowired) @Component public ...
- 获取项目中静态文件的三种方式
1.this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()+"/***" 2.S ...
- spring配置datasource三种方式
转自:http://blog.csdn.net/yangyz_love/article/details/8199207 1.使用org.springframework.jdbc.datasource. ...
最新文章
- git提交忽略权限问题
- RHEL/CentOS 一些不错的第三方软件包仓库
- 谈谈mysql优化_浅谈MySQL SQL优化
- mybatis-查询过程
- OGG重复记录导致复制进程挂起
- as与c++的反射机制对比
- 常见的8个前端防御性编程方案
- 十个习惯让你精通新的开发技术
- 基于JAVA+SpringMVC+MYSQL的图书管理系统
- 硬件开发板-嵌入式开发
- CART算法原理及实现
- 字符串怎样实例化成对象
- 《版式设计——日本平面设计师参考手册》—第1章置入其他格式的文件
- storm the 少儿英语_米粒英语绘本课堂——The Snowstorm
- 【TWVRP】基于matlab灰狼算法求解带时间窗的车辆路径规划问题【含Matlab源码 361期】
- linux服务器 网速测试
- 图片、图标、代码资源网站
- 【SSM分布式架构电商项目-32】Dubbo入门
- 关于技术部管理的一些思考
- 计算机二级python考试资料(1)
热门文章
- 《软技能·代码之外的生存指南》读书笔记 ——自我营销
- thinksystem sr550 安装ubuntu14.04 无法识别网卡驱动(连不了网)
- python制作微信个人二维码怎么做_如何用Python制作微信的好友背景墙?
- 全国计算机竞赛保送清华,竞赛入清华_是不是如果获得全国各学科竞赛的一等奖就能保送清华_淘题吧...
- Javaweb中上传图片,获取相对路径,绝对路径
- GitHub标星5.6K,2020腾讯又一力作开源的Android UI框架——QMUI Android
- mac自带邮箱添加邮箱_如何在Mac上的Mail中创建或删除邮箱
- 华为Java机试题__转载
- 下载神器aria2和他的客户端Persepolis
- javaweb项目实训总结_JAVAWEB实训心得体会