一、需求背景
具体的项目不便多说,简单来说是外部将结构化数据发送至 kafka 的数十个 topic。
本项目需要消费所有这些数据,并根据topic,存入不同的table。每条结构化数据都拥有公共字段 uid。
根据uid 和 table 将映射到某个具体的数据库 dataSource。
本文主要是实现根据已知的消息,自动将dao层的sql调用映射到不同的数据库连接,至于kafka 等数据来源是什么,并不重要。
因此,下文的实现,仅涉及到一些 Druid 和 aop层面的东西。
二、配置过程
2.1 添加Druid依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
2.2 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
default-db:
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/defaultDb
username: postgres
password: Gjm6sCZV4h6zl3zSqgRoMMN5ckfKiCbJgKeiA...
db1:
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/db1
username: postgres
password: Gjm6sCZV4h6zl3zSqgRoMMN5ckfKiCbJgKeiA...
- 此处可以配置需要的任意多个数据库。
- 密码采用密文的时候,需要在创建 DataSource Bean 之前解析出明文。
- 配置DataSource不一定需要采用上述代码的配置方式,完全可以更改属性字段或者自定义配置文件。
2.3 java中获取配置好的DataSource 配置
采用其他的单独的置文件的可以诸多java自带的工具类获取,不赘述
采用 application.yml 方式获取配置非常简单。 如下构建 DruidProperties.java类即可一次性获取所有DB 配置:
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidProperties {
private Map<String, Map<String, String>> druid;
private String type;
public String getType() {
return type;
}
public DruidProperties setType(String type) {
this.type = type;
return this;
}
public Map<String, DbProperties> getDruid() {
Map<String, DbProperties> map = new HashMap<>();
for(Map.Entry<String, Map<String, String>> entry : druid.entrySet()) {
map.put(entry.getKey(), JSON.parseObject(JSON.toJSONString(entry.getValue()), DbProperties.class));
}
return map;
}
public DruidProperties setDruid(Map<String, Map<String, String>> druid) {
this.druid = druid;
return this;
}
protected static class DbProperties {
private String driverClassName;
private String url;
private String username;
private String password;
public String getDriverClassName() {
return driverClassName;
}
public DbProperties setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
return this;
}
public String getUrl() {
return url;
}
public DbProperties setUrl(String url) {
this.url = url;
return this;
}
public String getUsername() {
retur