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. 这时,我们很直 ...
随机推荐
- 当下较热web前端技术汇总
Web前段技术发展很快,主流技术日新月异,想想自己刚毕业那会用的asp技术,现在已经很少有主流网站在使用了.再到后来的J2EE框架,然后SpringMVC大行其道,但是最近各种js框架被广为传播,Ht ...
- js加减乘除在线计算器代码
js加减乘除在线计算器代码 在线演示本地下载
- Java—将文件压缩为zip文件
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import ...
- css3 画小蜜蜂
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Android的HttpUrlConnection类的GET和POST请求
/** * get方法使用 */ private void httpGet() { new Thread() { @Override public void run() { //此处的LOGIN是请求 ...
- Leetcode0006--ZigZag Conversion
[转载请注明]https://www.cnblogs.com/igoslly/p/9017638.html 来看一下题目: The string "PAYPALISHIRING" ...
- SQL基本操作——通配符
SQL 通配符:在搜索数据库中的数据时,SQL 通配符可以替代一个或多个字符.SQL 通配符必须与 LIKE 运算符一起使用.在 SQL 中,可使用以下通配符: 通配符 描述 % 替代一个或多个字符 ...
- day03-执行python方式、变量及数据类型简介
目录 执行Python程序的两种方式 1. 第一种:交互式 2. 第二种:命令式 3. Python执行程序的三个阶段 变量 变量 什么是变量 Python中的变量 变量名的命名规范 内存管理 定义变 ...
- Java 之jdbc连接mysql数据库
package jdbc; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; ...
- PAT_A1133#Splitting A Linked List
Source: PAT A1133 Splitting A Linked List (25 分) Description: Given a singly linked list, you are su ...