SpringBoot实战入门:3小时构建整合MyBatis-Plus与Redis的Web服务

这次我们来看一个面向初学者的 SpringBoot 快速入门学习路径。这个标题虽然带有“直男式教学”和“3小时搞定”的噱头,但核心指向一个非常实际的需求:如何高效、系统地掌握 SpringBoot 的核心开发能力。对于刚接触 Java 后端或从传统 SSM 框架转型的开发者来说,SpringBoot 的自动配置、内嵌服务器和“约定大于配置”的理念是巨大的生产力提升,但面对海量的教程和组件,如何抓住重点、快速搭建可运行的项目并理解其原理,是学习的关键。

本文不会空谈概念,而是聚焦于一套可落地的“最小可行学习方案”。我们将围绕一个典型的 SpringBoot 应用骨架,串联起项目创建、核心配置、数据访问、缓存集成、权限控制、接口文档生成等关键环节。目标是让你在理解核心流程的基础上,能独立完成一个具备基础 CRUD、缓存和认证功能的 Web 服务,并对接主流的 MySQL 和 Redis。整个过程强调动手实践,每个环节都提供可运行的代码示例和配置,帮你绕过初期最常见的配置坑。

1. 核心能力速览:SpringBoot 学习路径聚焦

在开始动手之前,我们先明确通过这条学习路径,你将掌握哪些具体能力,以及需要什么样的准备。

能力项说明与目标
核心掌握理解 SpringBoot 自动装配原理,掌握基于注解的开发模式,能独立创建和运行项目。
数据持久化集成 MyBatis-Plus,完成从实体类、Mapper 到 Service 的完整数据层开发,实现基础 CRUD。
缓存集成集成 Redis,实现缓存配置、数据存取及缓存注解(如@Cacheable)的使用。
Web 开发开发 RESTful API,处理请求参数、响应结果及全局异常。
权限认证集成 Spring Security 或 Sa-Token,实现基于 Token 的接口权限控制。
接口文档集成 Knife4j 或 SpringDoc,自动生成并在线调试 API 文档。
项目打包使用 Maven 或 Gradle 将应用打包为可独立运行的 JAR 文件。
环境要求JDK 8+(推荐 JDK 11 或 17),Maven 3.6+或 Gradle,IDE(推荐 IntelliJ IDEA)。
辅助服务需要本地或远程的MySQL 5.7+Redis 5+服务。
学习特点实战驱动,通过构建一个功能递进的项目来学习各组件,而非孤立看理论。

2. 适用场景与学习边界

这套学习方案主要适合以下人群:

  • Java 后端初学者:希望快速上手一个现代、主流的 Java Web 框架。
  • SSM/SSH 框架转型者:想了解 SpringBoot 如何简化传统配置。
  • 需要快速原型验证的开发者:SpringBoot 能极快地搭建出可演示的后端服务。
  • 求职面试准备者:SpringBoot 是 Java 后端岗位的必备技能,实战经验至关重要。

它能帮你解决:

  1. “从哪开始学”的迷茫:提供一条清晰、线性的实践路径。
  2. “配置太复杂”的困扰:基于 SpringBoot 的自动配置,大幅减少 XML 配置。
  3. “组件不会整合”的问题:演示如何将数据库、缓存、安全等常用组件有机组合。

需要注意的边界:

  1. 不是深度源码剖析:本文侧重于应用层快速上手,对 SpringBoot 启动流程、自动装配源码的深入分析需要另行学习。
  2. 不是微服务架构教程:不会涉及 Spring Cloud、服务注册发现、配置中心等微服务组件。
  3. 需要基础 Java 知识:假定你已掌握 Java 基础语法、面向对象概念以及基本的 SQL 知识。
  4. 关注合法合规:项目中使用的所有技术组件均为开源产品,请确保在学习和测试环境中使用。若用于生产,请遵循各自的开源协议。

3. 环境准备与前置检查

开始编码前,请确保你的开发环境已就绪。这是后续所有步骤的基础。

3.1 基础软件安装

  1. JDK:确保已安装 JDK 8 或以上版本。推荐使用 JDK 11 或 17(LTS 版本)。在终端执行java -version验证。

    java -version # 应输出类似:openjdk version "11.0.19" ...
  2. Maven:用于项目构建和依赖管理。安装后执行mvn -v验证。

    mvn -v # 应输出 Apache Maven 版本信息

    建议配置国内镜像(如阿里云镜像)以加速依赖下载。修改~/.m2/settings.xml文件。

  3. IDE:强烈推荐使用IntelliJ IDEA(社区版或旗舰版)。它对 SpringBoot 的支持最为完善,可以极大提升开发效率。

3.2 辅助服务安装与启动

我们的项目需要数据库和缓存,请提前准备好。

  1. MySQL

    • 安装:从官网下载安装包或使用 Docker 快速启动。
    • 验证:使用命令行或客户端(如 Navicat, MySQL Workbench)连接,确保服务运行。
    • 创建数据库:我们后续会用到,先创建一个名为springboot_demo的数据库。
      CREATE DATABASE IF NOT EXISTS `springboot_demo` DEFAULT CHARACTER SET utf8mb4;
  2. Redis

    • 安装:Windows 用户可下载微软维护的版本或使用 WSL;Linux/macOS 用户可通过包管理器安装。
    • 验证:启动 Redis 服务后,使用redis-cli ping命令,收到PONG响应即表示成功。
      redis-cli ping # PONG

4. 项目创建与初始化

我们将使用 Spring Initializr 来生成项目骨架,这是最标准、最快捷的方式。

4.1 通过 IDEA 创建项目

  1. 打开 IntelliJ IDEA,选择New Project
  2. 左侧选择Spring Initializr
  3. 填写项目元数据:
    • Project SDK:选择你安装的 JDK。
    • Namedemo(或你喜欢的项目名)
    • Location:选择项目存放路径。
    • TypeMaven
    • LanguageJava
    • PackagingJar
    • Java Version11(与你安装的 JDK 版本匹配)
    • Groupcom.example
    • Artifactdemo
  4. 点击Next,进入依赖选择页面。在这里勾选我们初期需要的依赖
    • Spring Web:用于构建 Web 应用,包含 RESTful API 支持。
    • Lombok:简化 Java Bean 的编写(自动生成 getter/setter 等)。
    • MySQL Driver:MySQL 数据库连接驱动。
    • MyBatis Framework:数据持久层框架。(注意:这里我们先选 Spring 官方的 MyBatis Starter,后续会换成 MyBatis-Plus)
  5. 点击Next,选择项目路径,然后Finish。IDEA 会自动下载初始依赖并打开项目。

4.2 调整依赖为 MyBatis-Plus

Spring Initializr 没有直接提供 MyBatis-Plus 的选项,我们需要手动修改pom.xml文件。

  1. 找到项目根目录下的pom.xml
  2. 移除之前选择的MyBatis Framework依赖(如果已勾选),并添加 MyBatis-Plus 的 Starter 依赖。同时,我们提前把 Redis 和 Knife4j 的依赖也加上。
    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- ... 其他父项目、groupId 等配置 ... --> <dependencies> <!-- Spring Boot Web Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- MySQL Driver --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <!-- MyBatis-Plus Starter (替换官方的 mybatis-spring-boot-starter) --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> <!-- 请使用最新稳定版 --> </dependency> <!-- Redis Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- Knife4j 接口文档 (基于 Swagger 3) --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-spring-boot-starter</artifactId> <version>4.4.0</version> <!-- 请使用最新稳定版 --> </dependency> <!-- Spring Boot Test Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <!-- ... 其他配置 ... --> </project>
  3. 修改完成后,IDEA 通常会提示 Maven 依赖变更,点击刷新按钮(或右键pom.xml->Maven->Reload project)下载新依赖。

5. 核心功能开发与验证

现在,我们从数据层到接口层,一步步构建功能。

