springmvc mysql 动态切换数据源

spring mvc中可以将数据库源配置在applicationContext.xml文件dataSource中,一个dataSource对应一个数据库源,绑定到sessionFactory中,在后台dao层通过sessionFactory连接数据库。若项目中有多个数据源,那若配置多个sessionFactory显然不符合开闭原则,正确的是配置多个dataSource,通过在sessionFactory关联不同的dataSource连接不同的数据库。


下面是applicationContext.xml的配置

首先,配置多个dataSource

<bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${url1}" />  
		<property name="driverClass" value="${driverClassName}"/>  
        <property name="user" value="${usernames}"/>  
        <property name="password" value="${passwords}"/>  
	</bean>
	<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${url2}" />  
		<property name="driverClass" value="${driverClassName}" />  
        <property name="user" value="videoread"/>  
        <property name="password" value="2sd5j4fcg0h"/>  
</bean>	
配置dynamicDataSource

	<bean id="dynamicDataSource" class="com.sohu.util.DynamicDataSource">
		<property name="targetDataSources">
			<map key-type="java.lang.String">  
                <entry value-ref="dataSource1" key="dataSource1"></entry>  
                <entry value-ref="dataSource2" key="dataSource2"></entry>  
            </map> 
		</property>
		<property name="defaultTargetDataSource" ref="dataSource1"></property>
	</bean>
配置sessionFactory

	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dynamicDataSource"/>
		<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
	</bean>
配置transactionManger

	<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
        <property name="sessionFactory" ref="sessionFactory" />  
    </bean>
DynamicDataSource类

public class DynamicDataSource extends AbstractRoutingDataSource{
    public static final String DATA_SOURCE_1 = "dataSource1";
    public static final String DATA_SOURCE_2 = "dataSource2";
    
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
    public static void setCustomerType(String customerType) {
    	contextHolder.set(customerType);
    }
    public static String getCustomerType() {
    	return contextHolder.get();
    }
    public static void clearCustomerType() {
    	contextHolder.remove();
    }
    @Override
    protected Object determineCurrentLookupKey() {
    	System.out.println(getCustomerType());
    	return getCustomerType();
    }
}

IndexController

对数据源的切换必须在进入业务层之前进行切换

@Controller
@RequestMapping("indexController")
public class IndexController {
	@Resource
	private SessionFactory sessionFactory;
	
	@RequestMapping("dynamicSouce")
	public String dynamicSouce(){
		DynamicDataSource.setCustomerType(DynamicDataSource.DATA_SOURCE_2);
		Session session = sessionFactory.openSession();
		BigInteger count = (BigInteger) session.createSQLQuery("select count(*) from videoinfo").uniqueResult();
		System.out.println(count);
		return "result";
	}
}
报错:A ResourcePool could not acquire a resource from its primary factory or sour

解决:dataSource配置出错

情况1:value元素值之间出现空格(人为添加)

情况2:value结束标签换行(当value值比较长时,Ctrl+Shift+F的时就会换行)

情况3:


1、applicationContext.xml读取jdbc.properties的变量值,${username} ${password}一直报错

2、若在value值里直接填入jdbcURL的值,应该把用于转义的反斜杠去掉


参考:

http://blog.csdn.net/wangpeng047/article/details/8866239

http://www.itpub.net/thread-1906608-1-1.html

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页