【DB系列】JdbcTemplate之多数据源配置与使用

文章目录
  1. I. 环境准备
    1. 1. 数据库相关
    2. 2. 项目环境
  2. II. 多数据源支持
    1. 1. 数据源配置
    2. 2. JdbcTemplate实例化
    3. 3. 测试case
    4. 4. 小结
  3. II. 其他
    1. 0. 项目
    2. 1. 一灰灰Blog

虽然我们前面的db系列教程更多的是基于单数据源的db操作,但是实际的业务开发中,难免会遇到一个项目配置多个数据源的情况,接下来本文将介绍一下多个数据源可以怎么配置,我们的JdbcTemplate又应该如何获取

I. 环境准备

1. 数据库相关

以mysql为例进行演示说明,因为需要多数据源,一个最简单的case就是一个物理库上多个逻辑库,本文是基于本机的mysql进行操作

创建数据库teststory,两个库下都存在一个表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就行了

当然实际的项目中,我们一般会借助HerbernateMyabtisJooq等orm框架,那么使用orm时,多数据源又应该怎么处理呢? (请持续关注,相关博文即将上线)

II. 其他

0. 项目

系列博文

项目源码

1. 一灰灰Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

一灰灰blog


打赏 如果觉得我的文章对您有帮助,请随意打赏。
分享到