基于Spring Boot的成绩管理系统后台实现
下面是一个完整的成绩管理系统后台实现,使用Spring Boot框架,包含学生管理、课程管理和成绩管理功能。
1. 项目结构
src/main/java/com/example/grademanagement/
├── config/ # 配置类
├── controller/ # 控制器
├── dto/ # 数据传输对象
├── entity/ # 实体类
├── exception/ # 异常处理
├── repository/ # 数据访问层
├── service/ # 业务逻辑层
│ └── impl/ # 服务实现
└── GrademanagementApplication.java # 启动类
2. 主要依赖 (pom.xml)
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 数据访问 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3. 实体类设计
3.1 学生实体 (Student.java)
package com.example.grademanagement.entity;
import jakarta.persistence.*;
import lombok.Data;
import java.util.List;
@Entity
@Data
@Table(name = "students")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String studentId; // 学号
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String gender;
private String className; // 班级
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
private List<Grade> grades;
}
3.2 课程实体 (Course.java)
package com.example.grademanagement.entity;
import jakarta.persistence.*;
import lombok.Data;
import java.util.List;
@Entity
@Data
@Table(name = "courses")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String courseCode; // 课程代码
@Column(nullable = false)
private String courseName;
private Integer credit; // 学分
@OneToMany(mappedBy = "course", cascade = CascadeType.ALL)
private List<Grade> grades;
}
3.3 成绩实体 (Grade.java)
package com.example.grademanagement.entity;
import jakarta.persistence.*;
import lombok.Data;
@Entity
@Data
@Table(name = "grades")
public class Grade {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "student_id", nullable = false)
private Student student;
@ManyToOne
@JoinColumn(name = "course_id", nullable = false)
private Course course;
@Column(nullable = false)
private Double score; // 成绩
private String semester; // 学期
}
4. 数据访问层 (Repository)
4.1 学生仓库 (StudentRepository.java)
package com.example.grademanagement.repository;
import com.example.grademanagement.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;
public interface StudentRepository extends JpaRepository<Student, Long> {
Student findByStudentId(String studentId);
List<Student> findByNameContaining(String name);
List<Student> findByClassName(String className);
}
4.2 课程仓库 (CourseRepository.java)
package com.example.grademanagement.repository;
import com.example.grademanagement.entity.Course;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CourseRepository extends JpaRepository<Course, Long> {
Course findByCourseCode(String courseCode);
List<Course> findByCourseNameContaining(String courseName);
}
4.3 成绩仓库 (GradeRepository.java)
package com.example.grademanagement.repository;
import com.example.grademanagement.entity.Grade;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface GradeRepository extends JpaRepository<Grade, Long> {
List<Grade> findByStudentId(Long studentId);
List<Grade> findByCourseId(Long courseId);
@Query("SELECT g FROM Grade g WHERE g.student.id = ?1 AND g.course.id = ?2")
Grade findByStudentAndCourse(Long studentId, Long courseId);
@Query("SELECT AVG(g.score) FROM Grade g WHERE g.course.id = ?1")
Double findAverageScoreByCourse(Long courseId);
}
5. 业务逻辑层 (Service)
5.1 学生服务接口 (StudentService.java)
package com.example.grademanagement.service;
import com.example.grademanagement.entity.Student;
import java.util.List;
public interface StudentService {
Student addStudent(Student student);
Student updateStudent(Long id, Student student);
void deleteStudent(Long id);
Student getStudentById(Long id);
Student getStudentByStudentId(String studentId);
List<Student> getAllStudents();
List<Student> searchStudents(String keyword);
}
5.2 学生服务实现 (StudentServiceImpl.java)
package com.example.grademanagement.service.impl;
import com.example.grademanagement.entity.Student;
import com.example.grademanagement.repository.StudentRepository;
import com.example.grademanagement.service.StudentService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StudentServiceImpl implements StudentService {
private final StudentRepository studentRepository;
public StudentServiceImpl(StudentRepository studentRepository) {
this.studentRepository = studentRepository;
}
@Override
public Student addStudent(Student student) {
if (studentRepository.findByStudentId(student.getStudentId()) != null) {
throw new RuntimeException("学号已存在");
}
return studentRepository.save(student);
}
@Override
public Student updateStudent(Long id, Student student) {
Student existingStudent = studentRepository.findById(id)
.orElseThrow(() -> new RuntimeException("学生不存在"));
existingStudent.setName(student.getName());
existingStudent.setGender(student.getGender());
existingStudent.setClassName(student.getClassName());
return studentRepository.save(existingStudent);
}
@Override
public void deleteStudent(Long id) {
studentRepository.deleteById(id);
}
@Override
public Student getStudentById(Long id) {
return studentRepository.findById(id)
.orElseThrow(() -> new RuntimeException("学生不存在"));
}
@Override
public Student getStudentByStudentId(String studentId) {
return studentRepository.findByStudentId(studentId);
}
@Override
public List<Student> getAllStudents() {
return studentRepository.findAll();
}
@Override
public List<Student> searchStudents(String keyword) {
return studentRepository.findByNameContaining(keyword);
}
}
5.3 成绩服务接口 (GradeService.java)
package com.example.grademanagement.service;
import com.example.grademanagement.entity.Grade;
import java.util.List;
public interface GradeService {
Grade addGrade(Grade grade);
Grade updateGrade(Long id, Grade grade);
void deleteGrade(Long id);
Grade getGradeById(Long id);
List<Grade> getGradesByStudentId(Long studentId);
List<Grade> getGradesByCourseId(Long courseId);
Double getAverageScoreByCourse(Long courseId);
Grade getGradeByStudentAndCourse(Long studentId, Long courseId);
}
6. 控制器 (Controller)
6.1 学生控制器 (StudentController.java)
package com.example.grademanagement.controller;
import com.example.grademanagement.entity.Student;
import com.example.grademanagement.service.StudentService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/students")
public class StudentController {
private final StudentService studentService;
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
@PostMapping
public ResponseEntity<Student> addStudent(@RequestBody Student student) {
return ResponseEntity.ok(studentService.addStudent(student));
}
@PutMapping("/{id}")
public ResponseEntity<Student> updateStudent(
@PathVariable Long id, @RequestBody Student student) {
return ResponseEntity.ok(studentService.updateStudent(id, student));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteStudent(@PathVariable Long id) {
studentService.deleteStudent(id);
return ResponseEntity.noContent().build();
}
@GetMapping("/{id}")
public ResponseEntity<Student> getStudentById(@PathVariable Long id) {
return ResponseEntity.ok(studentService.getStudentById(id));
}
@GetMapping("/student-id/{studentId}")
public ResponseEntity<Student> getStudentByStudentId(
@PathVariable String studentId) {
return ResponseEntity.ok(studentService.getStudentByStudentId(studentId));
}
@GetMapping
public ResponseEntity<List<Student>> getAllStudents() {
return ResponseEntity.ok(studentService.getAllStudents());
}
@GetMapping("/search")
public ResponseEntity<List<Student>> searchStudents(
@RequestParam String keyword) {
return ResponseEntity.ok(studentService.searchStudents(keyword));
}
}
6.2 成绩控制器 (GradeController.java)
package com.example.grademanagement.controller;
import com.example.grademanagement.entity.Grade;
import com.example.grademanagement.service.GradeService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/grades")
public class GradeController {
private final GradeService gradeService;
public GradeController(GradeService gradeService) {
this.gradeService = gradeService;
}
@PostMapping
public ResponseEntity<Grade> addGrade(@RequestBody Grade grade) {
return ResponseEntity.ok(gradeService.addGrade(grade));
}
@PutMapping("/{id}")
public ResponseEntity<Grade> updateGrade(
@PathVariable Long id, @RequestBody Grade grade) {
return ResponseEntity.ok(gradeService.updateGrade(id, grade));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteGrade(@PathVariable Long id) {
gradeService.deleteGrade(id);
return ResponseEntity.noContent().build();
}
@GetMapping("/{id}")
public ResponseEntity<Grade> getGradeById(@PathVariable Long id) {
return ResponseEntity.ok(gradeService.getGradeById(id));
}
@GetMapping("/student/{studentId}")
public ResponseEntity<List<Grade>> getGradesByStudentId(
@PathVariable Long studentId) {
return ResponseEntity.ok(gradeService.getGradesByStudentId(studentId));
}
@GetMapping("/course/{courseId}")
public ResponseEntity<List<Grade>> getGradesByCourseId(
@PathVariable Long courseId) {
return ResponseEntity.ok(gradeService.getGradesByCourseId(courseId));
}
@GetMapping("/average/{courseId}")
public ResponseEntity<Double> getAverageScoreByCourse(
@PathVariable Long courseId) {
return ResponseEntity.ok(gradeService.getAverageScoreByCourse(courseId));
}
@GetMapping("/student-course")
public ResponseEntity<Grade> getGradeByStudentAndCourse(
@RequestParam Long studentId, @RequestParam Long courseId) {
return ResponseEntity.ok(
gradeService.getGradeByStudentAndCourse(studentId, courseId));
}
}
7. 异常处理
7.1 全局异常处理器 (GlobalExceptionHandler.java)
package com.example.grademanagement.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> handleRuntimeException(RuntimeException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("服务器内部错误: " + e.getMessage());
}
}
8. 应用配置
8.1 数据库配置 (application.properties)
# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/grade_management?useSSL=false
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
# 服务器配置
server.port=8080
9. 启动类
package com.example.grademanagement;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GrademanagementApplication {
public static void main(String[] args) {
SpringApplication.run(GrademanagementApplication.class, args);
}
}
10. API文档
系统提供以下主要API端点:
学生管理
POST /api/students
- 添加学生
GET /api/students
- 获取所有学生
GET /api/students/{id}
- 获取指定ID的学生
PUT /api/students/{id}
- 更新学生信息
DELETE /api/students/{id}
- 删除学生
成绩管理
POST /api/grades
- 添加成绩
GET /api/grades/student/{studentId}
- 获取学生所有成绩
GET /api/grades/course/{courseId}
- 获取课程所有成绩
GET /api/grades/average/{courseId}
- 获取课程平均分