• SpringBoot校园二手书管理系统


      各位好呀,本次介绍项目是基于SpringBoot开发的一个校园二手书管理系统,有部分功能由本人完成(如:前端样式、精准查询、模糊查询、导出Execel),本篇文章,着重聚焦技术要点,提前告知修改项目需要的前置知识!

    使用技术

       由Maven构建的项目,技术栈是由SpringBoot+Mybatis+Thymeleaf组成,其中项目引入了一些中间件,如PageHelper(分页插件)、Lombok(数据层配置)、easyexcel(导出execel形式数据)

    • Lombok是什么?

       使用Lombok提供的注解,可以快速生成类的getter、setter和构造方法等等,当变量发生改变时,也不再需要修改对这些方法进行修改,Lombok会搞定这件事。

    比如以下代码的 @AllArgsConstructor注解就是生成类的全参构造方法, @Data注解作用是给类的成员变量添加getter和setter方法

    1. @Data
    2. @NoArgsConstructor
    3. @AllArgsConstructor
    4. public class Book {
    5.     private int id;
    6.     private String name;
    7.     private String publisher;
    8.     private String code;
    9.     private String author;
    10.     private double price;
    11.     private int newDeg;
    12.     private int uId;
    13.     private String uname;
    14.     private int state;
    15.     private String sname;
    16.     private Date publishTime;
    17. }

    系统功能

    1.用户登录(含验证码)

    2.二手书管理

    3.订单管理

    4.撤销订单管理
     

    5.院系管理

    6.专业管理

    7.用户信息管理

    功能简读

    • 精准查询和模糊查询的区别?

    拿订单查询功能为例,精准查询将会在数据库里匹配用户输入的所有字符,在sql语句里相当于where column = ? 模糊查询使用的是mysql的关键字like来对所有搜索条件进行模糊查询,但是下拉列表选中条件还是以精准匹配进行查询

    下面找出对应的OrderMapper.xml文件

    1. <!-- 订单精准查询-->
    2.     <select id="selectAccuracyOrder" resultType="order">
    3.         select o.id as id,o.id_buy as id_buy,u.nickname as nickname,u.tel as tel,u.address as address,
    4.         o.book_id as book_id,b.name as name,b.publisher as publisher,b.code as code,b.author as author,b.price as
    5.         price,b.newDeg as newDeg,b.uId as uId,
    6.         o.time as time,o.state as state,s.name as sname
    7.         from orders o inner join
    8.         user u on o.id_buy = u.id inner join
    9.         state s on o.state = s.id inner join
    10.         book b on o.book_id = b.id
    11.         <where>
    12.             <if test="oid!=null">
    13.                 and o.id = #{oid}
    14.             </if>
    15.             <if test="username!=null">
    16.                 and u.nickname = #{username}
    17.             </if>
    18.             <if test="status!=null">
    19.                 and o.state = #{status}
    20.             </if>
    21.         </where>
    22.     </select>
    1.  <!-- 订单模糊查询-->
    2.     <select id="selectLikeOrder" resultType="order">
    3.         select o.id as id,o.id_buy as id_buy,u.nickname as nickname,u.tel as tel,u.address as address,
    4.         o.book_id as book_id,b.name as name,b.publisher as publisher,b.code as code,b.author as author,b.price as
    5.         price,b.newDeg as newDeg,b.uId as uId,
    6.         o.time as time,o.state as state,s.name as sname
    7.         from orders o inner join
    8.         user u on o.id_buy = u.id inner join
    9.         state s on o.state = s.id inner join
    10.         book b on o.book_id = b.id
    11.         <where>
    12.             <if test="oid!=null">
    13.                 and o.id = #{oid}
    14.             </if>
    15.             <if test="username!=null">
    16.                 and u.nickname like concat('%',#{username},'%')
    17.             </if>
    18.             <if test="status!=null">
    19.                 and o.state = #{status}
    20.             </if>
    21.         </where>
    22.     </select>
    • 以Execel文件形式导出数据如何实现?

    EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目,由阿里巴巴提供,学习链接:EasyEcel官网
    注意:在这个项目中,所有的导出Excel功能默认是导出当前检索的所有页数据

    第一步:导入easyexcel坐标

    1. <dependency>
    2.     <groupId>com.alibaba</groupId>
    3.     <artifactId>easyexcel</artifactId>
    4.     <version>3.0.5</version>
    5. </dependency>

    第二步:设置单元格的列名以及样式(以导出用户数据为例)

    1. @Data
    2. @ToString
    3. @NoArgsConstructor
    4. @AllArgsConstructor
    5. @ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER) //水平居中
    6. public class UserExcelData {
    7.     @ExcelProperty("编号")
    8.     private Integer id;
    9.     @ExcelProperty("用户名")
    10.     private String username;
    11.     @ExcelProperty("姓名")
    12.     private String name;
    13.     @ExcelProperty("院系")
    14.     @ColumnWidth(20)
    15.     private String depart;
    16.     @ExcelProperty("专业")
    17.     @ColumnWidth(20)
    18.     private String major;
    19.     @ExcelProperty("年级")
    20.     @ColumnWidth(10)
    21.     private Integer grade;
    22. }

    其中@ExcelProperty注解代表导出该成员变量的值对应列名,@ContentStyle是设置表格样式
    第三步:定义js导出事件并编写后端接口

    前端核心代码:

    1. <!-- form搜索输入框 -->
    2. <form th:action="@{/user/query}" method="post" id="queryform">
    3.     <div class="content_right_content">
    4.   <span>
    5.     <input name="btnType" id="btnType" value="1" th:value="${btnType}" hidden>
    6.     <input name="pageNum" id="pageNum" value="1" hidden>
    7.     用户名:<input type="text" placeholder="请输入用户名" name="username" th:value="${username}">&nbsp;&nbsp;
    8.     姓名:<input type="text" placeholder="请输入姓名" name="name" th:value="${name}">&nbsp;&nbsp;&nbsp;
    9.     学院:<select name="depart_id">
    10.           <option value="0">全部</option>
    11.           <option th:value="${depart.id}" th:each="depart:${departList}"
    12.                                         th:selected="${select_depid} == ${depart.id}"
    13.                                         th:text="${depart.name}"></option>
    14.         </select>&nbsp;&nbsp;
    15.     专业:<select name="major_id">
    16.           <option value="0">全部</option>
    17.           <option th:value="${major.id}" th:each="major:${majorList}"
    18.                                         th:selected="${select_majorid} == ${major.id}"
    19.                                         th:text="${major.name}"></option>
    20.         </select>&nbsp;&nbsp;
    21.             <button class="btn btn-success btn-sm" onclick="queryTypeSumbit(1)">精确查询</button>
    22.             <button class="btn btn-success btn-sm" onclick="queryTypeSumbit(2)">模糊查询</button>
    23.   </span>
    24.     </div>
    25. </form>
    26. <class="btn btn-primary" style="color: white;position: absolute;left: 0" value="1" onclick="exportSumbit()">导出全部数据</a>

    前端js处理事件

    1. function exportSumbit() {
    2.     var myform = document.getElementById("queryform");
    3.     myform.setAttribute("action""/user/export");
    4.     myform.submit();
    5. }

    主要工作:获取表单DOM,自动提交到后端控制器(Controller),控制器接受到请求就会根据搜索条件查询全部的数据,然后将这些数据以excel文件形式返回给前端

    后端控制器:

    1.  /*
    2.         导出Execel
    3.      */
    4.     @RequestMapping("/user/export")
    5.     @ResponseBody
    6.     public String exportExcel(@RequestParam(value = "username", required = falseString username,
    7.                               @RequestParam(value = "name", required = falseString name,
    8.                               @RequestParam(value = "depart_id", required = false) Integer depart_id,
    9.                               @RequestParam(value = "major_id", required = false) Integer major_id,
    10.                               @RequestParam(value = "btnType", defaultValue = "1") Integer btnType,
    11.                               @RequestParam(defaultValue = "1") Integer pageNum,
    12.                               @RequestParam(defaultValue = "12") Integer pageSize,
    13.                               HttpServletResponse response) throws IOException {
    14.         List<User> users = null;
    15.         if (btnType == 1) {
    16.             //精准查询
    17.             users = userService.accuracyQueryUser(StringUtils.isEmpty(username) ? null : username, StringUtils.isEmpty(name) ? null : name,
    18.                     depart_id == null || depart_id == 0 ? null : depart_id, major_id == null || major_id == 0 ? null : major_id);
    19.         } else if (btnType == 2) {
    20.             //模糊查询(对用户名和姓名模糊查询)
    21.             users = userService.likeQueryUser(StringUtils.isEmpty(username) ? null : username, StringUtils.isEmpty(name) ? null : name,
    22.                     depart_id == null || depart_id == 0 ? null : depart_id, major_id == null || major_id == 0 ? null : major_id);
    23.         }
    24.         System.out.println("users size : " + users.size());
    25.         List<UserExcelData> list = new ArrayList<>();
    26.         for (User user : users) {
    27.             list.add(new UserExcelData(user.getId(), user.getNickname(), user.getName(), user.getDepartName(), user.getMajorName(), user.getGrade()));
    28.         }
    29.         //设置响应头信息
    30.         response.setContentType("application/vnd.ms-excel");
    31.         response.setCharacterEncoding("utf-8");
    32.         String fileName = URLEncoder.encode("用户信息""Utf-8");
    33.         response.setHeader("Content-Disposition""attachment;filename*=UTF-8''" + fileName + ".xlsx");
    34.         //获得输出流
    35.         ServletOutputStream outputStream = response.getOutputStream();
    36.         //工作簿对象
    37.         ExcelWriterBuilder writerBuilder = EasyExcel.write(outputStream, UserExcelData.class);
    38.         //工作表对象
    39.         ExcelWriterSheetBuilder sheet = writerBuilder.sheet();
    40.         //导出Excel
    41.         sheet.doWrite(list);
    42.         outputStream.close();
    43.         return "";
    44.     }

    效果展示:

    小结:使用EasyExcel进行数据的导出不依赖于前端控件,还是在于后端改变响应头信息将真正数据反馈到前端

    源码获取方式

    wx《源码小客栈》,回复"校园"或"二手书"获取完整说明文章,

    源码从菜单栏 "源码" -> "Java"中获取

  • 相关阅读:
    C++的哈希 && 哈希表 && 哈希桶
    【中间件】redis持久化方式
    逼格提升:内存泄漏检测工具
    基于JAVA双峰县在线房屋租售网站计算机毕业设计源码+数据库+lw文档+系统+部署
    Vue2源码学习笔记 - 15.响应式原理—nextTick
    软件测试工程师怎么样面试上好的公司?
    零基础Linux_26(多线程)线程池代码+单例模式+线程安全
    目标检测新SOTA:YOLOv9 问世,新架构让传统卷积重焕生机
    C++基础——输入输出和缺省参数讲解
    Vue+ElementUI项目打包部署到Ubuntu服务器中
  • 原文地址:https://blog.csdn.net/calm_programmer/article/details/126690200