🎇个人主页:Ice_Sugar_7
🎇所属专栏:JavaEE
🎇欢迎点赞收藏加关注哦!
图书管理系统 v1.0
- 🍉登录
- 🍉图书操作
- 🍌图书类
- 🍌页面信息
- 🍌操作
- 🍉前端页面
- 🍌展示图书
- 🍌添加图书
- 🍌更新图书
🍉登录
首先需要准备个登录页面,前端代码如下:
<!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({
url: "/UserController/login",
type: "post",
data: {
username: $("#username").val(),
password: $("#password").val()
},
success: function (result) {
if (result == "") {
//密码正确
location.href = "book_list.html";
} else {
alert(result);
}
}
});
}
</script>
</body>
</html>
页面如下:
登录的逻辑为:前端输入用户名和密码,传给后端,后端根据用户名,到数据库查找用户信息(是否有这名用户),然后将输入的 password 和数据库中的用户密码进行匹配,看是否正确
后端准备个用户信息的类:
@Data
public class UserInfo {
private Integer id;
private String userName;
private String password;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}
接下来是验证登录信息,根据 Spring MVC 的框架完成代码:
@RestController
@RequestMapping("/UserController")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/login")
public String login(String username, String password, HttpSession session) {
//用户名或密码为空
if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password))
return "用户名和密码不能为空";
//先从数据库中找找有没有这个用户名
UserInfo userInfo = userService.queryByName(username);
if(userInfo == null) return "用户不存在";
if(!userInfo.getPassword().equals(password)) return "密码错误"; //账号和密码不一致
session.setAttribute(Constants.USER_SESSION_KEY,userInfo); //成功登录后保存用户信息
return "";
}
}
public class Constants {
public static final String USER_SESSION_KEY = "user_session_key";
}
public class UserService {
@Autowired
private UserInfoMapper userInfoMapper;
public UserInfo queryByName(String userName) {
return userInfoMapper.queryByName(userName);
}
}
@Mapper
public interface UserInfoMapper {
@Select("select id,user_name,password,delete_flag,create_time,update_time" +
" from user_info where user_name = #{userName} and delete_flag = 0")
public UserInfo queryByName(String userName);
}
🍉图书操作
🍌图书类
先准备个图书的类:
@Data
public class BookInfo {
private Integer id; //图书编号
private String bookName; //书名
private String author; //作者
private Integer count; //数量
private BigDecimal price; //定价
private String publish; //出版社
private Integer status; //状态 1表示可以借阅;2表示不可借阅
private String statusCN; //到时页面呈现书的借阅状态要用中文
private Date createTime; //创建时间
private Date updateTime; //更新时间
}
使用枚举表示图书状态:
public enum BookStatus {
DELETE(0,"删除"), //采用逻辑删除
NORMAL(1,"可借阅"),
FORBIDDEN(2,"不可借阅"),
;
BookStatus(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
private Integer code;
private String desc;
/**
* 根据 code 返回描述信息
* @return
*/
public static BookStatus getDescByCode(Integer code) {
switch (code) {
case 0: return DELETE;
case 1: return NORMAL;
case 2: return FORBIDDEN;
}
return FORBIDDEN;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
🍌页面信息
需要实现翻页功能,每页展示若干本图书(这里默认每页 10 本书)
用一个 PageRequest 的类表示页面信息:当前页数和当前页第一本书的下标;PageResult 记录总的信息:页面数、每一页的信息等
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageRequest {
private Integer offset; //当前页起始位置的元素下标
private Integer pageNum = 1; //当前页数 默认在第一页
private Integer pageSize = 10; //每页展示的记录数 默认为 10 条
public Integer getOffset() {
return (pageNum - 1) * pageSize;
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageResult<T> {
private List<T> records;
private Integer count;
private PageRequest pageRequest;
}
🍌操作
这个系统我们需要实现这几个功能:添加图书、删除单本图书、批量删除图书、修改图书信息
Controller 类:
@Slf4j
@RestController
@RequestMapping("BookController")
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping("addBook")
public String addBook(BookInfo bookInfo) {
//打日志
log.info("添加图书,bookInfo:{}",bookInfo);
//检验参数是否为空
if(!StringUtils.hasLength(bookInfo.getBookName())
|| !StringUtils.hasLength(bookInfo.getAuthor())
|| bookInfo.getCount() == null
|| bookInfo.getPrice() == null
|| !StringUtils.hasLength(bookInfo.getPublish())
|| bookInfo.getStatus() == null) {
return "添加的图书信息不能为空";
}
//添加图书
try {
Integer res = bookService.insertBook(bookInfo);
if(res > 0) return "";
} catch (Exception e) {
log.error("添加图书异常,e:",e);
}
return "添加失败";
}
@RequestMapping("getBookListByPage")
public PageResult<BookInfo> getBookListByPage(PageRequest pageRequest, HttpSession httpSession) {
//return bookService.queryBookByPage(pageRequest.getPageSize(),pageRequest.getOffset());
log.info("查询图书列表,请求参数pageRequest:{}",pageRequest);
PageResult<BookInfo> bookList = bookService.queryBookByPage(pageRequest);
return bookList;
}
@RequestMapping("queryBookById")
public BookInfo queryBookById(Integer bookId) {
if(bookId == null || bookId <= 0) return new BookInfo();
BookInfo bookInfo = bookService.queryBookById(bookId);
return bookInfo;
}
@RequestMapping("updateBook")
public String updateBook(BookInfo bookInfo) {
log.info("修改图书,bookInfo:{}",bookInfo);
try {
Integer res = bookService.updateBook(bookInfo);
if(res > 0) return "";
} catch (Exception e) {
log.error("修改图书异常,e:",e);
}
return "修改失败";
}
@RequestMapping("batchDeleteBookByIds")
public boolean batchDeleteBookByIds(@RequestParam List<Integer> ids) {
log.info("批量删除图书,books:{}",ids);
try{
bookService.batchDeleteBookByIds(ids);
} catch (Exception e) {
log.error("删除异常,e:",e);
return false;
}
return true;
}
}
Service 类:
@Service
public class BookService {
@Autowired
private BookInfoMapper bookInfoMapper;
public Integer insertBook(BookInfo bookInfo) {
return bookInfoMapper.insertBook(bookInfo);
}
public PageResult<BookInfo> queryBookByPage(PageRequest pageRequest) {
//获取总记录数
Integer count = bookInfoMapper.count();
//获取当前页的记录
List<BookInfo> bookInfos = bookInfoMapper.queryBookByPage(pageRequest.getPageSize(),pageRequest.getOffset());
//处理状态 将状态码转为状态——可借阅/不可借阅
for(BookInfo bookInfo : bookInfos) {
bookInfo.setStatusCN(BookStatus.getDescByCode(bookInfo.getStatus()).getDesc());
}
return new PageResult<>(bookInfos,count,pageRequest);
}
public BookInfo queryBookById(Integer bookId) {
return bookInfoMapper.queryBookById(bookId);
}
public Integer updateBook(BookInfo bookInfo) {
return bookInfoMapper.updateBook(bookInfo);
}
public void batchDeleteBookByIds(List<Integer> ids) {
bookInfoMapper.batchDeleteBookByIds(ids);
}
}
Mapper 接口
@Mapper
public interface BookInfoMapper {
@Select("select * from book_info where status != 0 order by id limit #{limit},#{offset}")
public List<BookInfo> queryBookByPage(Integer offset,Integer limit); //offset 当前页第一本书的下标 limit 一页最多展示多少本书
@Select("select count(1) from book_info where status != 0")
public Integer count();
@Insert("insert into book_info(book_name,author,count,price,publish,status) values " +
"(#{bookName},#{author},#{count},#{price},#{publish},#{status})")
public Integer insertBook(BookInfo bookInfo);
@Select("select id,book_name,author,count,price,publish,status,create_time,update_time " +
"from book_info where id = #{bookId} and status != 0")
public BookInfo queryBookById(Integer bookId);
public Integer updateBook(BookInfo bookInfo);
public void batchDeleteBookByIds(List<Integer> ids);
}
更新图书和批量删除采用 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.yj.librarymanagement.mapper.BookInfoMapper">
<update id="updateBook">
update book_info
<set>
<if test="bookName != null">
book_name = #{bookName},
</if>
<if test="author != null">
author = #{author},
</if>
<if test="count != null">
count = #{count},
</if>
<if test="price != null">
price = #{price},
</if>
<if test="publish != null">
publish = #{publish},
</if>
<if test="status != null">
status = #{status}
</if>
</set>
where id = #{id}
</update>
<update id="batchDeleteBookByIds">
update book_info set status = 0
where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</update>
</mapper>
🍉前端页面
🍌展示图书
<!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>
</tbody>
</table>
<div class="demo">
<ul id="pageContainer" class="pagination justify-content-center"></ul>
</div>
<script>
getBookListByPage();
function getBookListByPage() {
$.ajax({
url:"BookController/getBookListByPage" + location.search,
type:"get",
success: function (result) {
console.log(result.records);
if(result.records == null) { //判断相等是== 不是=
alert("没有图书");
return;
}
var finnalHtml = "";
for (var book of result.records) {
finnalHtml += '<tr>';
finnalHtml += '<td><input type="checkbox" name="selectBook" value="' + book.id + '" id="selectBook" class="book-select"></td>';
finnalHtml += '<td>' + book.id + '</td>';
finnalHtml += '<td>' + book.bookName + '</td>';
finnalHtml += '<td>' + book.author + '</td>';
finnalHtml += '<td>' + book.count + '</td>';
finnalHtml += '<td>' + book.price + '</td>';
finnalHtml += '<td>' + book.publish + '</td>';
finnalHtml += '<td>' + book.statusCN + '</td>';
finnalHtml += '<td>';
finnalHtml += '<div class="op">';
finnalHtml += '<a href="book_update.html?bookId=' + book.id + '">修改</a>';
finnalHtml += '<a href="javascript:void(0)" onclick="deleteBook(' + book.id + ')">删除</a>';
finnalHtml += '</div></td></tr>';
}
$("tbody").html(finnalHtml);
//翻页信息
$("#pageContainer").jqPaginator({
totalCounts: result.count, //总记录数
pageSize: 10, //每页的个数
visiblePages: 5, //可视页数
currentPage: result.pageRequest.pageNum, //当前页码
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);
if(type == "change") {
location.href = "book_list.html?pageNum="+page;
}
}
});
}
});
}
function deleteBook(id) {
var isDelete = confirm("确认删除?");
if (isDelete) {
//删除图书(逻辑删除)
$.ajax({
url: "/BookController/updateBook",
type: "post",
data: {
id: id,
status: 0
},
success: function () {
//刷新页面
location.href = "book_list.html"
}
});
}
}
function batchDelete() {
var isDelete = confirm("确认批量删除?");
if (isDelete) {
//获取复选框的id
var ids = [];
$("input:checkbox[name='selectBook']:checked").each(function () {
ids.push($(this).val());
});
console.log(ids);
//批量删除
$.ajax({
url: "/BookController/batchDeleteBookByIds?ids=" + ids,
type: "post",
success: function (result) {
if (result) {
alert("批量删除成功");
location.href = "book_list.html"
}
}
});
}
}
</script>
</div>
</body>
</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>
</tbody>
</table>
<div class="demo">
<ul id="pageContainer" class="pagination justify-content-center"></ul>
</div>
<script>
getBookListByPage();
function getBookListByPage() {
$.ajax({
url:"BookController/getBookListByPage" + location.search,
type:"get",
success: function (result) {
console.log(result.records);
if(result.records == null) { //判断相等是== 不是=
alert("没有图书");
return;
}
var finnalHtml = "";
for (var book of result.records) {
finnalHtml += '<tr>';
finnalHtml += '<td><input type="checkbox" name="selectBook" value="' + book.id + '" id="selectBook" class="book-select"></td>';
finnalHtml += '<td>' + book.id + '</td>';
finnalHtml += '<td>' + book.bookName + '</td>';
finnalHtml += '<td>' + book.author + '</td>';
finnalHtml += '<td>' + book.count + '</td>';
finnalHtml += '<td>' + book.price + '</td>';
finnalHtml += '<td>' + book.publish + '</td>';
finnalHtml += '<td>' + book.statusCN + '</td>';
finnalHtml += '<td>';
finnalHtml += '<div class="op">';
finnalHtml += '<a href="book_update.html?bookId=' + book.id + '">修改</a>';
finnalHtml += '<a href="javascript:void(0)" onclick="deleteBook(' + book.id + ')">删除</a>';
finnalHtml += '</div></td></tr>';
}
$("tbody").html(finnalHtml);
//翻页信息
$("#pageContainer").jqPaginator({
totalCounts: result.count, //总记录数
pageSize: 10, //每页的个数
visiblePages: 5, //可视页数
currentPage: result.pageRequest.pageNum, //当前页码
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);
if(type == "change") {
location.href = "book_list.html?pageNum="+page;
}
}
});
}
});
}
function deleteBook(id) {
var isDelete = confirm("确认删除?");
if (isDelete) {
//删除图书(逻辑删除)
$.ajax({
url: "/BookController/updateBook",
type: "post",
data: {
id: id,
status: 0
},
success: function () {
//刷新页面
location.href = "book_list.html"
}
});
}
}
function batchDelete() {
var isDelete = confirm("确认批量删除?");
if (isDelete) {
//获取复选框的id
var ids = [];
$("input:checkbox[name='selectBook']:checked").each(function () {
ids.push($(this).val());
});
console.log(ids);
//批量删除
$.ajax({
url: "/BookController/batchDeleteBookByIds?ids=" + ids,
type: "post",
success: function (result) {
if (result) {
alert("批量删除成功");
location.href = "book_list.html"
}
}
});
}
}
</script>
</div>
</body>
</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/add.css">
</head>
<body>
<div class="container">
<div class="form-inline">
<h2 style="text-align: left; margin-left: 10px;"><svg xmlns="http://www.w3.org/2000/svg" width="40"
fill="#17a2b8" class="bi bi-book-half" viewBox="0 0 16 16">
<path
d="M8.5 2.687c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z" />
</svg>
<span>修改图书</span>
</h2>
</div>
<form id="updateBook">
<input type="hidden" class="form-control" id="bookId" name="id">
<div class="form-group">
<label for="bookName">图书名称:</label>
<input type="text" class="form-control" id="bookName" name="bookName"/>
</div>
<div class="form-group">
<label for="bookAuthor">图书作者</label>
<input type="text" class="form-control" id="bookAuthor" name="author"/>
</div>
<div class="form-group">
<label for="bookStock">图书库存</label>
<input type="text" class="form-control" id="bookStock" name="count"/>
</div>
<div class="form-group">
<label for="bookPrice">图书定价:</label>
<input type="number" class="form-control" id="bookPrice" name="price">
</div>
<div class="form-group">
<label for="bookPublisher">出版社</label>
<input type="text" id="bookPublisher" class="form-control" name="publish"/>
</div>
<div class="form-group">
<label for="bookStatus">图书状态</label>
<select class="custom-select" id="bookStatus" name="status">
<option value="1" selected>可借阅</option>
<option value="2">不可借阅</option>
</select>
</div>
<div class="form-group" style="text-align: right">
<button type="button" class="btn btn-info btn-lg" onclick="update()">确定</button>
<button type="button" class="btn btn-secondary btn-lg" onclick="javascript:history.back()">返回</button>
</div>
</form>
</div>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script>
$.ajax({
url: "/BookController/queryBookById" + location.search,
type: "get",
success: function (book) {
if(book != null) {
$("#bookId").val(book.id);
$("#bookName").val(book.bookName);
$("#bookAuthor").val(book.author);
$("#bookStock").val(book.count);
$("#bookPrice").val(book.price);
$("#bookPublisher").val(book.publish);
$("#bookStatus").val(book.status);
}
}
})
function update() {
$.ajax({
url:"/BookController/updateBook",
type:"post",
data:$("#updateBook").serialize(),
success: function (result) {
if(result == "") {
//更新成功,跳转到展示页面
location.href = "book_list.html";
} else {
alert("修改失败:"+result);
}
},
error: function (error) {
console.log(error);
}
});
}
</script>
</body>
</html>