5.1 数据库连接与实体类

  1. 配置数据库连接:打开src/main/resources/application.properties文件,重命名为application.yml(YAML 格式更清晰),并配置:

    spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/springboot_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root # 你的数据库用户名 password: 123456 # 你的数据库密码 redis: host: localhost port: 6379 # password: # 如果 Redis 设置了密码,取消注释并填写 database: 0 timeout: 3000ms lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0 # MyBatis-Plus 配置 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台打印 SQL 日志,便于调试 global-config: db-config: id-type: auto # 主键策略,数据库自增 logic-delete-field: deleted # 全局逻辑删除字段名(如果要用) logic-delete-value: 1 # 逻辑已删除值 logic-not-delete-value: 0 # 逻辑未删除值 # Knife4j 配置 knife4j: enable: true # 开启 Knife4j 增强 setting: language: zh_cn
  2. 创建实体类:我们以一个简单的User用户表为例。在src/main/java/com/example/demo/entity包下创建User.java

    package com.example.demo.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.time.LocalDateTime; @Data // Lombok 注解,自动生成 getter, setter, toString 等 @TableName("sys_user") // 指定对应数据库表名 public class User { @TableId(type = IdType.AUTO) // 主键自增 private Long id; private String username; private String password; private String email; private Integer status; private LocalDateTime createTime; private LocalDateTime updateTime; }

5.2 MyBatis-Plus 数据层开发

MyBatis-Plus 提供了强大的 CRUD 接口,极大简化了开发。

  1. 创建 Mapper 接口:在src/main/java/com/example/demo/mapper包下创建UserMapper.java

    package com.example.demo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.demo.entity.User; import org.apache.ibatis.annotations.Mapper; @Mapper // 标记为 MyBatis 的 Mapper,Spring 会自动扫描 public interface UserMapper extends BaseMapper<User> { // 继承 BaseMapper 后,基础的 CRUD 方法已全部拥有,无需编写 XML // 如果需要复杂查询,可以在此定义方法,并在 resources/mapper/ 下编写对应的 XML }
  2. 创建 Service 层:在src/main/java/com/example/demo/service包下创建UserService.java接口及其实现。

    // UserService.java (接口) package com.example.demo.service; import com.baomidou.mybatisplus.extension.service.IService; import com.example.demo.entity.User; public interface UserService extends IService<User> { // 可以在此定义业务相关的方法 User getUserByUsername(String username); }
    // UserServiceImpl.java (实现类) package com.example.demo.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import com.example.demo.service.UserService; import org.springframework.stereotype.Service; @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { @Override public User getUserByUsername(String username) { LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(User::getUsername, username); return this.getOne(wrapper); } }

5.3 控制器与 RESTful API

现在创建 Controller 来暴露 HTTP 接口。

src/main/java/com/example/demo/controller包下创建UserController.java

package com.example.demo.controller; import com.example.demo.entity.User; import com.example.demo.service.UserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/user") @Tag(name = "用户管理", description = "用户相关接口") // Knife4j 接口分组 public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") @Operation(summary = "根据ID查询用户") // 接口描述 public User getUserById(@PathVariable Long id) { return userService.getById(id); } @GetMapping("/list") @Operation(summary = "获取用户列表") public List<User> getUserList() { return userService.list(); } @PostMapping @Operation(summary = "新增用户") public Boolean addUser(@RequestBody User user) { // 实际业务中,密码需要加密,此处仅为演示 return userService.save(user); } @PutMapping @Operation(summary = "更新用户") public Boolean updateUser(@RequestBody User user) { return userService.updateById(user); } @DeleteMapping("/{id}") @Operation(summary = "删除用户") public Boolean deleteUser(@PathVariable Long id) { return userService.removeById(id); } }

5.4 集成 Redis 缓存

Spring Data Redis 提供了简单的模板和注解式缓存。

  1. 配置 Redis 序列化(可选但推荐):为了在 Redis 中看到更可读的数据,可以配置 Key 和 Value 的序列化方式。创建一个配置类RedisConfig.java

    package com.example.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); // 设置 key 的序列化器 template.setKeySerializer(new StringRedisSerializer()); // 设置 value 的序列化器为 JSON template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); template.afterPropertiesSet(); return template; } }
  2. 使用缓存注解:修改UserService的实现,为getUserByUsername方法添加缓存。

    // 在 UserServiceImpl.java 中修改 getUserByUsername 方法 @Override @Cacheable(value = "user", key = "#username", unless = "#result == null") // 缓存名为user,key为用户名,如果结果为null则不缓存 public User getUserByUsername(String username) { System.out.println("从数据库查询用户: " + username); // 模拟缓存未命中时打印 LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(User::getUsername, username); return this.getOne(wrapper); }

    并在启动类DemoApplication上添加@EnableCaching注解以开启缓存功能。

    @SpringBootApplication @EnableCaching // 开启缓存注解支持 public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }

