springboot+mybatis框架搭建--6.配置myba
2019-03-08 本文已影响0人
小狼在IT
模拟一个读写分离了的数据库端:
![](https://img.haomeiwen.com/i11651855/503c4693a65bd4ea.png)
mytest数据库的user数据:
![](https://img.haomeiwen.com/i11651855/abad1a2931577c27.png)
mytest2数据库的user数据:
![](https://img.haomeiwen.com/i11651855/284a7d3e2b44be71.png)
1.配置application.properties
把原来的 spring.datasource 配置去掉,配置成如下信息:
#-------------------------------------------------------------
#master.datasource begin
master.datasource.type=com.alibaba.druid.pool.DruidDataSource
master.datasource.url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf-8&serverTimeZone=GMT%2B8
master.datasource.driverClassName=com.mysql.cj.jdbc.Driver
master.datasource.username=${dbUserName}
master.datasource.password=${dbpsw}
master.datasource.initialSize=5
master.datasource.minIdle=20
master.datasource.maxActive=50
master.datasource.maxWait=30000
master.datasource.timeBetweenEvictionRunsMillis=60000
master.datasource.minEvictableIdleTimeMillis=300000
master.datasource.validationQuery=SELECT 1
master.datasource.testWhileIdle=true
master.datasource.testOnBorrow=false
master.datasource.testOnReturn=false
master.datasource.poolPreparedStatements=true
master.datasource.maxPoolPreparedStatementPerConnectionSize=20
master.datasource.filters=stat,wall,slf4j
master.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
master.datasource.useGlobalDataSourceStat=true
#master.datasource end
#-------------------------------------------------------------
#-------------------------------------------------------------
#slave.datasource begin
slave.datasource.type=com.alibaba.druid.pool.DruidDataSource
slave.datasource.url=jdbc:mysql://localhost:3306/mytest2?useUnicode=true&characterEncoding=utf-8&serverTimeZone=GMT%2B8
slave.datasource.driverClassName=com.mysql.cj.jdbc.Driver
slave.datasource.username=${dbUserName}
slave.datasource.password=${dbpsw}
slave.datasource.initialSize=5
slave.datasource.minIdle=20
slave.datasource.maxActive=50
slave.datasource.maxWait=30000
slave.datasource.timeBetweenEvictionRunsMillis=60000
slave.datasource.minEvictableIdleTimeMillis=300000
slave.datasource.validationQuery=SELECT 1
slave.datasource.testWhileIdle=true
slave.datasource.testOnBorrow=false
slave.datasource.testOnReturn=false
slave.datasource.poolPreparedStatements=true
slave.datasource.maxPoolPreparedStatementPerConnectionSize=20
slave.datasource.filters=stat,wall,slf4j
slave.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
slave.datasource.useGlobalDataSourceStat=true
#slave.datasource end
#-------------------------------------------------------------
2.工具类--数据库上下文
public class DataSourceContextHolder {
public enum DbType{
MASTER,SLAVE
}
private static final ThreadLocal<DbType> contextHolder = new ThreadLocal<DbType>(){
@Override
protected DbType initialValue() {
return DbType.MASTER;
}
};
public static void setDBType(DbType dbType) {
if(dbType==null) {
throw new NullPointerException();
}
contextHolder.set(dbType);
}
public static DbType getDBType() {
return contextHolder.get()==null?DbType.MASTER:contextHolder.get();
}
public static void clearDBType() {
contextHolder.remove();
}
}
3.工具类--存储数据源
@Slf4j
public class MultipleDataSource extends AbstractRoutingDataSource {
@Override
public Logger getParentLogger() {
return null;
}
@Override
protected Object determineCurrentLookupKey() {
log.debug("----------------------------use DataSouce:" + DataSourceContextHolder.getDBType());
return DataSourceContextHolder.getDBType();
}
}
4.工具类--从数据库使用标记
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SlaveConnection {
}
5.工具类--配合SlaveConnection的Aspect
@Aspect
@Component
@Slf4j
public class SlaveConnectionInterceptor {
@Around("@annotation(SlaveConnection)")
public Object proceed(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
try {
log.info("set database connection to salve");
DataSourceContextHolder.setDBType(DataSourceContextHolder.DbType.SLAVE);
Object result = proceedingJoinPoint.proceed();
return result;
}finally {
DataSourceContextHolder.clearDBType();
log.info("restore database connection");
}
}
}
6.配置数据源
@Configuration
public class DataSourceConfiguration {
@Value("${master.datasource.type}")
private Class<? extends DataSource> dataSourceType;
@Bean(name = "masterDatasource")
@Primary
@ConfigurationProperties(prefix = "master.datasource")
public DataSource masterDatasource() {
System.out.println("-------------------- writeDataSource init ---------------------");
return DataSourceBuilder.create().type(dataSourceType).build();
}
@Bean(name = "slaveDatasource")
@ConfigurationProperties(prefix = "slave.datasource")
public DataSource slaveDatasource() {
System.out.println("-------------------- readDataSourceOne init ---------------------");
DataSource ds = DataSourceBuilder.create().type(dataSourceType).build();
System.out.println("-------------------- readDataSourceOne done ---------------------");
return ds;
}
7.配置mybatis使用多数据源
/**
* 必须等DataSourceConfiguration加载完才加载
*/
@Configuration
@AutoConfigureAfter({DataSourceConfiguration.class})
public class MybatisConfiguration extends MybatisAutoConfiguration {
public MybatisConfiguration(MybatisProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider, ResourceLoader resourceLoader, ObjectProvider<DatabaseIdProvider> databaseIdProvider, ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider) {
super(properties, interceptorsProvider, resourceLoader, databaseIdProvider, configurationCustomizersProvider);
}
@Resource(name = "masterDatasource")
private DataSource masterDataSource;
@Resource(name = "slaveDatasource")
private DataSource slaveDataSource;
@Bean(name = "multipleDataSource")
public MultipleDataSource multipleDataSource(){
Map<Object, Object> targetDataSources = new HashMap<Object, Object>(2);
targetDataSources.put(DataSourceContextHolder.DbType.MASTER,masterDataSource);
targetDataSources.put(DataSourceContextHolder.DbType.SLAVE,slaveDataSource);
MultipleDataSource multipleDataSource = new MultipleDataSource();
multipleDataSource.setTargetDataSources(targetDataSources);
multipleDataSource.setDefaultTargetDataSource(masterDataSource);
return multipleDataSource;
}
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
return super.sqlSessionFactory(multipleDataSource());
}
}
到此,所有设置完成,可以用了:
![](https://img.haomeiwen.com/i11651855/a20ad0776cdd482c.png)