以 MyBatis-Plus 为框架 搭建最简易多数据源(不同包下走不同的数据源)



1.1 引入pom依赖

 <!--引入springboot父工程依赖-->
    <!--引入依赖作用:
    可以省去version标签来获得一些合理的默认配置
    -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
    </parent>

    <!--因为用eureka,是springCloud的,所以引入springCloud版本锁定-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <!--spring cloud 版本 springBoott和springCloud版本要对应起来-->
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
    </properties>
    <!--引入Spring Cloud 依赖-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!--引入eureka-client jar包 这是eureka客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--因为要启动此项目,所以需要启动类-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--@Data 减少JavaBean get...set...方法-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--链接Spring BootMyBatis-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>


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



<!--两个用来做测试的jar包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>


    </dependencies>


1.2 application.yml 配置

server:
  #客户端端口号
  port: 8080


mybatis-plus:
  mapper-locations: classpath*:mappings/*/*.xml #扫描mapper
  type-aliases-package: com.it.mhh.entity #扫描实体类
  global-config:
    banner: false
    db-config:
      id-type: ID_WORKER #主键类型 NONE:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID", AUTO: MP自动决定;
      logic-not-delete-value: normal #逻辑删除配置
      logic-delete-value: deleted #逻辑删除配置
  configuration:
    map-underscore-to-camel-case: true

spring:
  datasource:
    master:
      driver-class-name: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://localhost:3306/mhh_master?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
      username: root
      password: root
    branch:
      driver-class-name: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://localhost:3306/mhh_branch?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
      username: root
      password: root
  application:
    #客户端注册名字 ,在注册中心Application的名字
    name: client-general-mapper

eureka:
  client:
    #因为是客户端,所以需要自我注册,注册到eureka-server中 默认:true
    register-with-eureka: true
    #从客户端拉取服务,后面你不止用自己一个服务,可能会通过feign接口调用server中别的服务,所以需要拉取服务 默认:true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka #注册中心地址,如果集群,有几个写几个,逗号分隔
  instance:
    # 更倾向使用ip地址,而不是host名
    prefer-ip-address: true
    #注册中心中测项目Status的名字
    instance-id: ${eureka.instance.ip-address}
    # ip地址 这是客户端的注册地址, eureka 会通过这个地址建立管道
    ip-address: 127.0.0.1  #默认0.0.0.0.0.0.1
    # 表示eureka client发送心跳给server端的频率,续约间隔,默认30秒(只要服务端没有接收到,并不会直接剔除,会先把Status变为Down状态)
    lease-renewal-interval-in-seconds: 5
    # 表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance
    lease-expiration-duration-in-seconds: 15



1.3 JavaBean对象

1.3.1 第一个数据源Master JavaBean对象

  • 用的都是mybatisplus注解
  • @Data中有五
  • 此javaBean对象对应的是MySql中的表 用@TableName注解指定表名
  • @TableField(fill = FieldFill.*)这个注解中的 fill 是指定数据库表的字段的填充策略
  • 实现myBatisPlus自动填充策略 要实现myBatisPlus里的MetaObjectHandler接口
  • 这里主要说下多数据源的配置 就不多说myBatisPlus的东西了(后期专门写个MyBatisPlus的)

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@TableName("student")
public class StudentMaster implements Serializable {

    public StudentMaster(long masterId, String masterName, Integer masterAge) {
        this.masterId = masterId;
        this.masterName = masterName;
        this.masterAge = masterAge;
    }

    /*
         INPUT 如果开发者没有手动赋值,则数据库通过自增的方式给主键赋值,如果开发者手动赋值,则存入该值。
         AUTO 默认就是数据库自增,开发者无需赋值。
         ASSIGN_ID MP 自动赋值,雪花算法。
         ASSIGN_UUID 主键的数据类型必须是 String,自动生成 UUID 进行赋值
       * */
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private long masterId;


    /*
        映射非主键字段,value 映射字段名
        exist 表示是否为数据库字段 false,如果实体类中的成员变量在数据库中没有对应的字段,则可以使用 exist,VO、DTO
        select 表示是否查询该字段
        fill 表示是否自动填充,将对象存入数据库的时候,由 MyBatis Plus 自动给某些字段赋值,create_time、update_time
    * */
    @TableField(value = "name")
    private String masterName;

    @TableField(value = "age")
    private Integer masterAge;


    // 第一次添加填充
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createDate;

    // 第一次添加的时候填充,但之后每次更新也会进行填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateDate;

}



1.3.2 第二个数据源Branch JavaBean对象

  • 用的都是mybatisplus注解
  • 此javaBean对象对应的是MySql中的表 用@TableName注解指定表名
  • @TableField(fill = FieldFill.*)这个注解中的 fill 是指定数据库表的字段的填充策略
  • 实现myBatisPlus自动填充策略 要实现myBatisPlus里的MetaObjectHandler接口
  • 这里主要说下多数据源的配置 就不多说myBatisPlus的东西了(后期专门写个MyBatisPlus的)

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;

@Data
@TableName("student")
public class StudentBranch {
    public StudentBranch(long branchId, String branchName, String branchAddress, String branchTeacher) {
        this.branchId = branchId;
        this.branchName = branchName;
        this.branchAddress = branchAddress;
        this.branchTeacher = branchTeacher;
    }

    /*
         INPUT 如果开发者没有手动赋值,则数据库通过自增的方式给主键赋值,如果开发者手动赋值,则存入该值。
         AUTO 默认就是数据库自增,开发者无需赋值。
         ASSIGN_ID MP 自动赋值,雪花算法。
         ASSIGN_UUID 主键的数据类型必须是 String,自动生成 UUID 进行赋值
       * */
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private long branchId;


    /*
        映射非主键字段,value 映射字段名
        exist 表示是否为数据库字段 false,如果实体类中的成员变量在数据库中没有对应的字段,则可以使用 exist,VO、DTO
        select 表示是否查询该字段
        fill 表示是否自动填充,将对象存入数据库的时候,由 MyBatis Plus 自动给某些字段赋值,create_time、update_time
    * */
    @TableField(value = "name")
    private String branchName;

    @TableField(value = "address")
    private String branchAddress;

    @TableField(value = "teacher")
    private String branchTeacher;

    // 第一次添加填充
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    // 第一次添加的时候填充,但之后每次更新也会进行填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

}




1.4 myBatisPlus自动填充策略

  • 这个主要是配合JavaBean对象中@TableField()中 fill 属性
  • @TableField()中 fill 属性为 FieldFill.INSERT表示只在第一次新增添加时赋值 走下面自己自动填充处理类 insertFill方法
  • @TableField()中 fill 属性为 FieldFill.INSERT_UPDATE 表示 新增修改时都会自动赋值 走下面自己自动填充处理类 updateFill方法
  • 实现自动填充策略 需实现MetaObjectHandler接口
  • setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)三个入参 第一个 给哪个属性赋值,把属性名填上,第二个 要自动填充什么值,第三个 为 元对象
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * 自动填充处理类
 * @author Mhh
 * @version 1.0
 * @see
 **/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
  private static final Logger logger = LoggerFactory.getLogger(MyMetaObjectHandler.class);


  public MyMetaObjectHandler() {
  }


  public void insertFill(MetaObject metaObject) {
    this.setFieldValByName("createDate", LocalDateTime.now(), metaObject);
    this.setFieldValByName("createTime", new Date(), metaObject);
    this.setFieldValByName("updateDate", LocalDateTime.now(), metaObject);
    this.setFieldValByName("updateTime", new Date(), metaObject);
  }

  public void updateFill(MetaObject metaObject) {
    this.setFieldValByName("updateDate", LocalDateTime.now(), metaObject);
    this.setFieldValByName("updateTime", new Date(), metaObject);
  }
}


1.5 数据源配置


1.5.1 Master数据源配置

  • 一个大坑: 我用的是MyBatisPlus MyBatisPlus有自己的数据源MybatisSqlSessionFactoryBean 用SqlSessionFactoryBean会报Invalid bound statement not found ** 错误
  • 驼峰命名: mybatisConfiguration.setMapUnderscoreToCamelCase(true);因为现在是自己手写DataSource了 所有yml配置的不再有作用
  • 引入自动填充类:注意引入一下刚才写的自定义自动填充类 因为现在是自己手写DataSource, java不会在自己帮我们引入 需要手动引入设置下 否则不生效
  • 配置mapper的xml形式文件: mapper的xml形式文件位置必须要配置 不然将报错:no statement,因为现在是自己手写DataSource了 所有yml配置的不再有作用
  • @MapperScan注解中属性配置: basePackages属性: 我需要的核心 指定扫描哪个包 那么这个包下的所有mapper就走此配置,sqlSessionFactoryRef属性:既然知道那些包下的mapper走那些配置了 那么这个属性就是指定的走那个数据源,@Bean已经指定数据源的名字了
  • @Primary: 表示这个数据源是默认数据源, 这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)
  • @ConfigurationProperties注解:中prefix 属性指定的就是 yml里配置的MySql的地址、账号和密码

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.it.mhh.utils.MyMetaObjectHandler;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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;

