动态数据源(dynamic dataSource)
目的
在web开发中经常会遇到一个应用需要连接多个数据源的情况, 可以将数据源理解为数据的服务器, 而应用作为获取数据的客户端就需要和多个数据服务器之间建立连接。
多数据源的连接颇像web服务器的连接。
本文基于springboot+ Mybatis + druid的环境,分析如何建立多数据源。
方法
添加动态数据源的方法 可以之间参考下面的两篇文章。
Spring Boot + Mybatis多数据源和动态数据源配置 - CSDN博客
druid/druid-spring-boot-starter at master · alibaba/druid · GitHub
原理:
考虑连接WEB服务器一般需要的技术方法:
- 确定服务器的Ip和端口号
- 因为http请求的无记忆性,所以引入了cookie和session技术记住用户
- 为了性能,使用http连接池。
相同的方式:在数据库连接时, 我们也需要相同的处理。 为了有个明显的对比,使用表格的方式列出
http请求 | 数据连接池 |
---|---|
服务器的Ip和端口号 | 定义数据源DataSource |
session | SqlSession |
http连接池 | DruidDataSource(阿里的数据库连接池) |
从上表可以看出Http请求和数据库连接池DataSource之间是非常相似的,只是两者连接时, 使用的协议不同。
从本质上讲: 协议也只不过是客户端和服务端之间的报文格式和交互通信方式的描述。
理清了数据库连接需要的信息, 下面只需要将上述三个点连接起来即可,
下面,我们通过代码看下springboot中如何将上述三点连接起来:
- 创建相应的数据源
@Bean(name = "ds2")
@ConfigurationProperties(prefix = "spring.datasource.db2") // application.properteis中对应属性的前缀
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
- 创建相应的sqlSession
通过mybatis-spring – MyBatis-Spring | 第五章 使用 SqlSession 中可以知道,mybatsi-spring其实是通过SqlSessionTemplate 来管理SqlSession
, SqlSessionFactory 来创建SqlSession. 所以想要使用SqlSession. 只需要提供SqlSessionTemplate 即可。spring会利用该对象进行session的创建和销毁
通过查看下SqlSessionTemplate的类,以及利用spring生成Bean的方式,很容易生成特定DataSource的SqlSessionTemplate。
@Bean
public SqlSessionFactory sqlSessionFactory1() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(ds1); // 使用titan数据源, 连接titan库
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate1() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory1()); // 使用上面配置的Factory
return template;
}
- 链接
现在对于spring来说, 只是生成了一个DataSource和DataSource像对应的Session管理器。 而在真正调用mybatis层方法的时候,并不知道该mapper层是想要访问哪一个数据源。
而链接方式即是加上如下的配置:
@MapperScan(basePackages = {"titan.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory1")
public class MybatisDbLogisticsServiceConfig {}
打开MapperScan的源码,可以看到下面的注释:
* @MapperScan("org.mybatis.spring.sample.mapper")
* public class AppConfig {
*
* @Bean
* public DataSource dataSource() {
* return new EmbeddedDatabaseBuilder()
* .addScript("schema.sql")
* .build();
* }
*
* @Bean
* public DataSourceTransactionManager transactionManager() {
* return new DataSourceTransactionManager(dataSource());
* }
*
* @Bean
* public SqlSessionFactory sqlSessionFactory() throws Exception {
* SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
* sessionFactory.setDataSource(dataSource());
* return sessionFactory.getObject();
* }
很容易的看出, 其用于将某一文件夹下的Mapper文件和特定的DataSource, DataSourceTransactionManager(事务管理器), SqlSessionFactory 相关联。
关联之后, 执行某一Mapper类时, 就可以知道访问哪一个具体的DataSource了。
- 连接池
关于连接池的配置, 可以使用
@Bean(name = "ds2")
@ConfigurationProperties(prefix = "spring.datasource.db2") // application.properteis中对应属性的前缀
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
并加上下面的配置:
spring.datasource.db2.type=com.alibaba.druid.pool.DruidDataSource
或者在声明数据源时直接使用DruidDataSourceBuilder的数据源构造器。
@Primary
@Bean
@ConfigurationProperties("spring.datasource.druid.one")
public DataSource dataSourceOne(){
return DruidDataSourceBuilder.create().build();
}
调试方式
在写完所有所需要的部分, 下面就需要检验多数据源是否生效。
最简单的检验方式就是将程序跑起来, 分别调用不同数据源的方法, 观察数据源的切换。
下面介绍下两种调试方法:
-
debug模式启动程序,并在调用mapper的方法内打断点。并查看Mapper的相关属性是否正确。这在检查数据源的属性(比如闲时检测)是否设置到数据源中至关重要。
另外一种, 可以连接mysql,并查看数据库的连接情况。
主要是使用下面的命令:
show processlist;
显示结果如下:
上面显示了该数据库的连接情况。 从中可以看出以下几点信息:
1: 有那些主机连接到该数据库 即Host列,
2: 每个连接的状态,即Command
3: 连接保持的时间 即 Time
复盘
- 多debug
- 多思考与联系
参考文献
mybatis – MyBatis 3 | 简介
mybatis-spring – MyBatis-Spring | 第六章 注入映射器
Spring Boot + Mybatis多数据源和动态数据源配置 - CSDN博客
druid/druid-spring-boot-starter at master · alibaba/druid · GitHub