spring mvc 配置DataSource以及动态数据源
1.DateSource的配置
dataSource元素使用基本的JDBC数据源接口来配置JDBC连接对象的资源
<context:property-placeholder location="classpath:jdbc.properties"/>
即可,这里location值为参数配置文件的位置,参数配置文件通常放在src目录下,而参数配置文件的格式跟java通用的参数配置文件相同,即键值对的形式,例如:
jdbc.properties文件的内容
在配置文件里这么定义bean:
test.jdbc.driverClassName=com.mysql.jdbc.Driver
test.jdbc.url=jdbc:mysql://localhost:3306/test
test.jdbc.username=root
test.jdbc.password=root
这样一来就可以为spring配置的bean的属性设置值了,比如spring有一个jdbc数据源的类DriverManagerDataSource
在配置文件里这么定义bean:
<bean id="testDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${test.jdbc.driverClassName}"/>
<property name="url" value="${test.jdbc.url}"/>
<property name="username" value="${test.jdbc.username}"/>
<property name="password" value="${test.jdbc.password}"/>
</bean>
2.动态数据源
多数据源问题很常见,例如读写分离数据库配置。
我们很多项目中业务都需要涉及到多个数据源,最简单的做法就是直接在java代码里面lookup需要的数据源,但是这样的做法很明显耦合度太高了,
而且当逻辑流程不够严谨的时候就会出现各种大家不愿意看到的问题,由于我们现在的大多项目已经离不开spring了,spring也提供各种强大的功能,
很明显这种动态数据源功能也包括在内,具体实现类请看org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
1)首先配置多个datasource
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver">
</property>
<property name="url" value="jdbc:jtds:sqlserver://10.82.81.51:1433;databaseName=standards">
</property>
<property name="username" value="youguess"></property>
<property name="password" value="youguess"></property>
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver">
</property>
<property name="url" value="jdbc:jtds:sqlserver://10.82.81.52:1433;databaseName=standards">
</property>
<property name="username" value="youguess"></property>
<property name="password" value="youguess"></property>
</bean>
2) 写一个DynamicDataSource类继承AbstractRoutingDataSource,并实现determineCurrentLookupKey方法
package com.standard.core.util;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return CustomerContextHolder.getCustomerType();
}
}
3) 利用ThreadLocal解决线程安全问题
<span style="color:#333333;">package com.standard.core.util;
public class CustomerContextHolder {
public static final String DATA_SOURCE_A = "dataSource";
public static final String DATA_SOURCE_B = "dataSource2";
</span><span style="color:#ff0000;"> <strong>private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); </strong> </span><span style="color:#333333;">
public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
}
public static String getCustomerType() {
return contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}</span>
4)
数据源
配置
<span style="color:#333333;"><bean id="dynamicDataSource" class="com.standard.core.util.DynamicDataSource" >
<property name="targetDataSources">
<map key-type="java.lang.String">
</span><span style="color:#ff0000;"> <entry value-ref="dataSource" key="dataSource"></entry> </span><span style="color:#333333;">
<entry value-ref="dataSource2" key="dataSource2"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource" >
</property>
</bean> </span>
5) 在DAOImpl中切换数据源
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_B);