由于采用分布式数据库,读写分离。所以有些查询只需要从只读库查询,这样可以极大地提高查询效率。那么,如何实现在项目中配置多数据源呢?下面将根据项目实际应用对多数据源的配置进行说明。
#DataSource Config
spring.datasource.druid.url=jdbc:mysql://***.drds.aliyuncs.com/***?useUnicode=true&characterEncoding=utf8&autoReconnect=true&characterSetResults=utf8
spring.datasource.druid.username=***
spring.datasource.druid.password=***
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.minIdle=5
spring.datasource.druid.maxActive=200
spring.datasource.druid.maxWait=60000
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
# OnlyRead DataSource
spring.datasource.slave.url=jdbc:mysql://***.drds.aliyuncs.com/***?useUnicode=true&characterEncoding=utf8&autoReconnect=true&characterSetResults=utf8
spring.datasource.slave.username=***
spring.datasource.slave.password=***
spring.datasource.slave.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.slave.minIdle=5
spring.datasource.slave.maxActive=200
spring.datasource.slave.maxWait=60000
spring.datasource.slave.timeBetweenEvictionRunsMillis=60000
spring.datasource.slave.minEvictableIdleTimeMillis=300000
spring.datasource.slave.validationQuery=SELECT 1 FROM DUAL
spring.datasource.slave.testWhileIdle=true
spring.datasource.slave.testOnBorrow=false
spring.datasource.slave.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.slave.poolPreparedStatements=true
spring.datasource.slave.maxPoolPreparedStatementPerConnectionSize=20
首先在配置文件配置多数据源,通过名称区分,一个叫druid,一个叫slave。
package com.school.config;
import javax.sql.DataSource;
import com.school.interceptor.PerformanceInterceptor;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.enums.DBType;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
@Configuration
@MapperScan(basePackages = { "com.school.business.employee.mapper",.....}, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MybatisPlusConfig {
@Primary
@Bean(name = "master")
@ConfigurationProperties(prefix = "spring.datasource.druid")
public DataSource master() {
return DataSourceBuilder.create().build();
}
@Autowired
@Qualifier("master")
private DataSource dataSource;
@Autowired
private MybatisProperties properties;
@Autowired
private ResourceLoader resourceLoader = new DefaultResourceLoader();
@Autowired(required = false)
private Interceptor[] interceptors;
@Autowired(required = false)
private DatabaseIdProvider databaseIdProvider;
/**
* mybatis-plus分页插件
*/
@Bean
@Primary
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor page = new PaginationInterceptor();
page.setDialectType("mysql");
return page;
}
/**
* 这里全部使用mybatis-autoconfigure 已经自动加载的资源。不手动指定 配置文件和mybatis-boot的配置文件同步
*
* @return
*/
@Primary
@Bean(name = "masterSqlSessionFactory")
public MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean() {
MybatisSqlSessionFactoryBean mybatisPlus = new MybatisSqlSessionFactoryBean();
mybatisPlus.setDataSource(dataSource);
mybatisPlus.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(this.properties.getConfigLocation())) {
mybatisPlus.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
// mybatisPlus.setConfiguration(properties.getConfiguration());
if (!ObjectUtils.isEmpty(this.interceptors)) {
mybatisPlus.setPlugins(this.interceptors);
}
// MP 全局配置,更多内容进入类看注释
GlobalConfiguration globalConfig = new GlobalConfiguration();
globalConfig.setDbType(DBType.MYSQL.name());
// ID 策略 AUTO->`0`("数据库ID自增")
// INPUT->`1`(用户输入ID") ID_WORKER->`2`("全局唯一ID") UUID->`3`("全局唯一ID")
globalConfig.setIdType(0);
mybatisPlus.setGlobalConfig(globalConfig);
// MybatisConfiguration mc = new MybatisConfiguration();
// mc.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
// mybatisPlus.setConfiguration(mc);
if (this.databaseIdProvider != null) {
mybatisPlus.setDatabaseIdProvider(this.databaseIdProvider);
}
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
mybatisPlus.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
mybatisPlus.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
}
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
mybatisPlus.setMapperLocations(this.properties.resolveMapperLocations());
}
return mybatisPlus;
}
/**
* SQL执行效率插件
*/
@Bean
@Profile("test")// 设置 test 环境开启
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
}
}
2.从数据源配置
package com.school.config;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.enums.DBType;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = { "com.school.mapper" }, sqlSessionFactoryRef = "querySqlSessionFactory")
public class QueryDBPlusConfig {
@Bean(name = "slave")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slave() {
return DataSourceBuilder.create().build();
}
@Autowired
@Qualifier("slave")
private DataSource dataSource;
@Autowired
private MybatisProperties properties;
@Autowired
private ResourceLoader resourceLoader = new DefaultResourceLoader();
@Autowired(required = false)
private Interceptor[] interceptors;
@Autowired(required = false)
private DatabaseIdProvider databaseIdProvider;
/**
* 这里全部使用mybatis-autoconfigure 已经自动加载的资源。不手动指定 配置文件和mybatis-boot的配置文件同步
*
* @return
*/
@Bean(name = "querySqlSessionFactory")
public MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean() {
MybatisSqlSessionFactoryBean mybatisPlus = new MybatisSqlSessionFactoryBean();
mybatisPlus.setDataSource(dataSource);
mybatisPlus.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(this.properties.getConfigLocation())) {
mybatisPlus.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
// mybatisPlus.setConfiguration(properties.getConfiguration());
if (!ObjectUtils.isEmpty(this.interceptors)) {
mybatisPlus.setPlugins(this.interceptors);
}
// MP 全局配置,更多内容进入类看注释
GlobalConfiguration globalConfig = new GlobalConfiguration();
globalConfig.setDbType(DBType.MYSQL.name());
// ID 策略 AUTO->`0`("数据库ID自增")
// INPUT->`1`(用户输入ID") ID_WORKER->`2`("全局唯一ID") UUID->`3`("全局唯一ID")
globalConfig.setIdType(0);
mybatisPlus.setGlobalConfig(globalConfig);
// MybatisConfiguration mc = new MybatisConfiguration();
// mc.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
// mybatisPlus.setConfiguration(mc);
if (this.databaseIdProvider != null) {
mybatisPlus.setDatabaseIdProvider(this.databaseIdProvider);
}
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
mybatisPlus.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
mybatisPlus.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
}
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
mybatisPlus.setMapperLocations(this.properties.resolveMapperLocations());
}
return mybatisPlus;
}
}
将只读库的mapper接口放在固定的包下面,即可区分用哪个数据源查询。