SpringBoot多数据源详细配置与使用(包含数据源和事务配置)
SpringBoot项目数据库配置文件中配置多个数据源:
#********* primary jdbc **************************
spring.datasource.druid.primary.url=jdbc:mysql://127.0.0.1:3306/one?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&useSSL=false
spring.datasource.druid.primary.username=test1
spring.datasource.druid.primary.password=test1
spring.datasource.druid.primary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.primary.test-on-borrow=true
spring.datasource.druid.primary.test-while-idle=true
#********* primary jdbc ************************** #********* two jdbc **************************
spring.datasource.druid.two.url=jdbc:mysql://127.0.0.2:3306/two?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&useSSL=false
spring.datasource.druid.two.username=test2
spring.datasource.druid.two.password=test2
spring.datasource.druid.two.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.two.test-on-borrow=true
spring.datasource.druid.two.test-while-idle=true
#********* two jdbc **************************
数据源one(即主数据源)配置:
package com.test.common.config; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; /**
* <p>Description: primary数据库配置类 </p>*/
@Configuration
@MapperScan(basePackages = {"com.test.one.dao"}, sqlSessionTemplateRef = "sqlSessionTemplate")
public class DataSourceConfig { @Bean(name = "dataSource")public DataSource Datasource() {
return DruidDataSourceBuilder.create().build();
} /**
* 返回primary数据库的会话工厂
* @param ds
* @return
* @throws Exception
*/
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory SqlSessionFactory(@Qualifier("dataSource") DataSource ds) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(ds);
return bean.getObject();
} @Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} /**
* 返回primary数据库的会话模板
* @param sessionFactory
* @return
* @throws Exception
*/
@Bean(name = "sqlSessionTemplate")
public SqlSessionTemplate SqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sessionFactory) throws Exception {
return new SqlSessionTemplate(sessionFactory);
}
}
@MapperScan(basePackages = {"com.test.one.dao"}, sqlSessionTemplateRef = "sqlSessionTemplate")项目启动扫描
com.test.one.dao路径下的dao使用主数据源
package com.test.common.config; import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.*; import java.util.Collections;
import java.util.HashMap;
import java.util.Map; /**
* <p>Description: primary事务配置 </p>*/
@Configurationpublic class TransactionConfig { /*
* 通过AOP切面设置全局事务,拦截service包下面所有方法
* AOP术语:通知(Advice)、连接点(Joinpoint)、切入点(Pointcut)、切面(Aspect)、目标(Target)、代理(Proxy)、织入(Weaving)
*/ /**
* 事务超时时间
*/
private static final int TX_METHOD_TIMEOUT = 5; /**
* 定义切点变量:拦截指定包下所有类的所有方法,返回值类型任意的方法
*/
private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.test.*.*.impl.*.*(..))"; /**
* <p>Description: springBoot事务配置</p>*/
@Bean(name="txAdvice")
public TransactionInterceptor txAdvice( @Qualifier("transactionManager") PlatformTransactionManager transactionManager){
/*事务管理规则,声明具备事务管理的方法名*/
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
/*只读事物、不做更新删除等
当前存在事务就用当前的事务,当前不存在事务就创建一个新的事务*/
RuleBasedTransactionAttribute readOnlyRule = new RuleBasedTransactionAttribute();
//设置当前事务是否为只读事务,true为只读*/
readOnlyRule.setReadOnly(true);
//transactiondefinition 定义事务的隔离级别;
// PROPAGATION_NOT_SUPPORTED事务传播级别5,以非事务运行,如果当前存在事务,则把当前事务挂起
readOnlyRule.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); RuleBasedTransactionAttribute requireRule = new RuleBasedTransactionAttribute();
//抛出异常后执行切点回滚*/
requireRule.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
//PROPAGATION_REQUIRED:事务隔离性为1,若当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。 */
requireRule.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//设置事务失效时间,如果超过5秒,则回滚事务
requireRule.setTimeout(TX_METHOD_TIMEOUT);
Map<String, TransactionAttribute> txMap = new HashMap<>(20); txMap.put("add*",requireRule);
txMap.put("save*", requireRule);
txMap.put("insert*",requireRule);
txMap.put("delete*",requireRule);
txMap.put("remove*",requireRule);
txMap.put("update*",requireRule);
txMap.put("modify*",requireRule); txMap.put("get*",readOnlyRule);
txMap.put("query*", readOnlyRule);
txMap.put("find*", readOnlyRule);
txMap.put("select*",readOnlyRule);
source.setNameMap(txMap);
TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, source);
return txAdvice;
} /**
* 利用AspectJExpressionPointcut设置切面=切点+通知(写成内部bean的方式)
*/
@Bean(name="txAdviceAdvisor")
public Advisor txAdviceAdvisor(@Qualifier("txAdvice") TransactionInterceptor txAdvice){
//切面(Aspect):切面就是通知和切入点的结合。通知和切入点共同定义了关于切面的全部内容——它的功能、在何时和何地完成其功能。
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); //声明和设置需要拦截的方法,用切点语言描写
pointcut.setExpression(AOP_POINTCUT_EXPRESSION); return new DefaultPointcutAdvisor(pointcut, txAdvice);
}
}
数据源two配置:
package com.test.common.config; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; /**
* <p>Description: two数据库配置类 </p>*/
@Configuration
@ConditionalOnProperty(prefix = "spring.datasource.druid.two" ,name = "url", matchIfMissing = false)
@MapperScan(basePackages = {"com.test.two.dao"}, sqlSessionTemplateRef = "twoSqlSessionTemplate")
public class twoDataSourceConfig { @Bean(name = "twoDataSource")
@ConfigurationProperties(prefix = "spring.datasource.druid.two")
public DataSource twoDatasource() {
return DruidDataSourceBuilder.create().build();
} /**
* 返回two数据库的会话工厂
* @param ds
* @return
* @throws Exception
*/
@Bean(name = "twoSqlSessionFactory")
public SqlSessionFactory twoSqlSessionFactory(@Qualifier("twoDataSource") DataSource ds) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(ds);
return bean.getObject();
} @Bean(name = "twoTransactionManager")
public DataSourceTransactionManager twoTransactionManager(@Qualifier("twoDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} /**
* 返回two数据库的会话模板
* @param sessionFactory
* @return
* @throws Exception
*/
@Bean(name = "twoSqlSessionTemplate")
public SqlSessionTemplate twoSqlSessionTemplate(@Qualifier("twoSqlSessionFactory") SqlSessionFactory sessionFactory) throws Exception {
return new SqlSessionTemplate(sessionFactory);
}
}
@MapperScan(basePackages = {"com.test.two.dao"}, sqlSessionTemplateRef = "twoSqlSessionTemplate")项目启动扫描
com.test.two.dao路径下的dao使用two数据源
package com.test.common.config; import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.*; import java.util.Collections;
import java.util.HashMap;
import java.util.Map; /**
* <p>Description: two事务配置 </p>*/
@Configuration
@ConditionalOnProperty(name ="spring.datasource.druid.two.driver-class-name",havingValue="com.mysql.cj.jdbc.Driver")
public class TransactionTwoConfig { /*
* 通过AOP切面设置全局事务,拦截service包下面所有方法
* AOP术语:通知(Advice)、连接点(Joinpoint)、切入点(Pointcut)、切面(Aspect)、目标(Target)、代理(Proxy)、织入(Weaving)
*/ /**
* 事务超时时间
*/
private static final int TX_METHOD_TIMEOUT = 5; /**
* 定义切点变量:拦截指定包下所有类的所有方法,返回值类型任意的方法
*/
private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.test.*.*.impl.*.*(..))"; /**
* <p>Description: springBoot事务配置</p>*/
@Bean(name="txAdvice-two")
public TransactionInterceptor txAdvice( @Qualifier("twoTransactionManager") PlatformTransactionManager transactionManager){
/*事务管理规则,声明具备事务管理的方法名*/
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
/*只读事物、不做更新删除等
当前存在事务就用当前的事务,当前不存在事务就创建一个新的事务*/
RuleBasedTransactionAttribute readOnlyRule = new RuleBasedTransactionAttribute();
//设置当前事务是否为只读事务,true为只读*/
readOnlyRule.setReadOnly(true);
//transactiondefinition 定义事务的隔离级别;
// PROPAGATION_NOT_SUPPORTED事务传播级别5,以非事务运行,如果当前存在事务,则把当前事务挂起
readOnlyRule.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); RuleBasedTransactionAttribute requireRule = new RuleBasedTransactionAttribute();
//抛出异常后执行切点回滚*/
requireRule.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
//PROPAGATION_REQUIRED:事务隔离性为1,若当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。 */
requireRule.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//设置事务失效时间,如果超过5秒,则回滚事务
requireRule.setTimeout(TX_METHOD_TIMEOUT);
Map<String, TransactionAttribute> txMap = new HashMap<>(20); txMap.put("add*",requireRule);
txMap.put("save*", requireRule);
txMap.put("insert*",requireRule);
txMap.put("delete*",requireRule);
txMap.put("remove*",requireRule);
txMap.put("update*",requireRule);
txMap.put("modify*",requireRule); txMap.put("get*",readOnlyRule);
txMap.put("query*", readOnlyRule);
txMap.put("find*", readOnlyRule);
txMap.put("select*",readOnlyRule);
source.setNameMap(txMap);
TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, source);
return txAdvice;
} /**
* 利用AspectJExpressionPointcut设置切面=切点+通知(写成内部bean的方式)
*/
@Bean(name="txAdviceAdvisor-two")
public Advisor txAdviceAdvisor(@Qualifier("txAdvice-two") TransactionInterceptor txAdvice){
//切面(Aspect):切面就是通知和切入点的结合。通知和切入点共同定义了关于切面的全部内容——它的功能、在何时和何地完成其功能。
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); //声明和设置需要拦截的方法,用切点语言描写
pointcut.setExpression(AOP_POINTCUT_EXPRESSION); return new DefaultPointcutAdvisor(pointcut, txAdvice);
}
}
SpringBoot多数据源详细配置与使用(包含数据源和事务配置)的更多相关文章
- 170629、springboot编程之Druid数据源和监控配置二
上篇是一种配置方式,虽然我们创建了servlet.filter但是没有任务编码,看着是不是很不爽.ok,接下来说一下简介的配置方式,使用代码注册Servlet,也是我个人比较推荐的! 1.创建Drui ...
- 170628、springboot编程之Druid数据源和监控配置一
Spring Boot默认的数据源是:org.apache.tomcat.jdbc.pool.DataSource,那么如何修改数据源呢?我已目前使用比较多的阿里数据源Druid为例,如果使用其他的数 ...
- spring boot配置druid数据源和监控配置
直接上代码: 一.pom.xml中添加依赖 <dependency> <groupId>com.github.drtrang</groupId> <artif ...
- 基于注解实现SpringBoot多数据源配置
1.功能介绍 在实际的开发中,同一个项目中使用多个数据源是很常见的场景.最近在学习的过程中使用注解的方式实现了一个Springboot项目多数据源的功能.具体实现方式如下. 2.在applicatio ...
- spring学习笔记(22)声明式事务配置,readOnly无效写无异常
在上一节内容中.我们使用了编程式方法来配置事务,这种优点是我们对每一个方法的控制性非常强.比方我须要用到什么事务,在什么位置假设出现异常须要回滚等.能够进行非常细粒度的配置.但在实际开发中.我们可能并 ...
- DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描
DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描 liuyuhang原创,未经允许禁止转载 系列目录连接 DB数据源之Spr ...
- Spring-Boot 多数据源配置+动态数据源切换+多数据源事物配置实现主从数据库存储分离
一.基础介绍 多数据源字面意思,比如说二个数据库,甚至不同类型的数据库.在用SpringBoot开发项目时,随着业务量的扩大,我们通常会进行数据库拆分或是引入其他数据库,从而我们需要配置多个数据源. ...
- Springboot 多数据源配置,结合tk-mybatis
一.前言 作为一个资深的CRUD工程师,我们在实际使用springboot开发项目的时候,难免会遇到同时使用多个数据库的情况,比如前脚刚查询mysql,后脚就要查询sqlserver. 这时,我们很直 ...
- springboot多数据源的配置与使用
转自:https://www.jianshu.com/p/34730e595a8c 之前在介绍使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源.在单数据源的情况下,Sp ...
- springboot区分开发、测试、生产多环境的应用配置(二)
转:https://www.jb51.net/article/139119.htm springboot区分开发.测试.生产多环境的应用配置(二) 这篇文章主要给大家介绍了关于maven profil ...
随机推荐
- list集合之流操作
1.根据某一个实体字段进行去重(分组)操作 List<Object> list = objectList.stream().collect(Collectors.collectingAnd ...
- 设置导航栏的title
self.navigationController.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObjectsAnd ...
- CCPC2021 广州 K. Magus Night
CCPC2021 广州 K. Magus Night 题意 给定整数区间 \([1,m]\) ,从中可重复的选择 \(n\) 个数,形成一个数列 \(\{a_n\}\) .问:所有满足 \(\gcd( ...
- 硬件路灯第一期CPU篇
CPU,central processing unit,也就是中央处理器,如果计算机是一个人的话,CPU就是他的大脑我们近下来会科普CPU的几大参数 1.主频假设CPU是建筑工地的话,主频相当于工人们 ...
- vue3 门户网站搭建1-路由
从 0 到 1搭建门户网站,记录一下. 因为需求不大,所以比较简单,门户和后台管理直接一个项目出来,路由配置则想的是: 1.门户,用 /portal 标识 2.后台管理,用 /admin 标识 3. ...
- K8S群集调度器
目录: 调度约束 Pod启动典型创建过程 调度过程 Predicate常见的算法 常见的优先级选项 指定调度节点 亲和性 键值运算关系 Pod亲和性和反亲和性 污点和容忍 污点 容忍 其他注意事项 c ...
- LocalDateTime与LocalDate
时间新特性 新生事物出现,必定是对旧事物的完善或者是缺陷的弥补. 本文章介绍LocalDate.LocalDateTime.在多线程的情况,相比较于Date.Calendar.SimpleDateFo ...
- IaaS--云硬盘(何恺铎《深入浅出云计算》笔记整理)
[概念] 云硬盘,又叫做"云盘"或者"云磁盘",就是云虚拟机上可以挂载和使用的硬盘.这里,它既包含了用于承载操作系统的系统盘,也包括了承载数据的数据盘.云厂商对 ...
- 调度器45—wake_affine
基于 Linux-5.10 一.wake_affine 简介 1. 背景 在进程唤醒选核路径中, wake_affine 倾向于将被唤醒进程(wakee)尽可能安排在 waker所在 CPU 上, 这 ...
- 简单理解gqrx是什么
gqrx:Gqrx是一个基于gnuradio和Qt架构,开发的一个开源的SDR接收机的应用.下图是他的一个运行界面: gnu radio GNU Radio是一个自由软件开发工具包,提供实现软件无线电 ...