【JavaEE进阶】 图书管理系统开发日记——叁

🌴前言

在前面我们实现了用户登录的接口。现在我们来实现图书列表展示页面。

🎋数据准备

创建图书表,并初始化数据

-- 图书表
DROP TABLE IF EXISTS book_info;
CREATE TABLE `book_info` (
	`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
	`book_name` VARCHAR ( 127 ) NOT NULL,
	`author` VARCHAR ( 127 ) NOT NULL,
	`count` INT ( 11 ) NOT NULL,
	`price` DECIMAL (7,2 ) NOT NULL,
	`publish` VARCHAR ( 256 ) NOT NULL,
	`status` TINYINT ( 4 ) DEFAULT 1 COMMENT '0-⽆效, 1-正常, 2-不允许借阅',
	`create_time` DATETIME DEFAULT now(),
	`update_time` DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;

-- 初始化图书数据
INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('活
着', '余华', 29, 22.00, '北京⽂艺出版社');
INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('平凡的
世界', '路遥', 5, 98.56, '北京⼗⽉⽂艺出版社');
INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('三
体', '刘慈欣', 9, 102.67, '重庆出版社');
INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('⾦字塔
原理', '⻨肯锡', 16, 178.00, '⺠主与建设出版社');

MyBatis和MySQL驱动依赖已经在用户登录时已经配置过了,直接用即可

🎄需求分析

首先我们先来看一下页面展示的效果
在这里插入图片描述

在分页时,第一页就展示10条数据,第二页我们也只显示10条数据

要想实现这个功能,从数据库中进⾏分⻚查询,我们要使⽤ LIMIT 关键字,格式为:limit 开始索引每⻚显⽰的条数(开始索引从0开始)

通过观察与思考,我们可以发现

开始索引的计算公式:开始索引=(当前⻚码-1)*每⻚显⽰条数

基于前端⻚⾯的分析,得出以下结论:

  1. 前端在发起查询请求时,需要向服务端传递的参数
  • currentPage当前⻚码 //默认值为1
  • pageSize每⻚显⽰条数 //默认值为10
  1. 后端响应时,需要响应给前端的数据
  • records所查询到的数据列表(存储到List集合中)
  • total总记录数(⽤于告诉前端显⽰多少⻚,显⽰⻚数为: (total + pageSize-1)/pageSize

翻⻚请求和响应部分,我们通常封装在两个对象中,并放在model文件路径下

🚩翻⻚请求对象类

除了需要currentPage当前⻚码和pageSize每⻚显⽰条数

我们还需要根据currentPage和pageSize,计算出来开始索引

代码如下:

@Data
public class PageRequest {
    private int currentPage = 1; // 当前⻚
    private int pageSize = 10; // 每⻚中的记录数
    private int offset;
    public int getOffset() {

        return (currentPage-1) * pageSize;
    }
}

🚩翻页响应对象类

该类博主设计的是返回一个对象。

该对象应该含有以下属性。

  • records所查询到的数据列表
  • total总记录数
  • PageRequest属性

添加PageRequest属性是为了避免后续还需要其他请求处的信息

同时给出相应的构造方法。

代码实现如下:

@Data
public class PageResult<T> {
    private int total;//所有记录数

    private List<T> records; // 当前⻚数据

    private PageRequest pageRequest;
    public PageResult(Integer total, PageRequest pageRequest, List<T> records)
    {
        this.total = total;
        this.pageRequest = pageRequest;
        this.records = records;
    }
}

🍃约定前后端交互接⼝

基于以上分析,我们来约定前后端交互接⼝

[请求]
/book/getListByPage?currentPage=1&pageSize=10
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
[参数]
[响应]
Content-Type: application/json
{
“total”: 25,
“records”: [{
“id”: 25,
“bookName”: “图书21”,
“author”: “作者2”,
“count”: 29,
“price”: 22.00,
“publish”: “出版社1”,
“status”: 1,
“statusCN”: “可借阅”
}, {

} ]
}

我们约定,浏览器给服务器发送⼀个 /book/getListByPage 这样的HTTP请求,通过currentPage参数告诉服务器,当前请求为第⼏⻚的数据,后端根据请求参数,返回对应⻚的数据

第一页可以不传递参数,默认为1

🌲后端服务器代码实现

依旧利用分层思想进行代码实现

🚩控制层

在该层我们只需要调用业务层的代码返回就好

@Slf4j
@RequestMapping("/book")
@RestController
public class BookController {
    @Autowired
    private BookService bookService;
    @RequestMapping("/getListByPage")
    public PageResult<BookInfo> getListByPage(PageRequest pageRequest) {
        log.info("获取图书列表, pageRequest:{}", pageRequest);
        PageResult<BookInfo> pageResults = bookService.getBookListByPage(pageRequest);
        return pageResults;
    }

}

🚩业务层

在书写业务层代码时我们需要考虑以下几点

  1. 翻⻚信息需要返回数据的总数和列表信息,需要查两次SQL

  2. 图书状态:图书状态和数据库存储的status有⼀定的对应关系

如果后续状态码有变动,我们需要修改项⽬中所有涉及的代码,这种情况,我们通常采⽤枚举类来处理映射关系

枚举类代码如下:

public enum BookStatus {
    DELETED(0,"⽆效"),
    NORMAL(1,"可借阅"),
    FORBIDDEN(2,"不可借阅");
    private Integer code;
    private String name;
    BookStatus(int code, String name) {
        this.code = code;
        this.name = name;
    }
    public static BookStatus getNameByCode(Integer code){
        switch (code){
            case 0: return DELETED;
            case 1: return NORMAL;
            case 2: return FORBIDDEN;
        }
        return null;
    }
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

此时我们只需要调用相应的数据层代码,查询相应的数据,并对查询到的数据进行状态码的更新。

最后构造新的响应对象,返回即可

代码实现如下:

@Service
public class BookService {
    @Autowired
    private BookInfoMapper bookInfoMapper;
    public PageResult<BookInfo> getBookListByPage(PageRequest pageRequest) {
        Integer count = bookInfoMapper.count();
        List<BookInfo> books = bookInfoMapper.queryBookListByPage(pageRequest);
        for (BookInfo book:books){
            book.setStatusCN(BookStatus.getNameByCode(book.getStatus()).getName());
        }
        return new PageResult<>(count,pageRequest, books);
    }

}

🚩数据层

数据层我们只需要进行两个查询即可

一个是返回最大数据长度,一个是查询当前页码的所有数据。

代码实现如下:

@Mapper
public interface BookInfoMapper {
    @Select("select count(1) from book_info where status<>0")
    Integer count();

    @Select("select * from book_info where status !=0 order by id desc limit #{offset}, #{pageSize}")
    List<BookInfo> queryBookListByPage(PageRequest pageRequest);
}

🚩测试后端代码

到这里后端代码就写完了,我们可以进行简单的测试,只需要在浏览器中输入

  • http://127.0.0.1:8080/book/getListByPage返回1-10条记录(按id降序)
  • http://127.0.0.1:8080/book/getListByPage?currentPage=2返回11-20条记录

此时说明后端代码已经书写成功

🌳客户端代码的完善

这里博主直接给出改变的相应代码。

实现如下:

getBookList();
function getBookList() {
    $.ajax({
        type: "get",
        url: "/book/getListByPage"+location.search,
        success: function (result) {
            console.log(result);
            if (result != null) {
                var finalHtml = "";
                for (var book of result.records) {
                    finalHtml += '<tr>';
                    finalHtml += '<td><input type="checkbox" name="selectBook" value="'+book.id+'" id="selectBook" class="book-select"></td>'
                    finalHtml += '<td>' + book.id + '</td>';
                    finalHtml += '<td>' + book.bookName + '</td>';
                    finalHtml += '<td>' + book.author + '</td>';
                    finalHtml += '<td>' + book.count + '</td>';
                    finalHtml += '<td>' + book.price + '</td>';
                    finalHtml += '<td>' + book.publish + '</td>';
                    finalHtml += '<td>' + book.statusCN + '</td>';
                    finalHtml += '<td><div class="op">';
                    finalHtml += '<a href="book_update.html?bookId=' + book.id + '">修改</a>'
                    finalHtml += '<a href="javascript:void(0)" onclick="deleteBoook(' + book.id + ')">删除</a>'
                    finalHtml += '</div></td>';
                    finalHtml += "</tr>";
                }
                $("tbody").html(finalHtml);

                //翻页信息
                $("#pageContainer").jqPaginator({
                    totalCounts: result.total, //总记录数
                    pageSize: 10,    //每页的个数
                    visiblePages: 5, //可视页数
                    currentPage: result.pageRequest.currentPage,  //当前页码
                    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 != 'init') {
                            location.href = "book_list.html?currentPage=" + page;
                        }
                    }
                });
            }
        }
    });
}

在这里插入图片描述

⭕总结

关于《【JavaEE进阶】 图书管理系统开发日记——叁》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/366398.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

通用缓存SpringCache

概述 在项目中&#xff0c;我们通常会把高频的查询进行缓存。如资讯网站首页的文章列表、电商网站首页的商品列表、微博等社交媒体热搜的文章等等&#xff0c;当大量的用户发起查询时&#xff0c;借助缓存提高查询效率&#xff0c;同时减轻数据库压力。 目前的缓存框架有很多:…

银行数据仓库体系实践(16)--数据应用之财务分析

总账系统 在所有公司中&#xff0c;财务分析的基础都是核算&#xff0c;那在银行的系统体系中&#xff0c;核算功能在业务发生时由业务系统如核心、贷款、理财中实现登记&#xff0c;各业务系统会在每天切日后统计当天各机构的核算科目的发生额与余额&#xff0c;并统一送到总账…

基于SSM的个性化旅游攻略定制系统设计与实现(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的个性化旅游攻略定制系统设计与实现&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xf…

Google Play上架:因行为透明度被拒审或下架的政策自查(基于区块链的内容)

近期很多朋友的项目出现因行为透明度问题被谷歌拒审或者已经上架的包被下架甚至封号,今天解释一下为什么会被封号下架,根据是什么? 目录 政策发布时间与截止时间政策内容政策背景政策解析和问题讲解政策发布时间与截止时间 基于区块链的内容相关政策,于2023-07-12 公布,…

大数据 - Hadoop系列《三》- MapReduce(分布式计算引擎)概述

上一篇文章&#xff1a; 大数据 - Hadoop系列《三》- HDFS&#xff08;分布式文件系统&#xff09;概述-CSDN博客 目录 12.1 针对MapReduce的设计构思 1. 如何对付大数据处理场景 2. 构建抽象编程模型 3. 统一架构、隐藏底层细节 12.2 分布式计算概念 12.3 MapReduce定义…

最近nvm安装报错的原因找到了——npm原淘宝镜像正式到期!

前言 &#x1f4eb; 大家好&#xff0c;我是南木元元&#xff0c;热爱技术和分享&#xff0c;欢迎大家交流&#xff0c;一起学习进步&#xff01; &#x1f345; 个人主页&#xff1a;南木元元 目录 背景 错误原因 问题排查 淘宝镜像 证书到期 问题解决 结语 背景 我们…

华为配置接口二三层切换示例

配置接口二三层切换示例 组网图形 图1 配置非自协商模式下速率和双工模式组网图 二三层切换简介配置注意事项组网需求配置思路操作步骤配置文件 二三层切换简介 基于接口板的硬件构造&#xff0c;某些形态设备上接口只能作为二层以太网接口&#xff0c;某些形态设备上接口…

炒黄金 vs 炒股:探寻投资路线的差异和各自的优势

在当前不景气的股市&#xff0c;人们越来越关注分散投资的方式&#xff0c;以期降低风险并稳定资产。炒黄金成为了一个备受关注的投资选择&#xff0c;与传统炒股相比&#xff0c;它到底有什么区别呢&#xff1f;本文将从多个维度深入分析这两种投资方式的差异以及各自的优势。…

红萝卜,咪咪甜,看斗看斗要过年

老了&#xff0c;老了&#xff0c;但少儿岁月唱过的川南儿歌&#xff0c;至今还能琅琅上口&#xff1a;“红萝卜&#xff0c;咪咪甜&#xff0c;看斗看斗要过年。” 2024年春节&#xff0c;眨眼工夫就要到来了。随着春运来临&#xff0c;人员流动增多&#xff0c; 呼吸道疾病的…

BetaFlight Current Calibration Guide

BetaFlight Current Calibration Guide Download link: BetaFlight_Current_Calibration_v2.xlsx This is a guide for how to use this xlsx file. If you want to know more about this file, please check BetaFlight开源代码之电流校准. Step 1 Filling Pre-Set-Scale, a…

Java/Python/Go不同开发语言基础数据结构和相关操作总结-Map篇

Java/Python/Go不同开发语言基础数据结构和相关操作总结 1. Java1.1 基础操作1.1.1 数据结构和定义方式1.1.2 增加1.1.3 修改1.1.4 查询1.1.5 删除1.1.6 获取总长度1.1.7 按key排序1.1.8 按value排序1.1.9 遍历 1.2 常用其他方法1.2.1 几种数据结构的对比 2. Go2.1基础操作2.1.…

ChatGPT实战100例 - (12) 结构化提示词 LangGPT 实战

文章目录 ChatGPT实战100例 - (12) 结构化提示词 LangGPT 实战一、LangGPT是什么?二、远古诗人 vs 现代诗人三、LangGPT Role模板实战 - 甩锅王Role模板特征提取四、 用AI实现提示词结构化ChatGPT实战100例 - (12) 结构化提示词 LangGPT 实战 一、LangGPT是什么? 随着大模型…

拓扑排序算法

操作对象&#xff1a;AOV网的点和边 有向无环图&#xff1a;有向图且不会形成回路 AOV网&#xff1a;在一个表示工程的有向图中&#xff0c;用顶点表示活动&#xff0c;用弧表示活动之间的优先关系&#xff0c;这样的有向图为顶点表示活动的网&#xff0c;称为AOV网 拓扑排序…

Python程序设计 函数基础

简单函数 函数&#xff1a;就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。 函数的使用包含两个步骤&#xff1a; 定义函数 —— 封装 独立的功能 调用函数 —— 享受 封装 的成果 函数的作用&#xff0c;在开发程序时&#xff0c;使用…

vue3.0中从proxy中取值

使用vue3.0时&#xff0c;因为底层是使用proxy进行代理的所以当我们打印一些值的时候是proxy代理之后的&#xff0c;是Proxy 对象&#xff0c;Proxy对象里边的[[Target]]才是真实的对象。也是我们需要的 第一种获取target值的方式&#xff1a; import { toRaw } from vue; le…

书生浦语2-对话-20B大模型部署实践

简介 书生浦语2.0是一个大语言模型&#xff0c;是商汤科技与上海 AI 实验室联合香港中文大学和复旦大学发布的新一代大语言模型。‘ 具体特性 有效支持20万字超长上下文&#xff1a;模型在 20 万字长输入中几乎完美地实现长文“大海捞针”&#xff0c;而且在 LongBench 和 L…

Linux系统编程之信号(下)

3、信号的保存 在聊这个之前首先要了解一些术语 实际执行信号的处理动作称为信号递达(Delivery) 信号从产生到递达之间的状态,称为信号未决(Pending)。 进程可以选择阻塞 (Block )某个信号。 被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作…

Windows10 安装 OpenSSH 配置 SFTP服务器

1、下载 https://github.com/PowerShell/Win32-OpenSSH/releases 2、默认安装 3、创建用户 4、修改配置文件 C:\ProgramData\ssh\sshd_config# 最后一行后面加入 ForceCommand internal-sftp# 设置用户登录后默认目录 Match User sftpuser ChrootDirectory C:\SFTP# Disable…

spring中生成jwtToken字符串以及解析手写通用工具类

当前使用JWT&#xff0c;肯定得提前准备jwt相关的导入依赖。 <!-- 关于jwt 生成令牌--> <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jjwt.version}</version> </dependency…

20240202在Ubuntu20.04.6下配置环境变量之后让nvcc --version显示正常

20240202在Ubuntu20.04.6下配置环境变量之后让nvcc --version显示正常 2024/2/2 20:19 在Ubuntu20.04.6下编译whiper.cpp的显卡模式的时候&#xff0c;报告nvcc异常了&#xff01; 百度&#xff1a;nvcc -v nvidia-cuda-toolkit rootrootrootroot-X99-Turbo:~/whisper.cpp$ WH…