Spring Boot MongoDB 分页工具类封装 (新手指南)

Spring Boot MongoDB 分页工具类封装 (新手指南)

目录

  1. 引言:为何需要分页工具类?
  2. 工具类一:PaginationUtils - 简化 Pageable 创建
    • 设计目标
    • 代码实现 (PaginationUtils.java)
    • 如何使用 PaginationUtils
  3. 工具类二:PageResponse<T> - 标准化分页响应 DTO
    • 设计目标
    • 代码实现 (PageResponse.java)
    • 如何使用 PageResponse<T>
  4. 整合示例:在 Controller 和 Service 中使用工具类
    • Controller 层 (UserController.java)
    • Service 层 (UserService.java)
  5. 重点内容总结
  6. 结语

1. 引言:为何需要分页工具类?

在之前的笔记中,我们学习了如何使用 PageablePage 来实现分页。虽然 Spring Data 提供了基础,但在实际项目中,我们经常会重复以下操作:

  • 从 HTTP 请求参数(页码、大小、排序字段、排序方向)创建 Pageable 对象。
  • 处理 用户友好的 1-based 页码Spring Data 内部 0-based 页码 之间的转换。
  • 处理排序参数的解析和 Sort 对象的构建。
  • 可能希望 标准化 API 返回的分页信息格式,使其更简洁或符合前端特定需求,而不是直接暴露 Spring Data 的 Page 结构。

封装分页工具类可以:

  • 减少重复代码:将通用的分页逻辑集中处理。
  • 提高可读性:使 Service 和 Controller 层的代码更专注于业务逻辑。
  • 统一规范:确保项目中分页参数处理和响应格式的一致性。
  • 简化使用:让新手更容易地实现正确的分页。

2. 工具类一:PaginationUtils - 简化 Pageable 创建

这个工具类的主要职责是接收前端传入的原始分页参数,并安全、便捷地将其转换为 Spring Data 所需的 Pageable 对象。

设计目标

  • 接收 1-based 页码,内部转换为 0-based。
  • 提供默认的页码和页面大小。
  • 支持单个或多个排序字段及方向的解析。
  • 处理无效或缺失的参数,提供合理的默认行为(如不排序)。

代码实现 (PaginationUtils.java)

