SpringBoot多数据源改造(一)
今天做一个需求,业务项目需要访问另一个项目的数据库。
常用两种方案:
1、另一个项目提供一个RestFul API,供调用方通过feign或其它httpClient等方式来访问。
2、项目中通过配置多数据源访问另一个项目库,当然必须有访问权限。
经过对比分析,决定采用第二种方案,原因:一方面,有访问另一个数据源的权限。另一方面,减少一层中间API服务可用性的依赖。
于是开始动手:
第一步,增加新数据源的配置类
@Configuration
@MapperScan(basePackages = {"com.XXX.ecc.YYY.dao"}, sqlSessionTemplateRef = "sqlSessionTemplate2")
public class DataSource2Config { /**
* 创建datasource对象
* @return
*/
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "YYY.datasource.prefix")// prefix值必须是application.properteis中对应属性的前缀
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
} /**
* 创建sql工程
* @param dataSource
* @return
* @throws Exception
*/
@Bean(name = "sqlSessionFactory2")
public SqlSessionFactory sqlSessionFactory2(@Qualifier("dataSource2") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//对应mybatis.type-aliases-package配置
bean.setTypeAliasesPackage("com.XXX.ecc.cloudbiz.domain");
//对应mybatis.mapper-locations配置
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:YYY_sqlmap/**/*.xml"));
//开启驼峰映射
bean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
return bean.getObject();
} /**
* 配置事务管理
* @param dataSource
* @return
*/
@Bean(name = "transactionManager2")
public DataSourceTransactionManager transactionManager2(@Qualifier("dataSource2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} /**
* sqlSession模版,用于配置自动扫描pojo实体类
* @param sqlSessionFactory
* @return
* @throws Exception
*/
@Bean(name = "sqlSessionTemplate2")
public SqlSessionTemplate sqlSessionTemplate2(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
} 第二步:
在resources下增加YYY_sqlmap文件夹,并且创建YYYMapper.xml,在@MapperScan(basePackages = {"com.XXX.ecc.YYY.dao"}指定的包下,创建YYYMapper.java文件。 第三步:改造原有数据源:增加MapperScan注解,增加事务配置及sessionFactory方法,并在事务、datasource、sessionfactory的方法加上@Primary注解,做为主数据源
@Configuration
@MapperScan(basePackages = {"com.XXX.ecc.zzz.dao"}, sqlSessionTemplateRef = "sqlSessionTemplate")
public class DruidConfig { private Logger logger = LoggerFactory.getLogger(getClass()); @Value("${spring.datasource.url}")
private String dbUrl; @Value("${spring.datasource.username}")
private String username; @Value("${spring.datasource.password}")
private String password; @Value("${spring.datasource.driver-class-name}")
private String driverClassName; @Value("${spring.datasource.initialSize}")
private int initialSize; @Value("${spring.datasource.minIdle}")
private int minIdle; @Value("${spring.datasource.maxActive}")
private int maxActive; @Value("${spring.datasource.maxWait}")
private int maxWait; @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis; @Value("${spring.datasource.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis; @Value("${spring.datasource.validationQuery}")
private String validationQuery; @Value("${spring.datasource.testWhileIdle}")
private boolean testWhileIdle; @Value("${spring.datasource.testOnBorrow}")
private boolean testOnBorrow; @Value("${spring.datasource.testOnReturn}")
private boolean testOnReturn; @Value("${spring.datasource.poolPreparedStatements}")
private boolean poolPreparedStatements; @Value("${spring.datasource.filters}")
private String filters; @Value("${spring.datasource.loginUserName}")
private String loginUserName; @Value("${spring.datasource.loginUserPassword}")
private String loginUserPassword; @Value("${spring.datasource.pwdDecrypt:config.decrypt=true}")
private Properties pwdDecryptProperties;
@Value("${spring.datasource.publicKey:''}")
private String publicKey; @Value("${spring.datasource.allow}")
private String allowIp;
@Value("${spring.datasource.deny}")
private String denyIp;
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
//IP白名单
reg.addInitParameter("allow",allowIp);
//IP黑名单
reg.addInitParameter("deny",denyIp);
//控制台管理用户
reg.addInitParameter("loginUsername", loginUserName);
reg.addInitParameter("loginPassword", loginUserPassword);
return reg;
} @Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
filterRegistrationBean.addInitParameter("profileEnable", "true");
filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
return filterRegistrationBean;
} @Bean(name = "dataSource")
@Primary
public DataSource druidDataSource(){
DruidDataSource datasource = new DruidDataSource(); datasource.setUrl(this.dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
try {
datasource.setFilters(filters);
pwdDecryptProperties.setProperty("config.decrypt.key",publicKey);
datasource.setConnectProperties(pwdDecryptProperties);
} catch (SQLException e) {
logger.error("druid configuration initialization filter", e);
}
return datasource;
} /**
* 创建sql工程
* @param dataSource
* @return
* @throws Exception
*/
@Bean(name = "sqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory2(@Qualifier("dataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//对应mybatis.type-aliases-package配置
bean.setTypeAliasesPackage("com.XXX.ecc.zzz.domain");
//对应mybatis.mapper-locations配置
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:sqlmap/**/*.xml"));
//开启驼峰映射
bean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
return bean.getObject();
} /**
* 配置事务管理
* @param dataSource
* @return
*/
@Bean(name = "transactionManager")
@Primary
public DataSourceTransactionManager transactionManager2(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} /**
* sqlSession模版,用于配置自动扫描pojo实体类
* @param sqlSessionFactory
* @return
* @throws Exception
*/
@Bean(name = "sqlSessionTemplate")
@Primary
public SqlSessionTemplate sqlSessionTemplate2(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
第四步:在项目启动类上去掉@MapperScan注解 至此,配置完成,编译启动测试即可。 注意事项:
1、@Primary在主数据源要配置上,否则在@Autowired时会出错或注入非期待的数据源
2、@Qualifier:当一个接口有多个实现类的时候使用,通过指定名称的注入,
SpringBoot多数据源改造(一)的更多相关文章
- SpringBoot多数据源改造(二)
在上一篇的内容中,主要介绍了spring boot项目的多数据源改造的涉及的基本配置及改动.在spring项目中,常用Mybatis做ORM操作数据库,并且分页操作是避免不了的. 因此,这一篇主要介绍 ...
- 搞定SpringBoot多数据源(3):参数化变更源
目录 1. 引言 2. 参数化变更源说明 2.1 解决思路 2.2 流程说明 3. 实现参数化变更源 3.1 改造动态数据源 3.1.1 动态数据源添加功能 3.1.2 动态数据源配置 3.2 添加数 ...
- Spring-Boot配置文件数据源配置项
Spring-Boot配置文件数据源配置项(常用配置项为红色) 参数 介绍 spring.datasource.continue-on-error = false 初始化数据库时发生错误时,请勿停止 ...
- SpringBoot多数据源动态切换数据源
1.配置多数据源 spring: datasource: master: password: erp_test@abc url: jdbc:mysql://127.0.0.1:3306/M201911 ...
- SpringBoot学习笔记(三):SpringBoot集成Mybatis、SpringBoot事务管理、SpringBoot多数据源
SpringBoot集成Mybatis 第一步我们需要在pom.xml里面引入mybatis相关的jar包 <dependency> <groupId>org.mybatis. ...
- 搞定SpringBoot多数据源(1):多套源策略
目录 1. 引言 2. 运行环境 3. 多套数据源 3.1 搭建 Spring Boot 工程 3.1.1 初始化 Spring Boot 工程 3.1.2 添加 MyBatis Plus 依赖 3. ...
- 搞定SpringBoot多数据源(2):动态数据源
目录 1. 引言 2. 动态数据源流程说明 3. 实现动态数据源 3.1 说明及数据源配置 3.1.1 包结构说明 3.1.2 数据库连接信息配置 3.1.3 数据源配置 3.2 动态数据源设置 3. ...
- SpringBoot多数据源:动态数据源
目录 1. 引言 2. 动态数据源流程说明 3. 实现动态数据源 3.1 说明及数据源配置 3.1.1 包结构说明 3.1.2 数据库连接信息配置 3.1.3 数据源配置 3.2 动态数据源设置 3. ...
- Springboot 多数据源配置,结合tk-mybatis
一.前言 作为一个资深的CRUD工程师,我们在实际使用springboot开发项目的时候,难免会遇到同时使用多个数据库的情况,比如前脚刚查询mysql,后脚就要查询sqlserver. 这时,我们很直 ...
随机推荐
- PCB Winform中的WebBrowser扩展拖放(拖拽)功能 实现方法
我们在Winform支持网页通常增加WebBrowser控件实现,相当于内嵌浏览器浏览网页使用, 而此WebBrowser默认情况是文件拖入功能是不支持的, 如何才能支持呢.在这里介绍如何实现方法 一 ...
- ural 1012. K-based Numbers. Version 2(大数dp)
和1009相同,只是n达到了180位,可以模拟大数加和大数乘,这里用的java中的大数. import java.math.BigInteger; import java.util.Scanner; ...
- Kubernetes 配置 Taint 和 Toleration(污点和容忍)
通过污点和容忍让pod运行在特定节点上 参考官网:https://k8smeetup.github.io/docs/concepts/configuration/taint-and-toleratio ...
- cocos creator学习
2019-05-30 22:23:27 按照前一节我发的教程做,大概了解了Cocos creator的基本布局 但是你发现你不好写代码(感觉视频没有提) 需要下载VS code软件,在其上进行编辑,教 ...
- scrapy 简单操作
1.创建一个简单的scrapy项目 scrapy startproject search(项目名称)按照提示cd searchscrapy genspider serachname search.co ...
- 【BZOJ2565】最长双回文串 (Manacher算法)
题目: BZOJ2565 分析: 首先看到回文串,肯定能想到Manacher算法.下文中字符串\(s\)是输入的字符串\(str\)在Manacher算法中添加了字符'#'后的字符串 (构造方式如下) ...
- Zookeeper概念学习系列之zookeeper的节点
znode有两种类型: 临时节点(ephemeral node) 和 持久节点(persistent node). znode的类型在创建时确定并且之后不能再修改. 短暂znode的客户端会话结束 ...
- java中使用String的replace方法替换html模板保存文件
在我们的D盘下有这样一个html模板,现在我们要做的就是解析news.template文件,从数据库中提取数据将数据添加到指定的模板位置上 <head> <title>{tit ...
- Angular——流程控制指令
基本介绍 (1)ng-repeat,类似于for循环,对数组进行遍历 (2)ng-switch on,ng-switch-when,类似于switch,case 基本使用 ng-repeat < ...
- 转载:使用FileReader对象的readAsDataURL方法来读取图像文件
文章转载自:http://blog.okbase.net/jquery2000/archive/1296.html: FileReader对象的readAsDataURL方法可以将读取到的文件编码成D ...