springboot mybatis 多数据源

2022-02-09  本文已影响0人  剑子仙迹

依赖

Pom 中导入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


<!--        mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>

<!--        mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>


<!--        连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

<!--        aop-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

    </dependencies>

习惯性的mapper 扫描

        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                    <include>**/*.yml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>

配置文件

spring:

  application:
    name: dynamic_test

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      one:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
        username: root
        password: Xu666666
      two:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
        username: root
        password: Xu666666
    initial-size: 1
    min-idle: 1
    max-active: 20
    max-wait: 60000
    time-between-eviction-runs-millis: 60000
    min-evictable-idle-time-millis: 300000


mybatis:
  mapper-locations: classpath:mapper/*.xml

构建配置文件

public interface DataSourceName {
    String FIRST = "one";
    String SECOND = "two";

}

public class DynamicDataSource extends AbstractRoutingDataSource {

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return getDataSource();
    }

    public static void setDataSource(String dataSource) {
        contextHolder.set(dataSource);
    }

    public static String getDataSource() {
        return contextHolder.get();
    }

    public static void clearDataSource() {
        contextHolder.remove();
    }
}



@Configuration
public class DynamicDataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.druid.one")
    public DataSource oneDataSource() {
        return new DruidDataSource();
    }


    @Bean
    @ConfigurationProperties("spring.datasource.druid.two")
    public DataSource twoDataSource() {
        return new DruidDataSource();
    }

    @Bean
    @Primary
    public DynamicDataSource dataSource(DataSource oneDataSource, DataSource twoDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>(2);
        // 每个key对应一个数据源
        targetDataSources.put(DataSourceName.FIRST, oneDataSource);
        targetDataSources.put(DataSourceName.SECOND, twoDataSource);
        return new DynamicDataSource(oneDataSource, targetDataSources);
    }
}



aop 进行注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DSAnnotation {

    String dsName() default DataSourceName.FIRST;

}


@Aspect
@Component
@Order(value = 1)
public class DSAspect {

    @Pointcut("@annotation(com.demedb.database.annotation.DSAnnotation)")
    public void dataSourcePointCut() {
    }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        // 在执行方法之前设置使用哪个数据源
        DSAnnotation ds = method.getAnnotation(DSAnnotation.class);
        if (ds == null) {
            DynamicDataSource.setDataSource(DataSourceName.FIRST);
        } else {
            DynamicDataSource.setDataSource(ds.dsName());
        }

        try {
            return point.proceed();
        } finally {
            DynamicDataSource.clearDataSource();
        }
    }

}

测试

@Autowired
private TestService testService;

@GetMapping("/list")
public String selectAll(){
    List<TestModel> ls = testService.selectAll();
    System.out.println(ls);
    return ls.toString();
}

@DSAnnotation(dsName = DataSourceName.SECOND)
@GetMapping("/list2")
public String selectAll02(){
    List<TestModel> ls = testService.selectAll();
    System.out.println(ls);
    return ls.toString();
}
上一篇 下一篇

猜你喜欢

热点阅读