springboot配置多数据源的一款框架(dynamic

网友投稿 687 2022-09-28


springboot配置多数据源的一款框架(dynamic

目录前言框架简介基本使用 框架说明与 springboot 的整合数据准备引入依赖springboot 配置文件启动类实体类service 层controller 层测试

前言

前篇博客介绍了用基本的方式做多数据源,可以应对一般的情况,但是遇到一些复杂的情况就需要扩展下功能了,比如:动态增减数据源、数据源分组,纯粹多库,读写分离一主多从,从其他数据库或者配置中心读取数据源等等。其实就算没有这些需求,使用此款框架实现多数据源也比之前要便捷,快速的多

框架简介

dynamic-datasource-spring-boot-starter 是一个基于 springboot 的快速集成多数据源的启动器

文档:https://github.com/baomidou/dynamic-datasource-spring-boot-starter

文档:https://gitee.com/baomidou/FkjIwACRdynamic-datasource-spring-boot-starter

它跟 mybatis-plus 是一个生态圈里的,都是由苞米豆团队出品,很容易集成 mybatis-plus

基本使用

框架说明

本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何 CRUD

配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下

切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换

默认的数据源名称为 master ,你可以通过 spring.datasource.dynamic.primary 修改

方法上的注解优先于类上注解

DS 支持继承抽象类上的 DS,暂不支持继承接口上的 DS

与 springboot 的整合

数据准备

springboot 版本:2.0.6.RELEASE

mysql 版本:5.7

分别创建数据库 test1,test2,数据库表均为 goods,数据不相同

CREATE TABLE `goods` (

`goodsId` bigint(11) unsigned NOT http://NULL AUTO_INCREMENT COMMENT 'id',

`goodsName` varchar(500) NOT NULL DEFAULT '' COMMENT 'name',

`subject` varchar(200) NOT NULL DEFAULT '' COMMENT '标题',

`price` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '价格',

`stock` int(11) NOT NULL DEFAULT '0' COMMENT 'stock',

PRIMARY KEY (`goodsId`)

) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='商品表';

test1 数据库数据如下

test2 数据库数据如下

引入依赖

至于其他依赖,不再赘述

com.baomidou

dynamic-datasource-spring-boot-starter

3.3.2

springboot 配置文件

配置文件详情可以参考官方文档

server.port=8080

#设置test1为主数据源

spring.datasource.dynamic.primary=master

#test1主数据源配置

spring.datasource.dynamic.datasource.master.url=jdbc:mysql://127.0.0.1:3306/test1?characterEncoding=utf8&useSSL=false&autoReconnect=true&serverTimezone=UTC

spring.datasource.dynamic.datasource.master.username=root

spring.datasource.dynamic.datasource.master.password=123456

spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.dynamic.datasource.master.type=com.alibaba.druid.pool.DruidDataSource

#druid连接池配置

spring.datasource.dynamic.datasource.master.druid.initial-size=5

spring.datasource.dynamic.datasource.master.druid.max-active=20

spring.datasource.dynamic.datasource.master.druid.min-idle=5

spring.datasource.dynamic.datasource.master.druid.max-wait=60000

#test2从数据源配置

spring.datasource.dynamic.datasource.slave.url=jdbc:mysql://127.0.0.1:3306/test2?characterEncoding=utf8&useSSL=false&autoReconnect=true&serverTimezone=UTC

spring.datasource.dynamic.datasource.slave.username=root

spring.datasource.dynamic.datasource.slave.password=123456

spring.datasource.dynamic.datasource.slave.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.dynamic.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource

#druid连接池配置

spring.datasource.dynamic.datasource.slave.druid.initial-size=5

spring.datasource.dynamic.datasource.slave.druid.max-active=20

spring.datasource.dynamic.datasource.slave.druid.min-idle=5

spring.datasource.dynamic.datasource.slave.druid.max-wait=60000

#mybatis配置

mybatis.mapper-locations=classpath:org/example/mapper/*.xml

mybatis.configuration.cache-enabled=true

#开启驼峰命名

mybatis.configuration.map-underscore-to-camel-case=true

#打印SQL

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

启动类

需要排除掉 DruidDataSourceAutoConfigure 类,不然启动会报错找不到配置的 url

@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)

@Slf4j

public class App {

public static void main(String[] args) {

SpringApplication.run(App.class, args);

log.info("------springboot running-----");

}

}

实体类

@Data

@ApiModel

public class Goods implements Serializable {

@ApiModelProperty(value = "商品id")

private Long goodsid;

@ApiModelProperty(value = "商品名称")

@NotBlank(message = "商品名称不能为空")

private String goodsname;

@ApiModelProperty(value = "商品描述")

@NotBlank(message = "商品描述不能为空")

private String subject;

@ApiModelProperty(value = "商品价格")

@NotNull(message = "商品价格不能为空")

private BigDecimal price;

@ApiModelProperty(value = "商品库存", example = "0")

@NotNull(message = "商品库存不能为空")

private Integer stock;

}

service 层

至于 dao 层,使用的是 mybatis-generator 插件自动生成

@Service

public class GoodServiceImpl implements GoodService {

@Autowired

private GoodsMapper goodsMapper;

@Override

public Goods selectOneGoods(Long goodsid) {

return goodsMapper.selectByPrimaryKey(goodsid);

}

@Override

public int addGoods(Goods goods) {

return goodsMapper.insertSelective(goods);

}

}

controller 层

@Controller

@RequestMapping(path = "/goods")

@Api(tags = "商品管理相关接口")

@Slf4j

public class GoodsController {

@Autowired

private GoodService goodService;

@GetMapping(path = "/selectOne")

@ResponseBody

@ApiOperation(value = "查询商品接口")

@ApiImplicitParam(name = "id", value = "商品id", required = true)

public ResultMap selectOne(@RequestParam(name = "id", defaultValue = "3") Long goodsid) {

Goods goods = goodService.selectOneGoods(goodsid);

log.info("查询到的商品数据:" + goods.toString());

if (StringUtils.isEmpty(goods)) {

return new ResultMap().fail().message("查询失败,没有您要的数据");

}

return new ResultMap().success().message("查询成功").data(goods);

}

@PostMapping(path = "/addGoods")

@ResponseBody

@ApiOperation(value = "添加商品的接口")

public ResultMap addGoods(@Valid Goods goods, @NotNull BindingResult bindingResult) {

if (bindingResult.hasErrors()){

String defaultMessage = Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();

return new ResultMap().fail().message(defaultMessage);

}

int i = goodService.addGoods(goods);

if (i > 0) {

return new ResultMap().success().message("添加成功");

}

return new ResultMap().fail().message("添加失败");

}

}

测试

service 层方法上都没有注解 @DS

使用 postman 测试第一个接口

使用 postman 测试第二个接口

以上两个接口测试说明:它们都默认操作的是主数据源 test1,证明我们配置文件中配置的主数据源 test1 是配置正确的,已经生效

service 层方法上加上注解 @DS 再测试

@Service

public class GoodServiceImpl implements GoodService {

@Autowired

private GoodsMapper goodsMapper;

@DS(value = "slave")// 切换数据源,并指定要访问的数据库名称

@Override

public Goods selectOneGoods(Long goodsid) {

return goodsMapper.selectByPrimaryKey(goodsid);

}

@Override

public int addGoods(Goods goods) {

return goodsMapper.insertSelective(goods);

}

}

使用 postman 测试第一个接口

此时 @DS 注解已生效,发生了数据源的动态切换

使用 postman 测试第二个接口

由于该接口没有 @DS 注解,所以没有发生数据源的切换,依然操作的是 test1 默认数据源

@DS 注解说明

注解

结果

没有@DS

默认数据源

@DS("dsName")

dsName可以为组名也可以为具体某个库的名称

@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解

@DS 官方建议使用在 service 层的方法上

该框架更详细的分析:https://jb51.net/article/222550.htm

项目源码:https://gitee.com/chaojiangcj/springboot-dynamic-datasource


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:防火墙基础之客户端防护(防火墙使用)
下一篇:域名被劫持了怎么办(域名被劫持是什么原因)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~