![cover](https://img-blog.csdnimg.cn/75907efac89443d0a4ce99231c433cf7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y6G6aOe6ZuoX3NtaWxl,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
springboot + thymeleaf + mybatis 的一个学生管理项目
springboot 整合 thymeleaf 的一个简单小项目
·
提示:技术用的是 springboot + thymeleaf + mybatis + bootstrap
制作不易, 希望大家可以支持一下博主。 整个项目私聊或者评论我会发给大家。
前言
提示:这里可以添加本文要记录的大概内容:
例如:里面包含分页功能和多表查询解决方案。这是我自己创建的一个项目, 之后会更新其他技术的项目, 希望大家支持支持。这个系列我会一直维护下去, 有问题直接私信。
效果展示
- bibi展示视频地址
- 功能页面
提示:以下是本篇文章正文内容,下面案例可供参考
一、MySQL文件
1.登录用户表
CREATE TABLE `user` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`realname` varchar(1026) DEFAULT NULL COMMENT '真实姓名',
`pwd` varchar(524) NOT NULL COMMENT '密码',
`gender` int DEFAULT NULL COMMENT '性别:0 男 1 女',
PRIMARY KEY (`id`,`username`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb3;
2.学生信息表
CREATE TABLE `student_info` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`sex` varchar(50) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`address` varchar(50) DEFAULT NULL,
`img` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb3 COMMENT='学生信息';
3.学生成绩表
CREATE TABLE `grade` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`course_no` varchar(50) NOT NULL,
`fraction` int DEFAULT NULL,
PRIMARY KEY (`id`,`course_no`)
) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb3 COMMENT='成绩表';
4.课程表
CREATE TABLE `curriculum` (
`course_no` varchar(50) NOT NULL,
`course_title` varchar(50) DEFAULT NULL,
`credit` int DEFAULT NULL,
PRIMARY KEY (`course_no`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COMMENT='课程表';
5.整个表的结构(很简单的表)
二、Java代码和前端代码
1.导入项目依赖的包(pom.xml)
代码如下(示例):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--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.2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--导入jQuery-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
<!--导入bootstrap-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
</dependencies>
2.登录和注册功能的实现
1.controller层
@Controller
@RequestMapping("/pub/user")
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService){
this.userService = userService;
}
/**
* 登录功能
* @return
*/
@GetMapping("/toLogin")
public String toLogin(){
return "/user/login";
}
@PostMapping("/login")
public String login(String username, String pwd, HttpSession session,Model model){
User user = userService.login(username, pwd);
if(user != null){
session.setAttribute("user", user);
return "redirect:/pri/student/findAll";
}
model.addAttribute("msg", "账号或密码错误");
return "user/login";
}
/**
* 注册功能
* @param model
* @return
*/
@GetMapping("/toRegister")
public String toRegister(Model model){
model.addAttribute("user", new User());
return "user/register";
}
@PostMapping("/register")
public String register(User user,Model model){
boolean flag = userService.register(user);
if(flag){
return "user/login";
}
model.addAttribute("msg", "命名不规范");
return "user/register";
}
/**
* 退出登录, 并且清除session会话
* @param session
* @return
*/
@GetMapping("/logout")
public String logout(HttpSession session){
//清除session会话
session.removeAttribute("user");
return "index";
}
/**
* 修改密码
* @param request
* @param model
* @return
*/
@GetMapping("/toRevise")
public String toRevise(HttpServletRequest request,Model model){
Integer id = Integer.parseInt(request.getParameter("id"));
User user = userService.findUserById(id);
model.addAttribute("user", user);
model.addAttribute("oldPwd",user.getPwd());
return "user/revise";
}
@PostMapping("/revise")
public String revise(User user,String oldPwd,Model model){
User oldUser = userService.findByUserByPwd(user.getId(),oldPwd);
if(oldUser != null){
userService.revise(user);
return "index"; //重新登录一下, 修改完密码
}
model.addAttribute("msg","旧密码不对");
return "user/revise";
}
}
2.前端界面
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<link rel = "stylesheet" th:href = "@{/bootstrap.min.css}"/>
<link rel = "stylesheet" th:href = "@{/bootstrap.min.js}"/>
<link rel = "stylesheet" th:href = "@{/jquery.min.js}"/>
<link rel="shortcut icon" href="/favicon1.ico"/>
<link rel="bookmark" href="/favicon1.ico"/>
<style>
body{
/*background-image: url(register.jpg);*/
background-repeat:no-repeat;
}
.header{
display: flex;
align-items: center;
justify-content:center;
}
.footer{
display: flex;
align-items: center;
justify-content:center;
}
.center{
background: url("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01d46d5d1ca689a801213763ef5aa9.jpg%401280w_1l_2o_100sh.jpg&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652583382&t=f0de528f4fa9dcc07332bc83ef8e988b");
height: 600px;
margin: 0;
display: flex;
align-items: center;
justify-content:center;
width: auto;
}
</style>
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container header">
<h2>学生信息管理系统</h2>
</div>
</nav>
<div class="center">
<form th:action="@{/pub/user/login}" method="post" class="form-horizontal">
<div class="form-group" style="width: 400px">
<label class="col-sm-2 control-label">账号:</label>
<div class="col-sm-9">
<input type="text" class="form-control" name="username" placeholder="账号">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">密码:</label>
<div class="col-sm-9">
<input type="password" class="form-control" name="pwd" placeholder="密码">
</div>
</div>
<div class="form-group" style="float: left; margin-left: 40px">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default" style="display:inline"> 登录</button>
<p th:if="${msg}!=null" th:text="${msg}" style="display:inline;color: red"></p>
</div>
</div>
<div class="form-group" style="float: left">
<div class="col-sm-offset-2 col-sm-10">
<a class="btn btn-default" th:href="@{/pub/user/toRegister}" role="button">注册</a>
</div>
</div>
</form>
</div>
<nav class="navbar navbar-default navbar-fixed-bottom">
<div class="container footer">
<h4>
<a href="#">CreateTime:2022-4-11 @Author:XHH</a>
</h4>
</div>
</nav>
</body>
</html>
效果展示
register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
<link rel = "stylesheet" th:href = "@{/bootstrap.min.css}"/>
<link rel = "stylesheet" th:href = "@{/bootstrap.min.js}"/>
<link rel = "stylesheet" th:href = "@{/jquery.min.js}"/>
<link rel="shortcut icon" href="/favicon1.ico"/>
<link rel="bookmark" href="/favicon1.ico"/>
<style>
body{
/*background-image: url(register.jpg);*/
background-repeat:no-repeat;
}
.header{
display: flex;
align-items: center;
justify-content:center;
}
.footer{
display: flex;
align-items: center;
justify-content:center;
}
.center{
background: url("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01d46d5d1ca689a801213763ef5aa9.jpg%401280w_1l_2o_100sh.jpg&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652583382&t=f0de528f4fa9dcc07332bc83ef8e988b");
height: 640px;
margin: 0;
display: flex;
align-items: center;
justify-content:center;
width: auto;
}
</style>
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container header">
<h2>学生信息管理系统</h2>
</div>
</nav>
<div class="center">
<form th:action="@{/pub/user/register}" method="post" class="form-horizontal">
<div class="form-group" style="width: 400px">
<label class="col-sm-2 control-label">账号:</label>
<div class="col-sm-9">
<input type="text" class="form-control" name="userName" placeholder="账号">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">姓名:</label>
<div class="col-sm-9">
<input type="text" class="form-control" name="realName" placeholder="姓名">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">性别:</label>
<div class="col-sm-9">
<input type="text" class="form-control" name="gender" placeholder="性别">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">密码:</label>
<div class="col-sm-9">
<input type="password" class="form-control" name="pwd" placeholder="密码">
</div>
</div>
<div class="form-group" style="float: left; margin-left: 40px">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default" style="display:inline"> 注册</button>
<p th:if="${msg}!=null" th:text="${msg}" style="display:inline;color: red"></p>
</div>
</div>
<div class="form-group" style="float: left">
<div class="col-sm-offset-2 col-sm-10">
<a class="btn btn-default" th:href="@{/pub/user/toLogin}" role="button">登录</a>
</div>
</div>
</form>
</div>
<nav class="navbar navbar-default navbar-fixed-bottom">
<div class="container footer">
<h4>
<a href="#">CreateTime:2022-4-11 @Author:XHH</a>
</h4>
</div>
</nav>
</body>
</html>
效果展示
3.学生信息展示功能(包括分页)
1.controller层
/**
* @Autor XHH
* @Time 2022-4-12
* 学生信息接口
*/
@Controller
@RequestMapping("/pri/student")
public class StudentController {
private StudentService studentService;
@Autowired
public void setStudentService(StudentService studentService){
this.studentService =studentService;
}
private CurriculumService curriculumService;
@Autowired
public void setCurriculumService(CurriculumService curriculumService){
this.curriculumService =curriculumService;
}
/**
* 查询功能
* @return
*/
@GetMapping("/findAll")
public String check(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", required = false, defaultValue = "5") Integer pageSize,
Model model){
Integer totalPage = null;
pageNum = (pageNum-1)*pageSize;
List<Student> studentList = studentService.findAll(pageNum,pageSize);
Integer pageTotal = studentService.findTotalRecord();
model.addAttribute("studentList",studentList);
//实行分页
if(pageTotal % pageSize == 0){
totalPage = pageTotal / pageSize;
}else{
totalPage = pageTotal / pageSize + 1;
}
model.addAttribute("totalPage",totalPage);
return "student/list";
}
/**
* 删除功能
* @param request
* @return
*/
@GetMapping("/delete")
public String delete(HttpServletRequest request){
int cId = Integer.parseInt(request.getParameter("id"));
// System.out.println(cId);
studentService.deleteStudent(cId);
return "redirect:/pri/student/findAll";
}
/**
* 添加功能
* @param model
* @return
*/
@GetMapping("/toAdd")
public String toAdd(Model model){
model.addAttribute("student",new Student());
return "student/add";
}
@PostMapping("/add")
public String add(Student student){
studentService.insertStudent(student);
return "redirect:/pri/student/findAll";
}
/**
* 更新接口
* @param request
* @param model
* @return
*/
@GetMapping("/toUpdate")
public String toUpdate(HttpServletRequest request,Model model){
int cId = Integer.parseInt(request.getParameter("id"));
Student student = studentService.findStudentById(cId);
model.addAttribute("student", student);
return "student/modify";
}
@PostMapping("/update")
public String update(Student student){
studentService.updateStudent(student);
return "redirect:/pri/student/findAll";
}
/**
* 学生信息详情
* @param request
* @param model
* @return
*/
@GetMapping("/findDetail")
public String findByIdDetail(HttpServletRequest request,Model model){
Integer id = Integer.parseInt(request.getParameter("id"));
Student student = studentService.findByIdDetail(id);
model.addAttribute("studentDetail",student);
return "student/detail";
}
/**
* 查询学生成绩, 正则维护中, 接口还没开发完全 如何才能使得集合映射到数据中去
* @param id
* @param model
* @return
*/
@GetMapping("/findGrade")
public String findByIdWithGrade(@RequestParam(value = "id", required = false, defaultValue = "1") Integer id,
Model model){
List<Grade> gradeList = studentService.findByIdWithGrade(id);
if(gradeList != null){
//这个是处理如何把课程编号转变为课程标题
String courseNo = null;
for(int i = 0; i < gradeList.size(); i++){
courseNo = gradeList.get(i).getCourseNo();
Curriculum curriculum = curriculumService.findCourseByNo(courseNo);
gradeList.get(i).setCourseNo(curriculum.getCourseTitle());
}
//这个是获取姓名
String name = (String)gradeList.get(0).getStudentList().get(0).getName();
model.addAttribute("gradeList",gradeList);
model.addAttribute("name", name);
return "student/grade";
}
return "error";
}
}
2.前端页面渲染
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>学生信息管理</title>
<link rel = "stylesheet" th:href = "@{/bootstrap.min.css}"/>
<link rel = "stylesheet" th:href = "@{/bootstrap.min.js}"/>
<link rel = "stylesheet" th:href = "@{/jquery.min.js}"/>
<link rel="shortcut icon" href="/favicon1.ico"/>
<link rel="bookmark" href="/favicon1.ico"/>
</head>
<body>
<div class="container" style="width: 940px;">
<div class="col-xs-9" style="width: 960px">
<div class="col-xs-12 col-md-4">
<h2>学生管理系统 <small>@XHH</small></h2>
</div>
<div class="col-xs-6 col-md-4 col-md-offset-4" style="float: right">
<div class="btn btn-default btn-lg" style="float: right" th:if="${#lists.isEmpty(session.user)}">
<h4>
<a th:href="@{/pub/user/toLogin}">登录</a>
</h4>
</div>
<div class="btn btn-default btn-lg" style="float: right" th:if="${not #lists.isEmpty(session.user)}">
<h4>
<span th:text="${session.user.getRealName()}"></span>
<span th:text="${session.user.getGender() == 1 ? '男' : '女'}"></span>
</h4>
</div>
<div class="btn btn-default btn-lg" style="float: right" th:if="${not #lists.isEmpty(session.user)}">
<h4>
<a th:href="@{/pub/user/toRevise(id=${session.user.getId})}">修改密码</a>
</h4>
</div>
<div class="btn btn-default btn-lg" style="float: right" th:unless="not ${#lists.isEmpty(session.user)}">
<h4>
<a th:href="@{/pub/user/toRegister}">注册</a>
</h4>
</div>
<div class="btn btn-default btn-lg" style="float: right" th:if="not ${#lists.isEmpty(session.user)}">
<h4>
<a th:href="@{/pub/user/logout}">注销</a>
</h4>
</div>
</div>
</div>
<div style="margin-top: 100px;width: 940px">
<div style="float: left;margin-right: 30px">
<h3>
<a class="btn btn-info" th:href="@{/pri/student/findAll}">学生管理</a>
</h3>
</div>
<div style="float: left;margin-right: 30px">
<h3>
<a class="btn btn-default" th:href="@{/pri/curriculum/findAll}">课程管理</a>
</h3>
</div>
<div style="float: left;margin-right: 30px">
<h3>
<a class="btn btn-primary" th:href="@{/pri/grade/findAll}">成绩管理</a>
</h3>
</div>
</div>
<div style="margin-top: 20px;width: 940px">
<table class="table table-hover">
<tr class="info">
<td>学号</td>
<td>姓名</td>
<td>性别</td>
<td>出生日期</td>
<td>家庭住址</td>
<td>操作</td>
</tr>
<tr class="warning" th:each="students : ${studentList}">
<td th:text="${students.id}"></td>
<td th:text="${students.name}"></td>
<td th:text="${students.sex}"></td>
<td th:text="${#dates.format(students.birthday, 'yyyy-MM-dd')}"></td>
<td th:text="${students.address}"></td>
<td>
<a class="btn btn-danger" th:href="@{/pri/student/delete(id=${students.id})}">删除</a>
<a class="btn btn-warning" th:href="@{/pri/student/toUpdate(id=${students.id})}">修改</a>
<a class="btn btn-info" th:href="@{/pri/student/findDetail(id=${students.id})}">个人信息</a>
<a class="btn btn-info" th:href="@{/pri/student/findGrade(id=${students.id})}" >成绩单</a>
</td>
</tr>
</table>
<nav aria-label="Page navigation" th:if="${totalPage} > 0" style="float: left">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li th:each="i: ${#numbers.sequence(1,totalPage)}">
<a th:href="@{/pri/student/findAll(pageNum=${i})}" th:text="${i}"></a>
</li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
<div style="float: right">
<a class="btn btn-info" th:href="@{/pri/student/toAdd}">新增</a>
</div>
</div>
<nav class="navbar navbar-default navbar-fixed-bottom">
<div class="container" style="display: flex;justify-content: center;align-items: center">
<h4 href="#" id="show">
@Author:XHH
@Time
<span></span>/<span></span>/<span></span> <span></span>:<span></span>:<span></span>
</h4>
</div>
</nav>
</div>
</body>
</html>
效果展示
总结
提示:里面有分页功能(手写), 然后还有随机头像等功能, 包括在thymeleaf中所遇到的问题, 可以详细参考一下我的例子。
更多推荐
所有评论(0)