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 ...
随机推荐
- QT 连接SQLIte数据库
1.新建一个qt应用程序 2.在.pro文件中添加 sql (下图,可以查看使用方法) 添加结构查看: 3.开始连接数据库 4.运行结果查看: 5.查看数据库文件: 6.使用可视化工具创建一个 ...
- vscode代码片段
{ "Print to console": { "prefix": "vue2", "body& ...
- 查看git的用户名和密码
转载自:https://www.cnblogs.com/xihailong/p/13354628.html 一.查看查看用户名 :git config user.name查看密码: git confi ...
- Software_Programming_bootstrap_book
2019-10-25 HTML index 11 p24 主页布局.
- Python学习—计算机与操作系统简介
计算机与操作系统简介 一.操作系统的主要发展史 1.手工操作--卡片穿孔 1946年第一台计算机诞生--20世纪50年代中期,计算机工作还在采用手工操作方式.此时还没有操作系统的概念.程序员将对应于程 ...
- jmeter接口自动化-读取CSV文件执行测试用例
一.在csv文件中编写好用例 首先在csv文件首行填写相关参数并编写测试用例.脚本可通过优先级参数控制执行哪些接口,通过请求方式执行不同端口下的接口,再读取csv文件时进行参数化. 二.设计测试脚本并 ...
- 当win7遭遇蓝屏代码0x0000006b
转载请注明来源:https://www.cnblogs.com/Sherlock-L/p/15069877.html 关键词:win7.蓝屏.0x0000006b 事发 话说在某个周末,当我打开电脑, ...
- 下载安装sqlyog
sqlyog下载地址: https://github.com/webyog/sqlyog-community/wiki/Downloads 下载社区版,然后傻瓜式安装
- 杂:pthread_cond_timedwait导致死锁
地球人都知道1:pthread_cond_timedwait使用时,需要对[条件]加锁.[条件]也是一种线程共享资源. 地球人都知道2:1个互斥锁不应该管理2类及以上的多线程共享资源 1+2=下面这样 ...
- API对象--Ingress(chrono《kubernetes入门实战课》笔记整理)
[概念说明] Service 的功能和运行机制,主要由 kube-proxy 控制的四层负载均衡,即根据IP.PORT来做负载均衡.而很多应用都是在7层做均衡更为合理,比如根据主机名.URI.请求头. ...