MyBatisPlus之多数据源
MyBatisPlus之多数据源
- 1.0 MyBatisPlus之多数据源
- 1.创建数据库及表
- 2.0 添加测试数据
- 3.0 删除mybatis_plus库中的product表
- 2.0 新建工程引入依赖
- 1.新建工程引入依赖
- 2.数据库代码
- 2.0 MyBatisPlus之多数据源代码
- 2.1 创建配置类
- 2.2 创建实体类
- 2.3 创建Mapper
- 2.4 创建Service及其ServiceImpl
- 2.5 启动类修改
- 2.6 测试多数据源
- 3.0 知识点扩展
- 特性
- 约定
- 使用方法`在这里插入代码片`
- 3.使用 @DS 切换数据源
文章顺序及整体目录可查看(点我即可)
1.0 MyBatisPlus之多数据源
适用于多种场景:纯粹多库、 读写分离、 一主多从、 混合模式等
场景说明:
我们创建两个库,分别为:mybatis_plus(以前的库不动)与mybatis_plus_1(新建),将mybatis_plus库的product表移动到mybatis_plus_1库,这样每个库一张表,通过一个测试用例分别获取用户数据与商品数据,如果获取到说明多库模拟成功
1.创建数据库及表
创建数据库mybatis_plus_1和表`product
CREATE DATABASE `mybatis_plus_1` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
use `mybatis_plus_1`;
CREATE TABLE product (
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',
price INT(11) DEFAULT 0 COMMENT '价格',
version INT(11) DEFAULT 0 COMMENT '乐观锁版本号',
PRIMARY KEY (id)
);
2.0 添加测试数据
INSERT INTO product (id, NAME, price) VALUES (1, '外星人笔记本', 100);
3.0 删除mybatis_plus库中的product表
use mybatis_plus;
DROP TABLE IF EXISTS product;
2.0 新建工程引入依赖
自行新建一个Spring Boot工程并选择MySQL驱动及Lombok依赖
1.新建工程引入依赖
自行新建一个Spring Boot工程并选择MySQL驱动及Lombok依赖
引入MyBaits-Plus的依赖及多数据源的依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
本人全部pom;
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>mybatisplus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatisplus</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.baomidou</groupId>-->
<!-- <artifactId>mybatis-plus-boot-starter</artifactId>-->
<!-- <version>3.3.1</version>-->
<!-- </dependency>-->
<!-- mybatis-plus核心包-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!-- mybatis-plus代码生成核心包 最低3.5.1-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<!-- freemarker我们实现的功能使用的freemarker引擎代码-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
<!-- 多数据源中使用的注解-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!--防止打war包出错-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
代码层次展示:
2.数据库代码
mybatis_plus_1
CREATE DATABASE `mybatis_plus_1` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
use `mybatis_plus_1`;
CREATE TABLE product (
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',
price INT(11) DEFAULT 0 COMMENT '价格',
version INT(11) DEFAULT 0 COMMENT '乐观锁版本号',
PRIMARY KEY (id)
);
INSERT INTO product (id, NAME, price) VALUES (1, '外星人笔记本', 100);
mybatis_plus
CREATE DATABASE `mybatis_plus` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
/*
Navicat Premium Data Transfer
Source Server : 本地mysql
Source Server Type : MySQL
Source Server Version : 50736
Source Host : localhost:3306
Source Schema : mybatis_plus
Target Server Type : MySQL
Target Server Version : 50736
File Encoding : 65001
Date: 16/10/2022 20:57:58
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`uid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
`age` int(11) NULL DEFAULT NULL COMMENT '年龄',
`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
`is_delect` int(255) NULL DEFAULT 0 COMMENT '是否删除',
`sex` int(255) NULL DEFAULT NULL COMMENT '性别',
PRIMARY KEY (`uid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'Jone', 18, 'test1@baomidou.com', 1, NULL);
INSERT INTO `t_user` VALUES (2, 'Jack', 20, 'test2@baomidou.com', 1, NULL);
INSERT INTO `t_user` VALUES (4, '我是老王', 18, 'test4@baomidou.com', 0, NULL);
INSERT INTO `t_user` VALUES (5, 'Billie', 10, 'test5@baomidou.com', 0, NULL);
INSERT INTO `t_user` VALUES (6, '老王', 10, '757631644001', 0, NULL);
INSERT INTO `t_user` VALUES (7, '老王超1', 10, '757631644111', 0, NULL);
INSERT INTO `t_user` VALUES (8, '闫文超2', 10, '757631644221', 0, NULL);
INSERT INTO `t_user` VALUES (9, '闫文超3', 10, '757631644331', 0, NULL);
INSERT INTO `t_user` VALUES (10, '闫文超4', 14, '757631644441', 0, NULL);
INSERT INTO `t_user` VALUES (11, '闫文超5', 15, '757631644771', 1, NULL);
INSERT INTO `t_user` VALUES (12, '闫文超6', 16, '757631644661', 0, NULL);
INSERT INTO `t_user` VALUES (13, '闫文超7', 17, '757631644771', 1, NULL);
INSERT INTO `t_user` VALUES (14, '我很心烦', 888, '757631644@qq.com', 0, NULL);
INSERT INTO `t_user` VALUES (15, '我很心烦', 888, '757631644@qq.com', 0, NULL);
INSERT INTO `t_user` VALUES (16, 'admin', 33, NULL, 0, 1);
SET FOREIGN_KEY_CHECKS = 1;
2.0 MyBatisPlus之多数据源代码
2.1 创建配置类
application.yml
spring:
# 配置数据源信息
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: master
# 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
# primary: master 指定的master 就是下面的这个 也就是他就是默认的数据源
master:
url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
slave_1:
url: jdbc:mysql://localhost:3306/mybatis_plus_1?characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
2.2 创建实体类
- Product
package com.example.mybatisplus.pojo;
import lombok.Data;
@Data
public class Product {
//默认字段id 即不需要指定
private Long id;
private String name;
private Integer price;
private Integer version;
}
- User
package com.example.mybatisplus.pojo;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
//指定数据库的表 操作和实际不一样用该注解
@TableName("t_user")
public class User {
// 指定默认的自增id
@TableId
private Long uid;
private String userName;
private Integer age;
private String email;
private Integer isDelect;
private Integer sex;
}
2.3 创建Mapper
- ProductMapper
在这里插入代码片
package com.example.mybatisplus.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mybatisplus.pojo.Product;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductMapper extends BaseMapper<Product> {
}
- UserMapper
package com.example.mybatisplus.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mybatisplus.pojo.User;
import org.springframework.stereotype.Repository;
//防止测试报错故加次注解
@Repository
public interface UserMapper extends BaseMapper<User> {
}
2.4 创建Service及其ServiceImpl
- ProductService
package com.example.mybatisplus.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mybatisplus.pojo.Product;
public interface ProductService extends IService<Product> {
}
- ProductServiceImpl
package com.example.mybatisplus.service.Impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mybatisplus.mapper.ProductMapper;
import com.example.mybatisplus.pojo.Product;
import com.example.mybatisplus.service.ProductService;
import org.springframework.stereotype.Service;
@DS("slave_1")
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
}
- UserService
package com.example.mybatisplus.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mybatisplus.pojo.User;
public interface UserService extends IService<User> {
}
- UserServiceImpl
package com.example.mybatisplus.service.Impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mybatisplus.mapper.UserMapper;
import com.example.mybatisplus.pojo.User;
import com.example.mybatisplus.service.UserService;
import org.springframework.stereotype.Service;
//指定数据库表(多数据源中) 对应 yml 中 master 对应的数据库
@DS("master")
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
2.5 启动类修改
MybatisPlusDatasourceApplication指定mapper
package com.example.mybatisplus;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.mybatisplus.mapper")
public class MybatisPlusDatasourceApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusDatasourceApplication.class, args);
}
}
2.6 测试多数据源
新建测试类进行测试;
package com.example.mybatisplus;
import com.example.mybatisplus.pojo.Product;
import com.example.mybatisplus.pojo.User;
import com.example.mybatisplus.service.ProductService;
import com.example.mybatisplus.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
class MybatisPlusDatasourceApplicationTests {
@Resource
UserService userService;
@Resource
ProductService productService;
@Test
void contextLoads() {
User user = userService.getById(1L);
Product product = productService.getById(1L);
System.out.println("User = " + user);
System.out.println("Product = " + product);
}
}
查询成功说明我们的测试成功;
3.0 知识点扩展
简介
dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。
官方文档:https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611
特性
- 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
- 支持数据库敏感配置信息 加密 ENC()。
- 支持每个数据库独立初始化表结构schema和数据库database。
- 支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。
- 支持 自定义注解 ,需继承DS(3.2.0+)。
- 提供并简化对Druid,HikariCp,BeeCp,Dbcp2的快速集成。
- 提供对Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等组件的集成方案。
- 提供 自定义数据源来源 方案(如全从数据库加载)。
- 提供项目启动后 动态增加移除数据源 方案。
- 提供Mybatis环境下的 纯读写分离 方案。
- 提供使用 spel动态参数 解析数据源方案。内置spel,session,header,支持自定义。
- 支持 多层数据源嵌套切换 。(ServiceA >>> ServiceB >>> ServiceC)。
- 提供 基于seata的分布式事务方案。
- 提供 本地多数据源事务方案。 附:不能和原生spring事务混用。
约定
1.本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
2.配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下。
3.切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换。
4.默认的数据源名称为 master ,你可以通过 spring.datasource.dynamic.primary 修改。
5.方法上的注解优先于类上注解。
6.DS支持继承抽象类上的DS,暂不支持继承接口上的DS。
使用方法在这里插入代码片
1.引入dynamic-datasource-spring-boot-starter。
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${version}</version>
</dependency>
2.配置数据源。
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
slave_1:
url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
slave_2:
url: ENC(xxxxx) # 内置加密,使用请查看详细文档
username: ENC(xxxxx)
password: ENC(xxxxx)
driver-class-name: com.mysql.jdbc.Driver
#......省略
#以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
# 多主多从 纯粹多库(记得设置primary) 混合配置
spring: spring: spring:
datasource: datasource: datasource:
dynamic: dynamic: dynamic:
datasource: datasource: datasource:
master_1: mysql: master:
master_2: oracle: slave_1:
slave_1: sqlserver: slave_2:
slave_2: postgresql: oracle_1:
slave_3: h2: oracle_2:
3.使用 @DS 切换数据源
@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。
注解 | 结果 |
---|---|
没有@DS | 默认数据源 |
@DS(“dsName”) | dsName可以为组名也可以为具体某个库的名称 |
@Service
@DS("slave")
public class UserServiceImpl implements UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List selectAll() {
return jdbcTemplate.queryForList("select * from user");
}
@Override
@DS("slave_1")
public List selectByCondition() {
return jdbcTemplate.queryForList("select * from user where age >10");
}
}
部分应用官方文档知识点进行扩展;