9.spring-图书管理系统

文章目录

  • 1.开发项目流程
    • 1.1开发开发
    • 1.2数据库的设计
  • 2.MySQL数据库相关代码
  • 3.构造图书结构
    • 3.1用户登录
    • 3.2图书列表
    • 3.3图书添加
    • 3.4图书删除
      • 3.4.1批量删除
    • 3.5图书查询(翻页)
  • 4.页面展示
    • 4.1登录页面
    • 4.2列表页面
    • 4.3增加图书页面
    • 4.4修改图书信息页面
  • 5.功能展示
    • 5.1增加图书信息
    • 5.2修改图书信息
    • 5.3删除单个图书
    • 5.4批量删除图书
    • 5.5翻页功能
  • 7.拓展知识
    • 7.1SpringBoot 中的mapper,service,controller,model 分别有什么用?
    • 7.2DAO层、Service层和Controller层的区别
    • 7.3 SSM系统架构
    • 7.4MySQL(关系型数据库)和mongodb(非关系型数据库)的区别
    • 7.5redis(非关系型数据库)

大家好,我是晓星航。今天为大家带来的是 相关的讲解!😀

1.开发项目流程

1.1开发开发

1.需求确认阶段:需求分析,需求评审

2.开发

1)方案设计
2)接口定义
3)开发业务代码
4)测试(自测+联调) - 和其他团队一起联合测试

3.提测阶段 - 测试人员

4.上线(发布)阶段

1.2数据库的设计

image-20240324143734595

数据库编码:

1.安装时修改

2.建表时修改

2.MySQL数据库相关代码

1.建库

create databases book_test default character set utf8mb4;

2.建表

用户表:

DROP TABLE IF EXISTS user_info;
CREATE TABLE user_info (id INT NOT NULL AUTO_INCREMENT,user_name VARCHAR(128) NOT NULL,password VARCHAR(128) NOT NULL,delete_flag TINYINT(4) NULL DEFAULT 0,create_time DATETIME DEFAULT now(),update_time DATETIME DEFAULT now() ON UPDATE now(),PRIMARY KEY(id),
UNIQUE INDEX user_name_UNIQUE (user_name ASC)) ENGINE = INNODB DEFAULT CHARACTER SET = utf8mb4 COMMENT ='用户表';

图书表:

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;

3.插入数据检验

用户表插入数据:

-- 初始化数据
INSERT INTo user_info (user_name,PASSWORD) VALUES ("admin","admin");
INSERT INTO user_info( user_name,PASSWORD) VALUES ("zhangsan","123456");

图书表插入数据:

-- 初始化图书数据
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,'民主与建设出版社');

批量化构造数据:

INSERT INTO book_info (book_name,author,count,price,publish) VALUES ('图书2','作者2',29,22.00,'出版社2'),('图书3','作者2',29,22.00,'出版社3'),('图书4','作者2',29,22.00,'出版社4'),('图书5','作者2',29,22.00,'出版社5'),('图书6','作者2',29,22.00,'出版社6'),('图书7','作者2',29,22.00,'出版社7'),('图书8','作者2',29,22.00,'出版社8'),('图书9','作者2',29,22.00,'出版社9'),('图书10','作者2',29,22.00,'出版社10'),('图书11','作者2',29,22.00,'出版社11');
INSERT INTO book_info (book_name,author,count,price,publish) VALUES ('图书12','作者2',29,22.00,'出版社12'),('图书13','作者2',29,22.00,'出版社13'),('图书14','作者2',29,22.00,'出版社14'),('图书15','作者2',29,22.00,'出版社15'),('图书16','作者2',29,22.00,'出版社16'),('图书17','作者2',29,22.00,'出版社17'),('图书18','作者2',29,22.00,'出版社18'),('图书19','作者2',29,22.00,'出版社19'),('图书20','作者2',29,22.00,'出版社20'),('图书21','作者2',29,22.00,'出版社21');

3.构造图书结构

3.1用户登录

约定前后端交互接口

[请求]
/user/login
Content-Type:application/x-www-form-urlencoded; charset-UTF-8[参数]
name=zhangsan&password=123456[响应]
true //账号密码验证正确,否则返回false

实现服务器代码

控制层