package com.example.yourproject.utils; // 根据你的项目结构调整包名import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.util.CollectionUtils; // Spring 提供的集合工具类
import org.springframework.util.StringUtils; // Spring 提供的字符串工具类import java.util.ArrayList;
import java.util.List;/*** 分页工具类** 帮助从原始请求参数创建 Spring Data Pageable 对象。* 核心功能:处理 1-based 页码转换、默认值、排序参数解析。*/
public final class PaginationUtils { // final class, 防止被继承// 默认页码(用户传入的第一页)private static final int DEFAULT_PAGE_NUMBER = 1;// 默认每页大小private static final int DEFAULT_PAGE_SIZE = 10;// 默认排序方向private static final Sort.Direction DEFAULT_SORT_DIRECTION = Sort.Direction.ASC;// 排序参数中,字段和方向的分隔符(例如 "name,desc")private static final String SORT_DELIMITER = ",";/*** 私有构造函数,防止实例化工具类*/private PaginationUtils() {throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");}/*** 创建 Pageable 对象。** @param pageInput 用户传入的页码 (从 1 开始计数)。如果为 null 或小于 1,则使用默认值 1。* @param sizeInput 用户传入的每页大小。如果为 null 或小于 1,则使用默认值 10。* @param sortInput 排序参数列表。每个字符串格式为 "fieldName,direction" (例如 "name,asc", "age,desc")。*                 direction 可以省略,默认为升序 (ASC)。*                 如果列表为空或 null,则不进行排序。* @return 配置好的 Pageable 对象。*/public static Pageable createPageable(Integer pageInput, Integer sizeInput, List<String> sortInput) {// 1. 验证并设置页码 (转换为 0-based)// 如果 pageInput 为 null 或 < 1,则使用默认页码 1。然后减 1 得到 0-based 页码。int page = (pageInput == null || pageInput < 1) ? DEFAULT_PAGE_NUMBER - 1 : pageInput - 1;// 2. 验证并设置页面大小// 如果 sizeInput 为 null 或 < 1,则使用默认大小 10。int size = (sizeInput == null || sizeInput < 1) ? DEFAULT_PAGE_SIZE : sizeInput;// 3. 解析排序参数Sort sort = parseSort(sortInput);// 4. 创建并返回 PageRequest 对象return PageRequest.of(page, size, sort);}/*** 创建带有默认排序的 Pageable 对象(如果未提供排序参数)。** @param pageInput 用户传入的页码 (从 1 开始计数)。* @param sizeInput 用户传入的每页大小。* @param sortInput 排序参数列表 (同上)。* @param defaultSort 默认的 Sort 对象。如果 sortInput 为空或无效,则使用此默认排序。* @return 配置好的 Pageable 对象。*/public static Pageable createPageable(Integer pageInput, Integer sizeInput, List<String> sortInput, Sort defaultSort) {int page = (pageInput == null || pageInput < 1) ? DEFAULT_PAGE_NUMBER - 1 : pageInput - 1;int size = (sizeInput == null || sizeInput < 1) ? DEFAULT_PAGE_SIZE : sizeInput;Sort sort = parseSort(sortInput);// 如果解析出的 sort 是 unsorted,并且提供了默认 sort,则使用默认 sortif (sort.isUnsorted() && defaultSort != null && defaultSort.isSorted()) {sort = defaultSort;}return PageRequest.of(page, size, sort);}/*** 解析排序参数字符串列表,构建 Sort 对象。** @param sortParams 排序参数列表,每个元素如 "field,direction" 或 "field"。* @return 如果参数有效则返回 Sort 对象,否则返回 Sort.unsorted()。*/private static Sort parseSort(List<String> sortParams) {if (CollectionUtils.isEmpty(sortParams)) {return Sort.unsorted(); // 没有提供排序参数,返回不排序}List<Sort.Order> orders = new ArrayList<>();for (String sortParam : sortParams) {// 跳过空或空白的排序参数if (!StringUtils.hasText(sortParam)) {continue;}String[] parts = sortParam.split(SORT_DELIMITER);// 第一个部分是字段名,必须存在String property = parts[0].trim();if (!StringUtils.hasText(property)) {continue; // 字段名为空,跳过}// 获取排序方向,如果没提供或无效,则使用默认方向Sort.Direction direction = DEFAULT_SORT_DIRECTION;if (parts.length > 1 && StringUtils.hasText(parts[1])) {// 尝试从字符串解析方向 (忽略大小写)try {direction = Sort.Direction.fromString(parts[1].trim());} catch (IllegalArgumentException e) {// 如果方向字符串无效 (例如 "ascend", "descend"), 使用默认值System.err.println("Invalid sort direction: " + parts[1] + ". Using default: " + DEFAULT_SORT_DIRECTION);// 这里可以选择打印日志或忽略错误}}// 创建 Sort.Order 对象并添加到列表orders.add(new Sort.Order(direction, property));}// 如果成功解析出至少一个有效的 Order,则创建 Sort 对象,否则返回 unsortedreturn orders.isEmpty() ? Sort.unsorted() : Sort.by(orders);}}

注释说明:

  • final class / private constructor: 这是工具类的标准写法,表明它不应该被继承或实例化。所有方法都是静态的。
  • 常量定义: 定义默认值和分隔符,方便修改和维护。
  • createPageable 方法:
    • 接收 Integer 类型的 pageInputsizeInput,允许传入 null
    • 核心: page = (pageInput == null || pageInput < 1) ? DEFAULT_PAGE_NUMBER - 1 : pageInput - 1; 这行处理了 null 值、小于 1 的无效值,并将用户习惯的 1-based 页码转换成 Spring Data 需要的 0-based 页码。
    • 调用 parseSort 方法处理排序参数。
    • 最后使用 PageRequest.of(page, size, sort) 创建 Pageable 实例。
  • createPageable (重载): 提供了一个可以传入默认 Sort 对象的版本,当用户没有提供任何有效排序时,可以使用这个默认排序。
  • parseSort 方法:
    • 处理 null 或空列表的情况,返回 Sort.unsorted()
    • 遍历 sortInput 列表中的每个字符串。
    • 使用 split(SORT_DELIMITER) 分割字段名和方向。
    • 进行健壮性检查 (字段名是否为空)。
    • 解析排序方向,使用 Sort.Direction.fromString() 并包含 try-catch 处理无效方向字符串,回退到默认方向。
    • 创建 Sort.Order 对象。
    • 最后使用 Sort.by(orders) 将所有有效的 Order 组合成 Sort 对象。如果列表为空,则 Sort.by() 返回 Sort.unsorted()
  • 依赖: 使用了 Spring Framework 提供的 StringUtilsCollectionUtils 进行空值检查,这是推荐的做法。

如何使用 PaginationUtils

在你的 Service 层Controller 层(取决于你处理分页参数的位置,通常在 Service 层更合适),你可以这样调用:

// 假设在 Service 层
import com.example.yourproject.utils.PaginationUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import java.util.List;// ...public Page<User> findUsersPaginated(Integer page, Integer size, List<String> sort) {// 使用工具类创建 Pageable 对象// 假设我们希望默认按 "createdAt" 降序排序Sort defaultSort = Sort.by(Sort.Direction.DESC, "createdAt");Pageable pageable = PaginationUtils.createPageable(page, size, sort, defaultSort);// 现在可以直接将 pageable 传递给 Repository 方法return userRepository.findAll(pageable); // 或者 userRepository.findByXXX(..., pageable);
}

3. 工具类二:PageResponse<T> - 标准化分页响应 DTO

这个类是一个数据传输对象 (DTO),用于包装分页查询的结果,提供一个统一、简洁的 JSON 结构给前端。

设计目标

  • 封装当前页的数据列表 (List<T>)。
  • 提供清晰的分页元数据(当前页码 (1-based)、每页大小、总记录数、总页数、是否首页/末页)。
  • 隐藏 Spring Data Page 对象的内部复杂结构。
  • 提供一个静态工厂方法,方便从 Page<T> 对象转换。

代码实现 (PageResponse.java)

package com.example.yourproject.dto; // DTO 通常放在 dto 包下import org.springframework.data.domain.Page;
import java.util.List;/*** 标准化的分页响应体 DTO (Data Transfer Object)** 用于封装分页查询结果,提供给 API 调用者一个简洁一致的结构。** @param <T> 数据的实体类型*/
public class PageResponse<T> {private final List<T> content;          // 当前页的数据列表private final int currentPage;          // 当前页码 (从 1 开始)private final int pageSize;             // 每页大小private final long totalElements;       // 总记录数private final int totalPages;           // 总页数private final boolean first;            // 是否为第一页private final boolean last;             // 是否为最后一页/*** 构造函数 (私有或包私有,推荐使用静态工厂方法创建)*/private PageResponse(List<T> content, int currentPage, int pageSize, long totalElements, int totalPages, boolean first, boolean last) {this.content = content;this.currentPage = currentPage;this.pageSize = pageSize;this.totalElements = totalElements;this.totalPages = totalPages;this.first = first;this.last = last;}/*** 静态工厂方法:从 Spring Data Page 对象创建 PageResponse 对象。* @param page Spring Data 的 Page 对象* @param <T>  数据的实体类型* @return 转换后的 PageResponse 对象*/public static <T> PageResponse<T> fromPage(Page<T> page) {if (page == null) {// 可以选择返回 null,或者一个表示空的 PageResponse,取决于你的 API 设计return new PageResponse<>(List.of(), 1, 0, 0L, 0, true, true); // 返回一个空响应示例// throw new IllegalArgumentException("Page object cannot be null");}return new PageResponse<>(page.getContent(),              // 获取数据列表page.getNumber() + 1,           // **核心转换:0-based to 1-based**page.getSize(),                 // 获取页面大小page.getTotalElements(),        // 获取总记录数page.getTotalPages(),           // 获取总页数page.isFirst(),                 // 是否第一页page.isLast()                   // 是否最后页);}// --- Getters ---public List<T> getContent() {return content;}public int getCurrentPage() {return currentPage;}public int getPageSize() {return pageSize;}public long getTotalElements() {return totalElements;}public int getTotalPages() {return totalPages;}public boolean isFirst() {return first;}public boolean isLast() {return last;}/** 预期 JSON 输出示例:* {*   "content": [ ... data objects ... ],*   "currentPage": 1,*   "pageSize": 10,*   "totalElements": 153,*   "totalPages": 16,*   "first": true,*   "last": false* }*/
}

注释说明:

  • 泛型 <T>: 使 PageResponse 可以用于任何类型的分页数据。
  • 字段: 只包含前端最关心的分页信息,字段名清晰。currentPage 特别设计为 1-based。
  • 构造函数: 设为 private,强制使用静态工厂方法创建实例,这是一种良好的实践。
  • fromPage 静态工厂方法:
    • 接收一个 Spring Data Page<T> 对象作为输入。
    • 做了 null 检查。
    • 核心: page.getNumber() + 1 将 Spring Data 的 0-based 页码转换为用户友好的 1-based currentPage
    • Page<T> 对象中提取所有需要的数据,填充到 PageResponse 的字段中。
  • Getters: 提供公共的 getter 方法,以便 Jackson 等库能正确地将对象序列化为 JSON。
  • JSON 示例: 注释中给出了预期的 JSON 输出格式,方便前后端对接。

如何使用 PageResponse<T>

在你的 Service 层 方法中,当从 Repository 获取到 Page<T> 对象后,使用 PageResponse.fromPage() 进行转换。然后 Controller 层 直接返回这个 PageResponse<T> 对象。

// 假设在 Service 层
import com.example.yourproject.dto.PageResponse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;// ...public PageResponse<User> findUsersPaginatedAndWrapped(Integer page, Integer size, List<String> sort) {Sort defaultSort = Sort.by(Sort.Direction.DESC, "createdAt");Pageable pageable = PaginationUtils.createPageable(page, size, sort, defaultSort);// 1. 从 Repository 获取 Page<User> 对象Page<User> userPage = userRepository.findAll(pageable);// 2. 使用 PageResponse.fromPage() 转换PageResponse<User> pageResponse = PageResponse.fromPage(userPage);// 3. 返回转换后的 PageResponse 对象return pageResponse;
}

4. 整合示例:在 Controller 和 Service 中使用工具类

下面展示如何在 Controller 和 Service 中协同使用这两个工具类。

Controller 层 (UserController.java)

Controller 负责接收 HTTP 请求参数,并将其传递给 Service 层。注意 @RequestParamsort 参数的处理。

package com.example.yourproject.controller;import com.example.yourproject.dto.PageResponse; // 导入 DTO
import com.example.yourproject.model.User;
import com.example.yourproject.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.List; // 需要导入 List@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService; // 假设 UserService 已更新/*** 获取用户列表 (使用分页工具类)** @param page API 接收的页码 (通常从 1 开始)。* @param size 每页大小。* @param sort 排序参数列表。可以接收多个 sort 参数,*             例如: /api/users?sort=name,asc&sort=age,desc*             Spring 会自动将其收集到 List<String> 中。* @return ResponseEntity 包装的 PageResponse<User> 对象。*/@GetMappingpublic ResponseEntity<PageResponse<User>> getAllUsersPaginated(@RequestParam(required = false) Integer page,        // required=false 让参数可选@RequestParam(required = false) Integer size,@RequestParam(required = false) List<String> sort) { // 接收排序参数列表// 调用更新后的 Service 方法,传入原始参数PageResponse<User> userPageResponse = userService.findUsersPaginatedAndWrapped(page, size, sort);// 返回标准化的 PageResponse DTOreturn ResponseEntity.ok(userPageResponse);}
}

关键点:

  • @RequestParam(required = false): 允许 page, size, sort 参数在请求中不提供,PaginationUtils 会使用默认值。
  • @RequestParam List<String> sort: Spring MVC 非常智能,如果 URL 中出现多个同名参数 (?sort=name,asc&sort=age,desc),它能自动将这些值收集到一个 List<String> 中。这正好符合我们 PaginationUtils 的设计!

Service 层 (UserService.java)

Service 层使用 PaginationUtils 创建 Pageable,调用 Repository,然后使用 PageResponse.fromPage() 包装结果。

package com.example.yourproject.service;import com.example.yourproject.dto.PageResponse; // 导入 DTO
import com.example.yourproject.model.User;
import com.example.yourproject.repository.UserRepository;
import com.example.yourproject.utils.PaginationUtils; // 导入工具类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;/*** 分页查询用户,并使用 PageResponse DTO 包装结果。** @param pageInput 来自 Controller 的页码 (1-based)* @param sizeInput 来自 Controller 的每页大小* @param sortInput 来自 Controller 的排序参数列表* @return PageResponse<User> 适合返回给客户端*/public PageResponse<User> findUsersPaginatedAndWrapped(Integer pageInput, Integer sizeInput, List<String> sortInput) {// 定义默认排序(可选,如果希望在用户未指定排序时应用)Sort defaultSort = Sort.by(Sort.Direction.DESC, "createdAt"); // 例如,默认按创建时间降序// 1. 使用 PaginationUtils 创建 Pageable// 将 Controller 传来的原始参数交给工具类处理Pageable pageable = PaginationUtils.createPageable(pageInput, sizeInput, sortInput, defaultSort);// 2. 调用 Repository 进行查询Page<User> userPage = userRepository.findAll(pageable);// Page<User> userPage = userRepository.findBySomeCondition(..., pageable); // 也可以用于条件查询// 3. 使用 PageResponse DTO 转换结果// 这一步将 Page<User> 转换成前端友好的 PageResponse<User>return PageResponse.fromPage(userPage);}
}

5. 重点内容总结

  1. PaginationUtils:
    • 核心职责: 将请求参数(1-based 页码、大小、排序字符串列表)转换为 Pageable 对象。
    • 关键特性: 自动处理 1-based 到 0-based 页码转换、参数默认值、复杂排序参数 ("field,direction") 解析。
    • 使用位置: 通常在 Service 层调用,用于准备传递给 Repository 的 Pageable
  2. PageResponse<T>:
    • 核心职责: 作为分页查询结果的标准化 DTO,提供简洁一致的 API 响应结构。
    • 关键特性: 包含数据列表 (content) 和清晰的分页元数据(1-based currentPage, totalElements, totalPages 等),通过静态工厂方法 fromPage(Page<T>) 方便地从 Spring Data Page 对象转换。
    • 使用位置: 在 Service 层将 Page<T> 结果转换为 PageResponse<T>,然后 Controller 直接返回此对象。
  3. 好处:
    • 简化: 大幅减少 Controller 和 Service 中的样板代码。
    • 健壮: 统一处理参数验证和默认值。
    • 清晰: 使代码更易读,API 响应更规范。
    • 易用: 对新手友好,隐藏了分页实现的细节。
  4. Controller 参数绑定: 利用 @RequestParam List<String> sort 可以优雅地接收多个排序参数。

6. 结语

通过封装 PaginationUtilsPageResponse<T> 这两个工具类,你可以极大地简化 Spring Boot 项目中 MongoDB(或其他 Spring Data 支持的数据库)的分页实现。这不仅提高了开发效率,也使得代码更加规范和易于维护,尤其是在团队协作或项目规模变大时。希望这份详细的笔记能帮助你轻松掌握并运用这些分页工具!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis的缓存、逆向工程、使用PageHelper、使用PageHelper

