springmvc+mybatis 配置多数据源相互切换

来源:互联网 发布:阿里云如何升级配置 编辑:程序博客网 时间:2024/06/04 23:30

         近日因为项目需求,需要动态切换数据源,就稍稍做了下研究,理解的不深,有不对的地方还望高人指点。

        直接贴上代码:

  resource.xml

 <bean id="sqlSessionFactory" class="com.hotent.core.mybatis.SqlSessionFactoryFactoryBean">        <property name="configLocation" value="classpath:/conf/configuration.xml"/>        <property name="mapperLocations" >        <list>        <value>classpath:/com/hotent/*/maper/*.map.xml</value>        </list>        </property>        <property name="dataSource" ref="dataSource"/>    </bean>    <bean id="dataSource" class="com.hotent.core.db.DynamicDataSource"><property name="targetDataSources"><map key-type="java.lang.String"><entry key="dataSourceOrg" value-ref="dataSourceOrg" /><entry key="defaultDataSource" value-ref="defaultDataSource" /></map></property><property name="defaultTargetDataSource" ref="defaultDataSource" /></bean> <bean id="dataSourceOrg"  class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close" >  <property name="driverClassName" value="${jdbc.driverClassNameOrg}"/><property name="url" value="${jdbc.urlOrg}"/><property name="username" value="${jdbc.usernameOrg}"/><property name="password" value="${jdbc.passwordOrg}"/> </bean>        <bean id="defaultDataSource"  class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close" >  <property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/> </bean><pre name="code" class="plain">


我这里配置数据库连接池用的是 com.alibaba.druid.pool.DruidDataSource 。下面的DynamicDataSource是实现AbstractRoutingDataSource 的 。

public class DynamicDataSource extends AbstractRoutingDataSource {/** * 取得当前使用那个数据源。 */@Overrideprotected Object determineCurrentLookupKey() {return DbContextHolder.getDbType();  }@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {// TODO Auto-generated method stubreturn null;}//设置数据源集合.    @Override    public void setTargetDataSources(Map targetDataSources) {        super.setTargetDataSources(targetDataSources);    }}

DbContextHolder.java

public class DbContextHolder{private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static final String DATA_SOURCE_DEFAULT = "defaultDataSource";   public static final String DATA_SOURCE_ORG = "dataSourceOrg";  /** * 设置当前数据库。 * @param dbType *//* @Resource private DynamicDataSource dds;*/public static void setDbType(String dbType){contextHolder.set(dbType);}/** * 取得当前数据源。 * @return */public static String getDbType(){String str = (String) contextHolder.get();if (null == str || "".equals(str))str = "1";return str;}/** * 清除上下文数据 */public static void clearDbType(){contextHolder.remove();}}
这里两个常量就是两个数据源的id.以后增加数据源,这里也要增加。setDbType就用做后面切换数据时候设置当前数据源。当完成操作以后要调用clearDbType方法恢复默认数据源。

test.java

public class test { @Testpublic void test() {ApplicationContext cxt = new ClassPathXmlApplicationContext(new String[] {"conf/app-context.xml"});IAuthenticate service = (IAuthenticate)cxt.getBean("iAuthenticate");SysOrg org = new SysOrg();org.setOrgId(123456789L);org.setOrgName("测试数据源");org.setAreaid(1L);//service.add(org);List<ISysOrg> sysorg_ =service.getAllOrgs(); JSONArray json =JSONArray.fromObject(sysorg_); System.out.println(json.toString());DbContextHolder.setDbType(DbContextHolder.DATA_SOURCE_ORG);//切换数据源List<ISysOrg> sysorg_1 =service.getAllOrgs(); JSONArray json1 =JSONArray.fromObject(sysorg_1); System.out.println(json1.toString()); DbContextHolder.clearDbType();//恢复默认数据源 }}

运行,切换成功。

中间遇到过一个问题,一直没有解决,还不知道是为什么,我用org.logicalcobwebs.proxool.ProxoolDataSource配置数据库连接池的时候数据源无法切换,后来改成com.alibaba.druid.pool.DruidDataSource、com.hotent.core.db.DynamicDataSource都可以。暂时还没查到原因。还望高人指点一下。

0 0