SpringBoot结合MyBatis实现多数据源配置
作者:mmseoamin日期:2023-12-25

SpringBoot结合MyBatis实现多数据源配置

一、前提条件

1.1、环境准备

SpringBoot框架实现多数据源操作,首先需要搭建Mybatis的运行环境。

由于是多数据源,也就是要有多个数据库,所以,我们创建两个测试数据库,分别是:【sp-demo01】和【sp-demo02】,如下图所示:

SpringBoot结合MyBatis实现多数据源配置,在这里插入图片描述,第1张

具体SQL代码:

  • 创建【sp-demo01】数据库。
    -- 创建数据库
    CREATE DATABASE sp-demo01;
     
    -- ----------------------------
    -- Table structure for t_emp
    -- ----------------------------
    DROP TABLE IF EXISTS `t_emp`;
    CREATE TABLE `t_emp` (
      `emp_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '员工ID',
      `emp_name` varchar(255) NOT NULL COMMENT '员工姓名',
      `age` int(11) DEFAULT NULL COMMENT '年龄',
      `dept_id` int(11) NOT NULL COMMENT '部门ID',
      PRIMARY KEY (`emp_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3002 DEFAULT CHARSET=utf8;
     
    -- ----------------------------
    -- Records of t_emp
    -- ----------------------------
    INSERT INTO `t_emp` VALUES ('2001', 'Lucy', '21', '1002');
    INSERT INTO `t_emp` VALUES ('3001', 'Tom', '25', '1001');
    
    • 创建【sp-demo02】数据库。
      -- 创建数据库
      CREATE DATABASE sp-demo02;
       
      -- ----------------------------
      -- Table structure for t_dept
      -- ----------------------------
      DROP TABLE IF EXISTS `t_dept`;
      CREATE TABLE `t_dept` (
        `dept_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门ID',
        `dept_name` varchar(255) NOT NULL COMMENT '部门名称',
        `desc` varchar(255) DEFAULT NULL COMMENT '描述',
        PRIMARY KEY (`dept_id`)
      ) ENGINE=InnoDB AUTO_INCREMENT=1003 DEFAULT CHARSET=utf8;
       
      -- ----------------------------
      -- Records of t_dept
      -- ----------------------------
      INSERT INTO `t_dept` VALUES ('1001', '研发部', '编写程序');
      INSERT INTO `t_dept` VALUES ('1002', '测试部', '寻找bug');
      

      1.2、如何配置

      MyBatis框架中,提供了一个**【@MapperScan】注解,该注解作用是指定mapper接口所在的路径,并且这个注解中,也可以指定使用哪个【SqlSessionFactory】对象,只需要通过该注解的【sqlSessionFactoryRef】**属性即可实现。

      这里的SqlSessionFactory就相当于是一个数据库,如果我们要配置多数据源,那就相当于是要在工程里面创建多个SqlSessionFactory对象,然后再使用的时候指定具体的SqlSessionFactory对象即可。

      SpringBoot结合MyBatis实现多数据源配置,在这里插入图片描述,第2张

      配置数据源,需要创建三个对象,分别是下面三个:

      • 第一个对象:创建DataSource对象。
      • 第二个对象:创建SqlSessionFactory对象。
      • 第三个对象:创建SqlSessionTmplate对象。

        知道了这个知识,那就可以进行多数据源配置啦。

        二、多数据源配置

        这里,我们就创建两个数据源作为测试案例,两个数据源分别叫做【MasterDataSource】和【SlaveDataSource】。

        2.1、创建数据源配置类

        (1)创建Master配置类

        在工程中,创建一个【MasterDataSourceConfig】配置类,代码如下所示:

        package com.spring.boot.demo.config;
         
        import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
        import org.apache.ibatis.session.SqlSessionFactory;
        import org.mybatis.spring.SqlSessionFactoryBean;
        import org.mybatis.spring.SqlSessionTemplate;
        import org.mybatis.spring.annotation.MapperScan;
        import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
        import org.springframework.beans.factory.annotation.Qualifier;
        import org.springframework.boot.context.properties.ConfigurationProperties;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.context.annotation.Primary;
        import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
         
        import javax.sql.DataSource;
         
        /**
         * @author Js
         * @version 1.0.0
         * @Date: 2023/09/06 19:16:30
         * @Description
         */
        @MapperScan(
                basePackages = "com.spring.boot.demo.master.mapper",
                sqlSessionFactoryRef = "masterSqlSessionFactory",
                sqlSessionTemplateRef = "masterSqlSessionTemplate"
        )
        @Configuration
        public class MasterDataSourceConfig {
         
            // 默认指定 master 作为主数据源
            @Primary
            // 注入数据源
            @Bean("masterDataSource")
            // 指定 master 数据源的配置信息前缀
            @ConfigurationProperties(prefix = "spring.datasource.master")
            public DataSource masterDataSource() {
                // 手动创建 Druid 数据源对象
                return DruidDataSourceBuilder.create().build();
            }
         
            // 创建 SqlSessionFactory 对象
            @Bean("masterSqlSessionFactory")
            public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource) throws Exception {
                // 创建 SqlSessionFactoryBean 对象
                SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
                // 设置数据源
                factoryBean.setDataSource(masterDataSource);
                // 设置 mapper 映射文件路径
                PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                factoryBean.setMapperLocations(resolver.getResources("classpath:mappers/master/**/*.xml"));
                // 设置 VFS
                factoryBean.setVfs(SpringBootVFS.class);
                // 返回 SqlSessionFactory 对象
                return factoryBean.getObject();
            }
         
            // 创建 SqlSessionTemplate 对象
            @Bean("masterSqlSessionTemplate")
            public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory masterSqlSessionFactory) {
                // 创建 SqlSessionTemplate 对象
                return new SqlSessionTemplate(masterSqlSessionFactory);
            }
         
        }
        

        (2)创建Slave配置类

        在工程中,创建一个【SlaveDataSourceConfig】配置类,代码如下所示:

        package com.spring.boot.demo.config;
         
        import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
        import org.apache.ibatis.session.SqlSessionFactory;
        import org.mybatis.spring.SqlSessionFactoryBean;
        import org.mybatis.spring.SqlSessionTemplate;
        import org.mybatis.spring.annotation.MapperScan;
        import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
        import org.springframework.beans.factory.annotation.Qualifier;
        import org.springframework.boot.context.properties.ConfigurationProperties;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
         
        import javax.sql.DataSource;
         
        /**
         * @author Js
         * @version 1.0.0
         * @Date: 2023/09/06 19:30:45
         * @Description
         */
        @MapperScan(
                basePackages = "com.spring.boot.demo.slave.mapper",
                sqlSessionFactoryRef = "slaveSqlSessionFactory",
                sqlSessionTemplateRef = "slaveSqlSessionTemplate"
        )
        @Configuration
        public class SlaveDataSourceConfig {
         
            // 注入数据源
            @Bean("slaveDataSource")
            // 指定 slave 数据源的配置信息前缀
            @ConfigurationProperties(prefix = "spring.datasource.slave")
            public DataSource slaveDataSource() {
                // 手动创建 Druid 数据源对象
                return DruidDataSourceBuilder.create().build();
            }
         
            // 创建 SqlSessionFactory 对象
            @Bean("slaveSqlSessionFactory")
            public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource slaveDataSource) throws Exception {
                // 创建 SqlSessionFactoryBean 对象
                SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
                // 设置数据源
                factoryBean.setDataSource(slaveDataSource);
                // 设置 mapper 映射文件路径
                PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                factoryBean.setMapperLocations(resolver.getResources("classpath:mappers/slave/**/*.xml"));
                // 设置 VFS
                factoryBean.setVfs(SpringBootVFS.class);
                // 返回 SqlSessionFactory 对象
                return factoryBean.getObject();
            }
         
            // 创建 SqlSessionTemplate 对象
            @Bean("slaveSqlSessionTemplate")
            public SqlSessionTemplate slaveSqlSessionTemplate(@Qualifier("slaveSqlSessionFactory") SqlSessionFactory slaveSqlSessionFactory) {
                // 创建 SqlSessionTemplate 对象
                return new SqlSessionTemplate(slaveSqlSessionFactory);
            }
         
        }
        

        2.2、添加数据源配置信息

        在【application.yml】中添加master、slave两个数据源的配置信息,如下:

        # 配置数据源
        spring:
          datasource:
            # master 数据源信息
            master:
              driver-class-name: com.mysql.cj.jdbc.Driver # 数据库驱动
              url: jdbc:mysql://localhost:3306/sp-demo01?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8 # 数据库地址
              username: root
              password: root
            # slave 数据源信息
            slave:
              driver-class-name: com.mysql.cj.jdbc.Driver # 数据库驱动
              url: jdbc:mysql://localhost:3306/sp-demo02?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8 # 数据库地址
              username: root
              password: root
        

        2.3、创建Mapper接口

        (1)创建Master的mapper接口

        在【com.spring.boot.demo.master.mapper】包下面,创建【EmpMapper】类。

        package com.spring.boot.demo.master.mapper;
         
        import com.spring.boot.demo.pojo.EmpBo;
         
        import java.util.List;
         
        public interface EmpMapper {
            /**
             * 查询所有员工
             */
            List queryAll();
        }
        

        (2)创建Slave的mapper接口

        在【com.spring.boot.demo.slave.mapper】包下面,创建【DeptMapper】类。

        package com.spring.boot.demo.slave.mapper;
         
        import com.spring.boot.demo.pojo.DeptBo;
        import org.apache.ibatis.annotations.Param;
         
        public interface DeptMapper {
            /**
             * 根据 ID 查询部门
             * @param deptId
             * @return
             */
            DeptBo getDeptById(@Param("deptId") Integer deptId);
        }
        

        2.4、创建XML映射文件

        (1)创建Master的XML映射文件

        在【mappers/master】目录下面,新建【EmpMapper.xml】映射文件。

        
        
        
            
        
        

        (2)创建Slave的XML映射文件

        在【mappers/slave】目录下面,新建【DeptMapper.xml】映射文件。

        
        
        
            
        
        

        2.5、编写测试类

        package com.spring.boot.demo.controller;
         
        import com.spring.boot.demo.master.mapper.EmpMapper;
        import com.spring.boot.demo.pojo.DeptBo;
        import com.spring.boot.demo.pojo.EmpBo;
        import com.spring.boot.demo.slave.mapper.DeptMapper;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
         
        import java.util.List;
         
        /**
        * @author Js
         * @version 1.0.0
         * @Date: 2023/09/06 20:30:10
         * @Description
         */
        @RestController
        @RequestMapping("/api")
        public class TestController {
         
            @Autowired
            private EmpMapper empMapper;
            @Autowired
            private DeptMapper deptMapper;
         
            @GetMapping("/demo")
            public String demo() {
                // 查询所有员工信息
                List empBoList = empMapper.queryAll();
                System.out.println(empBoList);
                // 查询每一个员工的部门信息
                for (EmpBo empBo : empBoList) {
                    DeptBo deptBo = deptMapper.getDeptById(empBo.getDeptId());
                    System.out.println(deptBo);
                }
                return "测试成功";
            }
         
        }
        

        2.6、运行测试

        经过上面几个步骤之后,最终的工程目录结果应该是下面这样子的,如下图:

        SpringBoot结合MyBatis实现多数据源配置,在这里插入图片描述,第3张

        启动工程,浏览器访问【http://localhost:8080/api/demo】,查看控制台输出结果。

        SpringBoot结合MyBatis实现多数据源配置,在这里插入图片描述,第4张

        到此,SpringBoot结合MyBatis框架实现多数据源配置就成功啦。