一、MyBatis的缓存 缓存&#xff1a;cache 缓存的作用&#xff1a;通过减少IO的方式&#xff0c;来提高程序的执行效率。 mybatis的缓存&#xff1a;将select语句的查询结果放到缓存&#xff08;内存&#xff09;当中&#xff0c;下一次还是这条select语句的话&#xff0c;直…

java中的JNI调用c库

1. 简单demo 如果是在某个项目中有包名就需要自己找ai问问去改写下cmd命令去编译执行等 java文件&#xff08;HelloJNI.java&#xff09; public class HelloJNI {// 声明 native 方法public native void sayHello();// 加载本地库static {System.loadLibrary("hello&quo…

人工智能:GPT技术应用与未来展望

GPT(Generative Pre-trained Transformer)作为自然语言处理领域的代表性技术,近年来在各行业的实际应用中展现出广泛潜力。结合其技术特性与行业需求,以下是GPT的主要应用场景、案例分析及未来挑战的总结: 一、核心应用领域与案例 文本生成与内容创作 自动化内容生产:GPT…

前端笔记-ECMAScript语法概览

更多详细可以查看1.1 ES6 教程 | 菜鸟教程 这里我将大概记录ES与JS大概不一样的部分&#xff0c;方便联合记忆。 历史与关系 ECMAScript&#xff1a;是一种由 Ecma 国际组织制定的脚本语言规范&#xff0c;它是 JavaScript 的标准化版本。ECMAScript 为 JavaScript 提供了语…

操作主机的管理

1.在AD林范围内&#xff0c;有哪几个操作主机角色 架构主机&#xff08;Schema Master&#xff09; 功能&#xff1a;负责整个AD林中所有对象和属性的定义&#xff0c;是唯一可以更新目录架构的DC。架构更新会从架构主机复制到目录林中的所有其他域控制器。 作用范围&#xf…

【Linux】网络编程

目录 端口号 网络字节序 socket编程 接口 sockaddr结构 udp网络程序 创建套接字 绑定 接收 发送 客户端需要绑定吗&#xff1f; 客户端执行方法 本地环回地址 终端文件 代码 tcp网络程序 SOCK_STREAM 监听 查询网络信息 获取新连接 地址转换函数 客户端绑…

Go 语言中的select是做什么的

Go 语言中的 select 是做什么的 在 Go 语言中&#xff0c;select 语句是用于处理多个通道&#xff08;channel&#xff09;操作的一种控制结构。它类似于 switch 语句&#xff0c;但专门用于并发编程&#xff0c;允许 Goroutine 在多个通道上等待操作&#xff08;发送或接收&a…

智慧班牌系统解决方案,SaaS智慧电子班牌云平台

智慧班牌系统解决方案 系统概述 智慧班牌是智慧校园建设不断发展的产物&#xff0c;是教育信息化改革的载体。通过智慧班牌可以高效便捷传递各种知识信息和通知信息、及时反馈课堂信息、实现班级的透明化管理。智慧班牌将学生平安考勤、异常出勤情况及时反馈至家长、老师&…

利用大模型和聚类算法找出 Excel 文件中重复或相似度高的数据,并使用 FastAPI 进行封装的详细方案

以下是一个利用大模型和聚类算法找出 Excel 文件中重复或相似度高的数据,并使用 FastAPI 进行封装的详细方案: 方案流程 数据读取:从 Excel 文件中读取数据。文本向量化:使用大模型将文本数据转换为向量表示。聚类分析:运用聚类算法对向量进行分组,将相似度高的数据归为…

【Docker基础】容器技术详解:生命周期、命令与实战案例

文章目录 一、什么是容器&#xff1f;二、为什么需要容器三、容器的生命周期容器状态容器OOM容器异常退出容器异常退出容器暂停 四、容器命令命令清单详细介绍 五、容器操作案例容器的状态迁移容器批量操作容器交互模式attached 模式detached 模式interactive 模式 容器 与 宿主…

Laravel 实现 队列 发送邮件功能