从数据库中,根据名称查询用户,如果可以查到,并且密码一致,就认为登录成功

import com.example.demo.model.UserInfo;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.stringutils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.Restcontroller;import javax.servlet.http.HttpSession;@RequestMapping("/user")
@Restcontrnller

model层 - 存放实体类:

UserInfo.java:

package com.example.book.model;import lombok.Data;import java.util.Date;@Data
public class UserInfo {private Integer id;private String userName;private String password;private Integer deleteFlag;private Date createTime;private Date updateTime;
}

Controller层:

UserController.java:

package com.example.book.controller;import com.example.book.constant.Constants;
import com.example.book.model.UserInfo;
import com.example.book.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpSession;@RequestMapping("/user")
@RestController
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/login")public Boolean login(String userName, String password, HttpSession session){//校验参数if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){return false;}//验证账号密码是否正确/*** if (userName.equals("admin")){ }  这种写法, 如果userName为null, 会报空指针异常* 开发习惯, 养成*///1. 根据用户名去查找用户信息UserInfo userInfo = userService.getUserInfoByName(userName);//2. 比对密码是否正确if (userInfo==null || userInfo.getId()<=0){return false;}if (password.equals(userInfo.getPassword())){//账号密码正确//存SessionuserInfo.setPassword("");session.setAttribute(Constants.SESSION_USER_KEY,userInfo);return true;}return false;}
}

根据用户名查用户信息,比对验证密码是否正确,账号密码正确后存Session,登录成功!

service层 - 主要是针对具体的问题的操作,把一些数据层的操作进行组合,间接与数据库打交道:

UserService.java:

package com.example.book.service;import com.example.book.mapper.UserInfoMapper;
import com.example.book.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate UserInfoMapper userInfoMapper;public UserInfo getUserInfoByName (String name) {return userInfoMapper.selectUserByName(name);}
}

Mapper层(Dao层):

UserInfoMapper.java:

package com.example.book.mapper;import com.example.book.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;@Mapper
public interface UserInfoMapper {/*** 根据用户名称查询用户信息* @param name* @return*/@Select("select * from user_info where user_name=#{name}")UserInfo selectUserByName(String name);}

3.2图书列表

可以由前端完成也可以由后端完成

前端完成:

image-20240325153145143

后端完成:

image-20240325153153208

model层 - 存放实体类:

PageResult.java:

package com.example.book.model;import lombok.Data;import java.util.List;@Data
public class PageResult<T> {/*** 当前页的记录*/private List<T> records;/*** 总记录数*/private Integer total;private PageRequest pageRequest;public PageResult(List<T> records, Integer total,PageRequest pageRequest) {this.records = records;this.total = total;this.pageRequest = pageRequest;}
}

PageRequest.java:

package com.example.book.model;import lombok.Data;@Data
public class PageRequest {/*** 当前页码*/private Integer currentPage=1;/*** 每页显示条数*/private Integer pageSize=10;private Integer offset;public Integer getOffset() {return (currentPage-1) * pageSize;}
}

controller层:

BookController.java

