1,对接口interface使用切面需要2.0以上版本 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.7.RELEASE</version> </parent>, 2,需要在某一个数据源上加@Primary ,否则默认装配数据源会报找到多个数据源错误
扫描类引入的是 tk.mybatis.spring.annotation.MapperScan
自定义MyBaseMapper不能放在scan扫描包内
import tk.mybatis.mapper.common.Mapper;
public interface MyBaseMapper<T> extends Mapper<T> {
}
本质就是切换数据源
org.mybatis
DateSource 定义注解 DateSourceContext 定义ThreadLocal上下文 DataSourceRouteAspect会拦截注解dataSource的方法,业务方法之前设置数据源,设置到ThreadLocal中 也可根据业务参数自主设置数据源,达到分库效果 DruidConfig 配置多数据源 MybatisConfig 扫描sql配置类 RouteDataSource 通过继承AbstractRoutingDataSource重写,获取ThreadLocal中的数据源 @Target({ ElementType.METHOD,ElementType.TYPE,ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DataSource { String value() default ""; } public class DataSourceContext { private static final ThreadLocal<String> context = new ThreadLocal<>(); public static void setDataSource(String value){ context.set(value); } public static String getDataSource(){ return context.get(); } public static void clearDataSource(){ context.remove(); } } @Aspect @Component public class DataSourceRouteAspect { @Before("@annotation(dataSource)") public void selectDateSource(JoinPoint point, DataSource dataSource){ String value = dataSource.value(); DataSourceContext.setDataSource(value); } @After("@annotation(dataSource)") public void removeDataSource(JoinPoint point, DataSource dataSource){ DataSourceContext.clearDataSource(); } } @Configuration public class DruidConfig { // @Value("${mysql.one.aliasName}") // private String aliasNameOne; // @Primary @Bean(name="dataSourceOne",initMethod = "init",destroyMethod = "close") @ConfigurationProperties(prefix = "mysql.one") public DruidDataSource dataSourceOne(){ DruidDataSource dataSource = new DruidDataSource(); dataSource.setQueryTimeout(300); dataSource.setTestWhileIdle(true); dataSource.setTestOnBorrow(true); dataSource.setTestOnReturn(true); dataSource.setTimeBetweenEvictionRunsMillis(600000); dataSource.setMinEvictableIdleTimeMillis(300000); return dataSource; } // @Bean(name="dataSourceTwo",initMethod = "init",destroyMethod = "close") // @ConfigurationProperties(prefix = "mysql.two") // public DruidDataSource dataSourceOne(){ // return dataSource; // } @Bean(name = "routeDataSource") public RouteDataSource dataSource(@Qualifier("dataSourceOne")DruidDataSource dataSourceOne // ,@Qualifier("dataSourceTwo")DruidDataSource dataSourceTwo ){ Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("dataSourceOne",dataSourceOne); // targetDataSources.put("dataSourceTwo",dataSourceTwo); RouteDataSource dataSource = new RouteDataSource(); dataSource.setTargetDataSources(targetDataSources); dataSource.setDefaultTargetDataSource(dataSourceOne); System.out.println("routeDataSource******************"+dataSource); return dataSource; } } import org.apache.ibatis.mapping.Environment; import org.apache.ibatis.transaction.TransactionFactory; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import tk.mybatis.spring.annotation.MapperScan import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; @Configuration @MapperScan("cn.com.xmh.ibatisMapper") public class MybatisConfig { @Autowired private RouteDataSource routeDataSource; @Bean(name="SqlSessionFactory") // @Primary public SqlSessionFactoryBean sqlSessionFactoryBean(){ TransactionFactory transactionFactory = new JdbcTransactionFactory(); Environment environment = new Environment("mytest",transactionFactory,routeDataSource); org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(environment); configuration.setMapUnderscoreToCamelCase(true); SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(routeDataSource); sqlSessionFactoryBean.setConfiguration(configuration); return sqlSessionFactoryBean; } @Bean(name="transactionManager") @Primary public PlatformTransactionManager transactionManager(){ return new DataSourceTransactionManager(routeDataSource); } } mapper配置类 import cn.com.config.dbConfig.DataSource; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; @Mapper public interface MyTestIbatis extends BaseMapper<String>{ @DataSource("dataSourceOne") @Select("select id from tbl_user") List<String> selectStr(); } import tk.mybatis.mapper.common.Mapper; public interface MyBaseMapper<T> extends Mapper<T> { } @Autowired MyTestIbatis myTestIbatis; myTestIbatis.selectStr() <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> spring.datasource.url=jdbc:mysql://127.0.0.1/xmh spring.datasource.username=root spring.datasource.password=admin spring.datasource.driver-class-name=com.mysql.jdbc.Driver mysql.one.url=jdbc:mysql://127.0.0.1/xmh mysql.one.userName=root mysql.one.password=admin mysql.one.initialSize= 5 mysql.one.minIdle= 5 mysql.one.maxActive= 20 mysql.one.maxWait= 6000 mysql.one.validationQuery= select 1 from dual mysql.one.drever-class-name= com.mysql.jdbc.Driver