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

菜菜打怪兽 发布于 2014/01/15 15:06
阅读 15K+
收藏 1

小弟接手了一个小项目,分别为三个数据库分别布在三个服务器上。现需要通过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>


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

加载中
0
菜菜打怪兽
菜菜打怪兽
大神们!快来啊!
0
王洪旭
王洪旭
我就来凑个热闹,帮你顶起来
王洪旭
王洪旭
回复 @菜菜打怪兽 : 客气了
菜菜打怪兽
菜菜打怪兽
也谢谢你~
0
快跑的蜗牛
快跑的蜗牛
帮你顶一下,密切关注中
0
菜菜打怪兽
菜菜打怪兽
呼叫大神~!
0
liuxin
liuxin

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

0
菜菜打怪兽
菜菜打怪兽

引用来自“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]

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

0
liuxin
liuxin

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

0
菜菜打怪兽
菜菜打怪兽

引用来自“liuxin”的答案

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

在哪里配置呢?
0
小小志
小小志

可以参考一下我的

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");
}

}

0
xdev
xdev

之前研究过,哈哈。

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

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

所以推荐方法1

liuxin
liuxin
这个第一点就是我要说的蛤蛤,LZ你照着这个配置,配置多套就好了
返回顶部
顶部