SpringMVC-mybatis-plus-基于aop实现动态连接多个数据库

在本项目中,连接了两个数据库,分别是management和platform库

一、调整数据库配置文件database.properties,配置多个jdbc连接

url_platform=jdbc:mysql://xxx.xxx.x.xx:xxxx/platform?characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT%2B8&noAccessToProcedureBodies=true&useAffectedRows=true
driver_platform=com.mysql.jdbc.Driver
user_platform=xxxx
password_platform=xxxx

url_management=jdbc:mysql://xxx.xxx.x.xx:xxxx/management?characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT%2B8&noAccessToProcedureBodies=true&useAffectedRows=true
driver_management=com.mysql.jdbc.Driver
user_management=xxxx
password_management=xxxx

三、项目代码完善

新建enum表示不同的数据源

package com.kongpkp.enums;

public enum DataSources {
    Platform,
    Management
}

通过 TheadLocal 来保存每个线程选择哪个数据源的标志(key):

package com.kongpkp.dataSource;

import com.kongpkp.enums.DataSources;

public class DataSourceTypeManager {
    private static final ThreadLocal<DataSources> dataSourceTypes = new ThreadLocal<DataSources>(){
        @Override
        protected DataSources initialValue(){
            return DataSources.Platform;
        }
    };

    public static DataSources get(){
        return dataSourceTypes.get();
    }

    public static void set(DataSources dataSourceType){
        dataSourceTypes.set(dataSourceType);
    }

    public static void reset(){
        dataSourceTypes.set(DataSources.Platform);
    }
}

定义 ThreadLocalRountingDataSource,继承AbstractRoutingDataSource:

package com.kongpkp.dataSource;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class ThreadLocalRountingDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceTypeManager.get();
    }
}

在配置文件applicationContext.xml中向 ThreadLocalRountingDataSource 注入 management和 platform 的数据源:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <!--扫描dao和service层的注解-->
    <context:component-scan base-package="com.kongpkp.infrastructure"/>

    <!--引入database.properties文件、配置数据源连接-->
    <context:property-placeholder location="classpath:database.properties"/>

    <!--配置数据源连接 platform -->
    <bean id="dataSource_platform" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="url" value="${url_platform}"/>
        <property name="username" value="${user_platform}"/>
        <property name="password" value="${password_platform}"/>
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="0" />
        <!-- 连接池最大使用连接数量 -->
        <property name="maxActive" value="20" />
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="20" />
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="0" />
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="60000" />
    </bean>

    <!--配置数据源连接 management -->
    <bean id="dataSource_management" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="url" value="${url_management}"/>
        <property name="username" value="${user_management}"/>
        <property name="password" value="${password_management}"/>
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="0" />
        <!-- 连接池最大使用连接数量 -->
        <property name="maxActive" value="20" />
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="20" />
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="0" />
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="60000" />
    </bean>

    <bean id="dataSource" class="com.kongpkp.dataSource.ThreadLocalRountingDataSource">
        <property name="defaultTargetDataSource" ref="dataSource_platform" />
        <property name="targetDataSources">
            <map key-type="com.kongpkp.enums.DataSources">
                <entry key="Platform" value-ref="dataSource_platform"/>
                <entry key="Management" value-ref="dataSource_management"/>
                <!-- 这里还可以加多个dataSource -->
            </map>
        </property>
    </bean>

    <!--创建sqlSessionFactory对象-->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configuration">
            <bean class="com.baomidou.mybatisplus.core.MybatisConfiguration">
                <property name="autoMappingBehavior" value="FULL"/>
                <property name="mapUnderscoreToCamelCase" value="true"/>
            </bean>
        </property>
        <!--分页插件-->
        <property name="plugins">
            <array>
                <bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
                    <property name="dbType" value="MYSQL"/>
                </bean>
            </array>
        </property>
    </bean>

    <!-- Transaction manager for a single JDBC DataSource -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 使用annotation定义事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" />

    <!--递归扫描dao成接口,进行动态映射-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.kongpkp.infrastructure.mapper"/>
    </bean>

</beans>

使用Spring AOP 来指定 dataSource 的 key ,从而dataSource会根据key选择 dataSource_platform 和 dataSource_management:

package com.kongpkp.aop;

import com.kongpkp.dataSource.DataSourceTypeManager;
import com.kongpkp.enums.DataSources;
import org.aspectj.lang.JoinPoint;
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;

@Aspect    // for aop
@Component // for auto scan
@Order(0)  // execute before @Transactional
public class DataSourceInterceptor {
    @Pointcut("execution(public * com.kongpkp.controller.IndexController.login(..))")
    public void dataSourceSlave(){
        System.out.println("Pointcut");
    };

    @Before("dataSourceSlave()")
    public void before(JoinPoint jp) {
        System.out.println("before");
        DataSourceTypeManager.set(DataSources.Management);
    }
}

启动项目,调用接口,访问的是com.kongpkp.controller.IndexController.login的方法,会连接到management库,调用其余的方法,会连接到platform库

SpringMVC-mybatis-plus-基于aop实现动态连接多个数据库

上一篇:DBeaver——超好用可视化数据库!(墙裂推荐(づ ̄3 ̄)づ╭?~)


下一篇:mybatis学习(十一、动态SQL)