今天做一个需求,业务项目需要访问另一个项目的数据库。

常用两种方案:

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多数据源改造(一)的更多相关文章

  1. SpringBoot多数据源改造(二)

    在上一篇的内容中,主要介绍了spring boot项目的多数据源改造的涉及的基本配置及改动.在spring项目中,常用Mybatis做ORM操作数据库,并且分页操作是避免不了的. 因此,这一篇主要介绍 ...

  2. 搞定SpringBoot多数据源(3):参数化变更源

    目录 1. 引言 2. 参数化变更源说明 2.1 解决思路 2.2 流程说明 3. 实现参数化变更源 3.1 改造动态数据源 3.1.1 动态数据源添加功能 3.1.2 动态数据源配置 3.2 添加数 ...

  3. Spring-Boot配置文件数据源配置项

    Spring-Boot配置文件数据源配置项(常用配置项为红色) 参数 介绍 spring.datasource.continue-on-error = false 初始化数据库时发生错误时,请勿停止 ...

  4. SpringBoot多数据源动态切换数据源

    1.配置多数据源 spring: datasource: master: password: erp_test@abc url: jdbc:mysql://127.0.0.1:3306/M201911 ...

  5. SpringBoot学习笔记(三):SpringBoot集成Mybatis、SpringBoot事务管理、SpringBoot多数据源

    SpringBoot集成Mybatis 第一步我们需要在pom.xml里面引入mybatis相关的jar包 <dependency> <groupId>org.mybatis. ...

  6. 搞定SpringBoot多数据源(1):多套源策略

    目录 1. 引言 2. 运行环境 3. 多套数据源 3.1 搭建 Spring Boot 工程 3.1.1 初始化 Spring Boot 工程 3.1.2 添加 MyBatis Plus 依赖 3. ...

  7. 搞定SpringBoot多数据源(2):动态数据源

    目录 1. 引言 2. 动态数据源流程说明 3. 实现动态数据源 3.1 说明及数据源配置 3.1.1 包结构说明 3.1.2 数据库连接信息配置 3.1.3 数据源配置 3.2 动态数据源设置 3. ...

  8. SpringBoot多数据源:动态数据源

    目录 1. 引言 2. 动态数据源流程说明 3. 实现动态数据源 3.1 说明及数据源配置 3.1.1 包结构说明 3.1.2 数据库连接信息配置 3.1.3 数据源配置 3.2 动态数据源设置 3. ...

  9. Springboot 多数据源配置,结合tk-mybatis

    一.前言 作为一个资深的CRUD工程师,我们在实际使用springboot开发项目的时候,难免会遇到同时使用多个数据库的情况,比如前脚刚查询mysql,后脚就要查询sqlserver. 这时,我们很直 ...

随机推荐

  1. [Swift通天遁地]四、网络和线程-(11)将服务器返回的JSON映射为实例对象

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  2. 347 Top K Frequent Elements 前K个高频元素

    给定一个非空的整数数组,返回其中出现频率前 k 高的元素.例如,给定数组 [1,1,1,2,2,3] , 和 k = 2,返回 [1,2].注意:    你可以假设给定的 k 总是合理的,1 ≤ k ...

  3. MVC系列学习(十二)-服务端的验证

    在前一讲,提到过,客户端的东西永远可以造假,所以我们还要在服务端进行验证 注意:先加载表单,后添加js文件,才能有效:而先加载js,后添加表单,是没有效果的 1.视图与Model中的代码如下 2.一张 ...

  4. Core 项目下使用SQl语句

    public static DataTable ExeQuery(string connectionString, CommandType cmdType, string cmdText) { usi ...

  5. Ajax——异步基础知识(三)

    封装异步请求 1.将函数作为参数进行使用 2.因为获取数据是在一个注册事件中获取的,所以只有事件触发的时候才会调用此函数 <!DOCTYPE html> <html lang=&qu ...

  6. (转)Hibernate关联映射——对象的三种关系

    http://blog.csdn.net/yerenyuan_pku/article/details/70148618 Hibernate关联映射——对象的三种关系 Hibernate框架基于ORM设 ...

  7. Centos7安装gitlab服务器

    1.先按照官方教程 https://about.gitlab.com/downloads/#centos7 大概内容如下: 1. Install and configure the necessary ...

  8. logback日志配置文件

    application.properties application.properties logback-spring.xml <?xml version="1.0" en ...

  9. jquery制作动态添加表单行与删除表单行

    <script type="text/javascript" src="js/jquery1.7.js"></script> <s ...

  10. 几校联考——day1题解

    T1 约数的个数(好像不可提交) 如果一个整数a能够整除整数b,那么a叫做b的约数.现在有N(1 <= N <= 100,000)个整数,对于其中的每一个数,请找出它在其余N - 1个整数 ...