首先,既然是多数据源,那么咱们就先看下数据源怎么配置的:java
javaconfig相似下面这样:spring
MapperScan注解经常使用配置以下:sql
basePackages:Base packages to scan for MyBatis interfaces,也就是mapper接口所在包名数据库
annotationClass:This property specifies the annotation that the scanner will search for,apache
也就是只扫描指定包下的指定注解做为mapper,一般为org.apache.ibatis.annotations.Mappermybatis
markerInterface:This property specifies the parent that the scanner will search for,只扫描指定包下指定父接口的子接口做为mapperapp
sqlSessionTemplateRef:指定这组mapper关联的sqlSessionTemplateide
sqlSessionFactoryRef:指定这组mapper关联的sqlSessionFactoryui
那么,问题来了,annotationClass,markerInterface都配置了或者都不配置会怎样?在org.mybatis.spring.annotation.MapperScannerRegistrar.registerBeanDefinitions中调用的org.mybatis.spring.mapper.ClassPathMapperScanner.registerFilters()代码以下:3d
一幕了然,若是都配置了,最终的mapper会是二者匹配的合集;若是都不配置,那么,最终的mapper会是basePackages下全部任意接口。
使用地方在org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.isCandidateComponent:
还有一个问题,sqlSessionTemplateRef和sqlSessionFactoryRef同时都配置了会怎样?或者不配置呢?
一般,若是只有一个sqlSessionFactory时是不须要配置的,只有容器中有多个时才须要指定一个。
若是都配置了呢?请看下面分析:
org.mybatis.spring.mapper.ClassPathMapperScanner.processBeanDefinitions(Set<BeanDefinitionHolder>)中处理每个以前扫描mapper生成的BeanDefinition时,会给每个BeanDefinition设置sqlSessionFactory,以下:
看到log没,很清楚:Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.
看完mapper的处理,再来看关联的sqlSessionFactory:
根据指定数据源类型利用org.springframework.boot.jdbc.DataSourceBuilder建立dataSource,目前主流的是使用阿里开源的Druid数据库链接池做为数据源:
sqlSessionFactory建立:
经过SqlSessionFactoryBean关联dataSource和MapperXML,再经过@MapperScan关联sqlSessionFactory和mapper接口
至此,单个数据源建立算是完成了。如题,多数据源怎么办?
方法一,手动配置多个dataSource,并在@MapperScan关联不一样的sqlSessionFactory和mapper接口。
方法二,动态数据源,继承org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource,重写determineTargetDataSource方法,从targetDataSources中获取对应数据源操做数据库,一般在前面业务代码根据具体怎样的状况选择怎样的dataSource,而后经过设置ThreadLocal变量,这里获取变量信息来返回对应数据源。切入业务逻辑能够经过aop切面从dao层方法名入手,也能够经过mybatis的拦截器获取sql信息和入参决定选择哪一个数据源。
PS:若是是读写分离,一般状况下主库读写权限,从库只读权限,事务DataSourceTransactionManager配置在主库的dataSource上,@Transactional会自动从配置事务的dataSource中获取链接。