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 ...
随机推荐
- oracle 2个数组列,剔除数组重复的数据。
一.下面这样不规则的,数据如何剔除掉.循环筛选replace替换掉. 序号 正常时间 剔除时间 1 2022-12-19,2022-12-20,2022-12-21,2022-12-22,202 ...
- SAP BW/4HANA学习笔记1
1.Master Data BW/4HANA BW/4HANA简介 BW/4HANA的前身是SAP BW(Business Warehouse),本质是一种数据仓库解决方案. 数据仓库解决方案: 1. ...
- Mac系统中安装Nginx
一.前言 本文介绍一下,如何在Mac系统中安装Nginx,把详细过程记录下来,方便以后查看,也方便大家学习. 二.正文 1.安装 Homebrew homebrew是什么?它是Mac中的一款软件包 ...
- redis底层数据结构之整数集合(intset)
整数集合(intset) 当一个集合只包含整数值元素,并且这个集合的元素数量不多时,redis会使用整数集合(intset)作为集合键的底层实现 整数集合用于保存整数值的集合抽象数据类型,它可以保存类 ...
- java poi技术基础案例
基础 HSSF - 提供读写Microsoft Excel格式档案的功能.(03版本,处理xls) XSSF - 提供读写Microsoft Excel OOXML格式档案的功能.(07版本,处理xl ...
- VUE如何创建一个项目
1.安装 Vite npm install -g create-vite-app 2.利用 Vite 安装 Vue3.0 项目 create-vite-app projectName 3.安装依赖运行 ...
- linux下启动rabbitmq,redis,nginx
这只是其中一种启动方法,也是我自己安装好后试过多次可以用的, 1,启动rabbitmq rabbitmqctl start_app rabbitmq程序端口是5672,可视化界面入口端口是15672, ...
- jquery 去除兄弟节点的class
function chooseCategory(dicCode,obj){ $(obj).siblings('a').removeClass("active"); $(obj).a ...
- WPF检测设备变化
如果在构造函数中设置会出现为空 HwndSource source = PresentationSource.FromVisual(this) as HwndSource; 此时 source = n ...
- jsonpath表达式
JsonPath是一种简单的方法来提取给定JSON文档的部分内容,其中正则表达式的包含或不包含配制有时候非常有用! json操作实例 { "store": { "book ...