5.5 集成 Knife4j 生成接口文档

Knife4j 的配置非常简单,我们之前已经在application.yml中开启了增强。现在需要创建一个配置类来设定文档信息。

config包下创建SwaggerConfig.java(或OpenApiConfig.java)。

package com.example.demo.config; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SwaggerConfig { @Bean public OpenAPI springShopOpenAPI() { return new OpenAPI() .info(new Info() .title("SpringBoot 实战项目 API 文档") .description("这是一个整合了 MyBatis-Plus、Redis 的 SpringBoot 演示项目") .version("v1.0.0")); } }

6. 功能测试与效果验证

现在,启动项目并逐一验证我们开发的功能。

6.1 启动项目与数据库表创建

  1. 启动主类:运行src/main/java/com/example/demo/DemoApplication.java中的main方法。控制台应看到 SpringBoot 的 Banner 和启动日志,没有报错。
  2. 自动建表:MyBatis-Plus 本身不提供 DDL 自动生成。为了快速测试,我们可以使用其代码生成器或在resources下放置一个schema.sql文件让 Spring Boot 启动时执行。这里我们手动执行 SQL 创建表:
    USE springboot_demo; CREATE TABLE IF NOT EXISTS `sys_user` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT NULL, `password` varchar(100) DEFAULT NULL, `email` varchar(100) DEFAULT NULL, `status` int DEFAULT '1', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

6.2 接口测试与缓存验证

  1. 访问接口文档:项目启动后,打开浏览器,访问http://localhost:8080/doc.html。你将看到 Knife4j 漂亮的接口文档页面,里面列出了我们编写的所有用户管理接口。

    • 验证点:能正常打开文档页面,且UserController下的接口清晰可见。
  2. 测试新增用户接口

    • 在 Knife4j 页面找到POST /api/user接口,点击“调试”。
    • 在请求体中输入 JSON:
      { "username": "testUser", "password": "123456", "email": "test@example.com" }
    • 点击“发送”,观察响应。应为true
    • 验证点:接口返回成功,并去数据库查询sys_user表,确认数据已插入。
  3. 测试查询用户列表接口

    • 调试GET /api/user/list接口。
    • 验证点:返回包含刚才新增用户的 JSON 数组。
  4. 测试 Redis 缓存

    • 调试GET /api/user/{id}接口,传入刚才新增用户的 ID。
    • 第一次调用时,控制台会打印“从数据库查询用户...”的 SQL 日志。
    • 立即再次调用同一个接口。如果缓存生效,控制台将不会再次打印 SQL 日志,且响应速度会更快。
    • 你还可以使用redis-cli命令行工具,执行keys *查看是否有user::testUser这样的键,验证数据是否已存入 Redis。
    • 验证点:第二次及后续查询不再访问数据库,证明@Cacheable注解生效。

6.3 项目打包与运行

  1. 使用 Maven 打包:在项目根目录下执行命令。

    mvn clean package -DskipTests

    命令执行成功后,会在target目录下生成demo-0.0.1-SNAPSHOT.jar文件。

  2. 运行 JAR 包

    java -jar target/demo-0.0.1-SNAPSHOT.jar

    验证点:应用应能正常启动,访问http://localhost:8080/doc.html接口文档依然可用。这证明我们成功构建了一个可独立部署的 SpringBoot 应用。

7. 常见问题与排查方法

在学习和实践过程中,你可能会遇到以下问题。这里提供排查思路。

