恋上蓝白 2017-10-31 12:42 采纳率: 0%
浏览 4441
已结题

SpringMVC+mybatis动态切换数据源,多数据库语言databaseId无效怎么解决。

1、采用SpringMVC+mybatis
2、动态切换数据源实现,单独测试有效

 public class DataSources extends AbstractRoutingDataSource{  
    @Override  
    protected Object determineCurrentLookupKey() {  
        return DataSourceSwitch.getDataSourceType();  
    }  
}  

3、Mybatis不同数据库语言支持实现,单独测试有效

 <!--支持多类型数据库配置-->
    <bean id="vendorProperties"
          class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="properties">
            <props>
                <prop key="Oracle">oracle</prop>
                <prop key="MySQL">mysql</prop>
            </props>
        </property>
    </bean>
    <bean id="databaseIdProvider" class="org.apache.ibatis.mapping.VendorDatabaseIdProvider">
        <property name="properties" ref="vendorProperties" />
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dynamicDataSource" />
        <property name="databaseIdProvider" ref="databaseIdProvider" />
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        …………

            <select id="getTime" resultType="java.lang.String" databaseId="oracle">
          select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual
    </select>

    <select id="getTime" resultType="java.lang.String" databaseId="mysql">
          select now()
    </select>

4、动态切换数据源之后再访问带有databaseId的dao方法就无效了。

5、看SqlSessionFactoryBean源码,databaseId相关代码如下

 if (this.databaseIdProvider != null) {
            try {
                configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));
            } catch (SQLException var24) {
                throw new NestedIOException("Failed getting a databaseId", var24);
            }
        }

                 public String getDatabaseId(DataSource dataSource) {
        if (dataSource == null) {
            throw new NullPointerException("dataSource cannot be null");
        } else {
            try {
                return this.getDatabaseName(dataSource);
            } catch (Exception var3) {
                log.error("Could not get a databaseId from dataSource", var3);
                return null;
            }
        }
    }

断点跟踪代码,只有启动服务的时候执行一次,切换数据源不执行,跪求求高手告知解决办法。献出全部C币。

  • 写回答

3条回答

  • paditang 2017-11-01 00:51
    关注

    http://blog.csdn.net/paditang/article/details/78297702 你看看这篇文章能不能帮到你。
    以下是mybatis的配置,其他和hibernate相同

     <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:p="http://www.springframework.org/schema/p" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd">
    
            <bean id="parentDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="${jdbc.driver}"/>    
            <!--initialSize: 初始化连接-->  
            <property name="initialSize" value="5"/>  
            <!--maxIdle: 最大空闲连接-->  
            <property name="maxIdle" value="15"/>  
            <!--minIdle: 最小空闲连接-->  
            <property name="minIdle" value="5"/>  
            <!--maxActive: 最大连接数量-->  
            <property name="maxActive" value="20"/> 
            <property name="minEvictableIdleTimeMillis" value="18000000"/> 
            <!--removeAbandoned: 是否自动回收超时连接-->  
            <property name="removeAbandoned" value="true"/>  
            <!--removeAbandonedTimeout: 超时时间(以秒数为单位)-->  
            <property name="removeAbandonedTimeout" value="180"/>  
            <!--maxWait: 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒-->  
            <property name="maxWait" value="3000"/>  
            <property name="validationQuery">  
            <value>SELECT 1</value>  
            </property>  
            <property name="testOnBorrow">  
            <value>true</value>  
            </property> 
        </bean>
    
        <bean parent="parentDataSource" id="db_record_read">
            <property name="url" value="${jdbc.url.read}"/>
            <property name="username" value="${jdbc.username.read}"/>  
            <property name="password" value="${jdbc.password.read}"/>  
        </bean>
    
        <bean parent="parentDataSource" id="db_record_write">
            <property name="url" value="${jdbc.url.write}"/>
            <property name="username" value="${jdbc.username.write}"/>  
            <property name="password" value="${jdbc.password.write}"/>  
        </bean>
    
        <bean parent="parentDataSource" id="db_vehicle">
            <property name="url" value="${jdbc.url.vehicle}"/>
            <property name="username" value="${jdbc.username.vehicle}"/>  
            <property name="password" value="${jdbc.password.vehicle}"/>  
        </bean>
    
        <bean parent="parentDataSource" id="db_admin">
            <property name="url" value="${jdbc.url.admin}"/>
            <property name="username" value="${jdbc.username.admin}"/>  
            <property name="password" value="${jdbc.password.admin}"/>  
        </bean>
    
    
        <bean class="com.xx.config.datasource.DynamicDataSource" id="dataSource">
            <property name="targetDataSources">
                <map key-type="java.lang.String">
                    <entry value-ref="db_record_read" key="db_record_read"></entry>
                    <entry value-ref="db_record_write" key="db_record_write"></entry>
                    <entry value-ref="db_vehicle" key="db_vehicle"></entry>
                    <entry value-ref="db_admin" key="db_admin"></entry>
                </map>
            </property>
            <property name="defaultTargetDataSource" ref="db_record_read"></property>
        </bean>
    
        <!-- 获取MyBatis sqlSessionFactory -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
            p:dataSource-ref="dataSource"
            p:configLocation="classpath:myBatisConf.xml"
            p:mapperLocations="classpath:com/xx/mapping/*.xml"><!-- 扫描Mapper文件 -->
             <property name="plugins">
                <array>
                  <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                      <!--使用下面的方式配置参数,一行配置一个 -->
                      <value>
                        helperDialect=MySql
                      </value>
                    </property>
                  </bean>
                </array>
             </property>
        </bean>
    
    
    
        <!-- 扫描直接使用mapper接口类操作dao -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"     
            p:basePackage="com.xx.mapping">
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        </bean>
        <!-- 配置事务管理器 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
    
        <!-- 配置基于注解的声明式事务 -->
        <tx:annotation-driven transaction-manager="transactionManager" />
    </beans>
    
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!