SSM多数据源实现

spring + mybatis 多数据源配置解决方案
配置多个不同的数据源,使用一个sessionFactory,在业务逻辑使用的时候自动切换到不同的数据源。
最近公司项目需求多数据源实现,以防忘记,记录下来方便下次查看。

首先是在applicationContext.xml里面配置多个数据源,我这里配置了两个。

<!-- 配置数据源 -->
	<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
		p:driverClassName="com.mysql.jdbc.Driver"
		p:url="jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxxxx" p:username="root"
		p:password="root">
		<property name="validationQuery">
			<value>SELECT 1</value>
		</property>
		<property name="testOnBorrow">
			<value>true</value>
		</property>
	</bean>
	<!-- 配置CRM数据源 -->
	<bean id="dataSourceCrm"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
		p:driverClassName="com.mysql.jdbc.Driver"
		p:url="jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxxxx" p:username="root"
		p:password="root">
		<property name="validationQuery">
			<value>SELECT 1</value>
		</property>
		<property name="testOnBorrow">
			<value>true</value>
		</property>
	</bean>

添加DatabaseContextHolder,用来保存当前应该使用的数据源名称:

package com.core.dynamic;

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

添加AbstractRoutingDataSource实现类,实现数据源路由选择:

package com.core.dynamic;

import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {

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

}

然后回到applicationContext.xml里面,配置动态数据源:

<bean id="dynamicDataSource"
		class="com.core.dynamic.DynamicDataSource">
		<property name="targetDataSources">
			<map key-type="java.lang.String">
				<!-- 指定lookupKey和与之对应的数据源 -->
				<entry key="dataSource" value-ref="dataSource"></entry>
				<entry key="dataSourceCrm" value-ref="dataSourceCrm"></entry>
			</map>
		</property>
		 <!-- 这里可以指定默认的数据源 -->
     	<property name="defaultTargetDataSource" ref="dataSource" />  
	</bean>

配置sessionFactory

<bean id="sqlSessionFactory"
		class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dynamicDataSource" />
		<property name="mapperLocations"
			value="classpath:com/*/dao/*.xml" />
	</bean>
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.*.dao" />
	</bean>

配置事务管理器及通过AOP配置提供事务增强,让service包下所有Bean的所有方法拥有事务

<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
		p:dataSource-ref="dynamicDataSource" />
	<!-- 通过AOP配置提供事务增强,让service包下所有Bean的所有方法拥有事务 -->
	<aop:config proxy-target-class="true">
		<aop:pointcut id="serviceMethod"
			expression="execution(* com.*.service..*(..)))" />
		<aop:advisor pointcut-ref="serviceMethod"
			advice-ref="txAdvice" />
	</aop:config>
	<tx:advice id="txAdvice"
		transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="*" />
		</tx:attributes>
	</tx:advice>

双数据源使用方法

package com.core.service;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.core.dao.CrmUserDao;
import com.core.dynamic.DynamicDataSourceHolder;
import com.core.entity.CrmUser;

@Service
public class CrmUserService{
	@Autowired
	private CrmUserDao crmUserDao;
	
	public CrmUser listById(CrmUser user){
		//切换数据源
		DynamicDataSourceHolder.setDataSource("dataSourceCrm");
		return crmUserDao.listById(user);
	}
}

补充:项目后期运行的时候报错提示找不到我所新建的dynamicDataSource类需要在配置文件中扫描配置上加上你的类目录

<!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
	<context:component-scan base-package="com.*.dao" />
	<context:component-scan base-package="com.*.dynamic" />

总结:双数据源配置实现起来过程并不是很复杂,细心就好,切换数据源的方法也可以将他封装成注解的方式,这里就不细说了,自己项目中因为所用到的双数据源的地方并不多,所以就没有去配置,有想法的朋友可以上网查找,网上有很多基于注解的方式切换数据源的文章。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值