第一步:创建一个DynamicDataSource的类,继承AbstractRoutingDataSource并重写determineCurrentLookupKey方法,代码如下:
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
// 从自定义的位置获取数据源标识
return DynamicDataSourceHolder.getDataSource();
}
}
第二步:创建DynamicDataSourceHolder用于持有当前线程中使用的数据源标识,代码如下:
public class DynamicDataSourceHolder {
/**
* 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
*/
private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>();
public static String getDataSource() {
return THREAD_DATA_SOURCE.get();
}
public static void setDataSource(String dataSource) {
THREAD_DATA_SOURCE.set(dataSource);
}
public static void clearDataSource() {
THREAD_DATA_SOURCE.remove();
}
}
到这里已经可以使用多数据源了,在操作数据库之前只要DynamicDataSourceHolder.setDataSource("dataSource2")即可切换到数据源2并对数据库db2进行操作了。
<context:property-placeholder location="classpath*:/main/config/application.properties" />
<!-- 支持aop注解 -->
<aop:aspectj-autoproxy />
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="${jdbc.driverClass}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="${jdbc.driverClass2}"></property>
<property name="url" value="${jdbc.url2}"></property>
<property name="username" value="${jdbc.user2}"></property>
<property name="password" value="${jdbc.password2}"></property>
</bean>
<bean id="dynamicDataSource" class="main.java.com.sy.util.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- 指定lookupKey和与之对应的数据源 -->
<entry key="dataSource1" value-ref="dataSource1"></entry>
<entry key="dataSource2" value-ref="dataSource2"></entry>
</map>
</property>
<!-- 这里可以指定默认的数据源 -->
<property name="defaultTargetDataSource" ref="dataSource1" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dynamicDataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
<property name="packagesToScan">
<value>main.java.com.sy.entity</value>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" >
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dynamicDataSource"/>
</bean>
示例代码如下:
@Service
public class DataServiceImpl implements DataService {
@Autowired
private DataMapper dataMapper;
@Override
public List<Map<String, Object>> getList1() {
// 没有指定,则默认使用数据源1
return dataMapper.getList1();
}
@Override
public List<Map<String, Object>> getList2() {
// 指定切换到数据源2
DynamicDataSourceHolder.setDataSource("dataSource2");
return dataMapper.getList2();
}
}