1. 环境准备与项目初始化在开始Spring Boot的增删改查开发前我们需要确保开发环境配置正确。我推荐使用IDEA 2024.1.3版本这是目前最稳定的版本与Spring Boot 3.2.x有很好的兼容性。1.1 IDEA基础配置首先打开IDEA进入File - New - Project创建新项目。选择Spring Initializr作为项目类型这是Spring官方提供的项目初始化工具能帮我们快速搭建基础框架。在SDK选择环节建议使用Java 17或21这是目前Spring Boot 3.x推荐使用的Java版本。注意社区版IDEA也能完成Spring Boot开发但部分企业级功能可能需要Ultimate版。如果遇到功能缺失可以考虑安装Spring Boot插件补充功能。项目创建时在Dependencies选项卡中勾选Spring Web (提供RESTful支持)Spring Data JPA (数据库操作)MySQL Driver (数据库连接)Lombok (简化实体类代码)1.2 数据库配置在application.properties文件中配置数据库连接spring.datasource.urljdbc:mysql://localhost:3306/springboot_demo?useSSLfalse spring.datasource.usernameroot spring.datasource.passwordyourpassword spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver spring.jpa.hibernate.ddl-autoupdate spring.jpa.show-sqltrue这里有几个关键点需要注意ddl-autoupdate会在应用启动时自动更新表结构适合开发环境show-sqltrue会在控制台打印SQL语句方便调试MySQL 8.0必须使用com.mysql.cj.jdbc.Driver驱动1.3 项目结构规划一个标准的Spring Boot项目结构如下src/main/java └── com.example.demo ├── controller # 控制器层 ├── model # 实体类 ├── repository # 数据访问层 ├── service # 业务逻辑层 └── DemoApplication.java # 启动类这种分层结构是Spring Boot项目的通用实践每层有明确的职责划分。我建议从一开始就遵循这种结构避免后期重构带来的麻烦。2. 实体类与Repository实现2.1 创建JPA实体类我们以学生信息管理系统为例首先创建Student实体类Entity Data NoArgsConstructor AllArgsConstructor public class Student { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; Column(nullable false) private String name; Column(unique true) private String studentNumber; private Integer age; private String gender; private String major; }这里使用了Lombok注解简化代码Data自动生成getter/setterNoArgsConstructor生成无参构造AllArgsConstructor生成全参构造GeneratedValue(strategy GenerationType.IDENTITY)表示主键自增这是MySQL的常用策略。2.2 创建Repository接口Spring Data JPA的强大之处在于它的Repository抽象public interface StudentRepository extends JpaRepositoryStudent, Long { ListStudent findByNameContaining(String name); ListStudent findByMajor(String major); OptionalStudent findByStudentNumber(String studentNumber); }这个接口虽然没有任何实现代码但Spring会自动为我们生成以下方法基本的CRUD操作分页和排序根据方法名自动推导的查询如findByNameContaining我在实际项目中发现合理命名查询方法可以避免大量重复代码。例如findByNameContaining会自动生成LIKE查询。2.3 自定义查询实现对于复杂查询可以使用Query注解Query(SELECT s FROM Student s WHERE s.age :minAge AND s.age :maxAge) ListStudent findByAgeBetween(Param(minAge) int minAge, Param(maxAge) int maxAge);这种方式比方法名推导更灵活可以处理复杂条件查询。在IDEA中编写JPQL时会有智能提示这是2024版的一个实用改进。3. Service层业务逻辑实现3.1 基础Service实现Service层负责业务逻辑处理是连接Controller和Repository的桥梁Service RequiredArgsConstructor public class StudentService { private final StudentRepository studentRepository; public Student createStudent(Student student) { if(studentRepository.existsByStudentNumber(student.getStudentNumber())) { throw new RuntimeException(学号已存在); } return studentRepository.save(student); } public ListStudent getAllStudents() { return studentRepository.findAll(); } public OptionalStudent getStudentById(Long id) { return studentRepository.findById(id); } public Student updateStudent(Long id, Student studentDetails) { Student student studentRepository.findById(id) .orElseThrow(() - new RuntimeException(学生不存在)); student.setName(studentDetails.getName()); student.setAge(studentDetails.getAge()); // 其他字段更新... return studentRepository.save(student); } public void deleteStudent(Long id) { Student student studentRepository.findById(id) .orElseThrow(() - new RuntimeException(学生不存在)); studentRepository.delete(student); } }这里有几个值得注意的点使用RequiredArgsConstructor自动注入Repository在创建学生时检查学号唯一性更新和删除操作前先检查实体是否存在3.2 异常处理改进上面的代码直接抛出RuntimeException实际项目中应该自定义异常ResponseStatus(HttpStatus.NOT_FOUND) public class StudentNotFoundException extends RuntimeException { public StudentNotFoundException(String message) { super(message); } } // 在Service中使用 throw new StudentNotFoundException(学生不存在);这样可以在Controller层统一处理异常返回更友好的错误信息。3.3 事务管理Spring默认对Repository方法启用事务但自定义Service方法需要显式声明Transactional public Student updateStudent(Long id, Student studentDetails) { // 方法实现... }Transactional可以确保方法内的多个数据库操作作为一个原子单元执行。我在实际项目中遇到过因为忘记加这个注解导致的数据不一致问题特别是在复杂的业务逻辑中。4. Controller层RESTful API实现4.1 基础CRUD接口使用Spring MVC实现RESTful APIRestController RequestMapping(/api/students) RequiredArgsConstructor public class StudentController { private final StudentService studentService; GetMapping public ResponseEntityListStudent getAllStudents() { return ResponseEntity.ok(studentService.getAllStudents()); } GetMapping(/{id}) public ResponseEntityStudent getStudentById(PathVariable Long id) { return studentService.getStudentById(id) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } PostMapping public ResponseEntityStudent createStudent(RequestBody Student student) { return ResponseEntity.status(HttpStatus.CREATED) .body(studentService.createStudent(student)); } PutMapping(/{id}) public ResponseEntityStudent updateStudent( PathVariable Long id, RequestBody Student studentDetails) { try { return ResponseEntity.ok(studentService.updateStudent(id, studentDetails)); } catch (RuntimeException e) { return ResponseEntity.notFound().build(); } } DeleteMapping(/{id}) public ResponseEntityVoid deleteStudent(PathVariable Long id) { try { studentService.deleteStudent(id); return ResponseEntity.noContent().build(); } catch (RuntimeException e) { return ResponseEntity.notFound().build(); } } }4.2 API文档生成IDEA 2024集成了Swagger UI的更好支持只需添加依赖dependency groupIdorg.springdoc/groupId artifactIdspringdoc-openapi-starter-webmvc-ui/artifactId version2.3.0/version /dependency启动应用后访问http://localhost:8080/swagger-ui.html即可看到API文档。我习惯在Controller方法上添加Operation注解补充说明Operation(summary 获取学生列表, description 返回所有学生信息) GetMapping public ResponseEntityListStudent getAllStudents() { // 方法实现 }4.3 分页与过滤对于大数据量查询应该实现分页GetMapping(/page) public ResponseEntityPageStudent getStudentsByPage( RequestParam(defaultValue 0) int page, RequestParam(defaultValue 10) int size) { return ResponseEntity.ok(studentService.getStudentsByPage(page, size)); } // Service实现 public PageStudent getStudentsByPage(int page, int size) { Pageable pageable PageRequest.of(page, size, Sort.by(name).ascending()); return studentRepository.findAll(pageable); }Spring Data的Page对象包含数据列表和分页元信息总页数、当前页等非常适合前端分页展示。5. 测试与调试技巧5.1 单元测试IDEA 2024对JUnit 5的支持更加完善。测试Service层的示例ExtendWith(MockitoExtension.class) class StudentServiceTest { Mock private StudentRepository studentRepository; InjectMocks private StudentService studentService; Test void shouldCreateStudent() { Student student new Student(null, 张三, 20240001, 20, 男, 计算机科学); when(studentRepository.save(any())).thenReturn(student); Student saved studentService.createStudent(student); assertNotNull(saved); assertEquals(张三, saved.getName()); } }使用Mockito可以隔离数据库依赖专注于测试业务逻辑。IDEA的测试运行器非常直观可以快速定位失败用例。5.2 集成测试测试Controller层的完整流程SpringBootTest AutoConfigureMockMvc class StudentControllerTest { Autowired private MockMvc mockMvc; MockBean private StudentService studentService; Test void shouldReturnStudentList() throws Exception { when(studentService.getAllStudents()).thenReturn(List.of( new Student(1L, 张三, 20240001, 20, 男, 计算机科学) )); mockMvc.perform(get(/api/students)) .andExpect(status().isOk()) .andExpect(jsonPath($[0].name).value(张三)); } }5.3 调试技巧IDEA 2024新增了几项实用调试功能条件断点右键点击断点可以设置触发条件交互式调试在调试过程中可以执行表达式流式调试对Stream操作可以逐步查看数据变化我经常使用Evaluate Expression功能在调试时快速验证某个假设而不需要修改代码重新部署。6. 高级功能与性能优化6.1 缓存集成Spring Boot可以轻松集成Redis缓存Cacheable(value students, key #id) public OptionalStudent getStudentById(Long id) { return studentRepository.findById(id); } CacheEvict(value students, key #id) public void deleteStudent(Long id) { // 删除实现 }只需要在application.properties中配置Redis连接并添加EnableCaching注解即可启用缓存。6.2 异步处理对于耗时操作可以使用AsyncAsync public CompletableFutureListStudent getAllStudentsAsync() { return CompletableFuture.completedFuture(studentRepository.findAll()); }记得在主类上添加EnableAsync启用异步支持。6.3 性能监控Spring Boot Actuator提供应用监控端点dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency配置后可以访问/actuator查看各种监控信息如健康状态、指标数据等。7. 常见问题与解决方案7.1 数据库连接问题常见错误Communications link failure解决方案检查MySQL服务是否启动验证连接URL中的端口和数据库名检查用户名密码是否正确对于MySQL 8.0确保使用正确的驱动类7.2 JPA映射问题常见错误Unknown column xxx in field list解决方案检查实体类字段名与数据库列名是否匹配确认Column注解配置正确检查数据库表结构是否与实体定义一致7.3 事务不回滚问题常见现象方法抛出异常但数据修改未回滚 解决方案确保方法上有Transactional注解确认抛出的是RuntimeException或Error检查是否在同一个类内部调用事务方法这会绕过代理7.4 IDEA特定问题代码自动完成不工作检查是否启用了Power Save Mode尝试File - Invalidate CachesSpring Boot启动类无法识别确保正确安装了Spring Boot插件检查项目SDK配置Lombok注解不生效安装Lombok插件启用注解处理Settings - Build - Compiler - Annotation Processors在实际开发中我发现保持IDEA和插件的最新版本能避免很多奇怪的问题。同时合理配置内存参数也很重要特别是运行大型Spring Boot项目时。