SpringBoot快速集成多数据源(自动版)

有些人因为看见所以相信,有些人因为相信所以看见

有目录,不迷路

最近研究了一下多数据源,这篇博客讲的是简单模式,下篇博客预计写自动切换模式

前期准备

本篇博客基于SpringBoot整合MyBatis-plus,如果有不懂这个的,

可以查看我的这篇博客:快速CRUD的秘诀之SpringBoot整合MyBatis-Plus

为了实现效果,先在本地的mysql库里面创建两个数据库:

然后在两个数据库里面,分别创建同样的users表,但是插入不同的数据,

mydb的数据:

mydb2的数据:

实现

1.在pom.xml中引入多数据源的依赖dynamic-datasource-spring-boot-starter

xml 复制代码
<!-- 多数据切换所需依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

2.在application.yml配置文件中配置多数据源:

yml 复制代码
sever:
  # 端口
  port: 8080

# 配置数据源
spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          # 数据库路径jdbc:mysql://localhost:3306/mydb 的缩写,并配置时区
          url: jdbc:mysql:///mydb?serverTimezone=GMT%2B8
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
        slave:
          url: jdbc:mysql:///mydb2?serverTimezone=GMT%2B8
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver

# 打印MyBatis SQL 日志
logging:
  level:
    com.guqueyue.test.dao: debug # 写接口的包名

注意:

  1. 这里数据源的名字可以自定义,什么masterslave都可以随意命名。
  2. 这里可以根据格式自行添加数据源的个数,并且支持多种数据库,如oracle达梦等。此处为了演示方便,都使用了mysql数据库。

3.编写代码

3.1.在持久层中查找users表的数据,并使用 @DS注解,切换数据源:

java 复制代码
package com.guqueyue.test.dao;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.guqueyue.test.entity.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @Author: guqueyue
 * @Description: 映射接口UserMapper
 * @Date: 2023/12/19
 **/
public interface UserMapper extends BaseMapper<User> {

    @DS("master") // 默认为主数据源,其实可以省略
    @Select("select * from users")
    List<User> selectUserList();

    @DS("slave") // 切换为slave数据源
    @Select("select * from users")
    List<User> selectUserListBySlave();

}

注意:

  1. @DS注解不止可以用在持久层,可以用在任意的类和方法上。
  2. @DS注解作用在方法上的优先级 > 类。

也就是说可以在类上加一个@DS注解默认一个该类的数据源,如 @DS("master")

再在具体的方法上加一个@DS注解做个性化指定,如 @DS("slave"),效果等同:

java 复制代码
/**
 * @Author: guqueyue
 * @Description: 映射接口UserMapper
 * @Date: 2023/12/19
 **/
@DS("master") // 默认为主数据源,其实可以省略
public interface UserMapper extends BaseMapper<User> {
    
    @Select("select * from users")
    List<User> selectUserList();

    @DS("slave") // 切换为slave数据源
    @Select("select * from users")
    List<User> selectUserListBySlave();

}

3.2.创建service接口:

java 复制代码
package com.guqueyue.test.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.guqueyue.test.entity.User;

import java.util.List;

/**
 * @Author: guqueyue
 * @Description: 用户service接口
 * @Date: 2023/12/19
 **/
public interface IUserService extends IService<User> {

    List<User> selectUserList(String type);
}

3.3.创建service实现类,并调用持久层接口,根据传入的参数切换不同的方法:

java 复制代码
package com.guqueyue.test.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guqueyue.test.dao.UserMapper;
import com.guqueyue.test.entity.User;
import com.guqueyue.test.service.IUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Author: guqueyue
 * @Description: 用户实现类
 * @Date: 2023/12/19
 **/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public List<User> selectUserList(String type) {

		 // do something: 此处可根据实际情况进行业务选择,如根据当前登录的用户信息来选择不同的数据库
        // 此处为了方便演示,直接用前端传入的type来判断

        return "slave".equals(type) ? userMapper.selectUserListBySlave()
                                    : userMapper.selectUserList();
    }
}

3.4.编写控制层代码:

java 复制代码
package com.guqueyue.test.controller;

import com.guqueyue.test.entity.User;
import com.guqueyue.test.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @Author: guqueyue
 * @Description: 用户控制层
 * @Date: 2023/12/19
 **/
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    /**
     * 查询用户列表
     * @return
     */
    @RequestMapping("/list")
    public List<User> userList(String type) {
        System.out.println("接收到的数据源类型为:" + type);

        return userService.selectUserList(type);
    }
}

演示

代码编写好了,我们就可以启动项目了:

控制台显示项目启动成功后,

在浏览器输入:http://localhost:8080/user/list?type=master,返回:

在浏览器输入:http://localhost:8080/user/list?type=slave,则返回:

功能实现。

参考

具体实现可以参考官方文档:多数据源

完结撒花!!!

相关推荐
ok!ko1 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
2401_857622661 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589361 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰2 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
哎呦没3 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch3 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
编程、小哥哥3 小时前
netty之Netty与SpringBoot整合
java·spring boot·spring
IT学长编程4 小时前
计算机毕业设计 玩具租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·玩具租赁系统
莹雨潇潇4 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
杨哥带你写代码4 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端