Spring配置RoutingDataSource实现mysql读写分离

580 阅读1分钟

首先我们先配置两个数据源:

<!-- 1:数据源 -->
<bean id="masterDs" class="com.alibaba.druid.pool.DruidDataSource"
	destroy-method="close">
	<property name="driverClassName" value="${jdbc.driverClassName}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<property name="password" value="${jdbc.password}" />
</bean>

<bean id="slaveDs" class="com.alibaba.druid.pool.DruidDataSource"
	destroy-method="close">
	<property name="driverClassName" value="${jdbc2.driverClassName}" />
	<property name="url" value="${jdbc2.url}" />
	<property name="username" value="${jdbc2.username}" />
	<property name="password" value="${jdbc2.password}" />
</bean>

接着 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource是一个路由分发数据源,负责对数据源的切换。由于它是抽象的,我们需要自己写一个类来继承它,并且实现里面的抽象方法。

public class P2PDataSource extends AbstractRoutingDataSource{

        //这个方法返回当前使用数据源的名称
        //DataSourceContext里面有一个线程变量,用来设置和获取当前线程也就是当前这个请求使用的数据源是哪一个
	@Override
	protected Object determineCurrentLookupKey() {
		if(DataSourceContext.get()==null){
			return null;
		}
		if(DataSourceContext.get().equals(BidConst.MASTER_DATASOURCE)){
			return "masterDs";
		}else{
			return "slaveDs";
		}
	}

}

数据源上下文:用来存储当前请求的数据源名称

public class DataSourceContext {

	private static ThreadLocal<String> dataSource=new ThreadLocal<>();
	
	public static void set(String dataSource){
		DataSourceContext.dataSource.set(dataSource);			
	}
	public static String get(){
		return DataSourceContext.dataSource.get();
	}
}

配置路由数据源

<!-- 配置路由分发DataSource -->
<bean id="dataSource" class="com.xmg.p2p.base.util.P2PDataSource">
	<property name="targetDataSources">
		<map>
			<entry key="master" value-ref="masterDs"></entry>
			<entry key="slave" value-ref="slaveDs"></entry>
		</map>
	</property>
	<property name="defaultTargetDataSource" ref="masterDs"></property>
</bean>

最后在需要读的serviceImpl的方法里面先设置数据源: DataSourceContext.dataSource.set(“slaveDs”); 然后在进行读的操作。