Mybatis-Plus多数据源插件 源码地址
前言
dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。
其支持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.x.x。
特性
- 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
- 支持数据库敏感配置信息 加密 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事务混用。
准备数据库
如下图所示, 我这边有名为cloud_order ,cloud_user两个数据库,并且创建了相同表结构的表
cloud_order.dynamic 数据
cloud_user.dynamic 数据
SpringBoot整合Mp
1、创建工程
2、添加依赖
这里springboot使用2.6.3版本, mp使用3.5.1
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.6.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>Mp-Dynamic-datasource-SpringBoot2.6.x</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- MyBatis-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.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
3、配置文件
server:
port: 8081
application:
name: dynamic-datasource
datasource:
dynamic:
primary: order
datasource:
order:
url: jdbc:mysql://127.0.0.1:3306/cloud_order?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
user:
url: jdbc:mysql://127.0.0.1:3306/cloud_user?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# mybatis-plus相关配置
mybatis-plus:
# xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
mapper-locations: classpath:mapper/*/*.xml
# 以下配置均有默认值,可以不设置
global-config:
db-config:
#主键类型 auto:"数据库ID自增" 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: auto
#字段策略 IGNORED:"忽略判断" NOT_NULL:"非 NULL 判断") NOT_EMPTY:"非空判断"
field-strategy: NOT_EMPTY
#数据库类型
db-type: MYSQL
configuration:
# 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
map-underscore-to-camel-case: true
# 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
call-setters-on-nulls: true
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4、生成代码
entity
package top.fate.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* @author fate急速出击
* @since 2022-06-08
*/
@Getter
@Setter
public class Dynamic implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String context;
}
mapper
package top.fate.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import top.fate.entity.Dynamic;
/**
* <p>
* Mapper 接口
* </p>
*
* @author fate急速出击
* @since 2022-06-08
*/
public interface DynamicMapper extends BaseMapper<Dynamic> {
}
DynamicMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.fate.mapper.DynamicMapper">
</mapper>
service
package top.fate.service;
import com.baomidou.mybatisplus.extension.service.IService;
import top.fate.entity.Dynamic;
/**
* <p>
* 服务类
* </p>
*
* @author fate急速出击
* @since 2022-06-08
*/
public interface IDynamicService extends IService<Dynamic> {
}
serviceimpl
package top.fate.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import top.fate.entity.Dynamic;
import top.fate.mapper.DynamicMapper;
import top.fate.service.IDynamicService;
/**
* <p>
* 服务实现类
* </p>
*
* @author fate急速出击
* @since 2022-06-08
*/
@Service
public class DynamicServiceImpl extends ServiceImpl<DynamicMapper, Dynamic> implements IDynamicService {
}
测试
这里我为了偷懒直接在controller切数据源了, 不建议学习这里我图快
package top.fate.controller;
import com.baomidou.dynamic.datasource.annotation.DS;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.fate.entity.Dynamic;
import top.fate.service.IDynamicService;
import java.util.List;
/**
* 控制器
*
* @author fate急速出击
* @since 2022-06-08
*/
@RestController
@AllArgsConstructor
@RequestMapping("/dynamic")
public class DynamicController {
private IDynamicService dynamicService;
@DS("user")
@GetMapping("list1")
public List<Dynamic> list1(){
return dynamicService.list();
}
@DS("order")
@GetMapping("list2")
public List<Dynamic> list2(){
return dynamicService.list();
}
}
写在最后
原创不易 ,请大家留个赞再走吧 !