7.1.StudentService接口和StudentServiceImpl类
7.2.TeacherService接口和TeacherServiceImpl类
7.3.CourseService接口和CourseServiceImpl类
4.AdminService和AdminServiceImpl类
一、后端以及数据库设计
1、数据库设计
首先我们需要先设计一下数据库都需存储哪些数据,作为简单地教务处管理系统我们就让他可以管理学生,教师和课程,正常来说应该还有班级,因为都是一样的处理逻辑,所以这里就没有进行设计班级管理。(!!重要部分已用颜色背景标注!! 前端相关的界面渲染资源附在文档携带的压缩包内)。
1.1.学生表设计
先说一下学生表的设计,我们需要每条记录的标识符(也就是id),接着就是学生姓名(sname),然后还有学号(sno),学生所在学院(dept),学生所在班级(classes),还需要个学生"存在"状态(status),这个字段用于进行"删除"一条信息,每个系统的删除一条信息并不是真的删除了这条信息,而是每次都查询每条信息的状态值来决定是否显示这条数据,在删除时进行更改status值来决定是否需要显示这条信息。在这里我们设置status为1时证明学生信息未被删除,如果为0则不显示此条信息。这种设置状态值的方式基本是每个管理系统的数据库的基本设置。后面的教师表和课程表也会用到这个状态。
1.2.教师表设计
教师表与学生表类似,也是需要标识符(id),教师姓名(tname),教师编号(tno),教师所属学院(dept),教师授课班级(clas),教师信息状态值(status)。
1.3.课程表设计
课程表与以上表设计相同,标识符(id),课程名称(courseName),课程编号(courseNo),课程状态(status)。
1.4.管理员表设计
管理员表为了存储管理员信息的,实际上与管理员表相对应的还应该权限表,因为是教务处管理系统,不可能只有一个管理员,所以需要分配每个管理员不同的权限,最终还需要一个超级管理员,超级管理员只能有一个用来分配权限和维护系统。由于本次做的系统是一个简单地教务处管理系统,所以就只做了一个管理员表用来做登录。由于没有权限的限制,管理员表就简单了很多,只需存储管理员账号和登录密码。和其他表一样也有个标识符(id)。
正常情况每个表都需要一个信息创建时间字段,这里不需要时间所以没有设计这个字段,而且每个表都应多预留出几个字段用于以后系统增加功能存储信息。
!!(提示:以上所有表字段未设置长度,最好根据情况设置长度,使用默认长度会浪费空余内存空间)!!
2、导入POM依赖
首先需要创建一个SpringBoot的项目,然后向pom文件中导入mysql,mybatis,thmeleaf依赖(thmeleaf是一个后端与前端交互的模板引擎后端通过thmeleaf向前端发送数据,前端通过thmeleaf接收数据)。(!!注意依赖版本)
<!--我用的springboot版本,各种工具依赖需要注意版本-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!--thymeleaf模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!--mysql5驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
<scope>runtime</scope>
</dependency>
<!--lombok-->
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<!--打包方式可不加-->
<packaging>jar</packaging>
3、SpringBoot配置文件编辑
SpringBoot配置文件在resources下默认名称为application.properties,也可将此文件更改后缀名为yaml或者yml都可作为springboot的配置文件。
#设置端口
server.port=8081
#设置数据库连接配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/edu_wyl?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
#模板引擎配置
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.mode=HTML
#关闭模板引擎缓存
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
#国际化的配置
spring.messages.basename=i18n.login
#整合mybatis
mybatis.type-aliases-package=com.wang.pojo
mybatis.mapper-locations=classpath:mapper/*.xml
国际化配置就是可以切换中英文(仅做了登录界面的)
4、自定义Config
4.1.MyMvcConfig类
首先需要进行创建自己的MVC控制类并实现WebMvcConfigurer接口
package com.wang.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/login.html").setViewName("login");
registry.addViewController("/main.html").setViewName("index");
}
//自定义国际化组件
@Bean
public LocaleResolver localeResolver() {
return new MyLocaleResolver();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/login.html", "/login", "/css/**", "/js/**", "/images/**", "/myplugs/**");
}
}
addViewControllers方法是控制首页进入时自动化控制相当于首页拦截。
addInterceptors方法是首页拦截时放行的控制这里只放行了登录页面的样式。
localeResolver方法返回的是自己注册的Bean,就是国际化配置
4.2.MyLocaleResolver类
创建自己的国际化配置MyLocaleResolver类实现接口LocaleResolver
package com.wang.config;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
//国际化
public class MyLocaleResolver implements LocaleResolver {
//解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
//获取请求中的语言参数
String language = request.getParameter("l");
Locale locale = Locale.CHINESE;//如果没有就使用默认的
//如果请求的链接携带了国际化的参数
if (!StringUtils.isEmpty(language)){
//zh_CN
String[] split = language.split("_");
//国家,地区
locale=new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
resolveLocale方法通过获取Http请求参数的格式来设置语言。
对应的需要在resources中添加一个i18n文件夹在此文件夹下存放国际化配置的语言格式
在login.properties中写的是页面首次进入的默认语言,在这里只做了中英文的切换并且只有登录页面做了语言切换。
登录页面只需更改登录按钮,账号密码输入框以及欢迎提示语。
在前端只需给后端传http请求参数就可以更改登录页面的语言
request.getParameter("l")
4.3.LoginHandlerInterceptor类
LoginHandlerInterceptor 也是自定义的类实现HandlerInterceptor 接口
package com.wang.config;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登陆成功之后应该有用户的session
Object loginUser = request.getSession().getAttribute("loginUser");
if (loginUser == null) {
request.getRequestDispatcher("/login.html").forward(request, response);
return false;
} else {
return true;
}
}
}
主要作用是拦截登录用户通过loginUser传递session,如果没有session证明登录失败,登录失败不会进入系统首页而是会停留在登录页面。主要的登录在LoginController类中
5、实体类编辑
实体类就是与数据库一致的结构,实体类名可以随便起,但是最好与数据表名相同,这样能保证在表特别多时可以做到看类名就能找到表。而实体类里面的属性名最好保证与表内字段一致,如果不一致不确定会不会在与前端传输数据时产生不必要的麻烦。
5.1.学生实体类
第一种写法:使用lombok插件自动生成实体属性和有参无参构造函数
第二种写法:手动编写属性和有参无参构造函数
5.2.教师实体类
与学生实体类一样
第一种方法:
第二种方法:
5.3.课程实体类
第一种写法:
第二种写法:
5.4.管理员实体类
第一种写法:
第二种写法:
6、mybatis配置
这里定义mapper都有哪些方法与数据库交互,并且每个mapper接口都对应有一个mapper.xml配置文件,配置文件中写的就是SQL语句通过接口回传。
6.1.StudentMapper
StudentMapper接口:
package com.wang.mapper;
import com.wang.pojo.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface StudentMapper {
List<Student> query(@Param("sname") String sname);
Student queryById(int id);
int addStudent(Student student);
int updateStudent(Student student);
int deleteStudent(int id);
}
StudentMapper.xml配置:
<?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">
<!-- 1.namespace:接口的一个路径 ,2.id :接口下抽象方法名
3.接口的返回值和resultType 对应上 ,4接口的参数 对应上-->
<mapper namespace="com.wang.mapper.StudentMapper">
<select id="query" resultType="com.wang.pojo.Student">
select *from student where status=1
<if test="sname != null and sname != ''">
and sname like concat('%',#{sname},'%')
</if>
</select>
<select id="queryById" resultType="Student">
select *from student where id=#{id} and status=1
</select>
<insert id="addStudent">
insert into student (sname,sno,dept,classes) values (#{sname},#{sno},#{dept},#{classes})
</insert>
<update id="updateStudent">
update student set sname=#{sname},sno=#{sno},dept=#{dept},classes=#{classes} where id=#{id}
</update>
<delete id="deleteStudent">
update student set status=0 where id=#{id}
</delete>
</mapper>
6.2.TeacherMapper
TeacherMapper接口:
package com.wang.mapper;
import com.wang.pojo.Teacher;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface TeacherMapper {
List<Teacher> query(@Param("teacherName") String teacherName);
int addTeacher(Teacher teacher);
Teacher queryById(Integer id);
void updateTeacher(Teacher teacher);
void deleteTeacher(@Param("id") int id);
}
TeacherMapper.xml配置:
<?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="com.wang.mapper.TeacherMapper">
<select id="query" resultType="com.wang.pojo.Teacher">
select *from teacher where status=1
<if test="teacherName != null and teacherName != ''">
and teacherName like concat('%',#{teacherName},'%')
</if>
</select>
<select id="queryById" resultType="com.wang.pojo.Teacher">
select * from teacher where id=#{id} and status=1
</select>
<insert id="addTeacher">
insert into teacher (teacherName, teacherNo, dept, teachClass) values (#{teacherName},#{teacherNo},#{dept},#{teachClass})
</insert>
<update id="updateTeacher">
update teacher set teacherName=#{teacherName},teacherNo=#{teacherNo},dept=#{dept},teachClass=#{teachClass} where id=#{id}
</update>
<delete id="deleteTeacher">
update teacher set status=0 where id=#{id}
</delete>
</mapper>
6.3.CourseMapper
CourseMapper接口:
package com.wang.mapper;
import com.wang.pojo.Course;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface CourseMapper {
List<Course> query(@Param("courseName") String courseName);
int add(Course course);
Course queryById(int id);
int updateCourse(Course course);
int deleteCourse(int id);
}
CourseMapper.xml配置:
<?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="com.wang.mapper.CourseMapper">
<select id="query" resultType="com.wang.pojo.Course">
select * from course where status=1
<if test="courseName != null and courseName != ''">
and courseName like concat('%',#{courseName},'%')
</if>
</select>
<select id="queryById" resultType="com.wang.pojo.Course">
select * from course where id=#{id} and status=1
</select>
<insert id="add">
insert into course (courseName,courseNo) values (#{courseName},#{courseNo})
</insert>
<update id="updateCourse">
update course set courseName=#{courseName},courseNo=#{courseNo} where id=#{id}
</update>
<delete id="deleteCourse">
update course set status=0 where id=#{id}
</delete>
</mapper>
6.4.AdminMapper
AdminMapper接口:
package com.wang.mapper;
import com.wang.pojo.Admin;
import org.apache.ibatis.annotations.Param;
public interface AdminMapper {
Admin findUser(@Param("username") String username, @Param("password") String password);
}
AdminMapper.xml配置:
<?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">
<!-- 1.namespace:接口的一个路径 ,2.id :接口下抽象方法名
3.接口的返回值和resultType 对应上 ,4接口的参数 对应上-->
<mapper namespace="com.wang.mapper.AdminMapper">
<select id="findUser" resultType="com.wang.pojo.Admin">
select *from admin where username=#{username} and password=#{password}
</select>
</mapper>
(!!这里的每个删除都是修改status值并没有真正删除,并且查询时也是根据status值查询,根据前端页面需求使用了模糊查询)
7、Service层编辑
说一下为什么编辑Service层,因为数据的安全性以及封装的特性,Controller层只能通过Service层拿到数据并且是在Service层实现类编辑后拿到的,起到了数据封装的作用,如果对数据有什么特殊操作可以在Service层的实现类中进行操作,而不是直接拿到原始数据进行一系列操作。
由于我这里没有什么数据可以进行操作就直接将数据返回了。
7.1.StudentService接口和StudentServiceImpl类
package com.wang.service;
import com.wang.pojo.Student;
import java.util.List;
public interface StudentService {
List<Student> query(String sname);
Student queryById(int id);
int addStudent(Student student);
int updateStudent(Student student);
int deleteStudent(int id);
}
package com.wang.service.impl;
import com.wang.mapper.StudentMapper;
import com.wang.pojo.Student;
import com.wang.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
StudentMapper studentMapper;
@Override
public List<Student> query(String name) {
return studentMapper.query(name);
}
@Override
public Student queryById(int id) {
return studentMapper.queryById(id);
}
@Override
public int addStudent(Student student) {
return studentMapper.addStudent(student);
}
@Override
public int updateStudent(Student student) {
return studentMapper.updateStudent(student);
}
@Override
public int deleteStudent(int id) {
return studentMapper.deleteStudent(id);
}
}
7.2.TeacherService接口和TeacherServiceImpl类
package com.wang.service;
import com.wang.pojo.Teacher;
import java.util.List;
public interface TeacherService {
List<Teacher> query(String teacherName);
int addTeacher(Teacher teacher);
Teacher queryById(Integer id);
void updateTeacher(Teacher teacher);
void deleteTeacher(int id);
}
package com.wang.service.impl;
import com.wang.mapper.TeacherMapper;
import com.wang.pojo.Teacher;
import com.wang.service.TeacherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TeacherServiceImpl implements TeacherService {
@Autowired
TeacherMapper teacherMapper;
@Override
public List<Teacher> query(String teacherName) {
return teacherMapper.query(teacherName);
}
@Override
public int addTeacher(Teacher teacher) {
return teacherMapper.addTeacher(teacher);
}
@Override
public Teacher queryById(Integer id) {
return teacherMapper.queryById(id);
}
@Override
public void updateTeacher(Teacher teacher) {
teacherMapper.updateTeacher(teacher);
}
@Override
public void deleteTeacher(int id) {
teacherMapper.deleteTeacher(id);
}
}
7.3.CourseService接口和CourseServiceImpl类
package com.wang.service;
import com.wang.pojo.Course;
import java.util.List;
public interface CourseService {
List<Course> query(String courseName);
int add(Course course);
Course queryById(int id);
int updateCourse(Course course);
int delete(int id);
}
package com.wang.service.impl;
import com.wang.mapper.CourseMapper;
import com.wang.pojo.Course;
import com.wang.service.CourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
CourseMapper courseMapper;
@Override
public List<Course> query(String courseName) {
return courseMapper.query(courseName);
}
@Override
public int add(Course course) {
return courseMapper.add(course);
}
@Override
public Course queryById(int id) {
return courseMapper.queryById(id);
}
@Override
public int updateCourse(Course course) {
return courseMapper.updateCourse(course);
}
@Override
public int delete(int id) {
return courseMapper.deleteCourse(id);
}
}
4.AdminService和AdminServiceImpl类
package com.wang.service;
import com.wang.pojo.Admin;
public interface AdminService {
Admin findUser(String username, String password);
}
package com.wang.service.impl;
import com.wang.mapper.AdminMapper;
import com.wang.pojo.Admin;
import com.wang.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
AdminMapper adminMapper;
@Override
public Admin findUser(String username, String password) {
return adminMapper.findUser(username, password);
}
}
8、Controller层编辑
8.1.LoginController类
LoginController就是前面Admin查询数据后的最终用途
package com.wang.controller;
import com.wang.pojo.Admin;
import com.wang.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
@Autowired
private AdminService adminService;
@RequestMapping("/login")
public String login(String username, String password, Model model, HttpSession session) {
Admin user = adminService.findUser(username, password);
if (user != null) {
session.setAttribute("loginUser", username);
return "redirect:/main.html";
} else {
model.addAttribute("msg", "用户名或密码错误!");
return "login";
}
}
@RequestMapping("/loginOut")
public String loginOut(HttpSession session) {
session.invalidate();
return "redirect:/login.html";
}
}
8.2.StudentController类
package com.wang.controller;
import com.wang.pojo.Student;
import com.wang.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/student")
public class StudentController {
@Autowired
StudentService studentService;
@RequestMapping("/query")
public String query(Student student, Model model) {
List<Student> list = studentService.query(student.getSname());
model.addAttribute("list", list);
return "role";
}
//添加页面
@RequestMapping("/insert")
public String insert() {
return "insert";
}
//执行添加
@RequestMapping("/addStu")
public String addStu(Student student) {
studentService.addStudent(student);
return "redirect:/student/query";
}
//修改页面
@GetMapping("/toupdate/{id}")
public String toUpdate(@PathVariable("id") Integer id, Model model) {
//查出原来的数据
Student student = studentService.queryById(id);
model.addAttribute("student", student);
return "update";
}
@RequestMapping("/updateStu")
public String updateStu(Student student) {
studentService.updateStudent(student);
return "redirect:/student/query";
}
//删除
@GetMapping("/deleteStu/{id}")
public String deleteStu(@PathVariable("id") Integer id) {
studentService.deleteStudent(id);
return "redirect:/student/query";
}
}
8.3.TeacherController类
package com.wang.controller;
import com.wang.pojo.Teacher;
import com.wang.service.TeacherService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/teacher")
public class TeacherController {
@Autowired
TeacherService teacherService;
@RequestMapping("/query")
public String query(String teacherName, Model model){
List<Teacher> list=teacherService.query(teacherName);
model.addAttribute("list2",list);
return "teacher";
}
@RequestMapping("/insert")
public String insert(){ return "teacherInsert";}
@RequestMapping("/addTeacher")
public String addTeacher(Teacher teacher){
teacherService.addTeacher(teacher);
return "redirect:/teacher/query";
}
@RequestMapping("/toupdate/{id}")
public String toUpdate(@PathVariable("id") Integer id, Model model){
Teacher teacher=teacherService.queryById(id);
model.addAttribute("teacher",teacher);
return "teacherUpdate";
}
@RequestMapping("/updateTeacher")
public String updateTeacher(Teacher teacher){
teacherService.updateTeacher(teacher);
return "redirect:/teacher/query";
}
@RequestMapping("/deleteTeacher/{id}")
public String deleteTeacher(@PathVariable("id") int id){
teacherService.deleteTeacher(id);
return "redirect:/teacher/query";
}
}
8.4.CourseController类
package com.wang.controller;
import com.wang.pojo.Course;
import com.wang.service.CourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/course")
public class CourseController {
@Autowired
CourseService courseService;
@RequestMapping("/query")
public String query(String courseName, Model model) {
List<Course> list = courseService.query(courseName);
model.addAttribute("list1", list);
return "course";
}
@RequestMapping("/insert")
public String insert() {
return "courseInsert";
}
@RequestMapping("/addCourse")
public String addCourse(Course course) {
courseService.add(course);
return "redirect:/course/query";
}
@RequestMapping("/toupdate/{id}")
public String toUpdate(@PathVariable("id") int id, Model model) {
Course course = courseService.queryById(id);
model.addAttribute("course", course);
return "courseUpdate";
}
@RequestMapping("/updateCourse")
public String updateCourse(Course course) {
courseService.updateCourse(course);
return "redirect:/course/query";
}
@RequestMapping("/deleteCourse/{id}")
public String deleteCourse(@PathVariable("id") int id) {
courseService.delete(id);
return "redirect:/course/query";
}
}
以上内容是数据库设计以及后端代码设计与编辑。
二、前端设计
在SpringBoot中前端页面的css,js,图片等页面渲染需放在resources下的static文件夹下而HTML页面需要放在resources下的templates下
1.登录页面
<html xmlns:th="http://www.thymeleaf.org"> 是thymeleaf模板引擎的命名空间前端使用thymeleaf接收数据必须引入。
th:href="@{/css/normalize.min.css} th:xxx是thymeleaf的特殊写法。
thymeleaf学习可以查看thymeleaf中文文档:https://fanlychie.github.io/post/thymeleaf.html
前面提到的登录页面的中英文切换就是通过这两个链接进行发送请求而l的参数就是页面发送的语言选择
<a th:href="@{/login.html(l=zh_CN)}" class="col-md-offset-4 col-lg-offset-4col-xl-offset-4" style="color: whitesmoke; text-decoration: none;">中文</a>
<a th:href="@{/login.html(l=en_US)}" style="color: whitesmoke;text-decoration: none;">English</a>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>登录</title>
<link rel="stylesheet" th:href="@{/css/normalize.min.css}">
<link rel="stylesheet" th:href="@{/css/style.css}">
<link rel="stylesheet" th:href="@{/css/bootstrap.css}">
<link rel="icon" th:href="@{/images/favicon.ico}" type="image/x-icon"/>
<link rel="bookmark" th:href="@{/images/favicon.ico}"type="image/x-icon"/>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/script.js}"></script>
</head>
<body>
<div id="formContainer" class="dwo">
<div class="formLeft">
<img th:src="@{/images/avatar.png}">
</div>
<div class="formRight">
<form th:action="@{/login}">
<header>
<h1 th:text="#{login.title}">欢迎登录</h1>
<p th:text="#{login.tip}">请登录</p>
<p style="color: red" th:text="${msg}"></p>
</header>
<section>
<label>
<input id="username" name="username" type="text" th:placeholder="#{login.username}">
<div class="border"></div>
</label>
<label>
<input id="psw" name="password" type="password" th:placeholder="#{login.password}">
<div class="border"></div>
</label>
<button type="submit">[[#{login.btn}]]</button>
</section>
<br>
<p>
<a th:href="@{/login.html(l=zh_CN)}" class="col-md-offset-4 col-lg-offset-4col-xl-offset-4" style="color: whitesmoke; text-decoration: none;">中文</a>
| <a th:href="@{/login.html(l=en_US)}" style="color: whitesmoke;text-decoration: none;">English</a>
</p>
</form>
</div>
</div>
</body>
</html>
2.用户界面
学生界面与教师,课程界面基本一样只是每次后端传的list不同,而且前端界面的请求需要与后端请求响应相同
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link rel="stylesheet" th:href="@{/css/amazeui.min.css}">
<link rel="stylesheet" th:href="@{/css/admin.css}">
<link rel="stylesheet" th:href="@{/css/bootstrap.css}">
<script th:src="@{/js/jquery-1.11.3.min.js}"></script>
<script type="text/javascript" th:src="@{/myplugs/js/plugs.js}"></script>
</head>
<body>
<div class="admin-content-body"style="" >
<div class="am-cf am-padding am-padding-bottom-0" >
<div class="am-fl am-cf"><strong class="am-text-primary am-text-lg">学生管理</strong><small></small></div>
</div>
<hr>
<div class="am-g">
<div class="am-u-sm-12 am-u-md-6">
<div class="am-btn-toolbar">
<div class="am-btn-group am-btn-group-xs">
<a type="button" th:href="@{/student/insert}" class="btn-sm btn btn-success">新增</a>
</div>
</div>
</div>
<div class="am-u-sm-8 am-u-md-4">
<div class="am-input-group am-input-group-sm">
<form th:action="@{/student/query}" class="form-inline">
<table>
<tr>
<td><input class="am-form-field" placeholder="请输入姓名" type="text" name="sname"></td>
<td><button class="am-btn am-btn-default" type="submit" id="btnsearch">搜索</button></td>
</tr>
</table>
<!--<span class="am-input-group-btn">-->
<!--</span>-->
</form>
</div>
</div>
</div>
<div class="am-g" style="margin-top: 5px;">
<div class="am-u-sm-12">
<table class="am-table am-table-striped am-table-hover">
<thead>
<tr>
<th class="table-title">
学生姓名
</th>
<th class="table-title">
学生学号
</th>
<th class="table-title">
院系
</th>
<th class="table-title">
班级
</th>
<th class="table-set">
操作
</th>
</tr>
</thead>
<tr th:each="list:${list}">
<td th:text="${list.getSname}"></td>
<td th:text="${list.getSno}"></td>
<td th:text="${list.getDept}"></td>
<td th:text="${list.getClasses}"></td>
<td>
<a class="btn btn-primary btn-sm" th:href="@{/student/toupdate/}+${list.getId()}">编辑</a>
<a class="btn btn-danger btn-sm" onclick="var del = (confirm('确定要删除吗?')); return del" th:href="@{/student/deleteStu/}+${list.getId()}" >删除</a>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
3.主界面
主界面是通过前端的连接形式进行拼接
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<title>管理系统</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="/images/favicon.ico" type="image/x-icon"/>
<link rel="bookmark" href="/images/favicon.ico" type="image/x-icon"/>
<!--link rel='stylesheet' type='text/css' href='css/googlefonts.css'-->
<!-- Bootstrap CSS -->
<link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.min.css}">
<!-- Theme CSS -->
<link rel="stylesheet" type="text/css" th:href="@{/css/vendor.css}">
<link rel="stylesheet" type="text/css" th:href="@{/css/theme.css}">
<link rel="stylesheet" type="text/css" th:href="@{/css/utility.css}">
<link rel="stylesheet" type="text/css" th:href="@{/css/custom.css}">
<style>
.nav li {
border-bottom: 1px solid #eee;
}
</style>
<script type="text/javascript" th:src="@{/js/jquery-1.11.3.min.js}"></script>
<script type="text/javascript" th:src="@{/myplugs/js/plugs.js}"></script>
</head>
<!-- Start: Header -->
<header class="navbar navbar-fixed-top">
<div class="navbar-branding"> <span id="toggle_sidemenu_l" class="glyphicons glyphicons-show_lines"></span>
<a class="navbar-brand" style="padding-top: 7px;">管理系统</a>
</div>
<div class="navbar-right">
<div class="navbar-menus">
<div class="btn-group" id="alert_menu">
<button type="button" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicons glyphicons-bell"></span> <b>3</b> </button>
</div>
<div class="btn-group" id="comment_menu">
</div>
<div class="btn-group" id="toggle_sidemenu_r">
<button type="button"> <span class="glyphicons glyphicons-parents"></span> </button>
</div>
</div>
</div>
</header>
<!-- End: Header -->
<!-- Start: Main -->
<div id="main">
<!-- Start: Sidebar -->
<aside id="sidebar_left">
<div class="user-info">
<div class="media">
<a class="pull-left" href="#">
<div class="media-object border border-purple br64 bw2 p2"> <img class="br64" th:src="@{/images/timg.gif}" alt="..."> </div>
</a>
<div class="mobile-link"> <span class="glyphicons glyphicons-show_big_thumbnails"></span> </div>
<div class="media-body">
<h5 class="media-heading mt5 mbn fw700 cursor">[[${session.loginUser}]]<span class="caret ml5"></span></h5>
<div class="media-links fs11">
<a style="text-decoration: none; outline: none;color: #000;" href="#">教务部</a><i class="fa fa-circle text-muted fs3 p8 va-m"></i>
<a style="text-decoration: none; outline: none;color: #000;" onclick="var del = (confirm('确定要退出吗?')); return del" th:href="@{/loginOut}">注销</a>
</div>
</div>
</div>
</div>
<div class="sidebar-menu">
<ul class="nav sidebar-nav">
<li>
<a class="accordion-toggle" th:href="@{/student/query}" target="right"> <span class="glyphicons glyphicons-settings"></span><span class="sidebar-title">学生管理</span><span class="caret"></span></a>
</li>
<li>
<a class="accordion-toggle" th:href="@{/course/query}" target="right"> <span class="glyphicons glyphicons-user"></span><span class="sidebar-title">课程管理</span><span class="caret"></span></a>
</li>
<li>
<a class="accordion-toggle" th:href="@{/teacher/query}" target="right"><span class="glyphicons glyphicons-user"></span><span class="sidebar-title">教师管理</span><span class="caret"></span></a>
</li>
</ul>
</div>
</aside>
<!-- End: Sidebar -->
<!-- Start: Content -->
<div style="position: absolute;left: 230px;width:83%;">
<iframe scrolling="yes" frameborder="0" name="right" th:src="@{/student/query}" width="100%" height="900"></iframe>
</div>
</div>
<script type="text/javascript">
</script>
</body>
</html>
4.用户修改信息界面
学生,教师,课程修改界面一致,也是需要更改的是请求以及实体类的属性设置
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" th:href="@{/css/amazeui.min.css}">
<link rel="stylesheet" th:href="@{/css/admin.css}">
<link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.min.css}">
<script type="text/javascript" th:src="@{/js/jquery-1.11.3.min.js}"></script>
<script type="text/javascript" th:src="@{/myplugs/js/plugs.js}"></script>
<style>
.admin-main{
padding-top: 0px;
}
</style>
</head>
<body>
<div class="am-cf admin-main">
<!-- content start -->
<div class="admin-content">
<div class="admin-content-body" >
<div class="am-g">
<form th:action="@{/student/updateStu}" class="am-form am-form-horizontal" method="post" style="padding-top:30px;" data-am-validator>
<input type="hidden" name="id" th:value="${student.getId()}">
<div class="am-form-group">
<div class="am-u-sm-9">
<label><a th:href="@{/student/query}"style="text-decoration: none; outline: none;color: #000;">返回</a></label><br/>
<label>学生姓名</label>
<input type="text" th:value="${student.getSname()}" name="sname">
</div>
</div>
<div class="am-form-group">
<div class="am-u-sm-9">
<label >学生编号</label>
<input type="text" th:value="${student.getSno()}" name="sno" >
</div>
</div>
<div class="am-form-group">
<div class="am-u-sm-9">
<label >所属院系</label>
<input type="text" th:value="${student.getDept()}" name="dept" >
</div>
</div>
<div class="am-form-group">
<div class="am-u-sm-9">
<label >所属班级</label>
<input type="text" th:value="${student.getClasses()}" name="classes" >
</div>
</div>
<div class="am-form-group">
<div class="am-u-sm-9 am-u-sm-push-3">
<button type="submit" class="btn btn-success btn-lg" >修改</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
5.用户新增界面
同样学生,教师,课程需要更改请求
<input type="text" name="sname">
<input type="text" name="sno">
<input type="text" name="classes">
(!!注意以上input标签name属性应与实体属性名对应)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" th:href="@{/css/amazeui.min.css}">
<link rel="stylesheet" th:href="@{/css/admin.css}">
<link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.min.css}">
<script type="text/javascript" th:src="@{/js/jquery-1.11.3.min.js}"></script>
<script type="text/javascript" th:src="@{/myplugs/js/plugs.js}"></script>
<style>
.admin-main {
padding-top: 0px;
}
</style>
</head>
<body>
<div class="am-cf admin-main">
<!-- content start -->
<div class="admin-content">
<div class="admin-content-body">
<div class="am-g">
<form th:action="@{/student/addStu}" class="am-form am-form-horizontal" method="post"
style="padding-top:30px;" data-am-validator>
<div class="am-form-group">
<div class="am-u-sm-9">
<label><a th:href="@{/student/query}"style="text-decoration: none; outline: none;color: #000;">返回</a></label><br/>
<label>学生姓名</label>
<input type="text" name="sname">
</div>
</div>
<div class="am-form-group">
<div class="am-u-sm-9">
<label>学生编号</label>
<input type="text" name="sno">
</div>
</div>
<div class="am-form-group">
<div class="am-u-sm-9">
<label>所属院系</label>
<input type="text" name="dept">
</div>
</div>
<div class="am-form-group">
<div class="am-u-sm-9">
<label>所属班级</label>
<input type="text" name="classes">
</div>
</div>
<div class="am-form-group">
<div class="am-u-sm-9 am-u-sm-push-3">
<button type="submit" class="btn btn-success btn-lg">添加</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
注意事项
在启动项目前需要在主启动类的上面加mapper扫描避免项目启动失败
package com.wang;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.wang.mapper")
public class StudentdemoApplication {
public static void main(String[] args) {
SpringApplication.run(StudentdemoApplication.class, args);
}
}
下图是项目文件夹结构。
前端设计中仅包含表单使用等与后端关联的代码 (文章已将本文的前端渲染绑定到文章)。
前端页面可随意使用,要注意前后端数据绑定。
以上全部内容仅是自学记录,可能有错误!!!注意辨别。