开发者社区> 问答> 正文

mybatis与spring整合配置多个数据源的问题 :报错

小弟接手了一个小项目,分别为三个数据库分别布在三个服务器上。现需要通过mybatis与spring整合这三个数据库,查询时在这三个库里分别查询后存到一个对象里显示到页面上。

现在不知道怎么配置来连接这三个数据源。代码如下:


applicationContext.xml:

 <!-- 使用annotation 自动注册bean,并保证@Required,@Autowired的属性被注入 -->
    <context:component-scan base-package="com.pcd" />
    

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@***.***.***.***:1521:***"/>
    <property name="username" value="***"/>
    <property name="password" value="***"/>
  </bean>

    <!-- 事务管理-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
      </bean>
      
      
      <!-- 事务的处理方式 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
          <tx:method name="query*" read-only="true" />
          <tx:method name="list*" read-only="true" />
          <tx:method name="update*"  />
          <tx:method name="delete*" />
          <tx:method name="*" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="ServicePointcut" expression="execution(* com.pcd.zzzxweb.*.*.*Service.*(..))"/>
         
        <aop:advisor advice-ref="txAdvice" pointcut-ref="ServicePointcut"/>
    </aop:config>
    <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
    
    
        <!-- myBatis配置 -->
    <!-- 配置SqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>    
        <property name="mapperLocations" >
            <list>
                <!-- mapper接口对应的xml路径 如果mapper接口的保内有和接口名一致的xml 则不用配置这个 -->
                <value>classpath:com/pcd/zzzxweb/**/*-Mapper.xml</value>
            </list>
        </property>    
    </bean>
    
     
    

    
    <!-- 通过扫描的模式,扫描目录在com/forsoft/xxx(xxx为项目名)目录下,所有的mapper都继承SqlMapper接口的接口, 这样一个bean就可以了 -->
    <bean name="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <property name="basePackage" value="com.pcd.zzzxweb"/>
       <property name="markerInterface" value="com.pcd.frame.mybatis.SqlMapper"/>
    </bean>
    
    <!--配置另一个数据源 -->
    
     <!-- 数据库连接池1 -->
    <bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@***.***.***.***:1521:***"/>
    <property name="username" value="***"/>
    <property name="password" value="***"/>
  </bean>
    
    
    <!-- 事务管理1-->
    <bean id="txManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource1"/>
      </bean>
    <tx:annotation-driven transaction-manager="txManager1" proxy-target-class="true"/>
    
        <!-- 配置SqlSessionFactoryBean1 -->
    <bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource1"/>
        <property name="configLocation" value="classpath:mybatis-config1.xml"/>    
        <property name="mapperLocations" >
            <list>
                <!-- mapper接口对应的xml路径 如果mapper接口的保内有和接口名一致的xml 则不用配置这个 -->
                <value>classpath:com/pcd/zzzxweb/**/*-Mapper.xml</value>
            </list>
        </property>    
    </bean>
    
    
    <!-- 通过扫描的模式,扫描目录在com/forsoft/xxx(xxx为项目名)目录下,所有的mapper都继承SqlMapper接口的接口, 这样一个bean就可以了 -->
    <bean name="mapperScannerConfigurer1" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <property name="basePackage" value="com.pcd.zzzxweb"/>
       <property name="markerInterface" value="com.pcd.frame.mybatis.SqlMapper1"/>
    </bean>
    
    
    
    
    
     <!-- 权限拦截器开始 -->
    <bean id="rc" class="com.pcd.frame.RightCheckService" scope="prototype">
        <property name="dataSource" ref="dataSource"/>
      </bean>
       <bean id="rightInterceptor" class="com.pcd.frame.interceptor.RightInterceptor" scope="prototype">   
        <property name="rc">
           <ref bean="rc" />
           </property>
     </bean>  
     <!-- 权限拦截器结束 -->
     
     <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" lazy-init = "true"/>
    <bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true">
        <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
    </bean>
 
     <!-- 系统模块管理开始 -->
    <bean id="operationAction" class="com.pcd.zzzxweb.operation.OperationAction" scope="prototype">
    </bean>
    <!-- 系统模块管理结束 -->
   
</beans>


求大神支招,小弟不胜感激!

展开
收起
kun坤 2020-06-14 15:28:33 694 0
1 条回答
写回答
取消 提交回答
  • 大神们!快来啊!######我就来凑个热闹,帮你顶起来######回复 @菜菜打怪兽 : 客气了######也谢谢你~######帮你顶一下,密切关注中######呼叫大神~!######

    把 sqlSessionFactory和dataSource1配置在一起算是一个完整的数据源,so你需要配置多个这样的组合

    ######

    引用来自“liuxin”的答案

    把 sqlSessionFactory和dataSource1配置在一起算是一个完整的数据源,so你需要配置多个这样的组合

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'LoadCodesServlet': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: [dataSource, dataSource1]

    此为报错明细,这事什么原因呢?

    ######

    你只配置了一个dataSource1,没有配置dataSource这个beanname

    ######

    引用来自“liuxin”的答案

    你只配置了一个dataSource1,没有配置dataSource这个beanname

    在哪里配置呢?
    ######

    可以参考一下我的

    public abstract class MultiBaseSqlSessionDaoSupport extends DaoSupport {


    private SqlSession multiSqlSession;


    @Resource(name = "multiSqlSession")
    public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
    this.multiSqlSession = sqlSessionTemplate;
    }


    public final SqlSession getSqlSession() {
    return this.multiSqlSession;
    }


    protected void checkDaoConfig() {
    notNull(this.multiSqlSession,
    "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required");
    }

    }

    ######

    之前研究过,哈哈。

    一、简单点,分三个模块(针对不同的库)提供服务(注意互相不要依赖),前面的action依赖这个三个模块,把服务类注入到action,就可以啦,重点是上面的mybatis的配置,要分开配置(也就是隔离,不让回报不存在表),配置三套相同的名字不一样的配置,其中包括:数据源,事务和aop拦截,sqlSessionFactory,mapperScannerConfigurer(这个是重点,可以配置指定对用的数据源中的mapper,也就是查询数据的类使用的数据源是那个,使用<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />指定,一定配置要正确不要把不同的数据库查询配置到一个sqlSessionFactory,这样就会查询不到表而报错或者是查询错误的数据库数据

    二、如果在同一个业务方法中需要操作多个数据库,而且要求事务一致性(如果不需要一致上面方法只要把配置事务拦截修改就可以,而且在一定程度上保证事务一致,不严格再同一个方法上开启多个事务,只要方法出现异常所有事务都会回滚,但是回滚和方法完成后提交事务时三个事务提交还是分开的,由于分开就造成不一致性,解决办法是分布式事务,如果系统允许情况下还是可以接受的),那么就必须使用分布式数据源和分布式jdbc驱动实现,不过这种效果性能很差,而且问题多多,最常产生的问题是锁表。

    所以推荐方法1

    ######这个第一点就是我要说的蛤蛤,LZ你照着这个配置,配置多套就好了
    2020-06-14 15:28:42
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载

相关实验场景

更多