SpringBoot整合MybatisPlus多数据源
前言
随着业务的不断扩展和复杂度的增加,我们在开发过程中往往需要访问多个数据库。比如:我们可能需要同时访问主数据库和从数据库,或者访问多个独立的数据库来处理不同的业务逻辑。这时候,我们就需要使用多数据源来实现对多个数据库的操作。
SpringBoot整合Mybatis-plus
在之前的文章SpringBoot整合MyBatis-Plus已经详细介绍过,本文就不在多做介绍了。
进行整合
引入pom依赖
com.alibaba druid-spring-boot-starter 1.2.19 com.baomidou mybatis-plus-generator 3.5.3.2 com.baomidou dynamic-datasource-spring-boot-starter 4.1.3
yml文件配置
spring: application: name: springboot-demo #配置数据库信息 datasource: dynamic: primary: master strict: false datasource: master: url: jdbc:mysql://ip:3306/test?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false&useAffectedRows=true&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: 账号 password: 密码 slave1: url: jdbc:mysql://ip:3306/test1?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false&useAffectedRows=true&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: 账号 password: 密码 type: com.alibaba.druid.pool.DruidDataSource #配置mybatis-plus信息 mybatis-plus: configuration: #日志 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #驼峰形式显示 map-underscore-to-camel-case: true mapper-locations: classpath:mybatis-mapper/*.xml global-config: db-config: #全局逻辑删除的实体字段名 logic-delete-field: isDeleted #逻辑已删除值(默认为1) logic-delete-value: 1 #逻辑未删除值(默认为0) logic-not-delete-value: 0
创建两个数据库及创建表
主数据库test
user表结构
从数据库test1
class_info表结构
创建各自的实体类
package com.example.springbootdemo.entity; import com.baomidou.mybatisplus.annotation.*; import com.example.springbootdemo.enums.GenderEnum; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; import java.time.LocalDateTime; /** * * 用户实体类 * * * @author yurenwei * @since 2023/9/7 */ @ApiModel(value = "用户参数", description = "用户参数") @Data @Accessors(chain = true) @TableName("user") public class User implements Serializable { private static final long serialVersionUID = 1L; /** * 主键id */ @ApiModelProperty(value = "主键id") @TableId(value = "id", type = IdType.ASSIGN_ID) private Long id; /** * 姓名 */ @ApiModelProperty(value = "姓名") private String userName; /** * 手机号 */ @ApiModelProperty(value = "手机号") private String phone; /** * 性别 */ @ApiModelProperty(value = "性别") private GenderEnum gender; /** * 地址 */ @ApiModelProperty(value = "地址") private String address; /** * 状态(0、禁用1、启用) */ @ApiModelProperty(value = "状态(0、禁用1、启用)") private Boolean status; /** * 注册时间 */ @ApiModelProperty(value = "注册时间") @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime registerTime; /** * 创建人 */ @ApiModelProperty(value = "创建人") private Long createBy; /** * 创建时间 */ @ApiModelProperty(value = "创建时间") @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; /** * 修改人 */ @ApiModelProperty(value = "修改人") private Long updateBy; /** * 修改时间 */ @ApiModelProperty(value = "修改时间") @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; /** * 是否删除(0、否1、是) */ @ApiModelProperty(value = "是否删除(0、否1、是)") private Boolean isDeleted; }
package com.example.springbootdemo.entity; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; import java.time.LocalDateTime; /** * * 班级实体类 * * * @author yurenwei * @since 2023/9/25 */ @ApiModel(value = "班级参数", description = "班级参数") @Data @Accessors(chain = true) @TableName("class_info") public class ClassInfo implements Serializable { private static final long serialVersionUID = 1L; /** * 主键id */ @ApiModelProperty(value = "主键id") @TableId(value = "id", type = IdType.ASSIGN_ID) private Long id; /** * 班级名称 */ @ApiModelProperty(value = "班级名称") private String className; /** * 创建人 */ @ApiModelProperty(value = "创建人") private Long createBy; /** * 创建时间 */ @ApiModelProperty(value = "创建时间") @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; /** * 修改人 */ @ApiModelProperty(value = "修改人") private Long updateBy; /** * 修改时间 */ @ApiModelProperty(value = "修改时间") @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; /** * 是否删除(0、否1、是) */ @ApiModelProperty(value = "是否删除(0、否1、是)") private Boolean isDeleted; }
创建各自mapper
package com.example.springbootdemo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.springbootdemo.entity.User; import org.springframework.stereotype.Repository; /** * * 用户mapper * * * @author yurenwei * @since 2023/9/7 */ @Repository public interface UserMapper extends BaseMapper { }
package com.example.springbootdemo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.springbootdemo.entity.ClassInfo; import org.springframework.stereotype.Repository; /** * * 班级mapper * * * @author yurenwei * @since 2023/9/25 */ @Repository public interface ClassInfoMapper extends BaseMapper { }
创建各自接口
package com.example.springbootdemo.mybatisplus; import com.baomidou.mybatisplus.extension.service.IService; import com.example.springbootdemo.entity.User; /** * * 用户接口 * * * @author yurenwei * @since 2023/9/7 */ public interface IUserService extends IService { }
package com.example.springbootdemo.mybatisplus; import com.baomidou.mybatisplus.extension.service.IService; import com.example.springbootdemo.entity.ClassInfo; /** * * 班级接口机 * * * @author yurenwei * @since 2023/9/25 */ public interface IClassInfoService extends IService { }
创建各自接口实现类
package com.example.springbootdemo.mybatisplus.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.springbootdemo.entity.User; import com.example.springbootdemo.mapper.UserMapper; import com.example.springbootdemo.mybatisplus.IUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; /** * * 用户接口实现类 * * * @author yurenwei * @since 2023/9/7 */ @Slf4j @Service public class UserServiceImpl extends ServiceImpl implements IUserService { }
package com.example.springbootdemo.mybatisplus.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.springbootdemo.entity.ClassInfo; import com.example.springbootdemo.mapper.ClassInfoMapper; import com.example.springbootdemo.mybatisplus.IClassInfoService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; /** * * 班级接口实现类 * * * @author yurenwei * @since 2023/9/25 */ @Slf4j @Service public class ClassInfoServiceImpl extends ServiceImpl implements IClassInfoService { }
怎么区分主从数据库呢
user表是在我们的主数据库master里,class_info表是在我们从数据库slave里,那么我们在开发的时候如何区分他们呢?
这就需要我们使用一个注解@DS 来进行区分,我们在各自的接口实现类上添加注解
编写测试类进行测试
package com.example.springbootdemo; import cn.hutool.core.util.IdUtil; import com.example.springbootdemo.entity.ClassInfo; import com.example.springbootdemo.entity.User; import com.example.springbootdemo.enums.GenderEnum; import com.example.springbootdemo.mybatisplus.IClassInfoService; import com.example.springbootdemo.mybatisplus.IUserService; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.time.LocalDateTime; @Slf4j @SpringBootTest public class SpringbootDemoApplicationTests { @Autowired private IUserService iUserService; @Autowired private IClassInfoService iClassInfoService; /** * 测试动态数据源 */ @Test public void testDynamicDatasource(){ User user = new User() .setId(IdUtil.getSnowflakeNextId()) .setUserName("测试") .setPhone("13000000000") .setGender(GenderEnum.MALE) .setAddress("山东") .setStatus(true) .setRegisterTime(LocalDateTime.now()); iUserService.save(user); ClassInfo c = new ClassInfo() .setId(IdUtil.getSnowflakeNextId()) .setClassName("三年一班"); iClassInfoService.save(c); log.info("---over---"); } }
执行测试类
查看数据库数据
两个数据库的两张表的数据都已经被成功插入。
至此,SpringBoot整合Mybatis-Plus多数据源结束了。