最近研究了一下多数据源,这篇博客讲的是简单模式,下篇博客预计写自动切换模式
前期准备
本篇博客基于SpringBoot整合MyBatis-plus,如果有不懂这个的,
可以查看我的这篇博客:快速CRUD的秘诀之SpringBoot整合MyBatis-Plus
为了实现效果,先在本地的mysql库里面创建两个数据库:
然后在两个数据库里面,分别创建同样的users表,但是插入不同的数据,
mydb的数据:
mydb2的数据:
实现
1.在pom.xml
中引入多数据源的依赖dynamic-datasource-spring-boot-starter
:
<!-- 多数据切换所需依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
2.在application.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 # 写接口的包名
注意:
- 这里数据源的名字可以自定义,什么
master
、slave
都可以随意命名。 - 这里可以根据格式自行添加数据源的个数,并且支持多种数据库,如
oracle
、达梦
等。此处为了演示方便,都使用了mysql
数据库。
3.编写代码
3.1.在持久层中查找users
表的数据,并使用 @DS
注解,切换数据源:
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();
}
注意:
@DS
注解不止可以用在持久层,可以用在任意的类和方法上。@DS
注解作用在方法上的优先级 > 类。
也就是说可以在类上加一个@DS
注解默认一个该类的数据源,如 @DS("master")
,
再在具体的方法上加一个@DS
注解做个性化指定,如 @DS("slave")
,效果等同:
/**
* @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接口:
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实现类,并调用持久层接口,根据传入的参数切换不同的方法:
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.编写控制层代码:
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,则返回:
功能实现。
代码地址
本文代码已开源:
git clone https://gitee.com/guqueyue/my-blog-demo.git
请切换到gitee
分支,然后查看dynamicDataSourceSimple
模块即可!
参考
具体实现可以参考官方文档:多数据源
完结撒花!!!