mysql通过MapperScan实现多数据源

MapperScan

org.mybatis.spring.annotation.MapperScan

在SpringBoot中集成MyBatis,可以在mapper接口上添加@Mapper注解,将mapper注入到Spring,但是如果每一给mapper都添加@mapper注解会很麻烦,这时可以使用@MapperScan注解来扫描包。

@MapperScan注解只会扫描包中的接口,不会扫描类,所以可以在包中写Provider类。

属性

basePackages

@MapperScan("com.demo.mapper"):扫描指定包中的接口

@MapperScan("com.demo..mapper"):一个代表任意字符串,但只代表一级包,比如可以扫到com.demo.aaa.mapper,不能扫到com.demo.aaa.bbb.mapper

@MapperScan("com.demo.**.mapper"):两个*代表任意个包,比如可以扫到com.demo.aaa.mapper,也可以扫到com.demo.aaa.bbb.mapper

sqlSessionFactoryRef

为该MapperScan扫描到的Mapper 注入的sqlSessionFactory

通过该属性可实现不同目录的mapper使用不同的数据源

在初始化SqlSessionFactory时,可以通过sqlSessionFactory.setPlugins(interceptors(dbConfig,mappingConfig))添加拦截器,比如读写分离拦截器,pageHelper拦截器,分表拦截器等

@Configuration
@MapperScan(
        basePackages = "com.xxx.newmapper",
        sqlSessionFactoryRef = "newOrderSqlSessionFactory"
)
@Import(CityMappingConfig.class)
public class NewOrderDbConfig extends AbstractDbConfig {

    @Resource
    private CityMappingConfig mappingConfig;

    // 配置文件
    private DbConfig dbConfig = PropertyUtil.newInstance(DbConfig.class).orElse(new DbConfig());


    @Bean(name = "newOrderDataSource")
    @ConfigurationProperties("spring.datasource.neworderdatasource")
    public DataSource userinfoDataSource() {
                return DataSourceBuilder.create().type(com.alibaba.druid.pool.DruidDataSource.class).build();
    }

    @Bean(name = "newOrderSqlSessionFactory")
    @DependsOn("cityConfig")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("newOrderDataSource") DataSource dataSource) throws Exception {
        return super.sessionFactory(dataSource, "classpath*:mapping/newmapper/*.xml", dbConfig,copyNewCityMappingConfig(mappingConfig));
    }

    @Bean(name = "newSqlTransactionManager")
    public PlatformTransactionManager sqlTransactionManager(@Qualifier("newOrderDataSource") DataSource dataSource) {
        return super.transactionManager(dataSource);
    }
    
    public Interceptor[] interceptors(DbConfig dbConfig, CityMappingConfig mappingConfig) {
        PrepareInterceptor prepareInterceptor = new PrepareInterceptor();
        prepareInterceptor.addPreHandler(new ShardingHandler(dbConfig,mappingConfig));//PrepareInterceptor是mybatis拦截器
        prepareInterceptor.addPreHandler(new ForceMasterHandler());

        QueryExecutorInterceptor.Query query = new QueryExecutorInterceptor.Query(dbConfig);
        UpdateExecutorInterceptor.Update update = new UpdateExecutorInterceptor.Update(dbConfig);

        //分页插件
        Interceptor interceptor = new PageInterceptor();
        Properties properties = new Properties();
        //数据库
        properties.setProperty("helperDialect", "mysql");
        //是否分页合理化
        interceptor.setProperties(properties);
        return new Interceptor[] {prepareInterceptor, query, update, interceptor};
    }

    protected SqlSessionFactory sessionFactory(DataSource dataSource, String locationPattern, DbConfig dbConfig, CityMappingConfig mappingConfig) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(locationPattern));
        sqlSessionFactory.setPlugins(interceptors(dbConfig,mappingConfig));
        return sqlSessionFactory.getObject();
    }

    protected PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}