ssm配置多个数据源说明
简介:一个项目,连接多个数据库,通过切换动态数据源,达到增删查改的目的;直接上代码,步骤如下:
1:配置多个连接信息
`#Thu Nov 22 18:09:33 CST 2012
jdbc1.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc1.url=jdbc:sqlserver://ip:端口号;DatabaseName=库名
jdbc1.username=用户名
jdbc1.password=密码
#mysql
jdbc2.url=jdbc:mysql://ip:端口号/zedadisplay
jdbc2.driver=com.mysql.jdbc.Driver
jdbc2.username=用户名
jdbc2.password=密码
2:配置动态数据源,将数据源交由sqlsessionfactory去处理;备注动态数据源部分需要重写jdbc的方法,即:com.siweisoft.utils.dynamicDataSource.DynamicDataSource包下的方法,包名可按照自己的报名去更改
<bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc1.url}" />
<property name="username" value="${jdbc1.username}" />
<property name="password" value="${jdbc1.password}" />
<property name="driverClassName" value="${jdbc1.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
</bean>
<bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc2.url}" />
<property name="username" value="${jdbc2.username}" />
<property name="password" value="${jdbc2.password}" />
<property name="driverClassName" value="${jdbc2.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
</bean>
<bean id="dataSource" class="com.siweisoft.utils.dynamicDataSource.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="dataSource1" value-ref="dataSource1" />
<entry key="dataSource2" value-ref="dataSource2"/>
</map>
</property>
<!-- 默认目标数据源为主库数据源 -->
<property name="defaultTargetDataSource" ref="dataSource1" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据库连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 加载mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
</bean>
3:重写jdbc方法(备注:DynamicDataSource 方法中的@Order(1)必不可少,如果不加出现的bug以及原因见总结)
public class DbContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal();
/** * 设置当前数据库。 * @param dbType */
public static void setDbType(String dbType) {
contextHolder.set(dbType);
}
/** * 取得当前数据源。 * @return */
public static String getDbType() {
String str = (String) contextHolder.get();
return str;
}
/** * 清除上下文数据 */
public static void clearDbType() {
contextHolder.remove();
}
}
public class DynamicDataSource extends AbstractRoutingDataSource {
/** * 取得当前使用那个数据源。 */
@Order(1)
@Override
protected Object determineCurrentLookupKey() {
return DbContextHolder.getDbType();
}
}
4:前期工作已完成,编写测试文件,用来操作数据库,本人将方法写在了service层(备注:重点就是DbContextHolder.setDbType(“dataSource2”);// 切换数据源这一句话,将需要切换数据源的地方,加上这一句话就可以“dataSource2”为:第二步bean的id)
@Service(“appUserCidService”)
public class AppUserCidService {
@Resource
private AppUserCidMapper appUserCidMapper;
public int UpdateCid(String userid) {
DbContextHolder.setDbType("dataSource4");// 切换数据源
return appUserCidMapper.updateByPrimaryKey(userid);
}
}
总结:如不加,会出现切换数据源不成功,仍然使用默认数据源的问题。原因:AbstractRoutingDataSource的determineCurrentLookupKey方法执行的比自己写的AOP切换逻辑执行的早,导致切换后还是用默认的数据源,AOP切面的执行顺序可以通过@Order注解调整解决