一. 什么是队列 在构建 Web 应用程序时&#xff0c;你可能需要执行一些任务&#xff0c;例如解析文件&#xff0c;发送邮件&#xff0c;大量的数据计算等等&#xff0c;这些任务在典型的 Web 请求期间需要很长时间才能执行。 庆幸的是&#xff0c;Laravel 可以创建在后台运行…

flink Shuffle的总结

关于 ** ​5 种 Shuffle 类型** 的区别、使用场景及 Flink 版本支持的总结&#xff1a; * 注意:下面是问AI具体细节与整理学习 1. 核心区别 Shuffle 类型核心特点使用场景Flink 版本支持Pipelined Shuffle流式调度&#xff0c;纯内存交换&#xff0c;低延迟&#xff08;毫秒级…

Git使用与管理

一.基本操作 1.创建本地仓库 在对应文件目录下进行&#xff1a; git init 输入完上面的代码&#xff0c;所在文件目录下就会多一个名为 .git 的隐藏文件&#xff0c;该文件是Git用来跟踪和管理仓库的。 我们可以使用 tree 命令&#xff08;注意要先下载tree插件&#xff09…

计算机视觉——深度学习图像处理中目标检测平均精度均值(mAP)与其他常用评估指标

概述 平均精度均值&#xff08;mAP&#xff09;是目标检测领域中最为流行且复杂的重要评估指标之一。它广泛用于综合总结目标检测器的性能。许多目标检测模型会输出类似以下的参数结果&#xff1a; Average Precision (AP) [ IoU0.50:0.95 | area all | maxDets100 ] 0.3…

C语言中单链表操作:查找节点与删除节点

一. 简介 前面学习了C语言中创建链表节点&#xff0c;向链表中插入节点等操作&#xff0c;文章如下&#xff1a; C语言中单向链表&#xff1a;创建节点与插入新节点-CSDN博客 本文继续学习c语言中对链表的其他操作&#xff0c;例如在链表中查找某个节点&#xff0c;删除链表…

WePY 框架:小程序开发的“Vue式”利器!!!

WePY 框架&#xff1a;小程序开发的“Vue式”利器 &#x1f680; 哈喽&#xff0c;大家好&#xff01;&#x1f44b; 今天我们要聊聊一个在微信小程序开发中大放异彩的框架——WePY&#xff01;它是什么&#xff1f;有什么特点&#xff1f;为啥值得一试&#xff1f;别急&#…

什么是微前端?有什么好处?有哪一些方案?

微前端&#xff08;Micro Frontends&#xff09; 微前端是一种架构理念&#xff0c;借鉴了微服务的思想&#xff0c;将一个大型的前端应用拆分为多个独立、自治的子应用&#xff0c;每个子应用可以由不同团队、使用不同技术栈独立开发和部署&#xff0c;最终聚合为一个整体产品…

【家政平台开发(33)】库存管理模块开发实战:从基础搭建到智能管控

本【家政平台开发】专栏聚焦家政平台从 0 到 1 的全流程打造。从前期需求分析,剖析家政行业现状、挖掘用户需求与梳理功能要点,到系统设计阶段的架构选型、数据库构建,再到开发阶段各模块逐一实现。涵盖移动与 PC 端设计、接口开发及性能优化,测试阶段多维度保障平台质量,…

Mysql个人笔记

Mysql个人笔记 sql基础书写规则和种类种类书写规则注释规则启动 DDL数据类型数据库的操作useshowcreatedrop 表的操作useshowcreate创建表复制表 dropalter Mysql的存储引擎 DMLselectselect语句like&#xff08;谓词&#xff09;where聚合函数&#xff1a;关于nullgroup byexi…

【重装系统】大白菜自制U盘装机,备份C盘数据,解决电脑启动黑屏/蓝屏

1. 准备 U 盘 U 盘容量至少 8G&#xff0c;备份 U 盘的数据&#xff08;后期会格式化&#xff09; 2. 从微软官网下载操作系统镜像 https://www.microsoft.com/zh-cn/software-download/windows11 3. 下载安装大白菜 https://www.alipan.com/s/33RVnKayUfY 4. 插入 U 盘&#…