Week 1-8: Spring Boot 学习计划完整项目

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-29 23:45:17 +08:00
commit f95aa18724
201 changed files with 18595 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
package com.learn.service.mp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.learn.entity.Student;
import com.learn.repository.mp.StudentMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
/**
* MyBatis-Plus 版本的学生服务
*
* 重点对比与 JPA 版本的差异:
* 1. 新增MP 用 insert()JPA 用 save()
* 2. 查询MP 用 LambdaQueryWrapper 构建条件JPA 用方法命名或 JPQL
* 3. 分页MP 用 Page + IPageJPA 用 PageRequest + Page
* 4. 更新MP 用 updateById()JPA 用 save()
*
* 关键武器LambdaQueryWrapper
* 用它构建条件,不用担心列名写错(基于 Lambda 表达式,编译期安全)
* 例如wrapper.eq(Student::getName, "张三") → WHERE name = '张三'
*/
@Service
public class StudentMpService {
private final StudentMapper mapper;
public StudentMpService(StudentMapper mapper) {
this.mapper = mapper;
}
// ==================== 增删改查 ====================
@Transactional
public Student add(Student student) {
mapper.insert(student); // MP: insert() 只用于新增
return student; // insert 后 student.id 已被自动回填
}
@Transactional(readOnly = true)
public List<Student> list() {
// MP 条件构造器:空的 wrapper → 查全部
// orderByDesc 让结果按成绩降序
LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByDesc(Student::getScore);
return mapper.selectList(wrapper);
}
@Transactional(readOnly = true)
public Optional<Student> getById(Long id) {
return Optional.ofNullable(mapper.selectById(id));
}
@Transactional
public Optional<Student> update(Long id, Student updated) {
Student existing = mapper.selectById(id);
if (existing == null) {
return Optional.empty();
}
if (updated.getName() != null) existing.setName(updated.getName());
if (updated.getAge() > 0) existing.setAge(updated.getAge());
if (updated.getEmail() != null) existing.setEmail(updated.getEmail());
if (updated.getScore() >= 0) existing.setScore(updated.getScore());
mapper.updateById(existing); // MP 用 updateById
return Optional.of(existing);
}
@Transactional
public boolean delete(Long id) {
return mapper.deleteById(id) > 0;
}
// ==================== 搜索 ====================
@Transactional(readOnly = true)
public List<Student> searchByKeyword(String keyword) {
return mapper.searchByKeyword(keyword);
}
@Transactional(readOnly = true)
public List<Student> findByName(String name) {
// MP 的 Lambda 方式构建条件
LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
wrapper.like(Student::getName, name); // WHERE name LIKE '%name%'
return mapper.selectList(wrapper);
}
// ==================== 分页(第 5 天) ====================
@Transactional(readOnly = true)
public IPage<Student> page(int pageNum, int pageSize) {
// MP 分页Page<Student>(页码, 每页条数)
Page<Student> page = new Page<>(pageNum, pageSize);
// 按成绩降序
LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByDesc(Student::getScore);
return mapper.selectPage(page, wrapper);
}
// ==================== 统计 ====================
@Transactional(readOnly = true)
public long count() {
return mapper.selectCount(null); // null = 无筛选条件
}
@Transactional(readOnly = true)
public long countByScoreRange(int min, int max) {
// MP 的 Lambda 方式构建范围条件
LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
wrapper.between(Student::getScore, min, max); // WHERE score BETWEEN min AND max
return mapper.selectCount(wrapper);
}
// ==================== 高级查询(演示 LambdaQueryWrapper 的威力) ====================
@Transactional(readOnly = true)
public List<Student> findExcellentStudents(int threshold) {
LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
wrapper.ge(Student::getScore, threshold) // WHERE score >= ?
.orderByDesc(Student::getScore);
return mapper.selectList(wrapper);
}
}