编辑
2024-11-14
实用工具
00

随着项目规模的扩大,单一数据源已无法满足复杂业务需求,多数据源(动态数据源)应运而生。本文将介绍两种 MyBatis-Plus 的多数据源扩展插件:开源生态的 dynamic-datasource 和 企业级生态的 mybatis-mate。

dynamic-datasource

dynamic-datasource 是一个开源的 Spring Boot 多数据源启动器,提供了丰富的功能,包括数据源分组、敏感信息加密、独立初始化表结构等。

特性

数据源分组:适用于多种场景,如读写分离、一主多从等。 敏感信息加密:使用 ENC() 加密数据库配置信息。 独立初始化:支持每个数据库独立初始化表结构和数据库。 自定义注解:支持自定义注解,需继承 DS。 简化集成:提供对 Druid、HikariCP 等连接池的快速集成。 组件集成:支持 Mybatis-Plus、Quartz 等组件的集成方案。 动态数据源:支持项目启动后动态增加或移除数据源。 分布式事务:提供基于 Seata 的分布式事务方案。

约定

本框架专注于数据源切换,不限制具体操作。 配置文件中以下划线 _ 分割的数据源首部为组名。 切换数据源可以是组名或具体数据源名。 默认数据源名为 master,可通过 spring.datasource.dynamic.primary 修改。 方法上的注解优先于类上的注解。

编辑
2024-11-14
实用工具
00

MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。

在 MyBatis-Plus 中,Wrapper 类是构建查询和更新条件的核心工具。以下是主要的 Wrapper 类及其功能:

  • AbstractWrapper:这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。它定义了条件构造的基本逻辑,包括字段(column)、值(value)、操作符(condition)等。所有的 QueryWrapper、UpdateWrapper、LambdaQueryWrapper 和 LambdaUpdateWrapper 都继承自 AbstractWrapper。

  • QueryWrapper:专门用于构造查询条件,支持基本的等于、不等于、大于、小于等各种常见操作。它允许你以链式调用的方式添加多个查询条件,并且可以组合使用 and 和 or 逻辑。

  • UpdateWrapper:用于构造更新条件,可以在更新数据时指定条件。与 QueryWrapper 类似,它也支持链式调用和逻辑组合。使用 UpdateWrapper 可以在不创建实体对象的情况下,直接设置更新字段和条件。

  • LambdaQueryWrapper:这是一个基于 Lambda 表达式的查询条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。这种方式提高了代码的可读性和可维护性,尤其是在字段名可能发生变化的情况下。

  • LambdaUpdateWrapper:类似于 LambdaQueryWrapper,LambdaUpdateWrapper 是基于 Lambda 表达式的更新条件构造器。它允许你使用 Lambda 表达式来指定更新字段和条件,同样避免了硬编码字段名的问题。

编辑
2024-11-14
学习记录
00

前提

如果被调用服务方法有HttpServletResponse,会导致调用失败,因为Feign不能处理HttpServletResponse

使用返回值ResponseEntity<org.springframework.core.io.Resource>进行处理

方法

调用方

java
@GetMapping("/download") public void download(@RequestParam(value = "fileUrl") String fileUrl, HttpServletResponse response){ try { ResponseEntity<org.springframework.core.io.Resource> responseEntity = remoteFileService.downloadByRes(fileUrl);; if (responseEntity.getStatusCode().is2xxSuccessful()) { org.springframework.core.io.Resource resource = responseEntity.getBody(); if (resource != null) { response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment;filename=" + resource.getFilename()); try (OutputStream outputStream = response.getOutputStream()) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = resource.getInputStream().read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.flush(); } } } else { response.setStatus(responseEntity.getStatusCodeValue()); } } catch (IOException e) { response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } }
编辑
2024-11-14
实用工具
00

说明

Seata 是阿里巴巴开源的分布式事务中间件,以高效并且对业务 0 侵入的方式,解决微服务场景下面临的分布式事务问题。 Seata 将为用户提供了 AT、TCC、SAGA 和XA 事务模式,为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本的GTS(Global Transaction Service 全局事务服务)。

github地址

AT模式

在 AT 模式下,用户只需关注自己的“业务 SQL”,用户的 “业务 SQL” 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作。

Server 端存储模式(store.mode)支持三种方式:

file:单机模式(默认为此模式),全局事务会话信息存储在内存中,读写并持久化至本地文件 root.data (bin\sessionStore\root.data) 中,性能较高。 db:高可用模式(Mysql 5.7+),全局事务会话信息通过db共享,相应性能差些。 redis:Seata-Server 1.3及以上版本支持,性能较高,但存在事务信息丢失风险,请提前配置适合当前场景的redis持久化配置。

创建 undo_log 表

Seata AT 模式 需要使用到 undo_log 表。

sql
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log CREATE TABLE `undo_log` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `branch_id` bigint(20) NOT NULL, `xid` varchar(100) NOT NULL, `context` varchar(128) NOT NULL, `rollback_info` longblob NOT NULL, `log_status` int(11) NOT NULL, `log_created` datetime NOT NULL, `log_modified` datetime NOT NULL, `ext` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
编辑
2024-11-14
实用工具
00

Service Interface

IService 是 MyBatis-Plus 提供的一个通用 Service 层接口,它封装了常见的 CRUD 操作,包括插入、删除、查询和分页等。通过继承 IService 接口,可以快速实现对数据库的基本操作,同时保持代码的简洁性和可维护性。

IService 接口中的方法命名遵循了一定的规范,如 get 用于查询单行,remove 用于删除,list 用于查询集合,page 用于分页查询,这样可以避免与 Mapper 层的方法混淆。

保存

  • save
  • saveBatch
  • saveOrUpdate
  • saveOrUpdateBatch

删除

  • remove
  • removeById
  • removeByIds
  • removeByMap

更新

  • update
  • updateById
  • updateBatchById

查询

  • get
  • getOne
  • getById
  • getObj
  • list
  • listByIds
  • listByMap
  • listMaps
  • page
  • count