mybatis提供的@MapperScan注解中有一个属性叫做sqlSessionTemplateRef,通过给这个属性提供不同的模板实现,可以在同一个项目中使用多数据源。

不过这种方式只能以包的粒度划分,最终的效果大概是:对com.XX.A包使用1号数据源,对com.XX.B包使用2号数据源。

如果需要更精细化的控制,可以考虑使用第三方框架,但不在本文涉及范围内。

GitHub - baomidou/dynamic-datasource-spring-boot-starter: dynamic datasource for springboot 多数据源 动态数据源 主从分离 读写分离 分布式事务https://github.com/baomidou/dynamic-datasource-spring-boot-starter

依赖

首先引入依赖:

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

SpringBoot2.X自带了数据源Hikari,如果是SpringBoot1.X,则需要自己单独引入一下。

当然,用其他数据源(比如druid)也可以。

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>3.4.5</version>
        </dependency>

配置文件

为了更清晰点,就不把数据库配置文件和主配置文件放一起了。

新建两个properties文件,放在resources目录下,分别存放两个数据源的配置

wms-mysql.properties

jdbc.wms.driverClassName = com.mysql.jdbc.Driver
jdbc.wms.url = jdbc:mysql://localhost:3306/wms_test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false
jdbc.wms.username = root
jdbc.wms.password = root

wcs-mysql.properties

jdbc.wcs.driverClassName = com.mysql.jdbc.Driver
jdbc.wcs.url = jdbc:mysql://localhost:3306/wcs_test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false
jdbc.wcs.username = root
jdbc.wcs.password = root

配置类

注意:basePackages配置的包路径,是Dao接口存放的路径,也是当前数据源配置项生效的范围。

第一个数据源配置类:

@Configuration
@PropertySource("classpath:wms-mysql.properties")
@MapperScan(basePackages = "com.zikoo.datasource.demo.wmsdao", sqlSessionTemplateRef = "wmsSqlSessionTemplate")
public class WmsDataSourceConfig {
    @Value("${jdbc.wms.driverClassName}")
    private String driverClassName;

    @Value("${jdbc.wms.url}")
    private String url;

    @Value("${jdbc.wms.username}")
    private String userName;

    @Value("${jdbc.wms.password}")
    private String password;

    @Primary
    @Bean(name = "wmsDataSource")
    public DataSource wmsDataSource() {
        HikariDataSource hikariDataSource = new HikariDataSource();
        hikariDataSource.setDriverClassName(driverClassName);
        hikariDataSource.setJdbcUrl(url);
        hikariDataSource.setUsername(userName);
        hikariDataSource.setPassword(password);
        hikariDataSource.setPoolName("wms");
        hikariDataSource.setMaxLifetime(290000);
        hikariDataSource.setMaximumPoolSize(64);
        hikariDataSource.setMinimumIdle(4);
        return hikariDataSource;
    }

    @Primary
    @Bean(name = "wmsSqlSessionFactory")
    public SqlSessionFactory wmsSqlSessionFactory(@Qualifier("wmsDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        sqlSessionFactory.setVfs(SpringBootVFS.class);

        //配置xml
//        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().
//                getResources(""));
        return sqlSessionFactory.getObject();
    }

    @Primary
    @Bean(name = "wmsTransactionManager")
    public DataSourceTransactionManager wmsTransactionManager(@Qualifier("wmsDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Primary
    @Bean(name = "wmsSqlSessionTemplate")
    public SqlSessionTemplate wmsSqlSessionTemplate(@Qualifier("wmsSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

第二个数据源配置类

@Configuration
@PropertySource("classpath:wcs-mysql.properties")
@MapperScan(basePackages = "com.zikoo.datasource.demo.wcsdao", sqlSessionTemplateRef = "wcsSqlSessionTemplate")
public class WcsDataSourceConfig {

    @Value("${jdbc.wcs.driverClassName}")
    private String driverClassName;

    @Value("${jdbc.wcs.url}")
    private String url;

    @Value("${jdbc.wcs.username}")
    private String userName;

    @Value("${jdbc.wcs.password}")
    private String password;

    @Bean(name = "wcsDataSource")
    public DataSource wcsDataSource() {
        HikariDataSource hikariDataSource = new HikariDataSource();
        hikariDataSource.setDriverClassName(driverClassName);
        hikariDataSource.setJdbcUrl(url);
        hikariDataSource.setUsername(userName);
        hikariDataSource.setPassword(password);
        hikariDataSource.setPoolName("wcs");
        hikariDataSource.setMaxLifetime(290000);
        hikariDataSource.setMaximumPoolSize(64);
        hikariDataSource.setMinimumIdle(4);
        return hikariDataSource;
    }

    @Bean("wcsSqlSessionFactory")
    public SqlSessionFactory wcsSqlSessionFactory(@Qualifier("wcsDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        sqlSessionFactory.setVfs(SpringBootVFS.class);

        //配置xml
//        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().
//                getResources(""));
        return sqlSessionFactory.getObject();
    }

    @Bean(name = "wcsTransactionManager")
    public DataSourceTransactionManager wcsTransactionManager(@Qualifier("wcsDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "wcsSqlSessionTemplate")
    public SqlSessionTemplate wcsSqlSessionTemplate(@Qualifier("wcsSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

目录结构

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