虽然我们前面的db系列教程更多的是基于单数据源的db操作,但是实际的业务开发中,难免会遇到一个项目配置多个数据源的情况,接下来本文将介绍一下多个数据源可以怎么配置,我们的JdbcTemplate又应该如何获取
I. 环境准备 1. 数据库相关 以mysql为例进行演示说明,因为需要多数据源,一个最简单的case就是一个物理库上多个逻辑库,本文是基于本机的mysql进行操作
创建数据库test
与 story
,两个库下都存在一个表money
(同名同结构表,但是数据不同哦)
1 2 3 4 5 6 7 8 9 10 CREATE TABLE `money` ( `id` int (11 ) unsigned NOT NULL AUTO_INCREMENT, `name` varchar (20 ) NOT NULL DEFAULT '' COMMENT '用户名' , `money` int (26 ) NOT NULL DEFAULT '0' COMMENT '钱' , `is_deleted` tinyint (1 ) NOT NULL DEFAULT '0' , `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' , `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' , PRIMARY KEY (`id` ), KEY `name` (`name` ) ) ENGINE =InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET =utf8mb4;
data
2. 项目环境 本项目借助SpringBoot 2.2.1.RELEASE
+ maven 3.5.3
+ IDEA
进行开发
下面是核心的pom.xml
(源码可以再文末获取)
1 2 3 4 5 6 7 8 9 10 <dependencies > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jdbc</artifactId > </dependency > </dependencies >
配置文件信息application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 spring: datasource: story: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/story?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: test: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: logging: level: root: info org: springframework: jdbc: core: debug
请注意上面的数据库配置,我们前面介绍的但数据库配置如下,它们层级并不一样,上面的配置需要我们自己额外进行加载解析
1 2 3 4 5 6 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/story?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password:
II. 多数据源支持 1. 数据源配置 SpringBoot帮我们省略了很多操作,单数据源时,在yaml文件中配置数据库相关信息之后,我们不需要任何其他操作,Spring会帮我们实例对应的DataSource
,然后借助它来创建JdbcTemplate
而多数据源则需要我们自己来额外处理了,请注意上面的配置信息,和默认的配置没什么差别,只是前缀多了一层,我们可以借助@ConfigurationProperties
来加载配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Configuration public class DataSourceConfiguration { @Primary @Bean (name = "storyDataSourceProperties" ) @ConfigurationProperties (prefix = "spring.datasource.story" ) public DataSourceProperties storyDataSourceProperties () { return new DataSourceProperties(); } @Primary @Bean (name = "storyDataSource" ) public DataSource storyDataSource (@Qualifier("storyDataSourceProperties" ) DataSourceProperties storyDataSourceProperties) { return storyDataSourceProperties.initializeDataSourceBuilder().build(); } @Bean (name = "testDataSourceProperties" ) @ConfigurationProperties (prefix = "spring.datasource.test" ) public DataSourceProperties testDataSourceProperties () { return new DataSourceProperties(); } @Bean (name = "testDataSource" ) public DataSource testDataSource (@Qualifier("testDataSourceProperties" ) DataSourceProperties testDataSourceProperties) { return testDataSourceProperties.initializeDataSourceBuilder().build(); } }
配置代码如上,一个是将数据源配置映射为bean DataSourceProperties
, 一个是根据数据源配置实例化DataSource
;
此外两个@Primary
注解,主要是为了设置默认的数据源
2. JdbcTemplate实例化 数据源已经获取到之后,再实例化JdbcTemplate
就很简单了,除了直接声明bean之外,也可以基于DataSource
来手动创建临时对象,下面给出两种使用姿势
定义对应的bean
,对于业务使用更友好
1 2 3 4 5 6 7 8 9 @Bean ("storyJdbcTemplate" )public JdbcTemplate storyJdbcTemplate (@Qualifier("storyDataSource" ) DataSource storyDataSource) { return new JdbcTemplate(storyDataSource); } @Bean ("testJdbcTemplate" )public JdbcTemplate testJdbcTemplate (@Qualifier("testDataSource" ) DataSource testDataSource) { return new JdbcTemplate(testDataSource); }
借助ApplicationContext
来实例化JdbcTemplate,使用更灵活
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Service public class JdbcServer implements ApplicationContextAware { private JdbcTemplate storyJdbcTemplate; private JdbcTemplate testJdbcTemplate; @Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException { Map<String, DataSource> map = applicationContext.getBeansOfType(DataSource.class ) ; System.out.println(map); storyJdbcTemplate = new JdbcTemplate(map.get("storyDataSource" )); testJdbcTemplate = new JdbcTemplate(map.get("testDataSource" )); } }
3. 测试case 最后简单测试一下上面创建的两个JdbcTemplate
是否访问不同的数据库
1 2 3 4 5 6 7 public void query () { List<Map<String, Object>> storyRes = storyJdbcTemplate.queryForList("select * from money where id in (1, 1000)" ); List<Map<String, Object>> testRes = testJdbcTemplate.queryForList("select * from money where id in (1, 1000)" ); System.out.println(storyRes); System.out.println("--------------" ); System.out.println(testRes); }
启动类如下
1 2 3 4 5 6 7 8 9 10 11 @SpringBootApplication public class Application { public Application (JdbcServer jdbcServer) { jdbcServer.query(); } public static void main (String[] args) { SpringApplication.run(Application.class ) ; } }
testcase
相同的sql,获取的结果并不一样,分别从两个库中获取的数据
4. 小结 使用多数据源,比较简单的思路就是自定义配置的加载方式,获取不同的DataSourceProperties
对象,然后基于它来创建DataSource
实例
利用JdbcTemplate
来操作db的应用场景,直接选择不同的数据源Datasource
就行了
当然实际的项目中,我们一般会借助Herbernate
、Myabtis
、Jooq
等orm框架,那么使用orm时,多数据源又应该怎么处理呢? (请持续关注,相关博文即将上线)
II. 其他 0. 项目 系列博文
项目源码
1. 一灰灰Blog 尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
一灰灰blog
Be the first person to leave a comment!