1.定义动态数据源,继承AbstractRoutingDataSourceimport
org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DatabaseContextHolder.getDatabaseType();
}
}
2.配置动态数据源
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
application.properties中添加一下配置
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://127.0.0.1/mytest?autoReconnect=true&failOverReadOnly=false&useUnicode=true&characterEncoding=utf-8
jdbc.username = root
jdbc.password = XXX
#the second datasource
jdbc.prod.driverClassName = com.mysql.jdbc.Driver
jdbc.prod.url = jdbc:mysql://127.0.0.1/mytest1?autoReconnect=true&failOverReadOnly=false&useUnicode=true&characterEncoding=utf-8
jdbc.prod.username = root
jdbc.prod.password = XXX
//数据库类型枚举类
public enum DatabaseType {
proddb,testdb
}
注入实例:
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
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;
/**
* springboot集成mybatis的基本入口 1)创建数据源(如果采用的是默认的tomcat-jdbc数据源,则不需要)
* 2)创建SqlSessionFactory 3)配置事务管理器,除非需要使用事务,否则不用配置
*/
@Configuration // 该注解类似于spring配置文件
@MapperScan(basePackages = "com.xxx.newedit.dao")
public class MyBatisConfig {
@Autowired
private Environment env;
/**
* 创建数据源(数据源的名称:方法名可以取为XXXDataSource(),XXX为数据库名称,该名称也就是数据源的名称)
*/
@Bean
public DataSource myTestDbDataSource() 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 myProdDbDataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", env.getProperty("jdbc.prod.driverClassName"));
props.put("url", env.getProperty("jdbc.prod.url"));
props.put("username", env.getProperty("jdbc.prod.username"));
props.put("password", env.getProperty("jdbc.prod.password"));
return DruidDataSourceFactory.createDataSource(props);
}
/**
* @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错
* @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例)
*/
@Bean
@Primary
public DynamicDataSource dataSource(@Qualifier("myTestDbDataSource") DataSource myTestDbDataSource,
@Qualifier("myProdDbDataSource") DataSource myProdDbDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DatabaseType.proddb, myProdDbDataSource);
targetDataSources.put(DatabaseType.testdb, myTestDbDataSource);
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("com.xxx.newedit");// 指定基包
fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/*.xml"));
return fb.getObject();
}
/**
* 配置事务管理器
*/
@Bean
public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}
}
Dao层配置:
public interface AppLogMapper {
/**
* 获取applog的信息
* @param request
* @return
*/
List<AppLogDTO> getAppLogList(AppLogRequest request);
}
3.使用方法
DatabaseContextHolder.setDatabaseType(DatabaseType.proddb);
appLogMapper.getAppLogList(request);