【Spring+MyBatis】_图书管理系统(上篇)-CSDN博客文章浏览阅读654次,点赞4次,收藏7次。(1)当前页的内容records(类型为List);参数:userName=admin&&password=admin。1、前端发送给后端:(封装为对象:PageRequest)创建用户表user_info和图书表book_info;2、后端发送给前端:(封装为对象:PageResult)以上两句都表示从num2+1行开始返回num1行数据;输入账号admin和密码admin后,即可成功登录;响应:成功返回true,失败返回false。请求:/User/login。https://blog.csdn.net/m0_63299495/article/details/145668975
上篇未完全完成,本篇继续完善功能。
目录
功能3:添加图书
4.1 约定前后端交互接口
4.2 后端接口
4.3 前端页面
4.4 单元测试
功能4:修改图书
5.1 约定前后端交互接口
5.2 后端接口
5.3 前端页面
5.4 单元测试
功能3:添加图书
4.1 约定前后端交互接口
接口定义:/Book/addBook;
参数:BookInfo;
返回值:告诉前端是否添加成功且若添加失败则返回错误信息,String类型:空表示添加成功,不为空则添加失败;
4.2 后端接口
在BookController类中增加相应方法:
@RequestMapping("/addBook")
public String addBook(BookInfo bookInfo){
log.info("接收到添加图书请求:bookInfo:{}",bookInfo);
// 参数校验
if(!StringUtils.hasLength(bookInfo.getBookName())
||!StringUtils.hasLength(bookInfo.getAuthor())
||bookInfo.getCount()<0
||bookInfo.getPrice()==null
||!StringUtils.hasLength(bookInfo.getPublish())) {
return "参数校验失败,请检查入参";
}
Integer result = bookService.addBook(bookInfo);
if(result<=0){
log.error("添加图书出错:bookInfo:{}",bookInfo);
return "添加图书出错,请联系管理员";
}
return "";
}
在BookService类中增加相应方法:
public Integer addBook(BookInfo bookInfo){
Integer result=0;
try{
result =bookInfoMapper.insertBook(bookInfo);
}catch (Exception e){
log.error("添加图书出错:e:{}",e);
}
return result;
}
在BookInfoMapper接口中增加相关方法声明:
@Insert("insert into book_info(book_name,author,count,price,publish,status)" +
"values (#{bookName},#{author},#{count},#{price},#{publish},#{status})")
Integer insertBook(BookInfo bookInfo);
4.3 前端页面
<!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="addBook">
<div class="form-group">
<label for="bookName">图书名称:</label>
<input type="text" class="form-control" placeholder="请输入图书名称" id="bookName" name="bookName">
</div>
<div class="form-group">
<label for="bookAuthor">图书作者</label>
<input type="text" class="form-control" placeholder="请输入图书作者" id="bookAuthor" name="author" />
</div>
<div class="form-group">
<label for="bookStock">图书库存</label>
<input type="text" class="form-control" placeholder="请输入图书库存" id="bookStock" name="count"/>
</div>
<div class="form-group">
<label for="bookPrice">图书定价:</label>
<input type="number" class="form-control" placeholder="请输入价格" id="bookPrice" name="price">
</div>
<div class="form-group">
<label for="bookPublisher">出版社</label>
<input type="text" id="bookPublisher" class="form-control" placeholder="请输入图书出版社" 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="add()">确定</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>
function add() {
$.ajax({
type:"post",
url:"/Book/addBook",
data:$("#addBook").serialize(), // 提交整个form表单
success:function (result){
if(result==""){
// 图书添加成功
location.href="book_list.html";
}else{
// 图书添加失败
alert("result");
}
}
});
}
</script>
</body>
</html>
注:可以通过$("#form表单id").serialize()提交整个form表单,包括form标签包裹的input、select、textarea等输入信息也会提交,其中每个标签按name属性命名,多个输入框拼接成查询字符串;
4.4 单元测试
1、测后端接口:
可在服务器端查看日志:
可在数据库中查看新增图书信息:
2、测试前端页面:
点击确定后弹窗添加成功,并跳转到book_list.html:
可在服务器处查看日志:
通过数据库查看新增图书信息:
功能4:修改图书
5.1 约定前后端交互接口
明确需求:
(1)点击修改按钮时,希望在修改图书页面显示当前图书信息;
(2)点击确定按钮时,希望保存修改的结果;
故而需要两个接口:
(1)接口1:根据id查询图书信息
① 路由映射:/Book/queryBookInfoById;
② 参数:bookId;
③ 返回结果:对应图书信息BookInfo;
(2)接口2:修改图书
① 路由映射:/Book/UpdateBook;
② 参数:BookInfo;
③ 返回结果:字符串,为空时表示修改成功,不为空表示修改失败,且返回错误信息;
5.2 后端接口
在BookController类中增加相关方法:
@RequestMapping("/queryBookInfoById")
public BookInfo queryBookInfoById(Integer bookId){
log.info("根据id查询图书:bookId{}",bookId);
try{
BookInfo bookInfo = bookService.queryBookInfoById(bookId);
return bookInfo;
}catch(Exception e){
log.error("查询图书失败:e{}",e);
}
return null;
}
@RequestMapping("/updateBook")
public String updateBook(BookInfo bookInfo){
log.info("接收到更新图书请求:booInfo{}",bookInfo);
Integer result= bookService.updateBook(bookInfo);
if(result ==0){
log.error("更新图书失败,请联系管理员");
return "更新图书失败,请联系管理员";
}
return "";
}
在BookService类中增加相关方法:
public BookInfo queryBookInfoById(Integer id){
return bookInfoMapper.selectBookById(id);
}
public Integer updateBook(BookInfo bookInfo){
Integer result=0;
try{
result = bookInfoMapper.updateBook(bookInfo);
}catch (Exception e){
log.error("更新图书失败:e{}",e);
}
return result;
}
在BookInfoMapper接口中增加相关方法声明:
@Select("select* from book_info where id=${id}")
BookInfo selectBookById(Integer id);
Integer updateBook(BookInfo bookInfo);
其中,为updateBook方法配置对应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.example.bookmanagementsystem.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='publish !=null'>
publish=#{publish},
</if>
<if test='price != null'>
price=#{price},
</if>
<if test='status !=null'>
status=#{status}
</if>
</set>
where id =#{id};
</update>
</mapper>
注:对于update操作,由于后续删除图书信息也是逻辑删除,即通过update实现。对数据库的update操作使用较多,故采取xml方式使用MyBatis,需要在application.yml中增加mapper的相关配置:
mybatis:
mapper-locations: classpath:mapper/**Mapper.xml
5.3 前端页面
<!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({
type: "get",
url: "/Book/queryBookInfoById"+location.search,
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);
}else{
alert("图书不存在");
}
}
});
function update() {
$.ajax({
type: "post",
url: "/Book/updateBook",
data: $("#updateBook").serialize(),
success: function (result) {
if(result == ""){
location.href="book_list.html";
}else{
alert(result);
}
}
});
}
</script>
</body>
</html>
注:ajax使用$("#form表单id").serialize()提了整个form表单,包括书名、作者、库存、出版社、价格、状态等信息都可以获取到,但update操作还需要图书id,具体实现方法为:
在form表单下增加一个隐藏的input标签,修改图书页面加载时也同样将该id加载到页面中,只是不可见,再按照原本的获取整个form表单内容即可:
<input type="hidden" class="form-control" id="bookId" name="id">
否则会由于无法获取id而导致图书信息更新失败。
5.4 单元测试
1、测试后端接口1:
(1)测试参数1:
可在服务器端查看日志:
(2)测试参数2:
查看服务器日志:
测试后端接口2:
服务器处可查看日志:
通过数据库查看图书更新信息:
2、测试前端页面:
将id=12的图书的图书名更新为图书x2:
可在服务器端查看日志:
可在数据库中查看图书数据更新信息: