拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Spring Boot新手入门:从零搭建Java Web项目并连接MySQL数据库

在实际开发中很多新手开发者常被戏称为“菜鸟”在入门时面对海量的技术栈、复杂的配置和层出不穷的报错信息常常感到无从下手。一个看似简单的“Hello World”项目背后可能涉及环境变量、依赖管理、构建工具、运行时配置等一系列环节任何一个环节出错都可能导致程序无法运行。本文将以一个典型的Java Web项目为例模拟一位新手从零开始搭建一个Spring Boot应用并连接MySQL数据库的完整过程。我们将不假设任何前置知识而是从一个空文件夹开始逐步解释每一个命令、每一个配置项、每一个注解的作用并重点拆解在这个过程中最可能遇到的“坑”及其排查思路。通过这篇教程你将不仅学会如何搭建一个项目更重要的是理解每一步背后的“为什么”以及当程序不按预期运行时应该从哪里开始“发问”和排查。1. 理解项目骨架Spring Boot 与 Maven 的核心作用在开始写代码之前我们需要先理解将要使用的工具链。很多新手会直接复制粘贴命令和配置却不明白这些工具解决了什么问题导致一旦出现版本冲突或配置错误就束手无策。1.1 为什么选择 Spring BootSpring Boot 的核心价值是“约定大于配置”。在传统的 Spring MVC 项目中你需要手动配置大量的 XML 文件或 Java Config 来定义 DispatcherServlet、视图解析器、数据源、事务管理器等。Spring Boot 通过自动配置Auto-Configuration和起步依赖Starter Dependencies将这些繁琐的配置标准化。起步依赖例如当你引入spring-boot-starter-web它不仅引入了 Spring MVC 的库还内嵌了 Tomcat 服务器你无需再单独下载和配置 Tomcat。自动配置Spring Boot 会根据你引入的 jar 包自动推断并配置你需要的 Bean。比如当 classpath 下存在 MySQL 驱动和spring-boot-starter-data-jpa时它会尝试自动配置一个DataSource。对于新手来说这极大地降低了入门门槛让你可以更专注于业务逻辑而不是基础设施的搭建。1.2 Maven 是做什么的Maven 是一个项目构建和依赖管理工具。你可以把它想象成一个项目的“管家”依赖管理在pom.xml文件中声明你的项目需要哪些第三方库如 Spring、MySQL驱动、Jackson等Maven 会自动从中央仓库下载这些库及其依赖项并解决版本冲突。构建生命周期它定义了一套标准的构建流程如编译compile、测试test、打包package、安装install等。你只需要执行mvn clean package它就会按顺序执行清理、编译、运行测试、打包成 jar/war 文件。项目结构标准化Maven 约定了一套标准的目录结构如src/main/java,src/main/resources这有利于团队协作和工具集成。没有 Maven你需要手动下载几十个 jar 包并确保它们版本兼容这几乎是不可能完成的任务。2. 环境准备与项目初始化这是最容易出错的阶段。环境没配好后面所有步骤都可能失败。2.1 基础环境检查清单在开始之前请确保你的机器上已经安装了以下软件并且版本符合要求。打开你的终端Windows 用 CMD 或 PowerShellMac/Linux 用 Terminal逐一验证。软件检查命令预期输出示例作用Java JDKjava -versionopenjdk version “17.0.10” 2024-01-16项目的运行环境Spring Boot 3.x 需要 JDK 17。Mavenmvn -vApache Maven 3.9.6项目构建和依赖管理工具。MySQLmysql --versionmysql Ver 8.0.36 for Linux on x86_64本项目使用的数据库。你也可以使用 Docker 快速启动一个。Git (可选)git --versiongit version 2.43.0版本控制方便管理代码和回溯。如果任何一条命令显示“不是内部或外部命令”或“command not found”你需要先安装对应的软件。常见坑点 1JAVA_HOME 环境变量未配置或配置错误现象java -version可以运行但mvn -v报错提示JAVA_HOME未设置。原因Maven 需要依赖JAVA_HOME环境变量来定位 JDK 的安装位置。解决找到你的 JDK 安装路径例如C:\Program Files\Java\jdk-17。在系统环境变量中新建一个变量名称为JAVA_HOME值为上述路径。在Path变量中新增%JAVA_HOME%\bin。重新打开终端再次执行mvn -v。2.2 使用 Spring Initializr 快速生成项目手动创建pom.xml和目录结构容易出错推荐使用 Spring 官方提供的 start.spring.io 来生成项目骨架。访问网站打开浏览器进入https://start.spring.io。选择参数Project: MavenLanguage: JavaSpring Boot: 选择最新的稳定版如 3.2.3Project Metadata:Group:com.example(通常用公司域名倒写)Artifact:demo(你的项目名)Name:demoDescription:Demo project for Spring BootPackage name:com.example.demo(会自动生成)Packaging: Jar (Spring Boot 推荐的可执行 Jar)Java: 17 (与你的 JDK 版本一致)添加依赖在 Dependencies 区域点击 “ADD DEPENDENCIES”搜索并添加Spring Web(用于构建 Web API)Spring Data JPA(用于数据库操作)MySQL Driver(MySQL 数据库连接驱动)Lombok(可选用于简化 Java Bean 的 Getter/Setter 代码)生成项目点击页面下方的 “GENERATE” 按钮下载一个名为demo.zip的压缩包。解压并导入将压缩包解压到你的工作目录然后用你熟悉的 IDE如 IntelliJ IDEA 或 VS Code打开这个文件夹。关键文件结构预览demo/ ├── pom.xml # Maven 项目核心配置文件定义了依赖和构建方式 ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── demo/ │ │ │ └── DemoApplication.java # Spring Boot 主启动类 │ │ └── resources/ │ │ ├── application.properties # 配置文件我们将在这里配置数据库 │ │ └── static/ # 存放静态资源如 CSS, JS │ └── test/ # 测试代码目录 └── target/ # Maven 编译输出目录初始不存在3. 配置数据库与编写第一个实体类项目骨架有了接下来要让程序能连接到数据库并定义我们的数据表结构。3.1 配置 MySQL 数据库连接打开src/main/resources/application.properties文件。这个文件是 Spring Boot 默认的配置文件。我们将使用application.yml因为它结构更清晰。你可以将application.properties重命名为application.yml或者直接新建一个application.yml文件。在application.yml中添加以下配置spring: datasource: url: jdbc:mysql://localhost:3306/springboot_demo?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai username: root password: your_password # 替换为你的 MySQL root 密码 driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update # Hibernate 自动更新表结构 show-sql: true # 在控制台打印执行的 SQL 语句便于调试 properties: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect配置项解释spring.datasource.url: 数据库连接字符串。localhost:3306是 MySQL 默认地址和端口。springboot_demo是数据库名如果不存在JPA 在首次连接时会尝试创建取决于权限。serverTimezone参数非常重要不设置可能导致时间错误。spring.jpa.hibernate.ddl-auto: 这个参数控制着表结构的自动生成策略。create: 每次启动都会删除旧表创建新表。数据会丢失update: 启动时检查表结构如果不同则更新不会删除数据。开发环境常用validate: 仅验证表结构是否匹配不修改。create-drop: 类似create但在 SessionFactory 关闭时删除表。none: 不执行任何操作。生产环境必须使用这个并通过 Flyway/Liquibase 管理数据库变更注意在生产环境中绝对不要使用update。表结构的变更必须通过数据库迁移脚本如 Flyway来管理以保证变更的可控和可回滚。常见坑点 2数据库连接失败现象启动应用时控制台报错Access denied for user ‘root‘‘localhost‘或Unknown database ‘springboot_demo‘。排查检查密码确认application.yml中的密码是否正确。检查数据库是否存在登录 MySQL (mysql -u root -p)执行SHOW DATABASES;查看是否有springboot_demo。如果没有执行CREATE DATABASE springboot_demo;创建它。检查用户权限确保你使用的 MySQL 用户如 root有权限访问localhost和操作springboot_demo数据库。检查 MySQL 服务确保 MySQL 服务正在运行。3.2 定义实体类 (Entity)实体类对应数据库中的一张表。我们在src/main/java/com/example/demo/目录下新建一个entity包并在其中创建User.java。package com.example.demo.entity; import jakarta.persistence.*; import lombok.Data; import java.time.LocalDateTime; Entity // 标记这是一个 JPA 实体类对应数据库中的一张表 Table(name “user”) // 指定表名如果省略则默认使用类名 Data // Lombok 注解自动生成 getter, setter, toString, equals, hashCode 方法 public class User { Id // 标记为主键 GeneratedValue(strategy GenerationType.IDENTITY) // 主键自增策略MySQL的AUTO_INCREMENT private Long id; Column(nullable false, unique true) // 对应数据库字段非空且唯一 private String username; Column(nullable false) private String password; private String email; Column(name “created_at”) // 指定数据库中的列名 private LocalDateTime createdAt; PrePersist // JPA 生命周期回调在数据持久化插入之前执行 protected void onCreate() { createdAt LocalDateTime.now(); // 自动设置创建时间 } }代码解释Entity,Table,Id,GeneratedValue,Column都是 JPAJava Persistence API的标准注解用于完成对象与关系数据库的映射ORM。Data是 Lombok 的注解。如果没有它你需要手动为每个字段编写getter和setter方法。使用 Lombok 可以让代码更简洁。确保你的 IDE 安装了 Lombok 插件否则编译时可能会报错找不到getter/setter。LocalDateTime是 Java 8 引入的日期时间 API比旧的Date和Calendar更好用。PrePersist是一个回调方法在数据被插入数据库前自动为createdAt字段赋值为当前时间。4. 创建数据访问层与业务逻辑有了实体我们需要一个“仓库”来存取它。在 Spring Data JPA 中这个“仓库”叫Repository。4.1 创建 Repository 接口在src/main/java/com/example/demo/下新建一个repository包创建UserRepository.java接口。package com.example.demo.repository; import com.example.demo.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.Optional; Repository // 标记这是一个数据访问层组件可省略因为 JpaRepository 已经包含了 public interface UserRepository extends JpaRepositoryUser, Long { // 根据用户名查找用户 OptionalUser findByUsername(String username); // 检查用户名是否存在 boolean existsByUsername(String username); // 根据邮箱查找用户 OptionalUser findByEmail(String email); }神奇之处你不需要实现这个接口Spring Data JPA 会根据方法名如findByUsername在运行时自动生成实现。这遵循了“约定大于配置”的原则。extends JpaRepositoryUser, Long继承的泛型中User是实体类型Long是主键类型。OptionalT是 Java 8 引入的容器类用于避免null检查。如果查不到数据返回Optional.empty()而不是null更安全。4.2 创建服务层 (Service)服务层负责业务逻辑。在src/main/java/com/example/demo/下新建service包创建UserService.java。package com.example.demo.service; import com.example.demo.entity.User; import com.example.demo.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; Service // 标记这是一个业务逻辑层组件 public class UserService { Autowired // 自动注入 UserRepository 实例 private UserRepository userRepository; /** * 用户注册 * param username 用户名 * param password 明文密码 * param email 邮箱 * return 注册成功的用户对象 * throws RuntimeException 如果用户名已存在 */ public User register(String username, String password, String email) { // 1. 检查用户名是否已存在 if (userRepository.existsByUsername(username)) { throw new RuntimeException(“用户名已存在”); } // 2. 创建用户对象 User user new User(); user.setUsername(username); // 密码不应明文存储这里使用简单的 MD5 哈希生产环境应用更安全的算法如 BCrypt user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8))); user.setEmail(email); // createdAt 字段由 PrePersist 自动设置 // 3. 保存到数据库 return userRepository.save(user); } /** * 用户登录简单演示生产环境需用安全框架 * param username 用户名 * param password 明文密码 * return 登录成功的用户对象 * throws RuntimeException 如果用户名或密码错误 */ public User login(String username, String password) { // 1. 根据用户名查找用户 User user userRepository.findByUsername(username) .orElseThrow(() - new RuntimeException(“用户不存在”)); // 2. 验证密码 String inputPasswordHash DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8)); if (!inputPasswordHash.equals(user.getPassword())) { throw new RuntimeException(“密码错误”); } // 3. 返回用户信息生产环境应返回 Token return user; } }业务逻辑要点依赖注入Autowired让 Spring 容器自动将UserRepository的实现实例赋值给userRepository字段。密码处理绝对不要将明文密码存入数据库。这里使用了 Spring 自带的DigestUtils.md5DigestAsHex进行简单的哈希。注意MD5 已被证明不安全生产环境必须使用BCryptPasswordEncoder等加盐的强哈希算法。异常处理使用RuntimeException抛出业务异常。在真实的控制器层我们需要捕获这些异常并转换为友好的 HTTP 状态码和错误信息返回给前端。5. 创建 Web API 控制器服务层写好了现在需要暴露 HTTP 接口供前端调用。我们创建控制器Controller。在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 org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; RestController // 等同于 Controller ResponseBody直接返回 JSON 数据 RequestMapping(“/api/users”) // 定义该控制器下所有接口的基础路径 public class UserController { Autowired private UserService userService; PostMapping(“/register”) public User register(RequestBody RegisterRequest request) { // RequestBody 表示从 HTTP 请求体中解析 JSON 数据 return userService.register(request.getUsername(), request.getPassword(), request.getEmail()); } PostMapping(“/login”) public User login(RequestBody LoginRequest request) { return userService.login(request.getUsername(), request.getPassword()); } // 内部静态类用于接收请求体 static class RegisterRequest { private String username; private String password; private String email; // 省略 getter 和 setter (实际开发中需加上或使用 Lombok Data) public String getUsername() { return username; } public void setUsername(String username) { this.username username; } // ... 其他 getter/setter } static class LoginRequest { private String username; private String password; // ... getter/setter } }控制器要点RestController标记这个类是 Web 控制器并且其所有方法的返回值都会直接写入 HTTP 响应体通常转换为 JSON。RequestMapping(“/api/users”)为该控制器下的所有请求映射添加一个前缀/api/users。所以注册接口的完整路径是POST /api/users/register。PostMapping指定该方法处理 HTTP POST 请求。RequestBody将请求体中的 JSON 数据绑定到方法参数对象上。6. 运行与验证所有代码都已就绪现在是验证成果的时候了。6.1 启动应用程序找到主启动类DemoApplication.java其内容应该类似package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication // 核心注解开启组件扫描、自动配置等 public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }在你的 IDE 中右键点击这个类选择 “Run DemoApplication”。或者在项目根目录下打开终端执行 Maven 命令mvn spring-boot:run如果一切顺利你将在控制台看到 Spring Boot 的启动日志最后一行应该是类似这样的信息Started DemoApplication in 3.456 seconds (process running for 3.789)同时由于我们配置了show-sql: true当 JPA 操作数据库时你会在日志中看到生成的 SQL 语句。6.2 使用 API 测试工具进行测试Spring Boot 应用默认运行在8080端口。我们使用curl命令或 Postman 等工具来测试 API。1. 测试用户注册curl -X POST http://localhost:8080/api/users/register \ -H “Content-Type: application/json” \ -d ‘{ “username”: “testuser”, “password”: “mypassword123”, “email”: “testexample.com” }’预期成功响应JSON格式{ “id”: 1, “username”: “testuser”, “password”: “e10adc3949ba59abbe56e057f20f883e”, // MD5 哈希后的密码 “email”: “testexample.com”, “createdAt”: “2024-05-27T10:30:00” }2. 测试重复注册 再次发送相同的注册请求。预期错误响应应用会抛出RuntimeException(“用户名已存在”)Spring Boot 默认会返回一个包含错误堆栈的 JSON状态码 500。在生产环境中我们需要全局异常处理来返回更友好的错误信息。3. 测试用户登录curl -X POST http://localhost:8080/api/users/login \ -H “Content-Type: application/json” \ -d ‘{ “username”: “testuser”, “password”: “mypassword123” }’预期成功响应返回用户信息不含密码哈希则更佳。4. 测试密码错误登录curl -X POST http://localhost:8080/api/users/login \ -H “Content-Type: application/json” \ -d ‘{ “username”: “testuser”, “password”: “wrongpassword” }’预期错误响应抛出RuntimeException(“密码错误”)。6.3 验证数据库登录 MySQL查看数据是否真的被写入。mysql -u root -p USE springboot_demo; SELECT * FROM user;你应该能看到一条username为testuser的记录password字段是哈希值。7. 常见问题深度排查指南即使按照教程一步步操作你也可能会遇到问题。以下是基于这个项目的系统性排查路径。7.1 应用启动失败问题现象可能原因检查点与解决方案APPLICATION FAILED TO START1. 配置错误如数据库连接失败。2. 依赖冲突。3. 端口被占用。1.仔细阅读控制台日志Spring Boot 的启动失败信息通常非常详细会直接指出哪个 Bean 创建失败、哪个配置项有问题。第一屏的红色错误信息是关键。2.检查application.yml缩进是否正确YAML 对缩进敏感数据库IP、端口、用户名、密码是否正确数据库服务是否启动。3.检查端口如果报Port 8080 was already in use可以修改server.port配置或使用netstat -ano | findstr :8080(Windows) /lsof -i :8080(Mac/Linux) 找到占用进程并结束它。ClassNotFoundException或NoClassDefFoundError1. 依赖未正确下载。2. IDE 未正确导入 Maven 项目。1. 在项目根目录执行mvn clean compile观察是否下载依赖成功。2. 在 IDE 中右键点击pom.xml选择 “Maven” - “Reload Project”。3. 检查本地 Maven 仓库默认在~/.m2/repository是否有损坏可尝试删除相关依赖目录重新下载。BeanCreationExceptionSpring 容器无法创建某个 Bean通常是依赖注入失败或配置有误。1. 检查被Autowired的字段对应的类是否被 Spring 管理即是否有Service,Repository,Component等注解。2. 检查是否存在多个同类型的 Bean 导致注入歧义可使用Qualifier指定。7.2 API 请求不通或报错问题现象可能原因检查点与解决方案404 Not Found1. 请求 URL 错误。2. 控制器未扫描到。1. 确认请求的 Method (GET/POST) 和 URL 与RequestMapping,GetMapping,PostMapping定义的完全一致。2. 确认控制器类所在的包在主启动类DemoApplication的同级或下级目录。Spring Boot 默认扫描主类所在包及其子包。415 Unsupported Media Type请求头Content-Type不正确。对于接收RequestBody的 POST 接口必须设置Content-Type: application/json。400 Bad Request1. 请求体 JSON 格式错误。2. 字段类型不匹配。1. 使用 JSON 格式化工具检查 JSON 格式是否正确。2. 检查请求体中的字段名和类型是否与控制器方法参数类中的定义一致。500 Internal Server Error业务代码抛出未捕获的异常。1.查看控制台日志这是最重要的线索异常堆栈会打印出来。2. 检查是否是数据库操作失败如唯一约束冲突。3. 检查服务层UserService中抛出的RuntimeException。7.3 数据库相关问题问题现象可能原因检查点与解决方案表没有自动创建1.ddl-auto配置为none或validate。2. 数据库用户无建表权限。3. 实体类Entity注解缺失或包未被扫描。1. 确认application.yml中ddl-auto为update。2. 检查 MySQL 用户权限。3. 确认实体类在主启动类的扫描范围内。字段名或类型与预期不符JPA 命名策略或Column配置问题。1. 默认情况下JPA 会将camelCase字段名转换为snake_case列名如createdAt-created_at。2. 使用Column(name “my_column”)显式指定列名。3. 查看控制台show-sql打印的建表语句。中文乱码数据库、连接字符串或应用编码不统一。1. 确保数据库、表、字段的字符集为utf8mb4。2. 在 JDBC URL 中加上useUnicodetruecharacterEncodingutf-8。3. 确保应用代码文件编码为 UTF-8。8. 从学习到生产必须考虑的优化与安全这个简单的 Demo 可以运行但距离一个可上线的生产级应用还有很大差距。以下是几个关键的改进方向。8.1 全局异常处理目前业务异常直接抛出RuntimeException会返回 500 错误和堆栈信息这对用户不友好且不安全。我们需要一个全局异常处理器。package com.example.demo.handler; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import java.util.HashMap; import java.util.Map; RestControllerAdvice // 声明这是一个全局控制器异常处理类 public class GlobalExceptionHandler { ExceptionHandler(RuntimeException.class) // 处理所有 RuntimeException ResponseStatus(HttpStatus.BAD_REQUEST) // 返回 400 状态码 public MapString, Object handleBusinessException(RuntimeException e) { MapString, Object result new HashMap(); result.put(“code”, 400); result.put(“message”, e.getMessage()); // 返回业务异常信息 result.put(“data”, null); // 生产环境不应返回堆栈信息 result.put(“error”, e.toString()); return result; } // 可以添加更多 ExceptionHandler 来处理其他特定异常 }8.2 密码安全升级使用 BCrypt 替代 MD5。首先修改pom.xml添加 Spring Security 的密码编码器依赖即使你不用完整的 Security 功能。dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-security/artifactId /dependency然后在配置类或服务中创建PasswordEncoderBean。package com.example.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; Configuration public class SecurityConfig { Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }最后修改UserService注入并使用PasswordEncoder。Service public class UserService { Autowired private UserRepository userRepository; Autowired private PasswordEncoder passwordEncoder; // 注入 BCrypt 编码器 public User register(String username, String password, String email) { // ... 检查用户名 ... User user new User(); user.setUsername(username); // 使用 BCrypt 加密 user.setPassword(passwordEncoder.encode(password)); user.setEmail(email); return userRepository.save(user); } public User login(String username, String password) { User user userRepository.findByUsername(username) .orElseThrow(() - new RuntimeException(“用户不存在”)); // 使用 BCrypt 的 matches 方法验证 if (!passwordEncoder.matches(password, user.getPassword())) { throw new RuntimeException(“密码错误”); } return user; } }8.3 配置分离与多环境生产环境的数据库密码、密钥等敏感信息绝不能写在代码里。需要使用环境变量或外部配置文件。创建多环境配置文件application-dev.yml(开发环境)application-prod.yml(生产环境)在application.yml中指定激活的环境spring: profiles: active: activatedProperties # 通常通过启动参数 -Dspring.profiles.activeprod 指定在application-prod.yml中使用环境变量或配置中心spring: datasource: url: ${DB_URL:jdbc:mysql://prod-db:3306/demo} username: ${DB_USER} password: ${DB_PASSWORD} # 从环境变量读取启动时指定环境java -jar demo.jar --spring.profiles.activeprod8.4 接口文档与单元测试接口文档集成 Swagger/OpenAPI (springdoc-openapi-starter-webmvc-ui)自动生成 API 文档便于前后端联调。单元测试为UserService编写单元测试使用SpringBootTest和DataJpaTest确保业务逻辑正确。这是保证代码质量的基础。完成以上步骤你不仅完成了一个 Spring Boot 应用的搭建更走完了一个新手从“发问”到“入门”的完整认知闭环理解了工具链的价值、掌握了配置的方法、实现了核心业务、学会了排查问题的路径并了解了从演示代码到生产代码需要跨越的鸿沟。接下来你可以尝试集成 Redis 做缓存、使用 MyBatis-Plus 简化 DAO 层、或者学习 Spring Security 构建完整的认证授权体系每一步都遵循类似的“理解概念 - 配置环境 - 编写代码 - 运行验证 - 排查问题 - 优化改进”的实践循环。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门