班级信息管理系统
目录
一、环境配置
软件依赖
Srping boot 框架依赖项
二、实体类
Teacher 类
Student类
Classes类
三、Repository层
四、Service
ClassesService
ClassesServiceImp
StudentService
StudentServiceImp
TeacherService
TeacherServiceImp
五、Controller层
ClassesController
StudentController
TeacherController
indexController
六、前端网页设计(teacher类为例)
index_teacher
new_teacher
update_teacher
Index
一、环境配置
软件依赖
- Idea
- JDK20
- Mysql8.0
- bootstrap
Spring boot 框架依赖项
- Lombok
- Spring Boot
- DevToolsSpring Web
- Thymeleaf
- Spring Data
JPAMySQL Driver
二、实体类
在Java中,在MySQL中可以通过一个类来存储元数据,在MySQL中每一条记录则由该对象中的属性值表示。使用@Entity将该类注册为实体类实现对数据库相应字段的映射关系,并通过使用 mapper 的 @Table注解来指定与数据库的关系
Teacher****类
@Data
@Entity
@Table(name = "tb_teacher")
public class Teacher {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private long teaId;
@Column
private String teaName;
@Column
private String gender;
@Column
private String birth;
@Column
private String position;
@Override
public String toString() {
return teaName;
}
}
Student****类
@Data
@Proxy(lazy = false)
@Entity
@Table(name = "tb_student")
public class Student {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private long stuId;
@Column
private String className;
@Column
private String name;
@Column
private String gender;
@Column
private String birth;
}
Classes类
@Data
@Entity
@Table(name = "tb_classes")
public class Classes {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private long classId;
@Column
private String className;
@Column
private String teacher;
@Override
public String toString() {
return className;}
}
三、Repository层
repository被称为数据仓库。它位于业务层与数据层之间,并实现了对这两者的分离。该系统整合了相关的查询与存储功能,并增强了各层次之间的解耦能力。值得注意的是,在此过程中更换、升级ORM引擎不会对现有业务逻辑产生任何影响。以下将展示三个实体的具体接口配置情况。
//Classes
public interface ClassesRepository extends JpaRepository<Classes,Long>{}
//Student
public interface StudentRepository extends JpaRepository<Student,Long> {
List<Student> findAllByName(String name);
}
//Teacher
public interface TeacherRepository extends JpaRepository<Teacher,Long> {
List<Teacher> findAllByTeaName(String name);
}
四、Service
服务层的主要职责在于将控制器接收的请求转换为具体的业务操作,并协同完成数据存储与访问的相关操作。此外,在业务流程中还有一些需要逻辑判断和计算的部分。在设计过程中,默认的做法是分阶段实施:首先明确各实体类的功能规范,在相应的接口方法中进行详细定义;然后逐步细化到具体的业务功能实现步骤:第一阶段先完成各实体类之间的交互关系搭建;第二阶段则针对每一步骤中的具体业务需求进行代码编写
ClassesService
public interface ClassesService {
List<Classes> getAllClasses();
void saveClasses(Classes classes);
Classes getClassesById(long id);
void deleteClassesById(long id);
Page<Classes> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection);
}
ClassesServiceImp
@Service
public class ClassesServiceImp implements ClassesService {
@Autowired
private ClassesRepository classesRepository;
@Override
public List<Classes> getAllClasses() {
return classesRepository.findAll();
}
@Override
public void saveClasses(Classes classes) {
classesRepository.save(classes);
}
@Override
public Classes getClassesById(long id) {
Optional<Classes> optional = classesRepository.findById(id);
Classes classes;
if (optional.isPresent()) {
classes = optional.get();
} else {
throw new RuntimeException(" 找不到班级ID :: " + id);
}
return classes;
}
@Override
public void deleteClassesById(long id) {
classesRepository.deleteById(id);
}
@Override
public Page<Classes> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection) {
Sort sort = sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name())
? Sort.by(sortField).ascending()
: Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
return this.classesRepository.findAll(pageable);
}
}
StudentService
public interface StudentService {
List<Student> getAllStudent();
void saveStudent(Student student);
Student getStudentById(long id);
void deleteStudentById(long id);
List<Student> findAllByName(String name);
Page<Student> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection);
}
** StudentServiceImp**
@Service
public class StudentServiceImp implements StudentService {
@Autowired
private StudentRepository studentRepository;
@Override
public List<Student> getAllStudent() {
return studentRepository.findAll();
}
@Override
public void saveStudent(Student Student) {
studentRepository.save(Student);
}
@Override
public Student getStudentById(long id) {
Optional<Student> optional = studentRepository.findById(id);
Student student;
if (optional.isPresent()) {
student = optional.get();
} else {
throw new RuntimeException(" 找不到学生ID :: " + id);
}
return student;
}
@Override
public void deleteStudentById(long id) {
studentRepository.deleteById(id);
}
@Override
public List<Student> findAllByName(String name) {
return studentRepository.findAllByName(name);
}
@Override
public Page<Student> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection) {
Sort sort = sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name())
? Sort.by(sortField).ascending()
: Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
return this.studentRepository.findAll(pageable);
}
}
TeacherService
public interface TeacherService {
List<Teacher> getAllTeacher();
void saveTeacher(Teacher teacher);
Teacher getTeacherById(long id);
void deleteTeacherById(long id);
List<Teacher> findAllByTeaName(String name);
Page<Teacher> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection);
}
TeacherServiceImp
@Service
public class TeacherServiceImp implements TeacherService {
@Autowired
private TeacherRepository teacherRepository;
@Override
public List<Teacher> getAllTeacher() {
return teacherRepository.findAll();
}
@Override
public void saveTeacher(Teacher teacher) {
teacherRepository.save(teacher);
}
@Override
public Teacher getTeacherById(long id) {
Optional< Teacher > optional = teacherRepository.findById(id);
Teacher teacher;
if (optional.isPresent()) {
teacher = optional.get();
} else {
throw new RuntimeException(" 找不到老师ID :: " + id);
}
return teacher;
}
@Override
public void deleteTeacherById(long id) {
teacherRepository.deleteById(id);
}
@Override
public List<Teacher> findAllByTeaName(String name) {
return teacherRepository.findAllByTeaName(name);
}
@Override
public Page<Teacher> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection) {
Sort sort = sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name())
? Sort.by(sortField).ascending()
: Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
return this.teacherRepository.findAll(pageable);
}
}
五、Controller层
在HTTP请求中提取相关信息,并对其中的参数进行解析和筛选后分配至各个处理服务(service层),随后将这些参数按需求分配至各个处理服务(service层),并将处理后的结果返回给前端界面。
ClassesController
@Controller
public class ClassesController {
@Autowired
private ClassesService classesService;
@GetMapping("/class")
public String viewHomePage(Model model) {
return this.findPaginated(1, "className", "asc", model);
}
@GetMapping("/NewClassesForm")
public String NewClassesForm(Model model) {
Classes classes = new Classes();
model.addAttribute("classes", classes);
return "new_classes";
}
@PostMapping("/saveClasses")
public String saveClasses(@ModelAttribute("classes") Classes classes) {
classesService.saveClasses(classes);
return "redirect:/class";
}
@GetMapping("/classFormForUpdate/{id}")
public String FormForUpdate(@PathVariable(value = "id") long id, Model model) {
Classes classes = classesService.getClassesById(id);
model.addAttribute("classes", classes);
return "update_classes";
}
@GetMapping("/deleteClasses/{id}")
public String deleteClasses(@PathVariable(value = "id") long id) {
classesService.deleteClassesById(id);
return "redirect:/class";
}
//获取分页数据
@GetMapping("/classpage/{pageNo}")
public String findPaginated(@PathVariable (value = "pageNo") int pageNo,
@RequestParam("sortField") String sortField,
@RequestParam("sortDir") String sortDir,
Model model) {
int pageSize = 10;
Page<Classes> page = classesService.findPaginated(pageNo, pageSize, sortField, sortDir);
List<Classes> listClasses = page.getContent();
model.addAttribute("currentPage", pageNo);
model.addAttribute("totalPages", page.getTotalPages());
model.addAttribute("totalItems", page.getTotalElements());
model.addAttribute("sortField", sortField);
model.addAttribute("sortDir", sortDir);
model.addAttribute("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");
model.addAttribute("listClasses", listClasses);
return "index_classes";
}
}
StudentController
@Controller
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping("/student")
public String viewHomePage(Model model) {
return this.findPaginated(1, "name", "asc", model);
}
@GetMapping("/NewStudentForm")
public String NewStudentForm(Model model) {
Student student = new Student();
model.addAttribute("student", student);
return "new_student";
}
@PostMapping("/saveStudent")
public String saveStudent(@ModelAttribute("student") Student student) {
studentService.saveStudent(student);
return "redirect:/student";
}
@GetMapping("/studentFormForUpdate/{id}")
public String FormForUpdate(@PathVariable(value = "id") long id, Model model) {
Student student = studentService.getStudentById(id);
model.addAttribute("student", student);
return "update_student";
}
@GetMapping("/deleteStudent/{id}")
public String deleteStudent(@PathVariable(value = "id") long id) {
studentService.deleteStudentById(id);
return "redirect:/student";
}
@GetMapping("/queryStudent{newname}")
public String query(@PathVariable(value = "newname") String name, Model model) {
List<Student> listStudent = studentService.findAllByName(name);
model.addAttribute("listStudent", listStudent);
return "index_student";
}
//获取分页数据
@GetMapping("/studentpage/{pageNo}")
public String findPaginated(@PathVariable (value = "pageNo") int pageNo,
@RequestParam("sortField") String sortField,
@RequestParam("sortDir") String sortDir,
Model model) {
int pageSize = 10;
Page<Student> page = studentService.findPaginated(pageNo, pageSize, sortField, sortDir);
List<Student> listStudent = page.getContent();
model.addAttribute("currentPage", pageNo);
model.addAttribute("totalPages", page.getTotalPages());
model.addAttribute("totalItems", page.getTotalElements());
model.addAttribute("sortField", sortField);
model.addAttribute("sortDir", sortDir);
model.addAttribute("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");
model.addAttribute("listStudent", listStudent);
return "index_student";
}
}
TeacherController
@Controller
public class TeacherController {
@Autowired
private TeacherService teacherService;
@GetMapping("/")
public String index(){
return "index";
}
@GetMapping("/teacher")
public String viewHomePage(Model model) {
return this.findPaginated(1, "teaName", "asc", model);
}
@GetMapping("/NewTeacherForm")
public String NewTeacherForm(Model model) {
Teacher teacher = new Teacher();
model.addAttribute("teacher", teacher);
return "new_teacher";
}
@PostMapping("/saveTeacher")
public String saveTeacher(@ModelAttribute("teacher") Teacher teacher) {
teacherService.saveTeacher(teacher);
return "redirect:/teacher";
}
@GetMapping("/teacherFormForUpdate/{id}")
public String FormForUpdate(@PathVariable(value = "id") long id, Model model) {
Teacher teacher = teacherService.getTeacherById(id);
model.addAttribute("teacher", teacher);
return "update_teacher";
}
@GetMapping("/deleteTeacher/{id}")
public String deleteStudent(@PathVariable(value = "id") long id) {
teacherService.deleteTeacherById(id);
return "redirect:/teacher";
}
@GetMapping("/queryTeacher{newname}")
public String query(@PathVariable(value = "newname") String newname, Model model) {
List<Teacher> listTeacher = teacherService.findAllByTeaName(newname);
model.addAttribute("listTeacher", listTeacher);
return "index_teacher";
}
//获取分页数据
@GetMapping("/teacherpage/{pageNo}")
public String findPaginated(@PathVariable (value = "pageNo") int pageNo,
@RequestParam("sortField") String sortField,
@RequestParam("sortDir") String sortDir,
Model model) {
int pageSize = 10;
Page<Teacher> page = teacherService.findPaginated(pageNo, pageSize, sortField, sortDir);
List<Teacher> listTeacher = page.getContent();
model.addAttribute("currentPage", pageNo);
model.addAttribute("totalPages", page.getTotalPages());
model.addAttribute("totalItems", page.getTotalElements());
model.addAttribute("sortField", sortField);
model.addAttribute("sortDir", sortDir);
model.addAttribute("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");
model.addAttribute("listTeacher", listTeacher);
return "index_teacher";
}
}
indexController
//用于处理通用请求。
@Controller
public class indexController {
@GetMapping("/bootstrap.min.css")
public String css(){
return "bootstrap.min.css";
}
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
六、前端网页设计(teacher类为例)
index_teacher
用于查询,展示teacher表的数据。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>...</title>
<link rel="stylesheet" href="http://127.0.0.1:8080/bootstrap.min.css" >
</head>
<body>
<div class="my-1">
<!-- <a th:href = "@{/NewTeacherForm}" class="btn btn-primary btn-sm mb-3"> Add teacher </a> -->
<nav class="navbar navbar-light bg-light">
<form id="query-form" action="/queryTeacher" method="get">
<h6 class="text-secondary">查询名字</h6><input type="text" id="name-input" name="teaName" placeholder="名字">
<button type="button" class="btn btn-info"onclick="queryBookstore()">搜索</button>
</form>
<script>
function queryBookstore() {
var teacher = document.getElementById("name-input").value;
var url = "/queryTeacher" + encodeURIComponent(teacher);
window.location.href = url;
}
</script>
</nav>
<table border="1" class = "table table-striped table-responsive-md">
<thead>
<tr>
<th>
<a th:href="@{'/studentpage/' + ${currentPage} + '?sortField=teaName&sortDir=' + ${reverseSortDir}}">
名字</a>
</th>
<th>
<a th:href="@{'/studentpage/' + ${currentPage} + '?sortField=position&sortDir=' + ${reverseSortDir}}">
职称</a>
</th>
<th>
<a th:href="@{'/studentpage/' + ${currentPage} + '?sortField=gender&sortDir=' + ${reverseSortDir}}">
性别</a>
</th>
<th>
<a th:href="@{'/studentpage/' + ${currentPage} + '?sortField=birth&sortDir=' + ${reverseSortDir}}">
出生日期</a>
</th>
<th> 操作 </th>
</tr>
</thead>
<tbody>
<tr th:each="Teacher : ${listTeacher}">
<td th:text="${Teacher.teaName}"></td>
<td th:text="${Teacher.position}"></td>
<td th:text="${Teacher.gender}"></td>
<td th:text="${Teacher.birth}"></td>
<td> <a th:href="@{/teacherFormForUpdate/{id}(id=${Teacher.teaId})}" class="btn btn-primary">编辑</a>
<a th:href="@{/deleteTeacher/{id}(id=${Teacher.teaId})}" class="btn btn-danger">删除</a>
</td>
</tr>
</tbody>
</table>
<div th:if = "${totalPages > 1}">
<div class = "row col-sm-10">
<div class = "col-sm-3">
Total Rows: [[${totalItems}]]
</div>
<div class = "col-sm-5">
<span th:each="i: ${#numbers.sequence(1, totalPages)}">
<a th:if="${currentPage != i}" th:href="@{'/classpage/' + ${i}+ '?sortField=' + ${sortField} + '&sortDir=' + ${sortDir}}">[[${i}]]</a>
<span th:unless="${currentPage != i}">[[${i}]]</span>
</span>
</div>
<div class = "col-sm-1">
<a th:if="${currentPage < totalPages}" th:href="@{'/classpage/' + ${currentPage + 1}+ '?sortField=' + ${sortField} + '&sortDir=' + ${sortDir}}">Next</a>
<span th:unless="${currentPage < totalPages}">Next</span>
</div>
<div class="col-sm-1">
<a th:if="${currentPage < totalPages}" th:href="@{'/classpage/' + ${totalPages}+ '?sortField=' + ${sortField} + '&sortDir=' + ${sortDir}}">Last</a>
<span th:unless="${currentPage < totalPages}">Last</span>
</div>
</div>
</div>
</div>
</body>
</html>
new_teacher
用于创建表单信息传回后端,后端处理后存入数据库。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>...</title>
<link rel="stylesheet" href="http://127.0.0.1:8080/bootstrap.min.css" >
</head>
<body>
<div>
<h2>创建老师信息</h2>
<form action="#" th:action="@{/saveTeacher}" th:object="${teacher}" method="POST">
<input type="text" th:field="*{teaName}" placeholder="姓名" class="form-control mb-4 col-4" required="required">
<input type="text" th:field="*{position}" placeholder="职称" class="form-control mb-4 col-4" required="required">
<input type="date" th:field="*{birth}" placeholder="出生日期" class="form-control mb-4 col-4" required="required">
<select type="text" th:field="*{gender}" placeholder="性别" class="form-control mb-4 col-1" required="required">
<option selected value="男">男</option>
<option value="女">女</option>
</select>
<button type="submit" class="btn btn-info col-2"> 提交 </button>
</form>
<hr>
<a th:href="@{/student}"> 返回学生信息页 </a>
</div>
</body>
</html>
update_teacher
向后端请求数据,前端修改后重新传回后端处理。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>...</title>
<link rel="stylesheet" href="http://127.0.0.1:8080/bootstrap.min.css" >
</head>
<body>
<div >
<h2>编辑信息</h2>
<form action="#" th:action="@{/saveTeacher}" th:object="${teacher}" method="POST">
<input type="hidden" th:field="*{teaId}" />
<input type="text" th:field="*{teaName}" class="form-control mb-4 col-4">
<input type="text" th:field="*{position}" class="form-control mb-4 col-4">
<input type="date" th:field="*{birth}" class="form-control mb-4 col-4">
<select type="text" th:field="*{gender}" class="form-control mb-4 col-1">
<option selected value="男">男</option>
<option value="女">女</option>
</select>
<button type="submit" class="btn btn-info col-2"> 保存 </button>
</form>
<hr>
<a th:href="@{/teacher}"> 返回班级信息页</a>
</div>
</body>
</html>
Index
所有的功能页集成到此页面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Home</title>
</head>
<body>
<div class="sidebar sidebar-hide-to-small sidebar-shrink sidebar-gestures">
<div class="nano">
<div class="nano-content">
<ul>
<li class="label">班级管理系统</li>
<li><a class="sidebar-sub-toggle"><i class="ti-bar-chart-alt"></i> 学生 <span class="sidebar-collapse-icon ti-angle-down"></span></a>
<ul>
<li><a href="http://127.0.0.1:8080/student" target="index">学生信息</a></li>
<li><a href="http://127.0.0.1:8080/NewStudentForm"target="index">添加信息</a></li>
</ul>
</li>
<li><a class="sidebar-sub-toggle"><i class="ti-bar-chart-alt"></i> 老师 <span class="sidebar-collapse-icon ti-angle-down"></span></a>
<ul>
<li><a href="http://127.0.0.1:8080/teacher"target="index">老师信息</a></li>
<li><a href="http://127.0.0.1:8080/NewTeacherForm"target="index">添加信息</a></li>
</ul>
</li>
<li><a class="sidebar-sub-toggle"><i class="ti-bar-chart-alt"></i> 班级 <span class="sidebar-collapse-icon ti-angle-down"></span></a>
<ul>
<li><a href="http://127.0.0.1:8080/class"target="index">班级信息</a></li>
<li><a href="http://127.0.0.1:8080/NewClassesForm"target="index">添加信息</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="content-wrap">
<iframe style="height: 100%;width: 100%;padding: 0;margin: 0;" frameborder="0" name="index" src="hello">
</iframe>
</div>
</body>
</html>
