Spring Boot + MyBatis-Plus 构建图书管理系统:从数据库设计到RESTful API实战
在实际 Java Web 项目开发中图书管理系统是一个经典的练手项目它几乎涵盖了 CRUD、用户权限、数据分页、搜索过滤等后端开发的核心技能点。很多初学者在寻找一个结构清晰、代码规范、能跑通且能看懂的项目源码时常常会遇到各种问题要么是代码过于复杂依赖了过多未讲解的框架要么是项目残缺无法正常运行更常见的是项目附带了一堆“关注领取”、“付费解锁”的套路。本文将带你从零开始理解并实现一个简化但完整的图书管理系统后端服务。我们将使用 Spring Boot 作为基础框架整合 MyBatis-Plus 来简化数据层操作并采用 RESTful 风格设计 API。整个过程会聚焦于如何将业务需求如图书入库、借阅、归还、查询转化为具体的代码逻辑、数据库设计和接口实现并解释每一步背后的设计考量。最终你将获得一个可独立运行、代码结构清晰、便于扩展的项目原型并能掌握从设计到实现的完整链路。1. 理解图书管理系统的核心业务与数据模型在动手写代码之前必须先厘清系统要管理哪些实体Entity以及它们之间的关系。一个基础的图书管理系统通常涉及以下几个核心实体图书Book系统的核心资源需要记录其基本信息。用户User系统的使用者通常分为普通读者和管理员。借阅记录BorrowRecord连接用户和图书的纽带记录借阅行为的关键信息。1.1 实体属性定义与数据库表设计基于上述实体我们可以设计出对应的数据库表。这里使用 MySQL 作为示例数据库。1. 图书表book此表存储图书的静态信息。id作为主键isbn具有业务唯一性status字段用于标识图书当前是否可借。CREATE TABLE book ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID, isbn varchar(20) NOT NULL COMMENT 国际标准书号, name varchar(100) NOT NULL COMMENT 图书名称, author varchar(50) DEFAULT NULL COMMENT 作者, publisher varchar(100) DEFAULT NULL COMMENT 出版社, publish_date date DEFAULT NULL COMMENT 出版日期, price decimal(10,2) DEFAULT NULL COMMENT 价格, status tinyint(4) NOT NULL DEFAULT 0 COMMENT 状态0-可借阅1-已借出2-维护中, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_isbn (isbn), KEY idx_name (name), KEY idx_author (author) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT图书信息表;2. 用户表user此表存储系统用户信息。role字段用于区分用户角色是实现权限控制的基础。CREATE TABLE user ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID, username varchar(50) NOT NULL COMMENT 用户名, password varchar(100) NOT NULL COMMENT 密码加密存储, real_name varchar(50) DEFAULT NULL COMMENT 真实姓名, phone varchar(20) DEFAULT NULL COMMENT 手机号, role tinyint(4) NOT NULL DEFAULT 0 COMMENT 角色0-普通用户1-管理员, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;3. 借阅记录表borrow_record此表是业务的核心记录了借阅行为。它通过user_id和book_id关联用户和图书。borrow_time、due_time和return_time共同定义了借阅周期。CREATE TABLE borrow_record ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID, user_id bigint(20) NOT NULL COMMENT 借阅用户ID, book_id bigint(20) NOT NULL COMMENT 借阅图书ID, borrow_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 借阅时间, due_time datetime NOT NULL COMMENT 应还时间, return_time datetime DEFAULT NULL COMMENT 实际归还时间, status tinyint(4) NOT NULL DEFAULT 0 COMMENT 状态0-借阅中1-已归还2-已超期, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), KEY idx_user_id (user_id), KEY idx_book_id (book_id), KEY idx_due_time (due_time), CONSTRAINT fk_borrow_book FOREIGN KEY (book_id) REFERENCES book (id), CONSTRAINT fk_borrow_user FOREIGN KEY (user_id) REFERENCES user (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT借阅记录表;1.2 核心业务流程梳理数据模型建立后需要明确系统如何运转。主要业务流程如下图书入库管理员添加新图书信息系统初始化图书状态为“可借阅”。用户借书用户查询到可借阅的图书。发起借阅请求。关键业务逻辑系统需检查该图书状态是否为“可借阅”检查用户是否有未归还的图书或超期记录简单的风控。通过后创建借阅记录并将对应图书状态更新为“已借出”同时计算应还时间例如借阅30天。用户还书用户归还图书。关键业务逻辑系统根据图书ID找到未归还的借阅记录更新其“实际归还时间”和状态为“已归还”。同时将图书状态更新回“可借阅”。如果归还时间晚于应还时间需将借阅记录状态更新为“已超期”并可能触发后续处理如通知、限制借阅。查询与统计支持按条件查询图书、查询用户借阅历史、统计图书借阅排行等。理解这些流程是后续编写 Service 层业务逻辑代码的基础。2. 项目环境搭建与基础配置我们将使用 Spring Boot 2.7.x 版本它简化了 Spring 应用的初始搭建和配置过程。MyBatis-Plus 是一个强大的 MyBatis 增强工具可以极大减少单表 CRUD 的代码量。2.1 初始化 Spring Boot 项目使用 Spring Initializr 或 IDE 自带的 Spring Boot 项目创建向导生成一个 Maven 项目。关键依赖选择Spring Web用于构建 RESTful API。MyBatis Framework或直接选择MyBatis-Plus用于数据持久化。MySQL Driver连接 MySQL 数据库。Lombok简化 Java Bean 的编写可选但推荐。生成的pom.xml关键依赖部分如下dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3/version !-- 请使用当时最新稳定版 -- /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies2.2 数据库与 MyBatis-Plus 配置在application.yml或application.properties中配置数据源和 MyBatis-Plus。这里以 YAML 格式为例server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/library_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: your_password mybatis-plus: configuration: # 下划线命名自动转驼峰 map-underscore-to-camel-case: true # 控制台打印 SQL 日志开发环境开启 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: # 全局逻辑删除字段名如果使用逻辑删除 logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 # 主键类型 id-type: auto # 指定 mapper.xml 文件位置如果使用 XML 方式 mapper-locations: classpath*:/mapper/**/*.xml注意log-impl配置在开发阶段有助于调试 SQL但在生产环境务必关闭或改为文件日志避免泄露敏感信息和影响性能。2.3 项目目录结构规划一个清晰的项目结构有助于维护。建议采用如下分层结构src/main/java/com/example/library/ ├── LibraryApplication.java # 启动类 ├── config/ # 配置类如拦截器、WebMvc配置 ├── controller/ # 控制器层接收请求返回响应 │ ├── BookController.java │ ├── UserController.java │ └── BorrowController.java ├── service/ # 业务逻辑层 │ ├── impl/ │ │ ├── BookServiceImpl.java │ │ ├── UserServiceImpl.java │ │ └── BorrowServiceImpl.java │ ├── BookService.java │ ├── UserService.java │ └── BorrowService.java ├── mapper/ # 数据访问层MyBatis Mapper接口 │ ├── BookMapper.java │ ├── UserMapper.java │ └── BorrowMapper.java ├── entity/ # 实体类对应数据库表 │ ├── Book.java │ ├── User.java │ └── BorrowRecord.java ├── dto/ # 数据传输对象用于接口入参、出参 │ ├── request/ │ │ ├── BookQueryRequest.java │ │ ├── BorrowRequest.java │ │ └── UserLoginRequest.java │ └── response/ │ ├── BookVO.java │ └── BorrowRecordVO.java └── common/ # 通用类 ├── Result.java # 统一API响应封装 ├── GlobalExceptionHandler.java # 全局异常处理器 └── constants/ # 常量定义3. 核心功能模块实现我们将按照数据流动的顺序从 Entity 到 Mapper再到 Service 和 Controller实现图书管理、用户管理和借阅管理三个核心模块。3.1 实体类Entity与 Mapper 接口使用 MyBatis-Plus实体类通过注解与数据库表映射Mapper 接口只需继承BaseMapper即可获得丰富的单表操作方法。1. 图书实体Book.java使用TableName指定表名TableId指定主键TableField处理字段映射。package com.example.library.entity; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; Data TableName(book) public class Book { TableId(type IdType.AUTO) private Long id; private String isbn; private String name; private String author; private String publisher; TableField(publish_date) private LocalDate publishDate; private BigDecimal price; /** * 状态0-可借阅1-已借出2-维护中 */ private Integer status; TableField(fill FieldFill.INSERT) private LocalDateTime createTime; TableField(fill FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; }2. 图书数据访问接口BookMapper.java继承BaseMapper并指定泛型为Book。package com.example.library.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.library.entity.Book; import org.apache.ibatis.annotations.Mapper; Mapper public interface BookMapper extends BaseMapperBook { // 可以在此定义复杂的联合查询方法 // ListBook selectBooksWithBorrowInfo(); }同理创建User、BorrowRecord实体及其对应的UserMapper、BorrowRecordMapper。BorrowRecord实体中需要注意时间字段的类型LocalDateTime和关联字段。3.2 业务逻辑层Service实现Service 层承载核心业务规则。以借阅服务为例它涉及事务管理和多表操作。借阅服务接口BorrowService.javapackage com.example.library.service; import com.example.library.dto.request.BorrowRequest; import com.example.library.dto.response.BorrowRecordVO; import java.util.List; public interface BorrowService { /** * 借阅图书 * param request 借阅请求包含用户ID和图书ID * return 借阅记录ID */ Long borrowBook(BorrowRequest request); /** * 归还图书 * param bookId 图书ID * return 是否归还成功 */ Boolean returnBook(Long bookId); /** * 查询用户的借阅记录 * param userId 用户ID * return 借阅记录列表 */ ListBorrowRecordVO getBorrowRecordsByUser(Long userId); }借阅服务实现BorrowServiceImpl.java这里包含了借书和还书的核心业务逻辑并使用Transactional注解保证操作原子性。package com.example.library.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.example.library.dto.request.BorrowRequest; import com.example.library.dto.response.BorrowRecordVO; import com.example.library.entity.Book; import com.example.library.entity.BorrowRecord; import com.example.library.entity.User; import com.example.library.mapper.BookMapper; import com.example.library.mapper.BorrowRecordMapper; import com.example.library.mapper.UserMapper; import com.example.library.service.BorrowService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; Slf4j Service RequiredArgsConstructor // Lombok 注解自动注入final字段 public class BorrowServiceImpl implements BorrowService { private final BorrowRecordMapper borrowRecordMapper; private final BookMapper bookMapper; private final UserMapper userMapper; Override Transactional(rollbackFor Exception.class) public Long borrowBook(BorrowRequest request) { Long userId request.getUserId(); Long bookId request.getBookId(); // 1. 校验用户是否存在且状态正常 User user userMapper.selectById(userId); if (user null) { throw new RuntimeException(用户不存在); } // 2. 校验图书是否存在且状态为可借阅 Book book bookMapper.selectById(bookId); if (book null) { throw new RuntimeException(图书不存在); } if (!book.getStatus().equals(0)) { // 0 代表可借阅 throw new RuntimeException(图书当前不可借阅状态为 book.getStatus()); } // 3. (可选) 简单风控检查用户是否有超期未还的图书 LambdaQueryWrapperBorrowRecord queryWrapper new LambdaQueryWrapper(); queryWrapper.eq(BorrowRecord::getUserId, userId) .eq(BorrowRecord::getStatus, 2); // 2 代表已超期 Long overdueCount borrowRecordMapper.selectCount(queryWrapper); if (overdueCount 0) { throw new RuntimeException(您有超期未还的图书请先归还); } // 4. 创建借阅记录 BorrowRecord record new BorrowRecord(); record.setUserId(userId); record.setBookId(bookId); record.setBorrowTime(LocalDateTime.now()); record.setDueTime(LocalDateTime.now().plusDays(30)); // 假设借期30天 record.setStatus(0); // 0-借阅中 borrowRecordMapper.insert(record); // 5. 更新图书状态为“已借出” Book updateBook new Book(); updateBook.setId(bookId); updateBook.setStatus(1); // 1-已借出 bookMapper.updateById(updateBook); log.info(用户[{}]借阅图书[{}]成功借阅记录ID[{}], userId, bookId, record.getId()); return record.getId(); } Override Transactional(rollbackFor Exception.class) public Boolean returnBook(Long bookId) { // 1. 根据图书ID查询未归还的借阅记录 LambdaQueryWrapperBorrowRecord queryWrapper new LambdaQueryWrapper(); queryWrapper.eq(BorrowRecord::getBookId, bookId) .eq(BorrowRecord::getStatus, 0); // 0-借阅中 BorrowRecord record borrowRecordMapper.selectOne(queryWrapper); if (record null) { throw new RuntimeException(未找到该图书的有效借阅记录); } // 2. 更新借阅记录 record.setReturnTime(LocalDateTime.now()); // 判断是否超期 if (record.getReturnTime().isAfter(record.getDueTime())) { record.setStatus(2); // 2-已超期 } else { record.setStatus(1); // 1-已归还 } borrowRecordMapper.updateById(record); // 3. 更新图书状态为“可借阅” Book updateBook new Book(); updateBook.setId(bookId); updateBook.setStatus(0); // 0-可借阅 bookMapper.updateById(updateBook); log.info(图书[{}]归还成功借阅记录ID[{}], bookId, record.getId()); return true; } Override public ListBorrowRecordVO getBorrowRecordsByUser(Long userId) { LambdaQueryWrapperBorrowRecord queryWrapper new LambdaQueryWrapper(); queryWrapper.eq(BorrowRecord::getUserId, userId) .orderByDesc(BorrowRecord::getBorrowTime); ListBorrowRecord records borrowRecordMapper.selectList(queryWrapper); // 将 Entity 转换为 VO并关联查询图书名称等信息这里简化处理实际可能需联表查询 return records.stream().map(record - { BorrowRecordVO vo new BorrowRecordVO(); BeanUtils.copyProperties(record, vo); // 关联查询图书信息 Book book bookMapper.selectById(record.getBookId()); if (book ! null) { vo.setBookName(book.getName()); } return vo; }).collect(Collectors.toList()); } }3.3 控制器层Controller与 API 设计Controller 层负责接收 HTTP 请求调用 Service并返回统一格式的响应。我们设计 RESTful 风格的 API。统一响应封装Result.java这是前后端交互的一种良好实践使响应格式标准化。package com.example.library.common; import lombok.Data; import java.io.Serializable; Data public class ResultT implements Serializable { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(success); result.setData(data); return result; } public static T ResultT success() { return success(null); } public static T ResultT error(Integer code, String message) { ResultT result new Result(); result.setCode(code); result.setMessage(message); return result; } public static T ResultT error(String message) { return error(500, message); } }借阅控制器BorrowController.javapackage com.example.library.controller; import com.example.library.common.Result; import com.example.library.dto.request.BorrowRequest; import com.example.library.dto.response.BorrowRecordVO; import com.example.library.service.BorrowService; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.List; RestController RequestMapping(/api/borrow) RequiredArgsConstructor public class BorrowController { private final BorrowService borrowService; PostMapping public ResultLong borrow(RequestBody Validated BorrowRequest request) { Long recordId borrowService.borrowBook(request); return Result.success(recordId); } PutMapping(/return/{bookId}) public ResultBoolean returnBook(PathVariable Long bookId) { Boolean success borrowService.returnBook(bookId); return Result.success(success); } GetMapping(/user/{userId}) public ResultListBorrowRecordVO getRecordsByUser(PathVariable Long userId) { ListBorrowRecordVO records borrowService.getBorrowRecordsByUser(userId); return Result.success(records); } }相应的需要创建BorrowRequest和BorrowRecordVO等 DTO 对象来封装请求和响应数据。4. 功能验证与常见问题排查完成编码后需要启动项目并进行接口测试验证功能是否正常。4.1 启动应用与基础数据准备确保 MySQL 服务已启动并已创建library_db数据库。运行LibraryApplication的 main 方法启动 Spring Boot 应用。使用数据库工具或编写简单的初始化脚本向user表和book表插入一些测试数据。插入一个管理员用户和一个普通用户。插入几本状态为“可借阅”的图书。4.2 使用工具测试 API使用 Postman、cURL 或 IDE 自带的 HTTP Client 工具测试接口。测试借书流程请求POST http://localhost:8080/api/borrowHeadersContent-Type: application/jsonBody{ userId: 2, bookId: 1 }预期响应{ code: 200, message: success, data: 1 // 返回新生成的借阅记录ID }验证检查数据库borrow_record表应新增一条记录对应book表的status应变为 1已借出。测试还书流程请求PUT http://localhost:8080/api/borrow/return/1归还 bookId1 的图书预期响应{ code: 200, message: success, data: true }验证检查数据库对应borrow_record的return_time和status被更新对应book表的status变回 0可借阅。4.3 常见问题与排查路径在开发和测试过程中你可能会遇到以下典型问题问题现象可能原因检查方式处理建议应用启动失败报DataSource相关错误1. 数据库连接URL、用户名、密码错误。2. MySQL驱动版本与数据库版本不匹配。3. 数据库library_db不存在。1. 检查application.yml中的spring.datasource配置。2. 检查pom.xml中mysql-connector-j的版本。3. 登录MySQL确认数据库和用户权限。1. 修正配置信息。2. 调整驱动版本或升级数据库。3. 创建数据库。调用借书API返回“图书不存在”或“用户不存在”1. 传入的userId或bookId在数据库中不存在。2. 请求体JSON字段名与BorrowRequest类属性名不匹配。1. 检查数据库user和book表确认ID存在。2. 查看请求日志或使用调试工具确认Controller接收到的参数值。1. 使用正确的ID。2. 确保JSON字段名与Java类属性名一致注意驼峰命名。借书成功但图书状态未更新Service 方法未添加Transactional注解或事务未生效。1. 检查BorrowServiceImpl.borrowBook方法是否有Transactional。2. 查看日志是否有SQL执行但更新语句未提交。1. 添加Transactional(rollbackFor Exception.class)。2. 确认方法是否为publicSpring AOP 对非 public 方法无效。查询接口返回数据但某些字段如bookName为nullVO 对象中的字段未正确赋值。在BorrowRecordVO中定义了bookName但转换时未从Book实体获取。检查BorrowServiceImpl.getBorrowRecordsByUser方法中将BorrowRecord转换为BorrowRecordVO时是否设置了bookName。在转换逻辑中通过bookId查询Book实体并将其name赋值给 VO 的bookName字段。控制台未打印 SQL 日志MyBatis-Plus 的 SQL 日志配置未开启或级别不对。检查application.yml中mybatis-plus.configuration.log-impl配置。开发环境可设置为org.apache.ibatis.logging.stdout.StdOutImpl。生产环境应使用SLF4J并配置日志级别为DEBUG。5. 生产环境考量与扩展方向当前实现是一个可用于学习和理解基础流程的版本。若要用于实际生产环境还需要在以下方面进行加强5.1 安全与权限控制认证与授权集成 Spring Security 或 Shiro实现基于角色的访问控制RBAC。例如/api/book/的增删改操作应只允许ROLE_ADMIN访问。密码安全用户密码不应明文存储。使用BCryptPasswordEncoder等工具进行哈希加盐处理。API 安全考虑添加 Token 机制如 JWT进行无状态认证并对敏感操作实施防重放、限流等策略。5.2 数据校验与异常处理输入校验在 DTO 类中使用javax.validation注解如NotBlank,ISBN,Future进行参数校验并在 Controller 使用Validated触发。全局异常处理创建GlobalExceptionHandler使用RestControllerAdvice统一处理业务异常、校验异常和系统异常返回友好的错误信息而不是堆栈跟踪。业务状态码定义一套业务状态码枚举替代魔法数字如status0提高代码可读性。5.3 性能与扩展性数据库索引为高频查询条件如book.name,borrow_record.user_id建立索引但需注意索引对写操作的影响。分页查询MyBatis-Plus 内置了强大的分页插件。对于图书列表、借阅记录列表等接口务必实现分页避免一次性加载大量数据。缓存对于不常变动的数据如图书分类、出版社列表可以考虑引入 Redis 等缓存减轻数据库压力。服务拆分当系统复杂度增加可以考虑将用户服务、图书服务、借阅服务拆分为独立的微服务。5.4 监控与运维日志规范使用 SLF4J 配合 Logback/Log4j2合理设置日志级别将关键业务日志、错误日志、慢 SQL 日志等输出到文件便于排查问题。健康检查Spring Boot Actuator 可以提供应用健康状态、度量指标等信息。API 文档集成 Swagger 或 Knife4j自动生成在线 API 文档方便前后端协作。通过这个从零搭建的过程你不仅得到了一个可运行的图书管理系统代码更重要的是理解了如何将一个业务需求逐步分解为数据库设计、实体定义、服务逻辑和接口暴露的完整开发流程。接下来你可以基于这个原型尝试实现用户注册登录、图书分类管理、借阅超期罚款、数据统计报表等更复杂的功能从而深入掌握企业级应用开发的各个环节。

相关新闻

PyCharm插件配置全攻略:从代码质量到AI编程助手

PyCharm插件配置全攻略:从代码质量到AI编程助手

1. 从“能用”到“好用”:为什么你需要关注PyCharm插件如果你还在用“裸奔”的PyCharm,那你可能只发挥了它30%的功力。这不是危言耸听,而是我作为多年Python全栈开发者最深刻的体会。PyCharm本身是一个强大的IDE,但它的真正威力&a…

2026/8/23 20:27:40 阅读更多 →
C++11模板新特性解析:Alias Template、extern template与工程实践

C++11模板新特性解析:Alias Template、extern template与工程实践

1. 项目概述:为什么C11的Template特性是“崭新”的? 如果你是从C98/03时代一路走过来的老手,看到“崭新的Template特性”这个说法,可能会心一笑。确实,在C11之前,模板编程虽然强大,但更像是一门…

2026/8/23 20:27:39 阅读更多 →
游戏Mod冲突解决:手动合并anm2文件实现多Mod共存

游戏Mod冲突解决:手动合并anm2文件实现多Mod共存

最近在折腾《喵喵的结合》这款游戏时,发现很多玩家都遇到了一个共同的难题:想同时使用“套装显示”、“技能预览”和“事件中文”这几个非常实用的Mod,但它们之间却经常因为文件冲突而无法共存。要么是某个Mod不生效,要么是游戏直…

2026/8/23 20:27:39 阅读更多 →

最新新闻

高校实习管理系统开发:Spring Boot实战与架构设计

高校实习管理系统开发:Spring Boot实战与架构设计

1. 项目背景与核心价值这个实习实训管理系统是面向高校计算机专业毕业设计的典型开发案例。我在指导类似项目时发现,很多学生在开发这类系统时容易陷入"为了做而做"的困境,忽略了实际教学场景中的真实需求。这个系统本质上要解决的是高校实习管…

2026/8/23 21:14:13 阅读更多 →
WinRAR:从压缩工具到工作流伙伴,理解其价值与正确使用方式

WinRAR:从压缩工具到工作流伙伴,理解其价值与正确使用方式

你电脑里是不是也有一个用了很多年的压缩软件,每次打开都弹出一个“评估版本”的窗口,提醒你购买许可?你每次都熟练地点掉它,继续用着那些核心的解压、压缩功能。这个软件,大概率就是 WinRAR。 很多人对 WinRAR 的感情…

2026/8/23 21:14:13 阅读更多 →
FCL启动器全攻略:从零配置Minecraft模组环境到故障排查

FCL启动器全攻略:从零配置Minecraft模组环境到故障排查

最近在折腾 Minecraft 模组开发时,发现很多朋友对 FCL (Fancy Console Launcher) 启动器又爱又恨。爱的是它功能强大、开源免费,能轻松管理多个 Minecraft 版本和模组;恨的是其配置项繁多,从环境搭建到模组加载,每一步…

2026/8/23 21:14:13 阅读更多 →
手写VIO第一章:从四元数、SO(3)到李代数的数学筑基

手写VIO第一章:从四元数、SO(3)到李代数的数学筑基

1. 这不是“抄笔记”,而是亲手把VIO的数学骨架搭起来“手写VIO第1章(笔记作业)”——看到这个标题,我第一反应不是打开PDF划重点,而是立刻抓起草稿纸、铅笔和计算器。为什么?因为VIO(视觉惯性里…

2026/8/23 21:14:13 阅读更多 →
DeepSeek Harness 与 dsh-tui 插件:本地 AI 助手集成与终端交互实践

DeepSeek Harness 与 dsh-tui 插件:本地 AI 助手集成与终端交互实践

在 AI 助手和代码生成工具日益普及的今天,如何高效、便捷地在本地开发环境中集成这些能力,是提升开发者效率的关键。DeepSeek Harness 作为一个旨在简化 AI 模型本地部署与集成的工具,其官方插件生态的扩展,特别是像dsh-tui这样的…

2026/8/23 21:14:13 阅读更多 →
百元三模游戏手柄西圣GC1评测:霍尔摇杆扳机实测与多平台兼容性分析

百元三模游戏手柄西圣GC1评测:霍尔摇杆扳机实测与多平台兼容性分析

这次我们来看一款百元档位的三模游戏手柄——西圣GC1。对于预算有限但又不想在游戏体验上妥协的玩家来说,这个价位段的选择往往决定了是“能用”还是“好用”。西圣GC1主打三模连接、霍尔摇杆和扳机,以及不错的颜值,看起来是想在入门市场里卷…

2026/8/23 21:13:12 阅读更多 →

日新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/23 0:00:50 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/23 0:00:50 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/23 0:00:50 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/23 0:00:50 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/23 0:00:50 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/23 0:00:50 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/23 18:47:06 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →