当前位置: 首页 > news >正文

【Spring+MyBatis】_图书管理系统(中篇)

【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:

可在服务器端查看日志:

可在数据库中查看图书数据更新信息:

相关文章:

  • 禁止WPS强制打开PDF文件
  • linux环境-nginx通过nginx_upstream_check_module模块,配置服务自动检测-日志自动分割
  • 【Spring详解二】容器的基本实现
  • 制造运营管理(MOM)与仓库管理系统(WMS)何以相辅相成对企业的生产管理进行提升
  • ​实在智能与宇树科技、云深科技一同获评浙江省“人工智能服务商”、 “数智优品”​等荣誉
  • uniapp 连接mqtt
  • JAXB复杂对象反序列化
  • 计算机视觉:神经网络实战之手势识别(附代码)
  • 前端插件使用xlsx-populate,花样配置excel内容,根据坐添加标替换excel内容,修改颜色,合并单元格...。
  • 个人shell脚本分享
  • spring如何解决循环依赖的问题
  • 讯方·智汇云校华为官方授权培训机构
  • 突破反爬困境:从服务端渲染到客户端SPA,爬虫环境的演变与新挑战(一)
  • Linux(Centos 7.6)命令详解:cat
  • LeetCode47
  • 【ISO 14229-1:2023 UDS诊断(会话控制0x10服务)测试用例CAPL代码全解析⑩】
  • AI服务器散热黑科技:让芯片“冷静”提速
  • linux网络编程(1.5w字+内部程序理解网络)
  • 7-Zip Final绿色版:高效压缩解压缩工具
  • 机器学些|实战?
  • 柳向春:关于美国国会图书馆所藏《全芳备祖》的一些故事
  • “五一”从昆明机场出境1.4万人次,较去年增长7.7%
  • 特朗普:不谋求第三个总统任期,中意万斯鲁比奥“接棒”
  • 我驻旧金山总领事馆:黄石公园车祸中受伤同胞伤情稳定
  • 全国铁路迎来返程客流高峰,预计今日发送2040万人次
  • 青海大学常务副校长(正厅级)任延明已任省卫健委党组书记