【Spring+MyBatis】_图书管理系统(中篇)
- 开源代码
- 2025-08-30 13:03:03

【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。 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:// .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:// .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:
可在服务器端查看日志:
可在数据库中查看图书数据更新信息:
【Spring+MyBatis】_图书管理系统(中篇)由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【Spring+MyBatis】_图书管理系统(中篇)”