连接数据库时,需要url,userName,和password,怎么做到动态呢,那就是在使用时,根据你的设置,去连接不同的url,userName,和password,实现数据源的切换。
1.先写一个类来放数据源的key。
public class DataSourceKeyHolder {
private static final ThreadLocal<String> keyHolder = new ThreadLocal<>();
public static void setKey(String key) {
keyHolder.remove();
keyHolder.set(key);
}
public static String getKey() {
String s = keyHolder.get();
Assert.notNull(s, "key 不能为空");
return s;
}
public static void clear(){
keyHolder.remove();
}
}
2.写一个类继承extends AbstractRoutingDataSource
public class MyDynamicDataSource extends AbstractRoutingDataSource{
/**
* Determine the current lookup key. This will typically be
* implemented to check a thread-bound transaction context.
* <p>Allows for arbitrary keys. The returned key needs
* to match the stored lookup key type, as resolved by the
* {@link #resolveSpecifiedLookupKey} method.
*/
@Override
protected Object determineCurrentLookupKey() {
return DataSourceKeyHolder.getKey();
}
}
可以看到重写了determineCurrentLookupKey方法,里面的key值是取的DataSourceKeyHolder类线程里面我们自定义的key。 重写的determineCurrentLookupKey会根据你自定义的key取出resolvedDataSources这个map中的DataSource
3.以@Bean注入需要连接的数据库参数。
@Configuration
public class DynamicSataSourceConfig {
@Bean
public DriverManagerDataSource dataSource1() {
String url = "jdbc:mysql://localhost:3306/whw_test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai\n";
String userName = "root";
String password = "zaq12wsX";
return new DriverManagerDataSource(url, userName, password);
}
@Bean
public DriverManagerDataSource dataSource2() {
String url = "jdbc:mysql://localhost:3306/whw_test2?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai\n";
String userName = "root";
String password = "zaq12wsX";
return new DriverManagerDataSource(url, userName, password);
}
@Bean
public DriverManagerDataSource dataSource3() {
String url = "jdbc:mysql://localhost:3306/whw_test3?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai\n";
String userName = "root";
String password = "zaq12wsX";
return new DriverManagerDataSource(url, userName, password);
}
@Bean
public MyDynamicDataSource dynamicDataSource(Map<String, DriverManagerDataSource> map) {
HashMap<Object, Object> original = new HashMap<>(map);
MyDynamicDataSource myDynamicDataSource = new MyDynamicDataSource();
myDynamicDataSource.setTargetDataSources(original);
return myDynamicDataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(AbstractRoutingDataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
setTargetDataSources方法 把@Bean注入的数据源参数,从targetDataSources复制到resolvedDataSources这个map。
4.写个测试类
public class DynamicSataSourceTest {
public static void main(String[] args) {
try {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DynamicSataSourceConfig.class);
JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class);
dataSource1(jdbcTemplate);
dataSource2(jdbcTemplate);
dataSource3(jdbcTemplate);
}catch (Exception e){
e.printStackTrace();
}
}
public static void dataSource1( JdbcTemplate jdbcTemplate ){
DataSourceKeyHolder.setKey("dataSource1");
try {
UserBean testBean = jdbcTemplate.queryForObject("select * from t_test where id=?", new BeanPropertyRowMapper<>(UserBean.class), 1);
System.out.println(testBean);
}finally {
DataSourceKeyHolder.clear();
}
}
public static void dataSource2( JdbcTemplate jdbcTemplate ){
DataSourceKeyHolder.setKey("dataSource2");
try {
UserBean testBean = jdbcTemplate.queryForObject("select * from t_test where id=?", new BeanPropertyRowMapper<>(UserBean.class), 1);
System.out.println(testBean);
}finally {
DataSourceKeyHolder.clear();
}
}
public static void dataSource3( JdbcTemplate jdbcTemplate ){
DataSourceKeyHolder.setKey("dataSource3");
try {
UserBean testBean = jdbcTemplate.queryForObject("select * from t_test where id=?", new BeanPropertyRowMapper<>(UserBean.class), 1);
System.out.println(testBean);
}finally {
DataSourceKeyHolder.clear();
}
}
}
需要连接哪个数据库,在使用sql前DataSourceKeyHolder.setKey("dataSource1");
然后根据我们设定的 数据源key去读取相应的DataSource。
输出结果:
UserBean(id=1, name=test_mary, age=3.0)
UserBean(id=1, name=test2_mary, age=3.0)
UserBean(id=1, name=test3_mary, age=3.0)
切换成功。