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,101 @@
package com.learn.service.jpa;
import com.learn.entity.Student;
import com.learn.repository.jpa.StudentJpaRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
/**
* JPA 版本的学生服务
*
* @Transactional声明式事务。方法执行过程中如果抛出 RuntimeException
* 所有数据库操作会自动回滚。保证数据一致性。
* readOnly=true 表示只读,性能更好(跳过脏检查)。
*/
@Service
public class StudentJpaService {
private final StudentJpaRepository repository;
public StudentJpaService(StudentJpaRepository repository) {
this.repository = repository;
}
// ==================== 增删改查 ====================
@Transactional
public Student add(Student student) {
return repository.save(student); // JPA: save() 同时用于新增和更新
}
@Transactional(readOnly = true)
public List<Student> list() {
return repository.findAll(Sort.by(Sort.Direction.DESC, "score"));
}
@Transactional(readOnly = true)
public Optional<Student> getById(Long id) {
return repository.findById(id);
}
@Transactional
public Optional<Student> update(Long id, Student updated) {
return repository.findById(id).map(existing -> {
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());
// JPA 的 save: 有 ID 且存在则更新,无 ID 则新增
return repository.save(existing);
});
}
@Transactional
public boolean delete(Long id) {
if (repository.existsById(id)) {
repository.deleteById(id);
return true;
}
return false;
}
// ==================== 搜索 ====================
@Transactional(readOnly = true)
public List<Student> searchByKeyword(String keyword) {
return repository.searchByKeyword(keyword);
}
@Transactional(readOnly = true)
public List<Student> findByName(String name) {
return repository.findByNameContaining(name);
}
// ==================== 分页(第 5 天) ====================
@Transactional(readOnly = true)
public Page<Student> page(int pageNum, int pageSize) {
// JPA 分页PageRequest.of(页码从0开始, 每页条数, 排序)
PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize,
Sort.by(Sort.Direction.DESC, "score"));
return repository.findAll(pageRequest);
}
// ==================== 统计 ====================
@Transactional(readOnly = true)
public long count() {
return repository.count();
}
@Transactional(readOnly = true)
public long countByScoreRange(int min, int max) {
return repository.countByScoreRange(min, max);
}
}