1、关键pom
mysql
mysql-connector-java
8.0.15
com.baomidou
dynamic-datasource-spring-boot-starter
3.1.0
com.baomidou
mybatis-plus-boot-starter
3.1.0
2、application.properties动态数据源配置:
spring.datasource.dynamic.datasource.master.url,加黑的是mybatis-plus固定死的,不能修改,没有加黑的是动态数据源的名称,可以自定义
##数据源
#主
spring.datasource.dynamic.primary=master
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://192.168.43.10:3306/oauth?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password=123456
#备
spring.datasource.dynamic.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.dynamic.datasource.slave.url=jdbc:mysql://192.168.43.10:3306/oauth-resource?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.dynamic.datasource.slave.username=root
spring.datasource.dynamic.datasource.slave.password=123456
##mybatis plus
mybatis-plus.mapper-locations=classpath*:/mapper/*.xml
3、dao层注解
@DS("slave")
@Mapper
public interface TbContentMapper extends BaseMapper {
List getAll();
}
@DS("master")
@Mapper
public interface TbUserMapper extends BaseMapper {
TbUser getByUsername(@Param("userName") String userName);
}
4、启动类
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class Oauth2ServerApplication {
public static void main(String[] args) {
SpringApplication.run(Oauth2ServerApplication.class, args);
}
}
1、关键pom
mysql
mysql-connector-java
8.0.15
com.baomidou
mybatis-plus-boot-starter
3.1.0
2、application.properties动态数据源配置
#数据源
#主
spring.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.master.jdbc-url=jdbc:mysql://192.168.43.10:3306/oauth?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.master.username=root
spring.datasource.master.password=123456
#备
spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.jdbc-url=jdbc:mysql://192.168.43.10:3306/oauth-resource?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.slave.username=root
spring.datasource.slave.password=123456
3、定义一个动态数据源:继承AbstractRoutingDataSource 抽象类,并重写determineCurrentLookupKey()方法
package com.allen.test.mybatis;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
DataSourceType.DataBaseType dataBaseType = DataSourceType.getDataBaseType();
return dataBaseType;
}
}
4、创建一个切换数据源类型的类: ThreadLocal就是为了线程的安全性,每个线程之间不会相互影响
package com.allen.test.mybatis;
public class DataSourceType {
public enum DataBaseType {
MASTER, SLAVE
}
// 使用ThreadLocal保证线程安全
private static final ThreadLocal TYPE = new ThreadLocal();
// 往当前线程里设置数据源类型
public static void setDataBaseType(DataBaseType dataBaseType) {
if (dataBaseType == null) {
throw new NullPointerException();
}
System.err.println("[将当前数据源改为]:" + dataBaseType);
TYPE.set(dataBaseType);
}
// 获取数据源类型
public static DataBaseType getDataBaseType() {
DataBaseType dataBaseType = TYPE.get() == null ? DataBaseType.MASTER : TYPE.get();
System.err.println("[获取当前数据源的类型为]:" + dataBaseType);
return dataBaseType;
}
// 清空数据类型
public static void clearDataBaseType() {
TYPE.remove();
}
}
5、定义多个数据源:主要是将定义好的多个数据源放在动态数据源中
package com.allen.test.mybatis;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 参考博客地址:https://blog.csdn.net/tuesdayma/article/details/81081666?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
*/
@Configuration
@MapperScan(basePackages = "com.allen.test.dao", sqlSessionFactoryRef = "SqlSessionFactory")
public class DataSourceConfig {
@Primary
@Bean(name = "masterDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource getDateSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource getDateSource2() {
return DataSourceBuilder.create().build();
}
@Bean(name = "dynamicDataSource")
public DynamicDataSource DataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
@Qualifier("slaveDataSource") DataSource slaveDataSource) {
Map
6、定义AOP:就是不同业务切换不同数据库的入口,后续会修改为注解
package com.allen.test.mybatis;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class DataSourceAop {
@Before("execution(* com.allen.test.dao..*.getByUsername*(..))")
public void setDataSource2master() {
System.err.println("master业务");
DataSourceType.setDataBaseType(DataSourceType.DataBaseType.MASTER);
}
@Before("execution(* com.allen.test.dao..*.getAll*(..))")
public void setDataSource2slave() {
System.err.println("slave业务");
DataSourceType.setDataBaseType(DataSourceType.DataBaseType.SLAVE);
}
}
7、验证测试:定义两个mapper,分别对应不同的切点
package com.allen.test;
import com.allen.test.dao.TbContentMapper;
import com.allen.test.dao.TbUserMapper;
import com.allen.test.model.TbContent;
import com.allen.test.model.TbUser;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestServerApplication.class)
public class MutilDataSourceTest {
@Autowired(required = false)
private TbContentMapper tbContentMapper;
@Autowired(required = false)
private TbUserMapper tbUserMapper;
@Test
public void test() throws Exception {
//aop会切到master数据源
TbUser tbUser = tbUserMapper.getByUsername("admin");
System.out.println(tbUser);
//aop会切到slave数据源
List all = tbContentMapper.getAll();
System.out.println(all);
}
}