Mybatis系列:配置多数据源最简解决方案

现在主流的多数据源切换方式有:AOP 动态切换来做多数据源或者升级成Mybatis-Plus可以简单的配置多数据源,偶然见到大佬整理的很简单的多数据源的配置,改进一下,分享出来。

博主的另一篇:Mybatis AOP 切换数据源,仅供参考。

一、项目准备

1.1 pom.xml

没有特殊的依赖,mysql + mybatis + druid

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
    <!-- druid连接池-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>
</dependencies>

1.2 application.yml

我这里配置两个数据源:master 库和一个 slave 库,其中 master是默认库。可以有多个从库,自己去扩展吧,按照slave 库配置,再新增一个配置类即可。

spring:
  datasource:
    druid:
      master: # 主数据源
        username: master
        password: password
        driver-class-name: com.mysql.jdbc.Driver
        jdbc-url: jdbc:mysql://47.98.178.84:3306/master
        initialSize: 5
        minIdle: 5
        maxActive: 20
      slave: # 第二个数据源
        username: slave
        password: password
        driver-class-name: com.mysql.jdbc.Driver
        jdbc-url: jdbc:mysql://47.98.178.84:3306/slave
        initialSize: 5
        minIdle: 5
        maxActive: 20

1.3 初始化表

因为我的测试是在两个库分别插入数据,所以需要分别在两个库新建结构相同的表,sql如下:

DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_name` varchar(10) NOT NULL COMMENT '用户名',
  `pass_word` varchar(10) NOT NULL COMMENT '密码',
  `user_sex` varchar(10) DEFAULT NULL COMMENT '性别',
  `nick_name` varchar(10) DEFAULT NULL COMMENT '昵称',
  `gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

二、数据源配置

2.1 主数据源配置

@Configuration
@MapperScan(basePackages = "cn.van.mybatis.multipledata.simple.mapper.master", sqlSessionTemplateRef  = "masterSqlSessionTemplate")
// 指定主库扫描的 dao包,并给 dao层注入指定的 SqlSessionTemplate
public class DataSource1Config {
//    首先创建 DataSource
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.master")
    @Primary // 指定是主库
    public DataSource testDataSource() {
        return DataSourceBuilder.create().build();
    }
//  然后创建 SqlSessionFactory
    @Bean(name = "masterSqlSessionFactory")
    @Primary
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return bean.getObject();
    }
//  再创建事务
    @Bean(name = "masterTransactionManager")
    @Primary
    public DataSourceTransactionManager testTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
//  最后包装到 SqlSessionTemplate 中
    @Bean(name = "masterSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
  1. 首先创建 DataSource,然后创建 SqlSessionFactory,再创建事务,最后包装到 SqlSessionTemplate 中;
  2. @MapperScan(basePackages = "***", sqlSessionTemplateRef = "***"):指定主库扫描的 mapper 文件,并注入指定的 SqlSessionTemplate,同时SqlSessionFactorybean中指定xml文件位置;
  3. @Primary 说明指定了主库。

2.2 从库数据源配置

@Configuration
@MapperScan(basePackages = "cn.van.mybatis.multipledata.simple.mapper.slave", sqlSessionTemplateRef  = "db2SqlSessionTemplate")
// 指定分库扫描的 dao包,并给 dao层注入指定的 SqlSessionTemplate
public class DataSource2Config {
    //    首先创建 DataSource
    @Bean(name = "db2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.slave")
    public DataSource testDataSource() {
        return DataSourceBuilder.create().build();
    }
    //  然后创建 SqlSessionFactory
    @Bean(name = "db2SqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return bean.getObject();
    }
    //  再创建事务
    @Bean(name = "db2TransactionManager")
    public DataSourceTransactionManager testTransactionManager(@Qualifier("db2DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    //  最后包装到 SqlSessionTemplate 中
    @Bean(name = "db2SqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

相对于主库的配置,不同点有:

  1. 方法上没有@Primary的注解,说明是从库,(如果需要扩展,按照次配置新增即可);
  2. @MapperScan(basePackages = "***", sqlSessionTemplateRef = "***"):指定主库扫描的 mapper包 不同;
  3. @ConfigurationProperties(prefix = "spring.datasource.druid.**"):指定的数据源不同。

三、简单测试

3.1 业务层接口

这里的接口方法比较简单,主要是两个:将数据插入主库和从库,完整代码见文末。

  • TestService.java
public interface TestService {
    // 插入主库
    void insertMater(UserInfo userInfo);
    // 插入从库
    void insertSlave(UserInfo userInfo);
}
  • TestServiceImpl.java
@Service
public class TestServiceImpl implements TestService {
    @Resource
    User1Mapper user1Mapper;
    @Resource
    User2Mapper user2Mapper;

    public void insertMater(UserInfo userInfo) {
        user1Mapper.insert(userInfo);
    }

    public void insertSlave(UserInfo userInfo) {
        user2Mapper.insert(userInfo);
    }
}

mapper 接口和映射文件xml很简单,这里就不放出来了。

3.2 单元测试

  • 往主库(master) 新增数据
@Test
public void insertMater() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUserName("master");
    userInfo.setPassWord("password");
    userInfo.setUserSex("男");
    testService.insertMater(userInfo);
}
  • 往从库(slave) 新增数据
@Test
public void insertSlave() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUserName("slave");
    userInfo.setPassWord("password");
    userInfo.setUserSex("女");
    testService.insertSlave(userInfo);
}

经过测试,分别在在 master 库和 slave 库新增了不同的数据,证明我们的多数据源生效。

四、总结

如果你觉得:我只是想找一个简单的多数据支持而已,使用AOP配置多数据源有点小复杂,欢迎尝试该方式。

Github 示例源码

参考文章:Spring Boot(七):Mybatis 多数据源最简解决方案

4.1 日常求赞

博主祖传秘籍 Spring Boot 葵花宝典 开源中,欢迎前来吐槽,提供线索,告诉博主接下来更新哪方面文章,共同进步!

4.2 文化交流

  1. 风尘博客
  2. 风尘博客-掘金
  3. 风尘博客-博客园
  4. 风尘博客-CSDN
  5. Github

最新文章,欢迎关注:公众号-风尘博客;交流观点,欢迎添加:个人微信

风尘博客个人微信号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值