@Configuration
@MapperScan(basePackages = "com.it.mhh.master.dao", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {

    @Autowired
    private MyMetaObjectHandler myMetaObjectHandler;

    @Primary // 表示这个数据源是默认数据源, 这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)
    @Bean("masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master") //读取application.yml中的配置参数映射成为一个对象
    public DataSource getmasterDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean("masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        //SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //驼峰命名
        //org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisConfiguration.setMapUnderscoreToCamelCase(true);
        //引入自定以自动填充类
        GlobalConfig globalConfig=new GlobalConfig();
        globalConfig.setMetaObjectHandler(myMetaObjectHandler);
        bean.setGlobalConfig(globalConfig);
        //configuration.setMapUnderscoreToCamelCase(true);
        bean.setConfiguration(mybatisConfiguration);

        // mapper的xml形式文件位置必须要配置,不然将报错:no statement (这种错误也可能是mapper的xml中,namespace与项目的路径不一致导致)
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mappings/master/*.xml"));
        return bean.getObject();
    }

    @Primary
    @Bean("masterSqlSessionTemplate")
    public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}



1.5.1 branch数据源配置

  • 一个大坑: 我用的是MyBatisPlus MyBatisPlus有自己的数据源MybatisSqlSessionFactoryBean 用SqlSessionFactoryBean会报Invalid bound statement not found ** 错误
  • 驼峰命名: mybatisConfiguration.setMapUnderscoreToCamelCase(true);因为现在是自己手写DataSource了 所有yml配置的不再有作用
  • 引入自动填充类:注意引入一下刚才写的自定义自动填充类 因为现在是自己手写DataSource, java不会在自己帮我们引入 需要手动引入设置下 否则不生效
  • 配置mapper的xml形式文件: mapper的xml形式文件位置必须要配置 不然将报错:no statement,因为现在是自己手写DataSource了 所有yml配置的不再有作用
  • @MapperScan注解中属性配置: basePackages属性: 我需要的核心 指定扫描哪个包 那么这个包下的所有mapper就走此配置,sqlSessionFactoryRef属性:既然知道那些包下的mapper走那些配置了 那么这个属性就是指定的走那个数据源,@Bean已经指定数据源的名字了
  • @Primary: 表示这个数据源是默认数据源, 这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)
  • @ConfigurationProperties注解:中prefix 属性指定的就是 yml里配置的MySql的地址、账号和密码

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.it.mhh.utils.MyMetaObjectHandler;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.it.mhh.branch.dao", sqlSessionFactoryRef = "branchSqlSessionFactory")
public class BranchDataSourceConfig {

    @Autowired
    private MyMetaObjectHandler myMetaObjectHandler;

    @Bean("branchDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.branch")
    public DataSource getBranchDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean("branchSqlSessionFactory")
    public SqlSessionFactory branchSqlSessionFactory(@Qualifier("branchDataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //驼峰命名
        //org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisConfiguration.setMapUnderscoreToCamelCase(true);
        //configuration.setMapUnderscoreToCamelCase(true);
        //引入自定以自动填充类
        GlobalConfig globalConfig=new GlobalConfig();
        globalConfig.setMetaObjectHandler(myMetaObjectHandler);
        bean.setGlobalConfig(globalConfig);
        bean.setConfiguration(mybatisConfiguration);

        // mapper的xml形式文件位置必须要配置,不然将报错:no statement (这种错误也可能是mapper的xml中,namespace与项目的路径不一致导致)
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mappings/branch/*.xml"));
        return bean.getObject();
    }

    @Bean("branchSqlSessionTemplate")
    public SqlSessionTemplate branchSqlSessionTemplate(@Qualifier("branchSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}


1.6 雪花算法工具类

snowFlake.nextId():获得值,Long类型


public class SnowFlake {
    // 起始的时间戳
    private final static long START_STMP = 1577808000000L; //2020-01-01
    // 每一部分占用的位数,就三个
    private final static long SEQUENCE_BIT = 12; //序列号占用的位数
    private final static long MACHINE_BIT = 5; //机器标识占用的位数
    private final static long DATACENTER_BIT = 5; //数据中心占用的位数
    // 每一部分最大值
    private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
    private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
    private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
    // 每一部分向左的位移
    private final static long MACHINE_LEFT = SEQUENCE_BIT;
    private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
    private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
    private long datacenterId; //数据中心
    private long machineId; //机器标识
    private long sequence = 0L; //序列号
    private long lastStmp = -1L; //上一次时间戳

    public SnowFlake(long datacenterId, long machineId) {
        if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
            throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
        }
        if (machineId > MAX_MACHINE_NUM || machineId < 0) {
            throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
        }
        this.datacenterId = datacenterId;
        this.machineId = machineId;
    }

    //产生下一个ID
    public synchronized long nextId() {
        long currStmp = timeGen();
        if (currStmp < lastStmp) {
            throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
        }

        if (currStmp == lastStmp) {
            //if条件里表示当前调用和上一次调用落在了相同毫秒内,只能通过第三部分,序列号自增来判断为唯一,所以+1.
            sequence = (sequence + 1) & MAX_SEQUENCE;
            //同一毫秒的序列数已经达到最大,只能等待下一个毫秒
            if (sequence == 0L) {
                currStmp = getNextMill();
            }
        } else {
            //不同毫秒内,序列号置为0
            //执行到这个分支的前提是currTimestamp > lastTimestamp,说明本次调用跟上次调用对比,已经不再同一个毫秒内了,这个时候序号可以重新回置0了。
            sequence = 0L;
        }

        lastStmp = currStmp;
        //就是用相对毫秒数、机器ID和自增序号拼接
        return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
                | datacenterId << DATACENTER_LEFT       //数据中心部分
                | machineId << MACHINE_LEFT             //机器标识部分
                | sequence;                             //序列号部分
    }

    private long getNextMill() {
        long mill = timeGen();
        while (mill <= lastStmp) {
            mill = timeGen();
        }
        return mill;
    }

    private long timeGen() {
        return System.currentTimeMillis();
    }

}


1.7 xml配置

这里注意的是 一定要和手写数据源的mapper的xml形式文件位置对应起来
在这里插入图片描述

MasterDaoMapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.it.mhh.master.dao.MasterDaoMapper">

</mapper>

BranchDaoMapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.it.mhh.branch.dao.BranchDaoMapper">

</mapper>


1.8 启动类配置

  • 将雪花算法工具类引入到 ioc中
  • 雪花算法入参的两个值: 机器Id,只要不和别的机器Id重复就行(范围:0-32 0-32)
import com.it.mhh.utils.SnowFlake;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;

@EnableEurekaClient
@SpringBootApplication
public class MultipleDataSourcesApplication {

    public static void main(String[] args) {
        SpringApplication.run(MultipleDataSourcesApplication.class,args);
    }

    @Bean
    public SnowFlake snowFlake(){
        return new SnowFlake(0,0);
    }
}


1.9 数据源测试


1.9.1 Master数据源测试

Controller层:MasterController


import com.it.mhh.entity.StudentMaster;
import com.it.mhh.master.service.MasterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("master")
public class MasterController {

    @Autowired
    private MasterService masterService;


    @RequestMapping("/insertMaster")
    public Boolean insertMaster(@RequestBody StudentMaster studentMaster) {

        return masterService.insertMaster(studentMaster);
    }

    public Boolean updateMaster(@RequestBody StudentMaster studentMaster) {

        return masterService.updateMaster(studentMaster);
    }
}

ServiceImpl层:MasterServiceImpl

MyBatis-Plus的通用service:实现类继承ServiceImpl<操作实体的Mapper接口,具体实体类>,最后添加注解@Service将该类作为Spring容器下的Bean。

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.it.mhh.entity.StudentMaster;
import com.it.mhh.master.dao.MasterDaoMapper;
import com.it.mhh.master.service.MasterService;
import org.springframework.stereotype.Service;

@Service
public class MasterServiceImpl extends ServiceImpl<MasterDaoMapper, StudentMaster> implements MasterService {


    @Override
    public Boolean insertMaster(StudentMaster studentMaster) {
        return this.baseMapper.insert(studentMaster)>0?true:false;
    }
    
    @Override
    public Boolean updateMaster(StudentMaster studentMaster) {
        return this.baseMapper.updateById(studentMaster)>0?true:false;

    }
}


dao层:MasterDaoMapper

  • 哪个包下:这里我特意把包路径也截取了过来 对应手写数据源@MapperScan注解中的basePackages属性
package com.it.mhh.master.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.it.mhh.entity.StudentMaster;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface MasterDaoMapper extends BaseMapper<StudentMaster> {
    
}


测试:

  • 可以看到日期也添加进去了 我没有给日期赋值 表明上面的myBatisPlus自动填充策略生效
  • 通过@MapperScan注解扫描,可知是走的masterSqlSessionFactory此配置; masterSqlSessionFactory配置的MySql地址和表是localhost:3306/mhh_master
  • test方式测试结果:
    在这里插入图片描述

import com.it.mhh.entity.StudentMaster;
import com.it.mhh.master.controller.MasterController;
import com.it.mhh.utils.SnowFlake;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
public class MultipleDataSourcesApplicationTest {

    @Autowired
    private MasterController masterController; //主数据源
    

    @Autowired
    private SnowFlake snowFlake; //雪花算法

    @Test
    public void masterInsert() {
        Boolean aBoolean = masterController.insertMaster(new StudentMaster(snowFlake.nextId(), "小白", 12));
        System.out.println(aBoolean);
    }
}



1.9.2 Branch数据源测试

Controller层:MasterController


import com.it.mhh.branch.service.BranchService;
import com.it.mhh.entity.StudentBranch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("branch")
public class BranchController {
    @Autowired
    private BranchService branchService;

    @RequestMapping(value = "insertBranch")
    public Boolean insertBranch(@RequestBody StudentBranch studentBranch) {
        return  branchService.insertBranch(studentBranch);
    }
}

ServiceImpl层:MasterServiceImpl

MyBatis-Plus的通用service:实现类继承ServiceImpl<操作实体的Mapper接口,具体实体类>,最后添加注解@Service将该类作为Spring容器下的Bean。

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.it.mhh.branch.dao.BranchDaoMapper;
import com.it.mhh.branch.service.BranchService;
import com.it.mhh.entity.StudentBranch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BranchServiceImpl extends ServiceImpl<BranchDaoMapper, StudentBranch> implements BranchService {

 /*   @Autowired
    private BranchDaoMapper branchDaoMapper;*/

    public Boolean insertBranch(StudentBranch studentBranch) {
        return this.baseMapper.insert(studentBranch)>0?true:false;
    }
}



dao层:MasterDaoMapper

  • 哪个包下:这里我特意把包路径也截取了过来 对应手写数据源@MapperScan注解中的basePackages属性
package com.it.mhh.branch.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.it.mhh.entity.StudentBranch;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BranchDaoMapper extends BaseMapper<StudentBranch> {
}


测试:

  • 可以看到日期也添加进去了 我没有给日期赋值 表明上面的myBatisPlus自动填充策略生效
  • 通过@MapperScan注解扫描,可知是走的masterSqlSessionFactory此配置; masterSqlSessionFactory配置的MySql地址和表是localhost:3306/mhh_branch
  • test方式测试结果:
    在这里插入图片描述

import com.it.mhh.branch.controller.BranchController;
import com.it.mhh.entity.StudentBranch;
import com.it.mhh.utils.SnowFlake;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
public class MultipleDataSourcesApplicationTest {
    
    @Autowired
    private BranchController branchController; //分支数据源
    
    @Autowired
    private SnowFlake snowFlake; //雪花算法
  
    
    @Test
    public void branchInsaert(){
        Boolean aBoolean = branchController.insertBranch(new StudentBranch(snowFlake.nextId(), "小黑", "山东","小蓝"));
        System.out.println(aBoolean);//true
    }
}








链接:以 MyBatis-Plus 为框架 搭建最简易多数据源(不同包下走不同的数据源)祥例使用 源代码下载地址

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孟浩浩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值