springboot配置多數據源的一款框架(dynamic-datasource-spring-boot-starter)
前言
前篇博客介紹瞭用基本的方式做多數據源,可以應對一般的情況,但是遇到一些復雜的情況就需要擴展下功能瞭,比如:動態增減數據源、數據源分組,純粹多庫,讀寫分離一主多從,從其他數據庫或者配置中心讀取數據源等等。其實就算沒有這些需求,使用此款框架實現多數據源也比之前要便捷,快速的多
框架簡介
dynamic-datasource-spring-boot-starter
是一個基於 springboot
的快速集成多數據源的啟動器
文檔:https://github.com/baomidou/dynamic-datasource-spring-boot-starter
文檔:https://gitee.com/baomidou/dynamic-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 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
數據庫數據如下
引入依賴
至於其他依賴,不再贅述
<dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.3.2</version> </dependency>
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://www.jb51.net/article/222550.htm
項目源碼:https://gitee.com/chaojiangcj/springboot-dynamic-datasource
到此這篇關於springboot配置多數據源的一款框架的文章就介紹到這瞭,更多相關springboot多數據源配置內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- MyBatis-Plus 集成動態多數據源的實現示例
- SpringBoot項目中如何實現MySQL讀寫分離詳解
- 利用SpringBoot實現多數據源的兩種方式總結
- SpringBoot詳解如何實現讀寫分離
- Spring Boot監控SQL運行情況的全過程