ssm-alibaba连接池多数据源配置

1.新建DynamicDataSource.java内容如下:

package com.immo.ssm.common;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 配置多个数据源与切换数据源的方法
 * 
 * @author LinHai Tan
 *
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

	/**
	 * 内置对象
	 */
	private static DynamicDataSource obj = new DynamicDataSource();

	/**
	 * 保存所有dataSources的map
	 */
	private static Map dataSourceMap = new HashMap<>();

	/**
	 * 用于保存需要使用数据源的key的变量
	 */
	private static ThreadLocal dataSources = new ThreadLocal();

	/**
	 * 此类对象不需要有多个,私有构造方法
	 */
	private DynamicDataSource() {

	}

	/**
	 * 设置需要使用的数据源的key
	 * 
	 * @param dataSource
	 */
	public static void setDataSources(String dataSource) {
		dataSources.set(dataSource);
	}

	/**
	 * 获得需要使用的数据源的key
	 * 
	 * @return
	 */
	public static String getDataSources() {
		return dataSources.get();
	}

	/**
	 * 利用多态的特性,父类引用子类方法,为什么这么写请看源码
	 */
	@Override
	protected Object determineCurrentLookupKey() {
		String key = DynamicDataSource.getDataSources();
		if (StringUtils.isNotBlank(key) && !"dataSource".equalsIgnoreCase(key) && dataSourceMap.size() > 1) {
			setTargetDataSources(dataSourceMap);
		}
		return key;
	}

	/**
	 * 从新设置数据源,因为源码会把所有的数据源都遍历和判断,为了提升效率我们手动把自己能够使用的数据源提取出来
	 */
	@Override
	public void setTargetDataSources(Map targetDataSources) {
		// 获得默认的数据源和需要切换的数据源,本程序默认数据源的key为"dataSource",自己私有的数据源为所在的机构id
		Map myDataSources = getMyDataSources(targetDataSources);
		super.setTargetDataSources(myDataSources);
		super.setDefaultTargetDataSource(myDataSources.get("dataSource"));
		super.afterPropertiesSet();
	}

	/**
	 * 获取自己能够使用的数据源
	 * 
	 * @param targetDataSources
	 * @return
	 */
	private Map getMyDataSources(Map targetDataSources) {
		Map myDataSources = new HashMap<>();
		String myDataSourcesKey = DynamicDataSource.getDataSources();
		myDataSources.put("dataSource", targetDataSources.get("dataSource"));
		if (StringUtils.isNotBlank(myDataSourcesKey)) {
			Object dataSource = targetDataSources.get(myDataSourcesKey);
			if(dataSource != null){
				myDataSources.put(myDataSourcesKey, dataSource);
			}
		}
		return myDataSources;
	}

	/**
	 * 添加数据源
	 * 
	 * @param dataSourceName
	 * @param dataSource
	 */
	public void addDataSourceMap(String dataSourceName, DataSource dataSource) {
		dataSourceMap.put(dataSourceName, dataSource);
	}

	/**
	 * 初始化监听器时候会调用此方法把配置文件配置的数据源传入过来
	 * 
	 * @param dataSource
	 */
	public void setInitDataSource(DataSource dataSource) {
		dataSourceMap.put("dataSource", dataSource);
	}

	/**
	 * 获取内置对象
	 * 
	 * @return
	 */
	public static DynamicDataSource getObj() {
		return obj;
	}
}

2.修改spring与mybatis整合的配置文件:


        
            
                
            
        
        
        

3.我们需要写一个监听器,在项目启动的时候注入默认的数据源到map里面

ssm-alibaba连接池多数据源配置_第1张图片

代码如下:

package com.immo.ssm.listener;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Repository;

import com.alibaba.druid.pool.DruidDataSource;
import com.immo.ssm.common.DynamicDataSource;
import com.immo.ssm.common.Globals;
import com.immo.ssm.entity.BaseFunction;
import com.immo.ssm.entity.BaseMenu;
import com.immo.ssm.service.BaseFunctionService;
import com.immo.ssm.service.BaseMenuService;

@SuppressWarnings("rawtypes")
@Repository
public class InitListener implements ApplicationListener {
	// 在web 项目中(spring mvc),系统会存在两个容器
	// 一个是root application context ,另一个就是我们自己的 projectName-servlet
	// context(作为root application context的子容器)
	// 这种情况下,就会造成onApplicationEvent方法被执行两次。
	private static boolean isStart = false;

	@Autowired
	private BaseMenuService baseMenuService;
	
	@Autowired
	private BaseFunctionService baseFunctionService;
	
	@Autowired
	private  DruidDataSource dataSource;

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		try {
			if (!InitListener.isStart) {
				InitListener.isStart = true;
				List selectAllMenus = baseMenuService.selectAllMenus();
				Globals.setMenus(selectAllMenus);
				List selectAllFunction = baseFunctionService.selectAllFunction();
				Globals.setFunctions(selectAllFunction);
				DynamicDataSource.getObj().setInitDataSource(dataSource);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
这样就已经配置完成了,开始测试步骤
1.创建数据源,例如
                DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(driver);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		dataSource.setInitialSize(initialSize);
		dataSource.setMaxActive(maxActive);
		dataSource.setMaxIdle(maxIdle);
		dataSource.setMinIdle(minIdle);
		dataSource.setMaxWait(maxWait);
2.调用 DynamicDataSource的addDataSourceMap方法存入spring的数据源容器
DynamicDataSource.getObj().addDataSourceMap(dataSourceNamedataSource);

3.切换数据源的话就只需要调用DynamicDataSource的setDataSources方法,传入需要切换的数据源名称即可


你可能感兴趣的:(java,多数据源)