阿里云Druid连接池配置多个数据源 SSM框架

1.创建一个类,使用注解的形式,方便使用,该注解使用在Service层

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

@Retention(RetentionPolicy.RUNTIME)

public @interface DataSource {
String value();
}

 

2.创建一个切面方法,用于拦截所有的Service方法的调用,分配数据源

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());
}
}
}

3.

public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
// 从自定义的位置获取数据源标识
return DynamicDataSourceHolder.getDataSource();
}
}

4.

public class DynamicDataSourceHolder {

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

/**
* 配置mysql数据源
*/
public static final String mysql="mysql";
/**
* 配置oracle数据源
*/
public static final String oracle="oracle";
/**
* 配置sqlServer数据源
*/
public static final String sqlServer="sqlServer";

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();
}
}

5.配置配置文件

dbconfig.properties 把数据源信息储存到配置文件中,也可以配在spring-application中

url:jdbc:mysql://localhost:3306/parkmanager?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
driverClassName:com.mysql.jdbc.Driver
username:root
password:ok
filters:stat
maxActive:20
initialSize:1
maxWait:60000
minIdle:10
maxIdle:15
timeBetweenEvictionRunsMillis:60000
minEvictableIdleTimeMillis:300000
validationQuery:SELECT 'x'
testWhileIdle:true
testOnBorrow:false
testOnReturn:false
maxOpenPreparedStatements:20
removeAbandoned:true
removeAbandonedTimeout:1800
logAbandoned:true

ApplicationContext-dataSource.xml 一个对数据源操作的配置文件

<!-- 阿里 druid数据库连接池 -->
<bean id="mysqlDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<!-- 数据库基本信息配置 -->
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<property name="driverClassName" value="${driverClassName}" />
<property name="filters" value="${filters}" />
<!-- 最大并发连接数 -->
<property name="maxActive" value="${maxActive}" />
<!-- 初始化连接数量 -->
<property name="initialSize" value="${initialSize}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${maxWait}" />
<!-- 最小空闲连接数 -->
<property name="minIdle" value="${minIdle}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" />
<property name="validationQuery" value="${validationQuery}" />
<property name="testWhileIdle" value="${testWhileIdle}" />
<property name="testOnBorrow" value="${testOnBorrow}" />
<property name="testOnReturn" value="${testOnReturn}" />
<property name="maxOpenPreparedStatements" value="${maxOpenPreparedStatements}" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="${removeAbandoned}" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="${logAbandoned}" />
</bean>

 

多个数据源 把上面的配置复制粘贴就好

把所有数据源放在一个容器中方便sqlsession管理

<bean id="dataSource" class="com.flc.util.dataSource.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- 指定lookupKey和与之对应的数据源 -->
<entry key="mysql" value-ref="mysqlDataSource"></entry>
<entry key="oracle" value-ref="oracleDataSource"></entry>
<entry key="sqlServer" value-ref="sqlServerDataSource"></entry>
</map>
</property>
<!-- 这里可以指定默认的数据源 -->
<property name="defaultTargetDataSource" ref="mysqlDataSource" />
</bean>

配置sqlsession管理

<!-- sql会话模版 -->

<!--这里使用的是sqlSessionTemplate,也可以不实用,具体情况分析-->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory" />
</bean>
<!-- 配置mybatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
<!-- mapper扫描 -->
<property name="mapperLocations" value="classpath:mybatis/*/*.xml"></property>
</bean>

配置事务管理器

<!-- 拦截所有service层 同一走自定义的dataSourceAspect -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="Myadvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="delete*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception"/>
<tx:method name="insert*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="update*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="save*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<!-- <tx:method name="find*" propagation="SUPPORTS" read-only="true"/> -->
</tx:attributes>
</tx:advice>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="dataSourceAspect" class="com.flc.util.dataSource.DataSourceAspect" ></bean>
<aop:config>
<aop:aspect ref="dataSourceAspect" >
<!-- 拦截所有service方法 -->
<!-- 再service层打注解 -->
<aop:pointcut id="dataSourcePointcut" expression="execution(* com.flc.service..*(..))"/>
<aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
</aop:aspect>
</aop:config>

 

使用方法

@Service("userService")  //service调用
@DataSource(value=DynamicDataSourceHolder.mysql) //选择mysql数据库
public class UserService implements UserManager{

}

 

转载于:https://www.cnblogs.com/Sora-L/p/8949731.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值