SpringMVC(12)综合案例练习:图书管理系统(后续仍会使用)
文章目录
- SpringMVC(12)综合案例练习:图书管理系统(后续仍会使用)
- 观前提醒:
- [1. 接口文档描述:](#1. 接口文档描述:)
-
- [1.1 登录接口:](#1.1 登录接口:)
- [1.2 图书列表展示接口:](#1.2 图书列表展示接口:)
- [1.3 Book类字段说明:](#1.3 Book类字段说明:)
- [2. 后端代码:](#2. 后端代码:)
-
- [2.1 Book类:](#2.1 Book类:)
- [2.2 UserController类:](#2.2 UserController类:)
- [2.3 BookController类:](#2.3 BookController类:)
- [2.4 后端代码解释:](#2.4 后端代码解释:)
- [3. 接口测试结果:](#3. 接口测试结果:)
-
- [3.1 用户登录接口:](#3.1 用户登录接口:)
- [3.2 图书列表展示接口:](#3.2 图书列表展示接口:)
- [4. 前端代码:](#4. 前端代码:)
-
- [4.1 用户登录页面](#4.1 用户登录页面)
- [4.2 图书列表展示页面](#4.2 图书列表展示页面)
- [5. 运行结果:](#5. 运行结果:)
-
- [5.1 用户登录页面:](#5.1 用户登录页面:)
- [5.2 图书列表展示页面:](#5.2 图书列表展示页面:)
- [6. 总结:](#6. 总结:)
观前提醒:
如果大家要获取这篇博客涉及到的源代码,从我的 gitee中获取:
https://gitee.com/mrbgvhbhjv/java-ee-course/tree/master/后端代码/springboot_bookManage_System

代码自行下载即可。
这个图书管理系统,在我们学完Mybatis的时候,会再次使用这个系统来进行练习。
1. 接口文档描述:
1.1 登录接口:

1.2 图书列表展示接口:

1.3 Book类字段说明:

2. 后端代码:
定义Book类的时候,需要注意,定价 要求是高精准 的数据,我们使用的数据类型为BigDecimal。
在Java开发中,处理浮点数计算时,常常会遇到精度问题。为了避免这些问题,可以使用 BigDecimal 类 。BigDecimal类 提供了高精度的浮点数运算,适用于金融计算等对精度要求较高的场景。
2.1 Book类:
java
package org.example.springboot_bookmanage_system.book;
import lombok.Data;
import java.math.BigDecimal;
/**
* Created with IntelliJ IDEA.
* Description:
* Date: 2025-10-21
* Time: 下午2:09
*/
@Data
public class BookInfo {
private Integer bookID;
private String bookName;
private String author;
private Integer count;
private BigDecimal price;
private String publish;
private Integer status;
private String statusCN;
}
2.2 UserController类:
java
package org.example.springboot_bookmanage_system.book;
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created with IntelliJ IDEA.
* Description:
* Date: 2025-10-21
* Time: 下午2:18
*/
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public Boolean login(String username, String password, HttpSession session) {
// 1. 验证是否为空
//2.匹配用户名和密码
//3. 存储 Session
//4. 返回结果
if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
return false;
}
if ("admin".equals(username) && "admin".equals(password)) {
session.setAttribute("username", username);
return true;
}
return false;
}
}
2.3 BookController类:
java
package org.example.springboot_bookmanage_system.book;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.awt.print.Book;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Created with IntelliJ IDEA.
* Description:
* Date: 2025-10-21
* Time: 下午2:41
*/
@RequestMapping("/book")
@RestController
public class BookController {
@RequestMapping("/getList")
public List<BookInfo> getList(){
List<BookInfo> bookInfoList = mockData();
// 一般,是否可以借阅的信息文字,是由前端来设计的,后端是不用管的。
// 但是,我们这里为了测试,可以先加上
for(BookInfo bookInfo:bookInfoList){
if (bookInfo.getStatus() == 1){
bookInfo.setStatusCN("可借阅");
}else {
bookInfo.setStatusCN("不可借阅");
}
}
return bookInfoList;
}
public List<BookInfo> mockData(){
List<BookInfo> bookInfoList = new ArrayList<>();
for (int i = 1; i <= 15; i++) {
BookInfo bookInfo = new BookInfo();
bookInfo.setBookID(i);
bookInfo.setBookName("图书" + i);
bookInfo.setAuthor("作者" + i);
bookInfo.setCount(new Random().nextInt(100));
bookInfo.setPrice(new BigDecimal(new Random().nextInt(100)));
bookInfo.setPublish("出版社" + i);
bookInfo.setStatus( i%2==0?1:2 );//数据库中,常用数字来表示状态:1-可借阅 2-不可借阅
bookInfoList.add(bookInfo);
}
return bookInfoList;
}
}
一般,是否可以借阅的信息文字,是由前端来设计的,后端是不用管的,后端只需要返回 数字(0,1表示)给前端,前端会根据接口文档的描述,进行处理。
这里涉及到一个新的名词:mock(造假数据)
2.4 后端代码解释:
随机数生成:

new Random():表示生成一个随机数对象
new Random().nextInt():表示生成的是一个 int类型 的随机数对象。
new Random().nextInt(100):表示生成的是一个 int类型 的随机数对象,范围是 0~100
3. 接口测试结果:
3.1 用户登录接口:

3.2 图书列表展示接口:

4. 前端代码:
你从我 gitee 下载的图书管理系统的代码,需要修改的代码就这两个:login.html 和 book_list.html
其他的代码不变。
4.1 用户登录页面
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/login.css">
<script type="text/javascript" src="js/jquery.min.js"></script>
</head>
<body>
<div class="container-login">
<div class="container-pic">
<img src="pic/computer.png" width="350px">
</div>
<div class="login-dialog">
<h3>登陆</h3>
<div class="row">
<span>用户名</span>
<input type="text" name="userName" id="userName" class="form-control">
</div>
<div class="row">
<span>密码</span>
<input type="password" name="password" id="password" class="form-control">
</div>
<div class="row">
<button type="button" class="btn btn-info btn-lg" onclick="login()">登录</button>
</div>
</div>
</div>
<script src="js/jquery.min.js"></script>
<script>
function login ()
{
$.ajax({
type: "post",
url: "/user/login",
data: {
name: $("#userName").val(),
password: $("#password").val()
},
success: function (result)
{
if (result) {
//用户名密码验证成功
location.href = "book_list.html";
} else {
alert("用户名或密码错误");
}
}
});
// location.href = "book_list.html";
}
</script>
</body>
</html>
4.2 图书列表展示页面
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图书列表展示</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/list.css">
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script src="js/jq-paginator.js"></script>
</head>
<body>
<div class="bookContainer">
<h2>图书列表展示</h2>
<div class="navbar-justify-between">
<div>
<button class="btn btn-outline-info" type="button" onclick="location.href='book_add.html'">添加图书</button>
<button class="btn btn-outline-info" type="button" onclick="batchDelete()">批量删除</button>
</div>
</div>
<table>
<thead>
<tr>
<td>选择</td>
<td class="width100">图书ID</td>
<td>书名</td>
<td>作者</td>
<td>数量</td>
<td>定价</td>
<td>出版社</td>
<td>状态</td>
<td class="width200">操作</td>
</tr>
</thead>
<tbody>
<!-- <tr>
<td><input type="checkbox" name="selectBook" value="1" id="selectBook" class="book-select"></td>
<td>1</td>
<td>大秦帝国第一册</td>
<td>我是作者</td>
<td>23</td>
<td>33.00</td>
<td>北京出版社</td>
<td>可借阅</td>
<td>
<div class="op">
<a href="book_update.html?bookId=1">修改</a>
<a href="javascript:void(0)" onclick="deleteBook(1)">删除</a>
</div>
</td>
</tr>
<tr>
<td><input type="checkbox" name="selectBook" value="1" id="selectBook" class="book-select"></td>
<td>2</td>
<td>大秦帝国第二册</td>
<td>我是作者</td>
<td>23</td>
<td>33.00</td>
<td>北京出版社</td>
<td>可借阅</td>
<td>
<div class="op">
<a href="book_update.html?bookId=2">修改</a>
<a href="javascript:void(0)" onclick="deleteBook(2)">删除</a>
</div>
</td>
</tr>
<tr>
<td><input type="checkbox" name="selectBook" value="1" id="selectBook" class="book-select"></td>
<td>3</td>
<td>大秦帝国第三册</td>
<td>我是作者</td>
<td>23</td>
<td>33.00</td>
<td>北京出版社</td>
<td>可借阅</td>
<td>
<div class="op">
<a href="book_update.html?bookId=3">修改</a>
<a href="javascript:void(0)" onclick="deleteBook(3)">删除</a>
</div>
</td>
</tr>
<tr>
<td><input type="checkbox" name="selectBook" value="1" id="selectBook" class="book-select"></td>
<td>4</td>
<td>大秦帝国第四册</td>
<td>我是作者</td>
<td>23</td>
<td>33.00</td>
<td>北京出版社</td>
<td>可借阅</td>
<td>
<div class="op">
<a href="book_update.html?bookId=4">修改</a>
<a href="javascript:void(0)" onclick="deleteBook(4)">删除</a>
</div>
</td>
</tr> -->
</tbody>
</table>
<div class="demo">
<ul id="pageContainer" class="pagination justify-content-center"></ul>
</div>
<script>
getBookList();
function getBookList ()
{
$.ajax({
type: "get",
url: "/book/getList",
success: function (books)
{
var wholeHtml = "";
for (var book of books) {
// 拼接列表
wholeHtml += '<tr>';
wholeHtml += '<td><input type="checkbox" name="selectBook" value="' + book.bookID + '" id="selectBook" class="book-select"></td>';
wholeHtml += '<td>' + book.bookID + '</td>';
wholeHtml += '<td>' + book.bookName + '</td>';
wholeHtml += '<td>' + book.author + '</td>';
wholeHtml += '<td>' + book.count + '</td>';
wholeHtml += '<td>' + book.price + '</td>';
wholeHtml += '<td>' + book.publish + '</td>';
wholeHtml += '<td>' + book.statusCN + '</td>';
wholeHtml += '<td><div class="op">';
wholeHtml += '<a href="book_update.html?bookId=' + book.bookID + '">修改</a>';
wholeHtml += '<a href="javascript:void(0)" onclick="deleteBook(' + book.bookID + ')">删除</a>';
wholeHtml += '</div></td></tr>';
}
$("tbody").html(wholeHtml);
}
});
}
//翻页信息
$("#pageContainer").jqPaginator({
totalCounts: 100, //总记录数
pageSize: 10, //每页的个数
visiblePages: 5, //可视页数
currentPage: 1, //当前页码
first: '<li class="page-item"><a class="page-link">首页</a></li>',
prev: '<li class="page-item"><a class="page-link" href="javascript:void(0);">上一页<\/a><\/li>',
next: '<li class="page-item"><a class="page-link" href="javascript:void(0);">下一页<\/a><\/li>',
last: '<li class="page-item"><a class="page-link" href="javascript:void(0);">最后一页<\/a><\/li>',
page: '<li class="page-item"><a class="page-link" href="javascript:void(0);">{{page}}<\/a><\/li>',
//页面初始化和页码点击时都会执行
onPageChange: function (page, type)
{
console.log("第" + page + "页, 类型:" + type);
}
});
function deleteBook (id)
{
var isDelete = confirm("确认删除?");
if (isDelete) {
//删除图书
alert("删除成功");
}
}
function batchDelete ()
{
var isDelete = confirm("确认批量删除?");
if (isDelete) {
//获取复选框的id
var ids = [];
$("input:checkbox[name='selectBook']:checked").each(function ()
{
ids.push($(this).val());
});
console.log(ids);
alert("批量删除成功");
}
}
</script>
</div>
</body>
</html>
我们前端,类似这种 获取所有元素信息 的时候,一般是页面刷新的时候,就应该获取到的,没有触发条件。
5. 运行结果:
5.1 用户登录页面:

5.2 图书列表展示页面:

6. 总结:
这个是简易版本的图书管理系统(无Mybatis版)。
仅是用来练手的。
完整的图书管理系统,在这篇博客中:综合案例1:图书管理系统(1)项目准备,用户登录接口,添加图书接口
开始介绍。
最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!
下一篇博客: