切面和注解方式添加多个数据源

1、第一个数据源

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" lazy-init="false">
        <property name="url" value="${xinfang.url}"/>
        <property name="username" value="${xinfang.username}"/>
        <property name="password" value="${xinfang.password}"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="5"/>
        <property name="minIdle" value="20"/>
        <property name="maxActive" value="100"/>
        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="30000"/>
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="90000"/>

        <property name="validationQuery" value="SELECT 1"/>
        <property name="testWhileIdle" value="true"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>
        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --><!-- 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。分库分表较多的数据库,建议配置为false。 -->
        <property name="poolPreparedStatements" value="false"/>
        <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/>
        <!-- 配置监控统计拦截的filters,wall用于防止sql注入,stat用于统计分析 -->
        <property name="filters" value="wall"/>

        <property name="proxyFilters">
            <list>
                <ref bean="statfilter"/>
                <ref bean="logFilter"/>
            </list>
        </property>
    </bean>

2、第二个数据源

<bean id="dataSource_mid" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" lazy-init="false">
        <property name="url" value="${xinfang.mid.url}"/>
        <property name="username" value="${xinfang.mid.username}"/>
        <property name="password" value="${xinfang.mid.password}"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="5"/>
        <property name="minIdle" value="20"/>
        <property name="maxActive" value="100"/>
        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="30000"/>
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="90000"/>

        <property name="validationQuery" value="SELECT 1"/>
        <property name="testWhileIdle" value="true"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>
        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --><!-- 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。分库分表较多的数据库,建议配置为false。 -->
        <property name="poolPreparedStatements" value="false"/>
        <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/>
        <!-- 配置监控统计拦截的filters,wall用于防止sql注入,stat用于统计分析 -->
        <property name="filters" value="wall"/>

        <property name="proxyFilters">
            <list>
                <ref bean="statfilter"/>
                <ref bean="logFilter"/>
            </list>
        </property>
    </bean>

3、

<!-- 配置动态配置数据源 -->
    <bean id ="dynamicDataSource" class= "com.shencai.xf.common.dynamicDataSource.DynamicDataSource">
        <!-- 默认使用dataSource1的数据源 -->
        <property name ="defaultTargetDataSource" ref="dataSource"></property>
        <property name ="targetDataSources">
            <map key-type ="java.lang.String">
                <entry key= "dataSource" value-ref="dataSource"></entry>
                <entry key= "dataSource_mid" value-ref="dataSource_mid"></entry>
            </map>
        </property>

    </bean>

4、注解实现和数据源切换代码

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    String value() default "datasource";
}
public class DataSourceContextHolder {

    /**
     * 默认数据源
     */
    public static final String DEFAULT_DS = "dataSource";

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

    // 设置数据源名
    public static void setDB(String dbType) {
        System.out.println("切换到{"+dbType+"}数据源");
        contextHolder.set(dbType);
    }

    // 获取数据源名
    public static String getDB() {
        //return (contextHolder.get());
        if(contextHolder.get()==null){
            return DEFAULT_DS;
        }else{
            return (contextHolder.get());
        }
    }

    // 清除数据源名
    public static void clearDB() {
        contextHolder.remove();
    }

}
@Order(2)
public class DynamicDataSource extends AbstractRoutingDataSource {


    @Override
    protected Object determineCurrentLookupKey() {
        System.out.println("当前数据源为"+DataSourceContextHolder.getDB());
        return DataSourceContextHolder.getDB();
    }
}
@Order(1)
@Aspect
public class DynamicDataSourceAspect {


   //使用DS注解动作之后清除
   @After("@annotation(com.shencai.xf.common.dynamicDataSource.DataSource)")
   public void afterSwitchDS(JoinPoint point){
       System.out.println("清除当前数据源"+DataSourceContextHolder.getDB());
       DataSourceContextHolder.clearDB();
   }

    //使用DS注解动态切换
    @Before("@annotation(com.shencai.xf.common.dynamicDataSource.DataSource)")
    public void beforeSwitchDS(JoinPoint point){
        //获得当前访问的class
        Class<?> className = point.getTarget().getClass();
        //获得访问的方法名
        String methodName = point.getSignature().getName();
        //得到方法的参数的类型
        Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
        String dataSource = DataSourceContextHolder.DEFAULT_DS;
        try {
            // 得到访问的方法对象
            Method method = className.getMethod(methodName, argClass);
            // 判断是否存在@DS注解
            if (method.isAnnotationPresent(DataSource.class)) {
                DataSource annotation = method.getAnnotation(DataSource.class);
                // 取出注解中的数据源名
                dataSource = annotation.value();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 切换数据源
        DataSourceContextHolder.setDB(dataSource);
    }


}

5、

原文地址:https://www.cnblogs.com/wmqiang/p/11678880.html