1.首先是pom.xml中引用
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${alibaba.druid}</version>
</dependency>
2.yml文件中的配置
jdbc:
url: jdbc:mysql://localhost:3306/web?characterEncoding=UTF-8&zeroDateTimeBehavior=round&useSSL=false
username: root
password: accp
driverClassName: com.mysql.jdbc.Driver
jdbc1:
url: jdbc:mysql://localhost:3306/web1?characterEncoding=UTF-8&zeroDateTimeBehavior=round&useSSL=false
username: root
password: accp
driverClassName: com.mysql.jdbc.Driver
jdbc2:
url: jdbc:mysql://localhost:3306/accp?characterEncoding=UTF-8&zeroDateTimeBehavior=round&useSSL=false
username: root
password: accp
driverClassName: com.mysql.jdbc.Driver
3.創建DatabaseContextHolder.java 類
package com.test.web.common.mybatis;
public class DatabaseContextHolder {
private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();
public static void setDatabaseType(DatabaseType type){
contextHolder.set(type);
}
public static DatabaseType getDatabaseType(){
return contextHolder.get();
}
public static void close(){
contextHolder.remove();
}
}
4.創建多數據源枚舉類DatabaseType.java
package com.test.web.common.mybatis;
/**
* 數據源枚舉
*/
public enum DatabaseType {
ONEDB,TWODB,TDB
}
5.創建DynamicDataSource.java 類
package com.test.web.common.mybatis;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
protected Object determineCurrentLookupKey() {
return DatabaseContextHolder.getDatabaseType();
}
}
6.創建MyBatisConfig.java 類
package com.test.web.common.mybatis;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@Configuration // 該註解類似於spring配置文件
public class MyBatisConfig {
@Autowired
private Environment env;
/**
* 創建數據源(數據源的名稱:方法名可以取爲XXXDataSource(),XXX爲數據庫名稱,該名稱也就是數據源的名稱)
*/
@Bean
@Primary
public DataSource DbDataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", env.getProperty("jdbc.driverClassName"));
props.put("url", env.getProperty("jdbc.url"));
props.put("username", env.getProperty("jdbc.username"));
props.put("password", env.getProperty("jdbc.password"));
return DruidDataSourceFactory.createDataSource(props);
}
@Bean
public DataSource Db2DataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", env.getProperty("jdbc1.driverClassName"));
props.put("url", env.getProperty("jdbc1.url"));
props.put("username", env.getProperty("jdbc1.username"));
props.put("password", env.getProperty("jdbc1.password"));
return DruidDataSourceFactory.createDataSource(props);
}
@Bean
public DataSource Db3DataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", env.getProperty("jdbc2.driverClassName"));
props.put("url", env.getProperty("jdbc2.url"));
props.put("username", env.getProperty("jdbc2.username"));
props.put("password", env.getProperty("jdbc2.password"));
return DruidDataSourceFactory.createDataSource(props);
}
/**
* @Qualifier 根據名稱進行注入,通常是在具有相同的多個類型的實例的一個注入(例如有多個DataSource類型的實例)
*/
@Bean
public DynamicDataSource dataSource(@Qualifier("DbDataSource") DataSource myTestDbDataSource,
@Qualifier("Db2DataSource") DataSource myTestDb2DataSource,
@Qualifier("Db3DataSource") DataSource myTestDb3DataSource) {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DatabaseType.ONEDB, myTestDbDataSource);
targetDataSources.put(DatabaseType.TWODB, myTestDb2DataSource);
targetDataSources.put(DatabaseType.TDB, myTestDb3DataSource);
DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSources);// 該方法是AbstractRoutingDataSource的方法
dataSource.setDefaultTargetDataSource(myTestDbDataSource);// 默認的datasource設置爲myTestDbDataSource
return dataSource;
}
/**
* 根據數據源創建SqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception {
SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
fb.setDataSource(ds);// 指定數據源(這個必須有,否則報錯)
// 下邊兩句僅僅用於*.xml文件,如果整個持久層操作不需要使用到xml文件的話(只用註解就可以搞定),則不加
fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage"));// 指定基包
fb.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapper-locations")));//
fb.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
return fb.getObject();
}
/**
* 配置事務管理器
*/
@Bean
public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}
}
7.在啓動類中加上
@SpringBootApplication(exclude = {
MyBatisConfig.class
})
8.下面是在service中的使用
DatabaseContextHolder.close();
//切換數據源就使用枚舉類
DatabaseContextHolder.setDatabaseType(DatabaseType.ONEDB);