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.youkuaiyun.com/wangpeng047/article/details/8866239
http://www.itpub.net/thread-1906608-1-1.html