JAVA动态连接数据库
数据库配置
这里配置了两个数据库default db 和 dev db 都继承了BaseDBConfig
package com.springcloud.web.config.dataSource;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class BaseDBConfig {
private String username;
private String url;
private String password;
private String driverClassName;
}
package com.springcloud.web.config.dataSource;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DBDefaultConfig extends BaseDBConfig{
}
package com.springcloud.web.config.dataSource;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "db.dev")
public class DBDevConfig extends BaseDBConfig {
}
自定义动态数据库
通过继承AbstractRoutingDataSource来实现
package com.springcloud.web.config.dataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getDataSourceKey();
}
}
package com.springcloud.web.config.dataSource;
public class DynamicDataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setDataSourceKey(String key){
contextHolder.set(key);
}
public static String getDataSourceKey(){
return contextHolder.get();
}
public static void clearDataSourceKey(){
contextHolder.remove();
}
}
DynamicDataSourceConfig 这个类很重要,在dataSourceMap()这个方法中初始化了需要使用的数据库集合,通过key值来获取需要使用的数据库
package com.springcloud.web.config.dataSource;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DynamicDataSourceConfig {
@Autowired
DBDefaultConfig dbDefaultConfig;
@Autowired
DBDevConfig dbDevConfig;
private DataSource createDataSource(BaseDBConfig dbConfig){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(dbConfig.getDriverClassName());
dataSource.setUsername(dbConfig.getUsername());
dataSource.setPassword(dbConfig.getPassword());
return dataSource;
}
//需要切换的数据库集合,通过key值来获取需要使用的数据库
public Map<Object,Object> dataSourceMap(){
Map<Object,Object> sourceMap = new HashMap<>();
sourceMap.put("dev",createDataSource(dbDevConfig));
sourceMap.put("default",createDataSource(dbDefaultConfig));
return sourceMap;
}
@Bean("DynamicDataSource")
public DynamicDataSource dataSource(){
DynamicDataSource dataSource = new DynamicDataSource();
//需要设置默认数据库,否则在没有请求时,不知道连接哪个数据库,会报数据库连接错误
dataSource.setDefaultTargetDataSource(createDataSource(dbDefaultConfig));
dataSource.setTargetDataSources(dataSourceMap());
return dataSource;
}
@Bean("jdbcTemplate")
public NamedParameterJdbcTemplate jdbcTemplate(@Qualifier("DynamicDataSource") DynamicDataSource dataSource){
return new NamedParameterJdbcTemplate(new JdbcTemplate(dataSource));
}
}
测试数据库连接
package com.springcloud.web.controller;
import com.springcloud.web.config.dataSource.DynamicDataSourceContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController("/api")
public class DataSourceController {
@Autowired
UserMapper userMapper;
@GetMapping("/dataSource")
public Map<String,Object> testDataSourceType(String key){
DynamicDataSourceContextHolder.setDataSourceKey(key);
return userMapper.getUser();
}
}
在查询数据前需要调用 DynamicDataSourceContextHolder.setDataSourceKey(key)方法切换数据库,可以在拦截器或者过滤器中调用。这里传入参数key值为dev或者default,根据传入的key值不同,拿到对应数据库的user值。我在DynamicDataSourceConfig的dataSourceMap()方法中只设置了这两个key值,如果需要使用其他的数据库,只需要在这个方法中添加即可。