SpringBoot多PgSQL数据源的一种方式
· 阅读需 4 分钟
SpringBoot配置多个PgSQL的一种方式。
默认配置文件形式
多数据源最快的做法按照固定格式配置多数据源yaml文件。
spring:
datasource:
dynamic:
primary: main
datasource:
main:
username: admin
password: admin
url: jdbc:mysql://192.168.2.36:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
# 单数据源连接池配置
druid:
initial-size: 20
min-idle: 20
max-active: 1000
max-wait: 60000
query-timeout: 60000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
other1:
username: admin
password: admin
url: jdbc:mysql://192.168.2.37:3306/test2?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
# 可继承全局druid配置,也可单独覆盖
druid:
initial-size: 5
min-idle: 5
max-active: 100
启动类排除默认配置
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
最后在方法上通过注解DS就可以实现数据源的切换。
@Repository
@DS("other1")
public interface User2Mapper extends BaseMapper<User2> {
}
自定义配置文件形式
假如我不想按照默认的格式配置数据源信息,比如我就想放在其他地方:
extension:
model-parse:
tdimpRelease:
db: '{"dbName":"test","host":"192.168.2.38","password":"admin","port":5432,"tablePrefix":"dev_","type":"postgresql","username":"postgres"}'
主库还是按照默认的方式进行配置。
首先我们需要一个配置将主数据源打上标签@Primary
/**
* 主数据源
*/
@Configuration
public class PrimaryDataSourceConfig {
@Bean(name = "dataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return new DruidDataSource();
}
@Bean(name = "jdbcTemplate")
@Primary
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
}
然后配置我们的自定义数据源,同样增加一个配置文件。
@Configuration
@ConditionalOnProperty(
name = "extension.model-parse.tdimpRelease.enable",
havingValue = "true"
)
public class ReleasePgDataSourceConfig {
private static final Logger logger = LoggerFactory.getLogger(ReleasePgDataSourceConfig.class);
public static final String TEMPLATE = "releasePgJdbcTemplate";
@Value("${extension.model-parse.tdimpRelease.db:0}")
private String dbConfig;
@Bean(name = "releasePgDataSource")
public DataSource releasePgDataSource() {
JSONObject entries = JSONUtil.parseObj(dbConfig);
DruidDataSource ds = new DruidDataSource();
ds.setName("releasePgDataSource");
// ===== 基本连接信息 =====
ds.setUrl(String.format("jdbc:postgresql://%s:%d/%s"
, entries.getStr("host")
, entries.getInt("port")
, entries.getStr("dbName"))
);
ds.setUsername(entries.getStr("username"));
ds.setPassword(entries.getStr("password"));
ds.setDriverClassName("org.postgresql.Driver");
// ===== 连接池参数 =====
ds.setInitialSize(10);
ds.setMinIdle(10);
ds.setMaxActive(50);
ds.setMaxWait(60000);
// ===== 连接校验 =====
ds.setValidationQuery("SELECT 1");
ds.setTestWhileIdle(true);
ds.setTestOnBorrow(false);
ds.setTestOnReturn(false);
// ===== 空闲连接回收 =====
ds.setTimeBetweenEvictionRunsMillis(60000);
ds.setMinEvictableIdleTimeMillis(300000);
// ===== Druid 监控 =====
try {
ds.setFilters("stat,wall,slf4j");
} catch (SQLException e) {
logger.error("配置release pg druid监控失败!");
}
ds.setAsyncInit(false);
try {
ds.init();
} catch (SQLException e) {
logger.error("注册发布数据库连接池失败!发布数据库信息:{}", dbConfig, e);
}
return ds;
}
@Bean(name = "releasePgJdbcTemplate")
public JdbcTemplate releasePgJdbcTemplate() {
return new JdbcTemplate(releasePgDataSource());
}
}
这个时候服务启动,就会注册多个数据源。可以做个单元测试。
@ActiveProfiles("t-dev")
@SpringBootTest()
public class ReleasePgJdbcTemplateTest extends BaseTest {
private static final Logger logger = LoggerFactory.getLogger(ReleasePgJdbcTemplateTest.class);
@Resource
@Qualifier("releasePgJdbcTemplate")
private JdbcTemplate releasePgJdbcTemplate;
@Test
public void testQuery() {
List<Object> query = releasePgJdbcTemplate.query(
"select * from test limit 1",
new BeanPropertyRowMapper<>(Object.class)
);
logger.info("list:{}", JSONUtil.toJsonPrettyStr(query));
}
}
将连接池加入到监控页面。
修改主数据源配置文件,增加配置,开启监控页面。
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean =
new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
bean.addInitParameter("loginUsername", "admin");
bean.addInitParameter("loginPassword", "admin");
bean.addInitParameter("allow", "");
bean.addInitParameter("resetEnable", "false");
return bean;
}
然后将自定义数据源加入到监控页面。修改自定义数据源配置文件。
@Bean(name = "releasePgJdbcTemplate")
public JdbcTemplate releasePgJdbcTemplate() {
DataSource dataSource = releasePgDataSource();
// ========== 将自定义数据源注册到 Druid 监控 ==========
DruidDataSourceStatManager.addDataSource(dataSource, "releasePgDataSource");
logger.info("✅已经初始化发布Pgsql客户端!");
return new JdbcTemplate(dataSource);
}
打开监控页面:ip:port/druid
这种配置方式好处就是完全不影响主库的使用,如果后期增加数据源,按照配置再复制一个就行了。
缺点就是需要使用JdbcTemplate去操作数据库了。
