近日项目中因为涉及到一个需求是A系统某表的数据要与B系统的某表数据在数据上出现不一致的情况,需要做一个数据比对功能,这时候就涉及到两个系统的数据库的数据比对。
方案一,将A系统的数据导出到Excel文件,在B系统上做个Excel导入到数据库临时表,然后就都可以在B系统中做比对。
方案二,在B系统上配置双数据源分别连接A,B系统的数据库,在业务层控制切换数据源。这样就避免了方案一中导出导入Excel文件的操作
所以这里采用方案二,使用双数据源
- config.properties文件配置两个数据库的信息
##############################WMS
jdbc_url=jdbc\:jtds\:sqlserver\://192.168.1.1\:1433/database1
wms_jdbc_username=sa
wms_jdbc_password=sa
##################################ERP
erp_jdbc_url=jdbc\:jtds\:sqlserver\://192.168.1.2\:1433/database2
erp_jdbc_username=sa
erp_jdbc_password=sa
################################
- 创建数据源切换工具类
/**
* @Description: 数据源切换实现类类
* @ 用户切换数据源只要在程序中使用 DBContextHolder.setDBType("dataSourceName") 即可完成数据源切换
* */
public class DataSourceContextHolder {
// 多个登录用户可能需要同时切换数据源,所以这里需要写一个线程安全的ThreadLocal
private static final ThreadLocal<String>contextHolder = new ThreadLocal<String>();
//设置数据源
public static void setDbType(String dbType) {
contextHolder.set(dbType);
}
//获取当前数据源
public static String getDbType() {
return contextHolder.get();
}
//移除当前数据源
public static void clearDbType() {
contextHolder.remove();
}
}
- 创建数据源设定类,继承抽象类AbstractRoutingDataSource并实现它的determineCurrentLookupKey()方法
public class DynamicDataSource extends AbstractRoutingDataSource{
//由此方法的返回值决定具体从哪个数据源中获取连接
@Override
protected Object determineCurrentLookupKey() {
// TODO Auto-generated method stub
return DataSourceContextHolder.getDbType();
}
}
- spring中配置
<!-- 配置数据源 WMS-->
<bean name="dataSourceWMS" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${wms_jdbc_url}" />
<property name="username" value="${wms_jdbc_username}" />
<property name="password" value="${wms_jdbc_password}" />
<!-- 为了简洁 只列出相关配置,不显示连接池的其他配置 -->
</bean>
<!-- 配置数据源 ERP -->
<bean name="dataSourceERP" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${erp_jdbc_url}" />
<property name="username" value="${erp_jdbc_username}" />
<property name="password" value="${erp_jdbc_password}" />
<!-- 为了简洁 只列出相关配置,不显示连接池的其他配置 -->
</bean>
<bean name="dataSource" class="com.dao.DynamicDataSource" >
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSourceWMS" key="dataSourceWMS"></entry>
<entry value-ref="dataSourceERP" key="dataSourceERP"></entry>
</map>
</property>
<!--默认数据源-->
<property name="defaultTargetDataSource" ref="dataSourceWMS"></property>
</bean>
<!-- myBatis文件 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
<property name="mapperLocations" value="classpath:mybatis/*/*.xml" />
</bean>
<!-- 配置sqlSessionTemplate -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory" />
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
- 业务类中使用
public void selectERPandWMStoContrast(Page page) throws Exception {
//取ERP的数据
**DataSourceContextHolder.setDbType("dataSourceERP");**
List<PageData> erpList = (List<PageData>) dao.findForList("ReportMapper.getERPList", null);
erpList.size();//ERP中取出了7000条数据
//取WMS的数据
**DataSourceContextHolder.setDbType("dataSourceWMS");**
List<PageData> wmsList = (List<PageData>)dao.findForList("ReportMapper.getWMSListPage", NULL);
wmsList.size();//WMS中取出了20条数据
}
经验证能正常获取数据