首先加入依赖:
<!-- AOP-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--MySQL 连接驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--mybatis-plus数据持久层-->
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<!--druid数据连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
在配置文件增加下面配置:
spring:
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
aop:
auto: true
proxy-target-class: true
datasource:
druid:
db1:
url: jdbc:mysql://ip:端口/db1?useSSL=false&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true&rewriteBatchedStatements=true
username: ****#mysql账号
password: ***#mysql密码
driver-class-name: com.mysql.cj.jdbc.Driver
initialSize: 5
minIdle: 5
maxActive: 20
db2:
url: jdbc:mysql://****/db2?useSSL=false&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true&rewriteBatchedStatements=true
username: ****#mysql账号
password: ***#mysql密码
driver-class-name: com.mysql.cj.jdbc.Driver
initialSize: 5
minIdle: 5
maxActive: 20
mybatis:
type-aliases-package: com.*.*.entity #实体映射类包的位置
configuration:
# 驼峰下划线转换
map-underscore-to-camel-case: true
mapper-locations: classpath*:/mapper/**/*.xml
#设置druid后台访问白名单
druid:
config:
white-list: 127.0.0.1,loclhost
下面配置DruidConfig
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class DruidConfig {
@Value("#{'${druid.config.white-list}'.split(',')}")
private List<String> whitelist;
/**
* 注册ServletRegistrationBean
*
* @return
*/
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
// IP白名单
for (String ip : whitelist) {
reg.addInitParameter("allow", ip);
}
// IP黑名单(共同存在时,deny优先于allow)
// reg.addInitParameter("deny","127.0.0.1");
// 控制台管理用户
reg.addInitParameter("loginUsername", "**");//设置登陆账号
reg.addInitParameter("loginPassword", "***");//设置登陆密码
// 是否能够重置数据
reg.addInitParameter("resetEnable", "false");
return reg;
}
/**
* 注册FilterRegistrationBean
*
* @return
*/
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter(
"exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
filterRegistrationBean.addInitParameter("profileEnable", "true");
filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
filterRegistrationBean.addInitParameter("DruidWebStatFilter", "/*");
return filterRegistrationBean;
}
}
定义数据源枚举
public enum DBTYPE {
db1("db1"),
db2("db2"),
db3("db3");
private String value;
private DBTYPE(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
定义数据源上下文
public class DbContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal();
public DbContextHolder() {
}
public static void setDbType(DBTYPE dbTypeEnum) {
contextHolder.set(dbTypeEnum.getValue());
}
public static String getDbType() {
return (String)contextHolder.get();
}
public static void clearDbType() {
contextHolder.remove();
}
}
动态数据源设置
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* @program: common
* @description: 动态数据源
* @author: linwl
* @create: 2020-06-20 15:33
**/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
public Object determineCurrentLookupKey()
{
return DbContextHolder.getDbType();
}
}
定义动态数据源切换类
import db.DBTYPE;
import db.DbContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(value = -100)
@Slf4j
@Aspect
public class DataSourceSwitchAspect {
//数据源1切点
@Pointcut("execution(* com.*.mapper.db1..*.*(..))")
public void db1Aspect() {}
//数据源2切点
@Pointcut("execution(* com.*.mapper.db2..*.*(..))")
public void db2Aspect() {}
//数据源3切点
@Pointcut("execution(* com.*.mapper.db3..*.*(..))")
public void db3Aspect() {}
@Before("db1Aspect()")
public void getdb1() {
log.info("切换到db1 数据源...");
DbContextHolder.setDbType(DBTYPE.db1);
}
@Before("db2Aspect()")
public void getdb2() {
log.info("切换到db2 数据源...");
DbContextHolder.setDbType(DBTYPE.db2);
}
@Before("db3Aspect()")
public void getdb3() {
log.info("切换到db3 数据源...");
DbContextHolder.setDbType(DBTYPE.db3);
}
@After("db1Aspect()")
public void romvedb1() {
log.info("移除数据源");
DbContextHolder.clearDbType();
}
@After("db2Aspect()")
public void romvedb2() {
log.info("移除数据源");
DbContextHolder.clearDbType();
}
@After("db3Aspect()")
public void romvedb3() {
log.info("移除数据源");
DbContextHolder.clearDbType();
}
}
前期的配置基本完成了,接下来就是要进入MybatisPlus的配置了
配置如下:
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import db.DBTYPE;
import db.DynamicDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
@Configuration
@MapperScan("com.***.mapper")
@EnableTransactionManagement
@Slf4j
public class MybatisPlusConfig {
@Autowired private MybatisProperties properties;
private ResourceLoader resourceLoader = new DefaultResourceLoader();
@Autowired(required = false)
private DatabaseIdProvider databaseIdProvider;
/**
* mybatis-plus分页插件
* 文档:http://mp.baomidou.com
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor page = new PaginationInterceptor();
page.setDbType(DbType.MYSQL);
return new PaginationInterceptor();
}
@Bean(name = "db1")
@ConfigurationProperties(prefix = "spring.datasource.druid.db1")
public DataSource db1() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "db2")
@ConfigurationProperties(prefix = "spring.datasource.druid.db2")
public DataSource db2() {
return DruidDataSourceBuilder.create().build();
}
// @Bean(name = "db3")
// @ConfigurationProperties(prefix = "spring.datasource.druid.db3")
// public DataSource db3() {
// return DruidDataSourceBuilder.create().build();
// }
/**
* 动态数据源配置
*
* @return
*/
@Bean
@Primary
public DataSource multipleDataSource(
@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = new HashMap<>(3);
targetDataSources.put(DBTYPE.db1.getValue(), db1);
targetDataSources.put(DBTYPE.db2.getValue(), db2);
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(db1);
return dynamicDataSource;
}
@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory() throws Exception {
try {
MybatisSqlSessionFactoryBean mybatisPlus = new MybatisSqlSessionFactoryBean();
mybatisPlus.setDataSource(multipleDataSource(db1(), db2()));
if (StringUtils.hasText(this.properties.getConfigLocation())) {
mybatisPlus.setConfigLocation(
this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
mybatisPlus.setPlugins(paginationInterceptor());
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.getObject();
} catch (Exception e) {
log.error(MessageFormat.format("初始化Mybatis配置异常:{0}!", e.getMessage()));
throw e;
}
}
}
多数据源动态切换就大功告成!