package com.example.book.controller;import com.example.book.model.*;
import com.example.book.service.BookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpSession;
import java.util.List;@Slf4j
@RequestMapping("/book")
@RestController
public class BookController {@Autowiredprivate BookService bookService;@RequestMapping("/getBookListByPage")public Result getBookListByPage(PageRequest pageRequest, HttpSession session){log.info("查询翻页信息, pageRequest:{}",pageRequest);
//        //用户登录校验
//        UserInfo userInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);
//        if (userInfo==null|| userInfo.getId()<=0 || "".equals(userInfo.getUserName())){
//            //用户未登录
//            return Result.unlogin();
//        }//校验成功if (pageRequest.getPageSize()<0 || pageRequest.getCurrentPage()<1){return Result.fail("参数校验失败");}PageResult<BookInfo> bookInfoPageResult = null;try {bookInfoPageResult = bookService.selectBookInfoByPage(pageRequest);return Result.success(bookInfoPageResult);}catch (Exception e){log.error("查询翻页信息错误,e:{}",e);return Result.fail(e.getMessage());}}
}

service层:

BookService.java:

package com.example.book.service;import com.example.book.enums.BookStatusEnum;
import com.example.book.mapper.BookInfoMapper;
import com.example.book.model.BookInfo;
import com.example.book.model.PageRequest;
import com.example.book.model.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Slf4j
@Service
public class BookService {@Autowiredprivate BookInfoMapper bookInfoMapper;public PageResult<BookInfo> selectBookInfoByPage(PageRequest pageRequest) {if (pageRequest == null) {return null;}//获取总记录数Integer count = bookInfoMapper.count();//获取当前记录List<BookInfo> bookInfos = bookInfoMapper.selectBookInfoByPage(pageRequest.getOffset(), pageRequest.getPageSize());if (bookInfos != null && bookInfos.size() > 0) {for (BookInfo bookInfo : bookInfos) {//根据status 获取状态的定义bookInfo.setStatusCN(BookStatusEnum.getNameByCode(bookInfo.getStatus()).getName());}}return new PageResult<>(bookInfos, count, pageRequest);}/*** 添加图书** @param bookInfo* @return*/public Integer addBook(BookInfo bookInfo) {Integer result = 0;try {result = bookInfoMapper.insertBook(bookInfo);} catch (Exception e) {log.error("添加图书出错, e:{}", e);}return result;}public BookInfo queryBookInfoById(Integer id) {return bookInfoMapper.queryBookInfoById(id);}/*** 更新图书* @param bookInfo* @return*/public Integer updateBook(BookInfo bookInfo) {Integer result = 0;try {result = bookInfoMapper.updateBook(bookInfo);} catch (Exception e) {log.error("更新图书失败, e:{}", e);}return result;}public Integer batchDelete(List<Integer> ids){Integer result =0;try {result = bookInfoMapper.batchDelete(ids);}catch (Exception e){log.error("批量删除图书失败, ids:{}",ids);}return result;}
}

mapper层:

BookInfoMapper.java:

package com.example.book.mapper;import com.example.book.model.BookInfo;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface BookInfoMapper {/*** 获取当前页的信息* @param offset* @param pageSize* @return*/@Select("select * from book_info where status !=0 " +"order by id desc limit #{offset},#{pageSize}")List<BookInfo> selectBookInfoByPage(Integer offset, Integer pageSize);/*** 获取总记录数* @return*/@Select("select count(1) from book_info where status !=0")Integer count();@Insert("insert into book_info (book_name,author, count, price, publish, status) " +"values(#{bookName}, #{author}, #{count}, #{price},#{publish}, #{status})")Integer insertBook(BookInfo bookInfo);@Select("select * from book_info where id =#{id}")BookInfo queryBookInfoById(Integer id);Integer updateBook(BookInfo bookInfo);Integer batchDelete(List<Integer> ids);
}

3.3图书添加

前端代码:

image-20240326152454105

Controller层:

image-20240326152529837

service层:

image-20240326152608120

mapper层(Dao层):

image-20240326152634176

3.4图书删除

企业中很少使用delete语句
delete语句通常是在进行数据修复时才会使用

pg.测试人员进行测试,手工造一些数据,测试完成之后,这条数据就是脏数据了
这个脏数据(假数据) 没有任何价值的,需要把数据删掉,使用delete语句

逻辑删除,物理删除

image-20240326101620298

image-20240326140815832

前端代码:

image-20240326141430507 image-20240326141653479

3.4.1批量删除

image-20240326141711489

Controller层:

image-20240326141747075

service层:

image-20240326142106050

mapper层(Dao层):

image-20240326141822193

3.5图书查询(翻页)

Controller层:

image-20240326152744171

service层:

image-20240326152838700

mapper层(Dao层):

image-20240326152857339

4.页面展示

4.1登录页面

image-20240326162901803

登录失败:

image-20240326162919495

登录成功:

image-20240326162934694

4.2列表页面

image-20240326163009627

4.3增加图书页面

image-20240326163149057

image-20240326163200614

4.4修改图书信息页面

image-20240326163228825

image-20240326163238887

5.功能展示

5.1增加图书信息

image-20240326163149057

image-20240326163200614

5.2修改图书信息

image-20240326163228825
image-20240326163238887

5.3删除单个图书

image-20240326163531046

image-20240326163552634

image-20240326163612445

5.4批量删除图书

image-20240326163713219

image-20240326163726067

5.5翻页功能

image-20240326163757337

image-20240326163836758

7.拓展知识

7.1SpringBoot 中的mapper,service,controller,model 分别有什么用?

MSCM:

  1. controller - 控制层

相当于MVC的C层,controller通过service的接口来控制业务流程,也可通过接收前端传过来的参数进行业务操作。

  1. model - 数据模型层

相当于MVC的M层,存放实体类,与数据库中的属性值基本保持一致。

  1. service - 业务逻辑层

主要是针对具体的问题的操作,把一些数据层的操作进行组合,间接与数据库打交道(提供操作数据库的方法)。

要做这一层的话,要先设计接口,在实现类。

  1. mapper - 数据存储对象 (Dao)

相当于DAO层,mapper层直接与数据库打交道(执行SQL语句),接口提供给service层。

图书管理系统目录:

image-20240325144321175

7.2DAO层、Service层和Controller层的区别

image-20240324112001591

简化理解:

image-20240324112329505

图书管理系统目录:

image-20240325144321175

7.3 SSM系统架构

image-20240325143656658

7.4MySQL(关系型数据库)和mongodb(非关系型数据库)的区别

image-20240326155315647

MySQL:

image-20240326155434335

mongodb:

image-20240326155459830

7.5redis(非关系型数据库)

image-20240326162500120

感谢各位读者的阅读,本文章有任何错误都可以在评论区发表你们的意见,我会对文章进行改正的。如果本文章对你有帮助请动一动你们敏捷的小手点一点赞,你的每一次鼓励都是作者创作的动力哦!😘

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

语言基础 /CC++ 可变参函数设计与实践,va_ 系列实战详解(强制参数和变参数的参数类型陷阱)

文章目录 概述va_ 系列定义va_list 类型va_start 宏从变参函数的强制参数谈起宏 va_start 对 char 和 short 类型编译告警宏 va_start 源码分析猜测 __va_start 函数实现 va_arg 宏宏 va_arg 无法接受 char 和 short为啥va_arg可解析int却不能解析float类型&#xff1f;宏 va_a…

基于单片机的直流电机测速装置研究与设计

摘要: 基于单片机的直流电机测速装置采用了对直流电机的中枢供电回路串联取样电阻的方式实现对电机转速的精确实时测量。系统由滤波电路、信号放大电路、单片机控制电路以及稳压电源等功能模块电路构成。工作过程中高频磁环作为载体&#xff0c;利用电磁感应的基本原理对直流电…

spring boot 基础案例【4】使用Swagger2构建强大的API文档

教程1 案例教程 案例仓库 在线编程 在线编辑器运行&#xff1a;mvn spring-boot:run 教程2 基础教程 教程仓库 在线编程 本案例所在的仓库 本案例所在的文档 进入正文 1.文件目录 2.应用主类 地址:2.x/chapter2-2/src/main/java/com/didispace/chapter22/Chapter22Applicatio…

Secnet-智能路由系统 actpt_5g.data 信息泄露漏洞复现

0x01 产品简介 Secnet安网智能AC管理系统是广州安网通信技术有限公司&#xff08;简称“安网通信”&#xff09;的无线AP管理系统。 0x02 漏洞概述 Secnet-智能路由系统 actpt_5g.data 接口存在信息泄露漏洞&#xff0c;未经身份验证的远程攻击者可以利用此漏洞获取系统账户…

【JVM基础篇】JVM入门介绍

JVM入门介绍 为什么学习JVM 岗位要求 解决工作中遇到的问题 性能调优 真实案例 导出超大文件&#xff0c;系统崩溃从数据库中查询超大量数据出错消费者消费来不及导致系统崩溃Mq消息队列接受消息导致的内存泄漏业务高峰期系统失去响应 初识JVM 什么是JVM&#xff1f; JV…

C 语言中怎么产生真正的随机数?

在C语言中&#xff0c;要产生真正的随机数&#xff0c;我们通常使用标准库中的 <stdlib.h> 头文件中提供的随机数生成函数。 这些函数可以生成伪随机数&#xff0c;但它们在一定程度上是随机的&#xff0c;足以满足大多数应用程序的需求。 1. 伪随机数生成函数 C标准库…

【c++】string深度刨析以及实现

#pragma once #include<iostream> using namespace std; #include<assert.h> namespace bite {class string{public://迭代器 //像指针 底层不一定是指针 typedef char* iterator;iterator begin(){return _str;}iterator end(){return _str _size;}//const 版本…

网络端口占用问题的综合调研与解决方案

原创 Randy 拍码场 问题背景 去年底信息安全团队进行网络权限治理&#xff0c;要求所有应用实例使用静态IP&#xff0c;公网访问策略与静态IP绑定&#xff1b;之后实例重启时偶现“端口被占用”错误。通过分析总结应用日志&#xff0c;共有以下4种错误类型&#xff0c;实质都是…

kafka生产者消费者举例

文章目录 kafka介绍生产者消费者例子一、生产者二、消费者三、效果 KafkaTemplate KafkaListener kafka介绍 Kafka 是一款分布式流处理平台&#xff0c;它被设计用于高吞吐量、持久性、分布式的数据流处理。 Kafka 简介&#xff1a; Kafka 是一个高吞吐、分布式、基于发布 订阅…

深入了解 Flask Request

文章目录 获取请求数据获取请求信息文件上传总结 Flask 是一个轻量级的 Python Web 框架&#xff0c;其简洁的设计和灵活的扩展性使其成为了许多开发者的首选。在 Flask 中&#xff0c;处理 HTTP 请求是至关重要的&#xff0c;而 Flask 提供了丰富而强大的 request 对象来处理…

SpringAop详解

文章目录 一、Spring自定义注解1、什么是注解&#x1f468;‍&#x1f3eb;2、注解的目的或作用&#x1f49e;3、JDK内置注解&#x1f4ab; 【内置元注解 一共八个固定注解】4、元注解 &#x1f3af;5、自定义注解&#x1f4f8;5、Java反射API和类加载过程51、什么是反射基本原…

GT资源-Clock资源

一、Transmitter 时钟分布 XCLK&#xff1a;在使用TX buffer的模式下&#xff0c;XCLK来源于TXOUTCLK。在使用TX bypassing的模式下XCLK来源于TXUSERCLK。TXUSRCLK是GTX/GTH中PCS的内部逻辑时钟。TXUSRCLK2是GT Transceiver 用户侧逻辑时钟。 TXUSRCLK与TXUSRCLK2的关系 FPGA …

ECharts系列文章汇总(持续更新中)

ECharts介绍 ECharts是一款基于JavaScript的数据可视化图表库&#xff0c;提供了直观、生动、可交互、可个性化定制的数据可视化图表。以下是关于ECharts的详细介绍&#xff1a; 发展历程&#xff1a; ECharts最初由百度团队开源&#xff0c;并在2018年初捐赠给Apache基金会&…

【C++阅览室】C++之Vector(容器)

目录 vector的介绍 vector的使用 vector的定义 vector iterator 的使用 vector 空间增长问题 vector 增删查改 vector 迭代器失效问题。&#xff08;重点&#xff09; vector的介绍 1、 vector 是表示可变大小数组的序列容器&#xff0c;可以使用连…

大语言模型的后处理

后处理的输入 常规意义上的大模型处理流程 import torch from transformers import LlamaForCausalLM, LlamaTokenizer# 加载模型和tokenizer model LlamaForCausalLM.from_pretrained("decapoda-research/llama-7b-hf") tokenizer LlamaTokenizer.from_pretrain…

【0002day】citespace知网教程

文章目录 1.建立路径2.数据转换3.数据分析 citespace这个也可以用来分析研究方向。 1.建立路径 首先建立四个文件夹。 2.数据转换 这一步需要导出知网数据&#xff0c;然后还要转换数据。 首先需要选中数据。 导出数据&#xff0c;refworks 将数据下载到input里。 转换…

Linux 磁盘分区工具 gdisk / fdisk

fdisk 是传统的 Linux 磁盘分区工具&#xff0c;磁盘容量有2T的大小限制&#xff1b;gdisk 又叫 GPT fdisk, 作为 fdisk 的升级版&#xff0c;主要使用的是GPT分区类型&#xff0c;用来划分容量大于2T的硬盘&#xff0c;本文介绍使用方法。 简介 早期的磁盘使用 fdisk 工具分区…