SpringBoot整合MybatisPlus多数据源

2023年 9月 25日 48.4k 0

前言

随着业务的不断扩展和复杂度的增加,我们在开发过程中往往需要访问多个数据库。比如:我们可能需要同时访问主数据库和从数据库,或者访问多个独立的数据库来处理不同的业务逻辑。这时候,我们就需要使用多数据源来实现对多个数据库的操作。

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

image.png
user表结构

image.png

从数据库test1

image.png
class_info表结构

image.png

创建各自的实体类

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 来进行区分,我们在各自的接口实现类上添加注解

image.png

image.png

编写测试类进行测试

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---");
    }

}

执行测试类

image.png

查看数据库数据

image.png

image.png
两个数据库的两张表的数据都已经被成功插入。

至此,SpringBoot整合Mybatis-Plus多数据源结束了。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论