SpringCloud多數據源實現


1、枚舉多數據源-定義一一對應變量

/**
*
* 列出所有的數據源key(常用數據庫名稱來命名)
* 注意:
* 1)這里數據源與數據庫是一對一的
* 2)DatabaseType中的變量名稱就是數據庫的名稱
*/

public enum DatabaseType {
  test1,test2
}

2、將數據源變量保存在線程變量中

/**
*  
* 作用:1、保存一個線程安全的DatabaseType容器
*/
public class DatabaseContextHolder {

//將數據源枚舉變量保存在線程變量中
private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<DatabaseType>();

public static void setDatabaseType(DatabaseType type) {
contextHolder.set(type);
}

public static DatabaseType getDatabaseType() {
return contextHolder.get();
}
}

3、動態數據源

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
*  動態數據源(需要繼承AbstractRoutingDataSource)
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
protected Object determineCurrentLookupKey() {
return DatabaseContextHolder.getDatabaseType();
}
}

 

4、數據源配置

數據源1:

test1.driverClassName=org.postgresql.Driver
test1.url=jdbc:postgresql://localhost:5432/test1
test.username=test1

test1.password=123456

test1.remove-abandoned=true
test1.remove-abandoned-timeout=120
test1.test-on-borrow=true

數據源2:

test2.driverClassName=org.postgresql.Driver
test2.url=jdbc:postgresql://localhost:5432/test2
test2.username=test2

test2.password=123456

test2.remove-abandoned=true
test2.remove-abandoned-timeout=120
test2.test-on-borrow=true

 

5、數據源初始化

/**
* springboot集成mybatis的基本入口
* 1)創建數據源(如果采用的是默認的tomcat-jdbc數據源,則不需要)
* 2)創建SqlSessionFactory
* 3)配置事務管理器,除非需要使用事務,否則不用配置
*
*/
@Configuration // 該注解類似於spring配置文件
@MapperScan(basePackages = "cn.test.mapper")
public class MyBatisConfig {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private Environment env;

@Bean
public DataSource test1DataSource() throws Exception {
Properties props = new Properties();
props.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, env.getProperty("test1.driverClassName"));
props.put(DruidDataSourceFactory.PROP_URL, env.getProperty("test1.url"));
props.put(DruidDataSourceFactory.PROP_USERNAME, env.getProperty("test1.username"));

// 獲取數據庫密碼
props.put(DruidDataSourceFactory.PROP_PASSWORD, env.getProperty("test1.password"));
props.put(DruidDataSourceFactory.PROP_REMOVEABANDONED, env.getProperty("test1.remove-abandoned"));
props.put(DruidDataSourceFactory.PROP_REMOVEABANDONEDTIMEOUT, env.getProperty("test1.remove-abandoned-timeout"));
props.put(DruidDataSourceFactory.PROP_TESTONBORROW, env.getProperty("test1.test-on-borrow"));
return DruidDataSourceFactory.createDataSource(props);
}

@Bean
public DataSource test2DataSource() throws Exception {
Properties props = new Properties();
props.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, env.getProperty("test2.driverClassName"));
props.put(DruidDataSourceFactory.PROP_URL, env.getProperty("test2.url"));
props.put(DruidDataSourceFactory.PROP_USERNAME, env.getProperty("test2.username"));

// 獲取數據庫密碼 
props.put(DruidDataSourceFactory.PROP_PASSWORD, env.getProperty("test2.password"));
props.put(DruidDataSourceFactory.PROP_REMOVEABANDONED, env.getProperty("test2.remove-abandoned"));
props.put(DruidDataSourceFactory.PROP_REMOVEABANDONEDTIMEOUT, env.getProperty("test2.remove-abandoned-timeout"));
props.put(DruidDataSourceFactory.PROP_TESTONBORROW, env.getProperty("test2.test-on-borrow"));
return DruidDataSourceFactory.createDataSource(props);
}

/**
* @throws Exception
* @Primary 該注解表示在同一個接口有多個實現類可以注入的時候,默認選擇哪一個,而不是讓@autowire注解報錯
* @Qualifier 根據名稱進行注入,通常是在具有相同的多個類型的實例的一個注入(例如有多個DataSource類型的實例)
*/
@Bean
@Primary
public DynamicDataSource dataSource() throws Exception {
DataSource dataSource1 = test1DataSource();

DataSource dataSource2 = test2DataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DatabaseType.test1, dataSource1);

targetDataSources.put(DatabaseType.test2, dataSource2);

DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSources);// 該方法是AbstractRoutingDataSource的方法
dataSource.setDefaultTargetDataSource(dataSource1 );// 默認的datasource設置為dataSource 1
return dataSource;
}

/**
* 根據數據源創建SqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(ds);// 指定數據源(這個必須有,否則報錯)
// 加載配置mybatis-config
DefaultResourceLoader configResourceLoader = new DefaultResourceLoader();
Resource configResource = configResourceLoader.getResource("mybatis-config.xml");
bean.setConfigLocation(configResource);
// 添加mapper文件XML目錄
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:cn/test/mapper/*.xml");
bean.setMapperLocations(resources);

return bean.getObject();
}

/**
* 配置事務管理器
*/
@Bean
public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}

}

6、

①查詢test1的數據時,可以直接調用對應的mapper;(因為test1是默認數據源)

②查詢test2的數據時,需要在調用之前指定數據源,如下代碼:

DatabaseContextHolder.setDatabaseType(DatabaseType.test2);

③同時需要查詢test1和test2的數據時,需要在調用之前指定正確的數據源。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM