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 ...
随机推荐
- Vue CLI 2内置框架webpack框架结构解析
目前Vue已经到3.X版本,相应的Vue CLI也已经是Vue CLI 3版本,创建命令使用vue create,如果要用2.X版的vue init命令,需要全局安装一个桥接工具: npm insta ...
- 浅谈spark
spark spark是一个开源分布式计算框架,在于让计算更加快速,通常使用资源调度器yarn和spark自带的资源调度器standalond进行调度,spark相对于Hadoop更加快速,基于它是内 ...
- Centos.JAVA 环境安装
JAVA 环境安装 0x00.环境准备 OS CentOS JDK1.8 安装包 jdk-8u131-linux-x64.tar.gz 0x01.卸载自带的open jdk 执行rpm -qa | g ...
- 解决linux conda 命令行环境提示消失的方法
之前不知道这么搞的,一不小心改了conda的默认设置,后面再登录的时候发现环境名字看不见了,用着很难受,为了解决这个问题,后面发现,应该是我改了changeps1这个设置,他默认是开着的,可以用下面的 ...
- 蓝牙mesh组网实践(环境监测传感器应用)
目录 蓝牙mesh组网中的低功耗节点,在应用于低频率上传数据的传感器网络时有着得天独厚的功耗优势,在1min唤醒上传一包的情况下ch582的平均功耗仅有12uA,若每小时甚至每天采样一次数据并上传,平 ...
- Oracle —— 对表数据操作的各种小Tip
1.清空某表数据 TRUNCATE TABLE schema_name.table_name 例如:在名为test的schema下,有一张名为user的表,故此,可用TRUNCATE TABLE te ...
- nacos启动失败
报错如下: 通过第二个圈可以看出,没有发现9848端口,才想起来自己Spring Cloud Alibaba依赖对应的nacos版本是2.0.4,而启动的nacos服务却是1.x版本,才导致这个报错. ...
- HCIP-ICT实战进阶05-路由策略与策略路由
HCIP-ICT实战进阶05-路由策略与策略路由 0 前言 什么是路由策略? 基于报文的目的IP地址进行路由表查找, 之后转发数据; 针对控制平面, 为路由协议和路由表服务, 针对路由信息进行过滤或者 ...
- windows安装和重装系统后无法识别U盘
安装系统的方法: 1. 方案一,用大白菜制写入pe系统,但必须先准备Windows安装包 方案二,把ISO格式的系统安装包直接写入到u盘,写入U盘的方法请百度 2.开机看到电脑的logo后,按f2(不 ...
- python 操作 ES 一、基础操作
示例代码环境 python:3.8 es:7.8.0环境安装 pip install elasticsearch==7.8.0 from elasticsearch import Elasticsea ...