Spring Boot 如何动态配置数据库的加载本文介绍了如何在 Spring Boot 项目中动态配置数据库加载。通过
1. 背景
现项目有一个需求,期望通过在application.yml
配置文件中设置一个开关,来决定是否加载数据库。要求:
-
当开关的值为
true
时加载数据库; -
当开关的值为
false
或没有该配置时则不加载数据库。
2. 具体实现
2.1 数据库相关配置
application.yml
中添加配置spring.datasource.enabled
来决定是否加载数据库相关配置。
spring:
datasource:
#开启MySQL
enabled: true
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=GMT%2b8&characterEncoding=utf8&connectTimeout=30000&socketTimeout=30000&autoReconnect=true&cachePrepStmts=true&useServerPrepStmts=true
username: root
password: 123456
type: com.zaxxer.hikari.HikariDataSource
hikari:
# 连接池名称
pool-name: MyHikariCP
#最小空闲连接,默认值10,小于0或大于maximum-pool-size,都会重置为maximum-pool-size
minimum-idle: 10
#连接池最大连接数,默认是10 (cpu核数量 * 2 + 硬盘数量)
maximum-pool-size: 30
#空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。
idle-timeout: 600000
#连接最大存活时间,不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短
max-lifetime: 1800000
#连接超时时间:毫秒,小于250毫秒,否则被重置为默认值30秒
connection-timeout: 30000
#用于测试连接是否可用的查询语句
connection-test-query: SELECT 1
jpa:
database: mysql
show-sql: false
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
ddl-auto: update
properties:
hibernate:
jdbc:
batch_size: 100
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
enable_lazy_load_no_trans: true
open-in-view: false
2.2 启动类添加注解
启动类添加注解@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
,
代表默认情况下不自动加载数据库相关配置。
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class OcrsrvcApplication {
public static void main(String[] args) {
SpringApplication.run(OcrsrvcApplication.class, args);
}
}
2.3 新增DataSourceConfig
配置类
新增数据源配置类,用于自定义数据源的创建。
使用注解@ConditionalOnProperty
,这样可以根据特定属性的值来决定是否加载某个组件。
@Configuration
@ConditionalOnProperty(name = "spring.datasource.enabled", havingValue = "true")
@Slf4j
public class DataSourceConfig {
@Value("${spring.datasource.url}")
private String jdbcUrl;
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.hikari.pool-name}")
private String poolName;
@Value("${spring.datasource.hikari.minimum-idle}")
private int minimumIdle;
@Value("${spring.datasource.hikari.maximum-pool-size}")
private int maximumPoolSize;
@Value("${spring.datasource.hikari.idle-timeout}")
private long idleTimeout;
@Value("${spring.datasource.hikari.max-lifetime}")
private long maxLifetime;
@Value("${spring.datasource.hikari.connection-timeout}")
private long connectionTimeout;
@Value("${spring.datasource.hikari.connection-test-query}")
private String connectionTestQuery;
@Bean
public DataSource dataSource() {
log.info("====加载数据库===");
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl(jdbcUrl);
hikariConfig.setDriverClassName(driverClassName);
hikariConfig.setUsername(username);
hikariConfig.setPassword(password);
hikariConfig.setPoolName(poolName);
hikariConfig.setMinimumIdle(minimumIdle);
hikariConfig.setMaximumPoolSize(maximumPoolSize);
hikariConfig.setIdleTimeout(idleTimeout);
hikariConfig.setMaxLifetime(maxLifetime);
hikariConfig.setConnectionTimeout(connectionTimeout);
hikariConfig.setConnectionTestQuery(connectionTestQuery);
return new HikariDataSource(hikariConfig);
}
}
2.4 相关业务逻辑调整
涉及到使用数据库的相关业务逻辑,可在XxxRepository
类上添加注解@ConditionalOnProperty(name = "spring.datasource.enabled", havingValue = "true")
,这代表只有在启用数据库时,才会加载相应组件。
使用注解@Autowired(required = false)
注入XxxRepository
,代表允许为空,避免Bean不存在时出错
@Autowired(required = false)
private XxxRepository xxxRepository;
转载自:https://juejin.cn/post/7423706686173265954