数据源配置
数据源配置是Spring数据访问的基础,连接池管理数据库连接。
HikariCP配置(Spring Boot默认)
YAML
# application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5
maximum-pool-size: 20
idle-timeout: 30000
max-lifetime: 1800000
connection-timeout: 30000
pool-name: MyHikariPool
Java
@Configuration
public class HikariConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
ds.setUsername("root");
ds.setPassword("password");
ds.setMinimumIdle(5);
ds.setMaximumPoolSize(20);
return ds;
}
}
Druid配置
YAML
# application.yml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password
druid:
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
filters: stat,wall
Java
@Bean
public DataSource druidDataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setUrl("jdbc:mysql://localhost:3306/mydb");
ds.setUsername("root");
ds.setPassword("password");
ds.setInitialSize(5);
ds.setMaxActive(20);
ds.setFilters("stat,wall");
return ds;
}
多数据源配置
Java
@Configuration
public class MultiDataSourceConfig {
// 主数据源
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
// 从数据源
@Bean
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
// 主数据源JdbcTemplate
@Bean
@Primary
public JdbcTemplate primaryJdbcTemplate(
@Qualifier("primaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
// 从数据源JdbcTemplate
@Bean
public JdbcTemplate secondaryJdbcTemplate(
@Qualifier("secondaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
YAML
# application.yml
spring:
datasource:
primary:
url: jdbc:mysql://localhost:3306/primary_db
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
secondary:
url: jdbc:mysql://localhost:3306/secondary_db
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
动态数据源
Java
// 动态数据源上下文
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
// 动态路由数据源
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}
// 配置动态数据源
@Configuration
public class DynamicDataSourceConfig {
@Bean
public DataSource dynamicDataSource(
@Qualifier("primaryDataSource") DataSource primary,
@Qualifier("secondaryDataSource") DataSource secondary) {
DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("primary", primary);
targetDataSources.put("secondary", secondary);
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(primary);
return dynamicDataSource;
}
}
// 使用注解切换数据源
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value() default "primary";
}
// AOP切换数据源
@Aspect
@Component
public class DataSourceAspect {
@Before("@annotation(dataSource)")
public void switchDataSource(DataSource dataSource) {
DataSourceContextHolder.setDataSource(dataSource.value());
}
@After("@annotation(dataSource)")
public void restoreDataSource(DataSource dataSource) {
DataSourceContextHolder.clearDataSource();
}
}
// 使用示例
@Service
public class OrderService {
@DataSource("primary")
public void saveToPrimary(Order order) { }
@DataSource("secondary")
public void saveToSecondary(Order order) { }
}
连接池参数说明
| 参数 | HikariCP | Druid | 说明 |
|---|---|---|---|
| 最小连接数 | minimumIdle | minIdle | 最少保持的连接数 |
| 最大连接数 | maximumPoolSize | maxActive | 最大连接数 |
| 连接超时 | connectionTimeout | maxWait | 获取连接超时时间 |
| 空闲超时 | idleTimeout | minEvictableIdleTimeMillis | 连接空闲超时 |
| 最大存活 | maxLifetime | - | 连接最大存活时间 |
| 验证查询 | connectionTestQuery | validationQuery | 连接有效性查询 |
JNDI数据源
Java
@Configuration
public class JndiDataSourceConfig {
@Bean
public DataSource jndiDataSource() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return lookup.getDataSource("java:comp/env/jdbc/myDS");
}
}
YAML
spring:
datasource:
jndi-name: java:comp/env/jdbc/myDS
连接池监控
Java
// HikariCP监控
@Bean
public HikariDataSource hikariDataSource() {
HikariDataSource ds = new HikariDataSource();
// ... 配置
ds.setMetricRegistry(new MetricRegistry()); // Dropwizard Metrics
return ds;
}
// 获取连接池信息
HikariPoolMXBean pool = ds.getHikariPoolMXBean();
System.out.println("活跃连接: " + pool.getActiveConnections());
System.out.println("空闲连接: " + pool.getIdleConnections());
System.out.println("等待连接: " + pool.getThreadsAwaitingConnection());
要点总结
- Spring Boot默认使用HikariCP连接池
- Druid提供更丰富的监控和SQL防注入功能
- @Primary指定默认多数据源
- AbstractRoutingDataSource实现动态数据源切换
- ThreadLocal存储当前数据源标识
- 合理配置连接池参数优化性能
📝 发现内容有误?点击此处直接编辑