mybatis多数据源配置

多数据源有很多情况 ,下面介绍两种


1.数据来源于不同的数据库。

这样的配多个datasource就可以了,这样datasource,sessionFactory,mapper,session就会有多份。每增加一份就会多配这4种配置就好了,

如下两个数据源,datasource的配置就是配两个bean,id不一样就行了。其它的是这样:

<bean id="mybatisSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations" value="classpath*:sql/**/*.xml"/>
    <property name="configLocation" value="classpath:/conf/mybatis-config.xml"></property>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.highersoft.**.mapper,net.highersoft.**.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="mybatisSqlSessionFactory"></property>
    <property name="sqlSessionTemplateBeanName" value="mybatisSqlSession"></property>
</bean>


<bean id="mybatisSqlSession" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
    <constructor-arg index="0" ref="mybatisSqlSessionFactory"/>
</bean>

 
<bean id="evaluationSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="evaluationDataSource"/>
    <property name="mapperLocations" value="classpath*:sql/evaluation/*.xml"/>
    <property name="configLocation" value="classpath:/conf/mybatis-config.xml"></property>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="net.highersoft.modules.evaluation.dao"/>
    <property name="sqlSessionFactoryBeanName" value="evaluationSqlSessionFactory"></property>
    <property name="sqlSessionTemplateBeanName" value="evaluationSqlSession"></property>
</bean>
<bean id="evaluationSqlSession" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
    <constructor-arg index="0" ref="evaluationSqlSessionFactory"/>
</bean>

像上面一样同时配sqlSessionTemplate与sessionFactory可能会报错:

首先org.mybatis.spring.mapper.MapperScannerConfigurer$Scanner会报个警告:

[localhost-startStop-1] WARN  org.mybatis.spring.mapper.MapperScannerConfigurer$Scanner  - Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.

就是说sqlSessionTemplate与sessionFactory冲突了,不用sessionFactory,使用sqlSessionTemplate了,而如果sessionTemplate没有配

可能会报下面的错:

 [localhost-startStop-1] ERROR org.mybatis.spring.mapper.MapperFactoryBean  - Error while adding the mapper 'interface xx.Dao' to configuration.
java.lang.RuntimeException: Error parsing Mapper XML. Cause: org.apache.ibatis.builder.BuilderException: Error resolving class . Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'AppVersion'.  Cause: java.lang.ClassNotFoundException: Cannot find class: AppVersion
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:113)
	at org.apache.ibatis.type.TypeAliasRegistry.resolveAlias(TypeAliasRegistry.java:105)
所在正常配置只需要三个bean:

<bean name="salemanReportDataSource" class="com.alibaba.druid.pool.DruidDataSource" >
	<property name="url" value="${saleman.jdbc.url}"/>
	<property name="username" value="${saleman.jdbc.user}"/>
	<property name="password" value="${saleman.jdbc.password}"/>
</bean>

<bean id="salemanSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="salemanReportDataSource"/>
    <property name="mapperLocations" value="classpath*:com/xx/dao/api/saleman/*" />
</bean>

<bean id="saleManScan" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.xx.dao.saleman"/>
    <property name="sqlSessionFactoryBeanName" value="salemanSqlSessionFactory"></property>
</bean>


2.主从结构的不同数据库实例,有的代码要操作主库,有的操作从库.

解决办法,利用ThreadLocal保存使用数据库标识。

如在Controller或Service的方法上加一个自定义标注,使用spring aop处理这相标识,将其配置的标识写入ThreadLocal如下:

<aop:config>
        <aop:advisor
            pointcut="execution(* com..*Controller.*(..))"
            advice-ref="dataSourceAdvice" />
    </aop:config>

在dataSourceAdvice类里处理如下:

public void before(Method method, Object[] args, Object target) throws Throwable {
        try {
//DataSource是自定义标注
            if (method != null && method.isAnnotationPresent(DataSource.class)) {
                DataSource data = method.getAnnotation(DataSource.class);
               ThreadLocal.put(data.value());
            }
        } catch (Exception e) {
            logger.error("数据源配置有误", e);
            e.printStackTrace();
        }
    }

而在datasource配置sessionFactory的datasource时配置可选择的数据库,如:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath*:sql/**/*.xml"/>
</bean>

<bean id="dataSource" class="com.xx.MyRoutingDataSource "> 
        <property name="targetDataSources">   
              <map key-type="java.lang.String">   
                 <entry key="read" value-ref="readDataSource"/>
                 <entry key="write" value-ref="writeDataSource"/>
              </map>   
        </property>   
        <property name="defaultTargetDataSource" ref="readDataSource"/>   
    </bean>  

这个类的实现继承spring的AbstractRoutingDataSource :

public class MyRoutingDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceHolder.getDataSource();
    }

}
这样就一定程序上实现了主从数据库的选择与代码分离的效果。




文/中中 浏览次数:0次   2017-02-06 18:27:23

相关阅读

微信扫描-捐赠支持
加入QQ群-技术交流

评论: