博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring 配置多数据源 (案例)
阅读量:4624 次
发布时间:2019-06-09

本文共 6930 字,大约阅读时间需要 23 分钟。

*.properties配置:

<!--数据连接配置一-->

jdbc.type=mysql

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3066/qshop?useUnicode=true&amp;characterEncoding=UTF-8&amp;useFastDateParsing=false&amp;allowMultiQueries=true&amp;serverTimezone=GMT%2b8
jdbc.username=xxxxx
jdbc.password=xxxx

<!--数据连接配置二-->

merchant.jdbc.type=mysql

merchant.jdbc.driver=com.mysql.jdbc.Driver
merchant.jdbc.url=jdbc:mysql://localhost:3066/qshop_merchant?useUnicode=true&amp;characterEncoding=UTF-8&amp;useFastDateParsing=false&amp;allowMultiQueries=true&amp;serverTimezone=GMT%2b8
merchant.jdbc.username=xxxx
merchant.jdbc.password=xxxx

spring-application.xml配置:

<!-- 数据源一、数据源配置, 使用 druid 数据库连接池 -->

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}"/>

<!-- 基本属性 url、user、password -->

<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>

<!-- 配置初始化大小、最小、最大 -->

<property name="initialSize" value="${jdbc.pool.init}"/>
<property name="minIdle" value="${jdbc.pool.minIdle}"/>
<property name="maxActive" value="${jdbc.pool.maxActive}"/>

<!-- 配置获取连接等待超时的时间 -->

<property name="maxWait" value="60000"/>

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->

<property name="timeBetweenEvictionRunsMillis" value="60000"/>

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->

<property name="minEvictableIdleTimeMillis" value="300000"/>

<property name="validationQuery" value="${jdbc.testSql}"/>

<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>

<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)

<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->

<!-- 配置监控统计拦截的filters -->

<property name="filters" value="stat"/>
</bean>

<!-- 数据源二、商家数据源配置, 使用 druid 数据库连接池 -->
<bean id="merchantdataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${merchant.jdbc.driver}"/>

<!-- 基本属性 url、user、password -->

<property name="url" value="${merchant.jdbc.url}"/>
<property name="username" value="${merchant.jdbc.username}"/>
<property name="password" value="${merchant.jdbc.password}"/>

<!-- 配置初始化大小、最小、最大 -->

<property name="initialSize" value="${jdbc.pool.init}"/>
<property name="minIdle" value="${jdbc.pool.minIdle}"/>
<property name="maxActive" value="${jdbc.pool.maxActive}"/>

<!-- 配置获取连接等待超时的时间 -->

<property name="maxWait" value="60000"/>

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->

<property name="timeBetweenEvictionRunsMillis" value="60000"/>

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->

<property name="minEvictableIdleTimeMillis" value="300000"/>

<property name="validationQuery" value="${jdbc.testSql}"/>

<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>

<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)

<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->

<!-- 配置监控统计拦截的filters -->

<property name="filters" value="stat"/>
</bean>

<!--配置动态数据源-->

<bean id="dynamicDataSource" class="com.yryz.qshop.modules.dynamiclink.DynamicDataSource"> 

<property name="targetDataSources">

<map key-type="java.lang.String">
<!-- 指定lookupKey和与之对应的数据源 -->
<entry key="dataSource" value-ref="dataSource"></entry>
<entry key="merchantdataSource" value-ref="merchantdataSource"></entry>
</map>
</property>
<!-- 这里可以指定默认的数据源 {最好不要指定,指定后有坑}-->
<!-- <property name="defaultTargetDataSource" ref="dataSource" /> -->
</bean>

<bean id="dataSourceAspect" class="com.yryz.qshop.modules.dynamiclink.aspect.DataSourceAspect"/>

<aop:config>
<aop:aspect ref="dataSourceAspect">
<aop:pointcut id="dataSourcePointcut" expression="execution(* com.yryz.qshop.modules.merchantremote.service.*.*(..))"/>
<aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
</aop:aspect>
</aop:config>

动态数据源类:

DynamicDataSourceHolder.java

package com.yryz.qshop.modules.dynamiclink;

public class DynamicDataSourceHolder {

/**

* 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
*/
private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>();

public static String getDataSource() {

return THREAD_DATA_SOURCE.get();
}

public static void setDataSource(String dataSource) {

THREAD_DATA_SOURCE.set(dataSource);
}

public static void clearDataSource() {

THREAD_DATA_SOURCE.remove();
}
}

DynamicDataSource.java

package com.yryz.qshop.modules.dynamiclink;

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

public class DynamicDataSource extends AbstractRoutingDataSource{

@Override

protected Object determineCurrentLookupKey() {
// 从自定义的位置获取数据源标识
return DynamicDataSourceHolder.getDataSource();
}

}

DataSource注解:

package com.yryz.qshop.modules.dynamiclink.inter;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE,ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value();
}

拦截器

DataSourceAspect.java

package com.yryz.qshop.modules.dynamiclink.aspect;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.reflect.MethodSignature;

import com.yryz.qshop.modules.dynamiclink.DynamicDataSourceHolder;

import com.yryz.qshop.modules.dynamiclink.inter.DataSource;

public class DataSourceAspect {

/**

* 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
*
* @param point
* @throws Exception
*/
public void intercept(JoinPoint point) throws Exception {
Class<?> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
// 默认使用目标类型的注解,如果没有则使用其实现接口的注解
for (Class<?> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
}

/**

* 提取目标对象方法注解和类型注解中的数据源标识
*
* @param clazz
* @param method
*/
private void resolveDataSource(Class<?> clazz, Method method) {
try {
Class<?>[] types = method.getParameterTypes();
// 默认使用类型注解
if (clazz.isAnnotationPresent(DataSource.class)) {
DataSource source = clazz.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}
// 方法注解可以覆盖类型注解
Method m = clazz.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DataSource.class)) {
DataSource source = m.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}
} catch (Exception e) {
System.out.println(clazz + ":" + e.getMessage());
}
}
}

 

转载于:https://www.cnblogs.com/austinspark-jessylu/p/7497602.html

你可能感兴趣的文章
Python学习笔记-DAY-4
查看>>
WPF可视化一个简单的2D世界
查看>>
linux学习:CentOS、Mac上SSH的设置以及SceureCRT中的文件上传下载
查看>>
[svc]find+xargs/exec重命名文件后缀&文件操作工具小结
查看>>
MyBatis
查看>>
ZOJ
查看>>
链表的创建、增加、删除、改数据、遍历
查看>>
查看mysql表的字符集
查看>>
《鸟哥的Linux私房菜》读书笔记4
查看>>
关于SQL中的ROWNUM问题
查看>>
centos7安装mysql5.6
查看>>
CentOS7上搭建gitlab服务器
查看>>
jquery 插件大全
查看>>
UWP?UWP! - Build 2015有些啥?(2)
查看>>
求100到999之内的水仙花数
查看>>
11_控制线程_多线程同步
查看>>
luogu2085 最小函数值
查看>>
含参变量积分-Leibniz法则
查看>>
多态与重载
查看>>
Mybatis 的输入参数学习
查看>>