问题现象可能原因排查方式解决方案
启动时报java.net.ConnectException: Connection refused数据库或 Redis 服务未启动。1. 检查 MySQL 服务状态。
2. 检查 Redis 服务状态。
3. 确认application.yml中的连接地址、端口、密码是否正确。
启动相应的服务,或修正配置文件。
启动时报Failed to configure a DataSource未配置数据源,或数据库驱动依赖缺失。1. 检查pom.xml是否有mysql-connector-j依赖。
2. 检查application.ymlspring.datasource配置是否正确。
添加依赖,或正确配置数据源。如果暂时不用数据库,可在启动类排除数据源自动配置:@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
访问接口返回4041. 请求路径错误。
2. Controller 未被扫描到。
1. 核对浏览器地址或 Knife4j 中的接口路径。
2. 确认 Controller 类在启动类所在包或其子包下。
修正请求路径。或将启动类移动到更顶层的包。
MyBatis-Plus 打印的 SQL 中表名不对实体类未使用@TableName指定表名,或数据库表不存在。1. 检查实体类上的@TableName注解。
2. 检查数据库是否存在该表。
添加或修正@TableName注解。执行建表 SQL。
@Cacheable缓存不生效1. 启动类未加@EnableCaching
2. Redis 连接失败。
3. 方法被内部调用(非代理调用)。
1. 检查启动类注解。
2. 检查 Redis 配置和连接。
3. 确保缓存方法是通过 Spring 代理对象调用的(如从 Controller 调用 Service)。
添加注解,检查 Redis,确保调用方式正确。
Knife4j 页面doc.html无法访问1. 依赖未正确引入。
2. 路径被拦截。
3. 项目未启动成功。
1. 检查pom.xml中 knife4j 依赖。
2. 检查是否有安全框架(如 Security)拦截了静态资源。
3. 查看启动日志是否有错误。
确认依赖,调整安全配置,或直接访问http://localhost:8080/v3/api-docs看原始 JSON 是否存在。
打包后运行报No main manifest attributeMaven 打包插件配置问题,未指定主类。检查pom.xml中的spring-boot-maven-plugin插件。确保使用了 Spring Boot 的父工程或正确配置了该插件。

8. 最佳实践与进阶方向

完成基础功能搭建后,这里有一些建议帮助你走得更远。

  1. 代码分层清晰:坚持Controller->Service->Mapper的分层结构,各司其职。Controller只负责参数校验和响应封装,业务逻辑放在Service层。
  2. 使用统一响应体:定义如Result<T>这样的通用响应类,包含codemsgdata字段,使前端对接更规范。
  3. 全局异常处理:使用@ControllerAdvice@ExceptionHandler捕获并处理全局异常,返回友好的错误信息,而不是堆栈轨迹。
  4. 参数校验:在接收参数的 DTO 类上使用javax.validation注解(如@NotBlank,@Email)进行校验,并在 Controller 方法参数前加@Valid注解触发校验。
  5. 配置文件分离:将application.yml按环境拆分,如application-dev.yml(开发)、application-prod.yml(生产),通过spring.profiles.active指定激活的环境。
  6. 连接池监控:生产环境建议使用 Druid 连接池替代默认的 HikariCP,因为它提供了更强大的监控功能。
  7. 安全与权限:引入Spring Security或更轻量的Sa-Token进行完整的认证授权管理,而不仅仅是简单的 Token 校验。
  8. 单元测试:为 Service 层和 Controller 层编写单元测试(使用@SpringBootTest),保证代码质量。
  9. API 版本管理:如果 API 需要迭代,考虑在 URL 路径(如/api/v1/user)或请求头中管理版本号。
  10. 部署与监控:学习使用 Docker 容器化部署 SpringBoot 应用,并集成 Actuator 端点进行健康检查和指标监控。

这条学习路径的核心价值在于,它通过一个连贯的项目,将 SpringBoot 及其核心生态组件(Web、MyBatis-Plus、Redis、接口文档)串联起来,让你在动手实践中理解它们是如何协同工作的。先跑通这个“最小可行系统”,再根据实际需求,去深入每个组件的细节和高级特性,这样的学习效率最高,也最能建立信心。建议你将这个项目作为基础模板保存,后续的新项目或新功能都可以在此基础上快速扩展。