目录
一、设计数据库
建表命令:
二、实现Java代码
项目结构:
1、Maven的依赖包版本控制配置pom.xml
Springboot的application.yml配置文件:
2、实体类
3、Dao层
4、Mapper文件
5、Service层
6、Controller层
7、工具类Util
FileUtil:
StudentUpdateOrAddUtil:
8、View界面show.html
java 8 ,mysql 8
一、设计数据库
我做了一个学生的基本信息表,班级表,性别,状态,对于不常改动的信息,单独用个表可以降低数据库复杂度,便于改动。

建表命令:
1、
CREATE TABLE `student` (
`student_id` int NOT NULL AUTO_INCREMENT,
`student_number` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`student_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`student_img` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`student_age` int DEFAULT NULL,
`class_id` int DEFAULT NULL,
`state_id` int DEFAULT NULL,
`sex_id` int DEFAULT NULL,
PRIMARY KEY (`student_id`) USING BTREE,
KEY `class_id` (`class_id`),
KEY `sta_id` (`state_id`),
KEY `student_sex` (`sex_id`),
CONSTRAINT `student_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`class_id`),
CONSTRAINT `student_sex` FOREIGN KEY (`sex_id`) REFERENCES `stusex` (`sex_id`),
CONSTRAINT `student_state` FOREIGN KEY (`state_id`) REFERENCES `state` (`state_id`)
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb3
2、
CREATE TABLE `class` (
`class_id` int NOT NULL AUTO_INCREMENT,
`class_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`class_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb3
3、
CREATE TABLE `state` (
`state_id` int NOT NULL,
`state_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`state_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
4、
CREATE TABLE `stusex` (
`sex_id` int NOT NULL,
`sex_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`sex_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
二、实现Java代码
项目结构:

1、Maven的依赖包版本控制配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>edu.wsm</groupId>
<artifactId>studentController</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>studentController</name>
<description>studentController</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Springboot的application.yml配置文件:
spring:
thymeleaf:
cache: false
encoding: utf-8
prefix: classpath:/templates/
suffix: .html
check-template: true
servlet:
content-type: text/html
check-template-location: true
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://127.0.0.1:3306/students?useUnicode=true&characterEncoding=utf8
mybatis:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:mapper/*.xml
type-aliases-package: edu.wsm.domain
2、实体类
Student:
package edu.wsm.domain;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName Student
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:10
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class Student {
private Integer studentId; //学员ID
private String studentName; //学员姓名
private Integer studentAge; //学员年龄
private String studentImg; //学员头像
private StudentClass studentClass; //学员班级类对象
private StudentSex studentSex; //学员性别类对象
private StudentState studentState; //学员状态类对象
}
StudentClass:
package edu.wsm.domain;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName StudentClass
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:09
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class StudentClass {
private Integer classId; //班级ID
private String className; //班级名称
}
StudentSex:
package edu.wsm.domain;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName StudentSex
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:09
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class StudentSex {
private Integer sexId; //性别ID
private String sexName; //性别
}
StudentState:
package edu.wsm.domain;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName StudentState
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:08
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class StudentState {
private Integer stateId; //状态ID
private String stateName; //状态
}
3、Dao层
StudentDao:
package edu.wsm.dao;
import edu.wsm.domain.Student;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @ClassName StudentDao
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:13
* @Version 1.0
**/
@Mapper
public interface StudentDao {
public List<Student> selectAll();
public void delete(Integer studentId);
public void update(Student student);
public void insert(Student student);
}
ClassDao:
package edu.wsm.dao;
import org.apache.ibatis.annotations.Mapper;
/**
* @ClassName ClassDao
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:11
* @Version 1.0
**/
@Mapper
public interface ClassDao {
}
SexDao:
package edu.wsm.dao;
import org.apache.ibatis.annotations.Mapper;
/**
* @ClassName SexDao
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:11
* @Version 1.0
**/
@Mapper
public interface SexDao {
}
StateDao:
package edu.wsm.dao;
import org.apache.ibatis.annotations.Mapper;
/**
* @ClassName StateDao
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:12
* @Version 1.0
**/
@Mapper
public interface StateDao {
}
4、Mapper文件
StudentMapper:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.wsm.dao.StudentDao">
<resultMap id="studentMap" type="edu.wsm.domain.Student">
<id column="student_id" property="studentId" javaType="java.lang.Integer"></id>
<result column="student_name" property="studentName" javaType="java.lang.String" ></result>
<result column="student_age" property="studentAge" javaType="java.lang.Integer"></result>
<result column="student_img" property="studentImg" javaType="java.lang.String"></result>
<association property="studentClass" resultMap="edu.wsm.dao.ClassDao.studentClassMap"></association>
<association property="studentState" resultMap="edu.wsm.dao.StateDao.studentStateMap"></association>
<association property="studentSex" resultMap="edu.wsm.dao.SexDao.studentSexMap"></association>
</resultMap>
<select id="selectAll" resultMap="studentMap">
SELECT *
FROM student
INNER JOIN class ON student.class_id = class.class_id
INNER JOIN state ON student.state_id = state.state_id
INNER JOIN stusex ON student.sex_id = stusex.sex_id
</select>
<delete id="delete">
delete from student where student.student_id = #{studentId}
</delete>
<update id="update">
update student
set student_name = #{studentName} , student_age = #{studentAge} , student_img = #{studentImg} , class_id = #{studentClass.classId} , state_id = #{studentState.stateId} , sex_id = #{studentSex.sexId}
where student_id = #{studentId}
</update>
<insert id="insert">
insert into student (student_name,student_img,student_age,class_id,state_id,sex_id)
values (#{studentName},#{studentImg},#{studentAge},#{studentClass.classId},#{studentState.stateId},#{studentSex.sexId})
</insert>
</mapper>
StudentClassMapper:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.wsm.dao.ClassDao">
<resultMap id="studentClassMap" type="edu.wsm.domain.StudentClass">
<id column="class_id" property="classId" javaType="java.lang.Integer"></id>
<result column="class_name" property="className" javaType="java.lang.String"></result>
</resultMap>
</mapper>
StudentSexMapper:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.wsm.dao.SexDao">
<resultMap id="studentSexMap" type="edu.wsm.domain.StudentSex">
<id column="sex_id" property="sexId" javaType="java.lang.Integer"></id>
<result column="sex_name" property="sexName" javaType="java.lang.String"></result>
</resultMap>
</mapper>
StudentStateMapper:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.wsm.dao.StateDao">
<resultMap id="studentStateMap" type="edu.wsm.domain.StudentState">
<id column="state_id" property="stateId" javaType="java.lang.Integer"></id>
<result column="state_name" property="stateName" javaType="java.lang.String"></result>
</resultMap>
</mapper>
5、Service层
StudentService:
package edu.wsm.service;
import edu.wsm.dao.StudentDao;
import edu.wsm.domain.Student;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* @ClassName StudentService
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:15
* @Version 1.0
**/
@Service
public class StudentService {
@Resource
private StudentDao studentDao;
/**
* 查询
* @return
*/
public List<Student> searchAll(){
List<Student> studentList = studentDao.selectAll();
return studentList;
}
/**
* 删除
* @param studentId 学员ID
*/
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = {Exception.class})
public void deleteOne(Integer studentId){
studentDao.delete(studentId);
}
/**
* 更新
* @param student
*/
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = {Exception.class})
public void updateOne(Student student){
studentDao.update(student);
}
/**
* 添加
* @param student
*/
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = {Exception.class})
public void addOne(Student student){
studentDao.insert(student);
}
}
6、Controller层
StudentController:
package edu.wsm.controller;
import edu.wsm.domain.Student;
import edu.wsm.service.StudentService;
import edu.wsm.util.StudentUpdateOrAddUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.List;
/**
* @ClassName StudentController
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:17
* @Version 1.0
**/
@Slf4j
@Controller
@RequestMapping("/student")
public class StudentController {
@Resource
private StudentService studentService;
/**
* 查询学生列表
* @param model
* @return show view界面
*/
@RequestMapping("/search")
public String search(Model model){
List<Student> studentList = studentService.searchAll();
model.addAttribute("studentList",studentList);
System.out.println("-----查询操作成功-----");
return "show";
}
/**
* 根据Id删除学员
* @param studentId 学员ID
* @return
*/
@RequestMapping("/delete")
public String delete(@RequestParam("studentId") Integer studentId){
System.out.println("---------删除---------"+studentId);
studentService.deleteOne(studentId);
return "redirect:/student/search";
}
/**
* 更新学员操作
* @param studentId 学员ID
* @param studentName 学员名字
* @param multipartFile img
* @param studentAge 学员年龄
* @param studentClassId 班级ID
* @param studentStateId 状态ID
* @param studentSexId 性别ID
* @return
*/
@RequestMapping("/update")
public String update(Integer studentId,String studentName, @RequestPart("studentImg")MultipartFile multipartFile, Integer studentAge, Integer studentClassId, Integer studentStateId, Integer studentSexId){
Student student = StudentUpdateOrAddUtil.studentUpdateOrAddUtil(studentId,studentName,multipartFile.getOriginalFilename(),studentAge,studentClassId,studentStateId,studentSexId);
studentService.updateOne(student);
System.out.println(student.getStudentId());
System.out.println(student.getStudentName());
System.out.println("更新");
return "redirect:/student/search";
}
/**
* 添加学员操作
* @param studentId 学员ID
* @param studentName 学员名字
* @param multipartFile img
* @param studentAge 学员年龄
* @param studentClassId 班级ID
* @param studentStateId 状态ID
* @param studentSexId 性别ID
* @return
*/
@RequestMapping(value = "/add")
public String add(Integer studentId,String studentName, @RequestPart("studentImg")MultipartFile multipartFile, Integer studentAge, Integer studentClassId, Integer studentStateId, Integer studentSexId){
System.out.println(multipartFile.getName());
System.out.println(multipartFile.getContentType());
System.out.println(multipartFile.getOriginalFilename());
Student student = StudentUpdateOrAddUtil.studentUpdateOrAddUtil(studentId,studentName,multipartFile.getOriginalFilename(),studentAge,studentClassId,studentStateId,studentSexId);
studentService.addOne(student);
return "redirect:/student/search";
}
}
7、工具类Util
FileUtil:
package edu.wsm.util;
import java.util.UUID;
/**
* @ClassName FileUtil
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:06
* @Version 1.0
**/
public class FileUtil {
/**
* UUID获取随机文件名
* @return
*/
public static String getFileNewName(){
UUID uuid = UUID.randomUUID();
return uuid.toString().replace("-","");
}
/**
* 获取图片类型后缀名(.*)
* @param imgRealName
* @return
*/
public static String getImgName(String imgRealName){
return imgRealName.substring(imgRealName.lastIndexOf("."));
}
}
StudentUpdateOrAddUtil:
package edu.wsm.util;
import edu.wsm.domain.Student;
import edu.wsm.domain.StudentClass;
import edu.wsm.domain.StudentSex;
import edu.wsm.domain.StudentState;
/**
* @ClassName StudentUpdateOrAddUtil
* @Description TODO
* @Author Deer·Wang
* @Date 2021/12/11 13:01
* @Version 1.0
**/
public class StudentUpdateOrAddUtil {
/**
* 更新和添加操作的工具类,主要为了减少重复代码
* @param studentId
* @param studentName
* @param imgName
* @param studentAge
* @param studentClassId
* @param studentStateId
* @param studentSexId
* @return
*/
public static Student studentUpdateOrAddUtil(Integer studentId,String studentName, String imgName,
Integer studentAge, Integer studentClassId, Integer studentStateId, Integer studentSexId){
Student student = new Student();
StudentClass studentClass = new StudentClass();
studentClass.setClassId(studentClassId);
StudentState studentState = new StudentState();
studentState.setStateId(studentStateId);
StudentSex studentSex = new StudentSex();
studentSex.setSexId(studentSexId);
if(studentId!=null){
student.setStudentId(studentId);
}
student.setStudentName(studentName);
student.setStudentImg(imgName);
student.setStudentAge(studentAge);
student.setStudentClass(studentClass);
student.setStudentState(studentState);
student.setStudentSex(studentSex);
return student;
}
}
8、View界面show.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
#popup1 { /* 弹框的页面*/
/*opacity: 0.2;*/
width: 500px; /*宽度*/
height: 500px; /*高度*/
background: #9dff16; /*背景色*/
display: none; /*隐藏*/
z-index: 2; /*覆盖*/
position: absolute;
top: 100px;
left: 400px; /* 定位*/
}
#popup2 { /* 弹框的页面*/
/*opacity: 0.2;*/
width: 500px; /*宽度*/
height: 500px; /*高度*/
background: #9dff16; /*背景色*/
display: none; /*隐藏*/
z-index: 2; /*覆盖*/
position: absolute;
top: 100px;
left: 400px; /* 定位*/
}
</style>
<body>
<h1>!非常好看的界面!</h1>
<table id="ta" border="1px" cellspacing="0" cellpadding="1" width="80%">
<tr>
<th>编号</th><th>头像</th><th>姓名</th><th>性别</th><th>年龄</th><th>班级</th><th>状态</th><th>删除操作</th><th>更新操作</th>
</tr>
<tr th:each="students:${studentList}" style="text-align: center">
<td th:text="${students.studentId}"></td>
<td style="height: 50px;width: 50px"><img th:src="@{'/image/'+${students.studentImg}}" style="height: 50px;width: 50px"></td>
<td th:text="${students.studentName}"></td>
<td th:text="${students.studentSex.sexName}"></td>
<td th:text="${students.studentAge}"></td>
<td th:text="${students.studentClass.className}"></td>
<td th:text="${students.studentState.stateName}"></td>
<td>
<form name="delete" th:action="@{/student/delete}" method="post">
<input type="hidden" name="studentId" th:value="${students.studentId}"/>
<input type="submit" value="删除"/>
</form>
</td>
<td>
<input name="update" type="button" onclick="updateOne()" value="修改"/>
<!--弹出框修改div-->
<div id="popup1">
<h3>修改学生信息</h3>
<form name="update" th:action="@{/student/update}" method="post" enctype="multipart/form-data">
<input type="hidden" name="studentId" th:value="${students.studentId}"/>
姓名:<input type="text" name="studentName" value=""><br>
头像:<input type="file" name="studentImg" value=""><br>
性别:<input type="radio" name="studentSexId" value="1">男
<input type="radio" name="studentSexId" value="2">女<br>
年龄:<input type="number" name="studentAge" value="" min="1" max="150"><br>
班级:<input type="text" name="studentClassId" value=""/><br>
状态:<input type="text" name="studentStateId" value=""/><br>
<input type="submit" value="修改"/>
</form>
</div>
</td>
</tr>
</table>
<button type="button" name="add" onclick="addOne()">添加新学员</button>
<!--弹出框添加div-->
<div id="popup2">
<h3>添加新学员</h3>
<form name="update" th:action="@{/student/add}" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="studentName" value=""><br>
头像:<input type="file" name="studentImg" value=""><br>
性别:<input type="radio" name="studentSexId" value="1">男
<input type="radio" name="studentSexId" value="2">女<br>
年龄:<input type="number" name="studentAge" value="" min="1" max="150"><br>
班级:<input type="text" name="studentClassId" value=""/><br>
状态:<input type="text" name="studentStateId" value=""/><br>
<input type="submit" value="添加"/>
</form>
</div>
<script>
function updateOne() {
document.getElementById('popup1').style.display = 'block';
}
function addOne(){
document.getElementById('popup2').style.display = 'block';
}
</script>
</body>
</html>
