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 {
    @Autowired
    private 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())){
            //账号密码正确
            //存Session
            userInfo.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 {
    @Autowired
    private 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 {

    @Autowired
    private 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 {

    @Autowired
    private 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

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

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

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

相关文章

分布式与一致性协议之TCC协议

TCC协议 概述 虽然MySQL XA能实现数据层的分布式事务&#xff0c;解决多个MySQL操作的事务问题&#xff0c;但还面临别的问题:在接收到外部的指令后&#xff0c;需要访问多个内部系统&#xff0c;执行指令约定的操作&#xff0c;还必须保证指令执行的原子性(也就是事务要么全…

nestjs 全栈进阶--中间件

视频教程 22_nest中中间件_哔哩哔哩_bilibili 1. 介绍 在Nest.js框架中&#xff0c;中间件&#xff08;Middleware&#xff09;是一个非常重要的概念&#xff0c;它是HTTP请求和响应生命周期中的一个重要组成部分&#xff0c;允许开发者在请求到达最终的目的控制器方法之前或…

机器学习算法 - 逻辑回归

逻辑回归是一种广泛应用于统计学和机器学习领域的回归分析方法&#xff0c;主要用于处理二分类问题。它的目的是找到一个最佳拟合模型来预测一个事件的发生概率。以下是逻辑回归的一些核心要点&#xff1a; 基本概念 输出&#xff1a;逻辑回归模型的输出是一个介于0和1之间的…

【数据结构】队列详解(Queue)

文章目录 有关队列的概念队列的结点设计及初始化队列的销毁判空和计数入队操作出队操作 有关队列的概念 队列:只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO(First In First Out)入队列:进行插入操作的一端…

Redis不同数据类型value存储

一、Strings redis中String的底层没有用c的char来实现&#xff0c;而是使用SDS数据结构( char buf[])。 缺点:浪费空间 优势: 1.c字符串不记录自身的长度&#xff0c;所以获取一个字符串长度的复杂度是O(N),但是SDS记录分配的长度alloc,已使用长度len&#xff0c;获取长度的…

CSS文字描边,文字间隔,div自定义形状切割

clip-path: polygon( 0 0, 68% 0, 100% 32%, 100% 100%, 0 100% );//这里切割出来是少一角的正方形 letter-spacing: 1vw; //文字间隔 -webkit-text-stroke: 1px #fff; //文字描边1px uniapp微信小程序顶部导航栏设置透明&#xff0c;下拉改变透明度 onP…

[js] 递归,数组对象根据某个值进行升序或者降序

一、效果图 1.1 父级 1.2 父级与子级 二、代码 升序降序&#xff0c;只要把 a.num - b.num 改成 b.num - a.num <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, i…

pycharm 将项目连同库一起打包及虚拟环境的使用

目录 一、创建虚拟环境 1、用 anaconda 创建 2、Pycharm 直接创建 二、虚拟环境安装第三方库 1、创建项目后&#xff0c;启动终端(Alt F12)&#xff0c;或者点击下方标记处。 2、使用 pip 或者 conda 来进行三方库的安装或卸载 3、将项目中的库放入文档&#xff0c;便于…

Dual Aggregation Transformer for Image Super-Resolution论文总结

题目&#xff1a;Dual Aggregation Transformer&#xff08;双聚合Transformer&#xff09; for Image Super-Resolution&#xff08;图像超分辨&#xff09; 论文&#xff08;ICCV&#xff09;&#xff1a;Chen_Dual_Aggregation_Transformer_for_Image_Super-Resolution_ICCV…

Android之给Button上添加按压效果

一、配置stateListAnimator参数实现按压效果 1、按钮控件 <Buttonandroid:id"id/mBtnLogin"android:layout_width"match_parent"android:layout_height"48dp"android:background"drawable/shape_jfrb_login_button"android:state…

腾讯共享WiFi项目的加盟方式有哪些?

在这个互联互通的时代&#xff0c;共享经济的浪潮正以前所未有的力量席卷全球&#xff0c;而腾讯作为中国互联网巨头之一自然不会错过这场盛宴。其推出的腾讯共享WiFi项目自问世以来就备受瞩目&#xff0c;它不仅为用户提供便捷的上网服务&#xff0c;更为创业者打开了一个全新…

Language2Pose: Natural Language Grounded Pose Forecasting # 论文阅读

URL https://arxiv.org/pdf/1907.01108 TD;DR 19 年 7 月 cmu 的文章&#xff0c;提出一种基于 natural language 生成 3D 动作序列的方法。通过一个简单的 CNN 模型应该就可以实现 Model & Method 首先定义一下任务&#xff1a; 输入&#xff1a;用户的自然语言&…

win10电脑桌面便签纸怎么设置?添加桌面便签方法

对于上班族来说&#xff0c;电脑桌面上的电子便签纸是一项不可或缺的工具。在快节奏的工作环境中&#xff0c;我们经常需要随时记录重要信息、安排工作任务&#xff0c;而电子便签纸以其便捷性和实时性成为了我们的得力助手。 想象一下&#xff0c;在紧张的项目讨论中&#xf…

mysql 细分

索引选择性 索引列的唯一值数量 / 表中的总行数 mysql如何优化-CSDN博客 批量问题 批处理默认是逐条发送 SQL 到数据库的&#xff0c;没有充分利用数据库提供的原生批处理能力&#xff0c;需要额外的配置来启用真正的批处理支持&#xff0c;如使用ExecutorType.BATCH 自定…

提升网络性能,解决网络故障,了解AnaTraf网络流量分析仪

在当今数字化时代&#xff0c;网络性能监测与诊断(Network Performance Monitoring and Diagnosis,NPMD)成为了企业和个人关注的焦点。随着网络流量不断增长&#xff0c;确保网络的稳定性和高效性变得更加重要。在这个领域&#xff0c;AnaTraf网络流量分析仪是您不可或缺的得力…

自然资源-土地征收成片开发知识梳理

自然资源-土地征收成片开发知识梳理 1、什么是成片开发 &#xff1f; 自然资源部印发的《土地征收成片开发标准&#xff08;试行&#xff09;》对成片开发的概念做了界定&#xff0c;成片开发是指在国土空间规划确定的城镇开发边界内的集中建设区&#xff0c;由县级以上地方人…

章十二、数据库(1) —— 概述、MySQL数据库、SQL、DDL、DML、DQL、多表设计

为什么学习数据库&#xff1a; ● 实现数据持久化到本地&#xff1b; ● 使用完整的管理系统统一管理&#xff0c;可以实现结构化查询&#xff0c;方便管理&#xff1b; 一、 数据库概述 ● 数据库 数据库&#xff08;DataBase&#xff09;为了方便数据的 存储 和 管理 &…

LLM记录:五一 Llama 3 超级课堂

LLM记录&#xff1a;五一 Llama 3 超级课堂 想玩大模型&#xff0c;自己又没那个环境&#xff0c;参加五一 Llama 3 超级课堂&#xff0c;简单记录一下llama3-8b的相关体验&#xff0c;实在是邀请不到人&#xff0c;还好后面开放了24G显存&#xff0c;好歹模型能跑起来了&…

TCP UDP

传输层 端口号 tcp udp 网络层 IP地址 IP TCP&#xff0c;UDP 1&#xff0c;TCP是面向链接的协议&#xff0c;而UDP是无连接的协议; 2&#xff0c;TCP协议的传输是可靠的&#xff0c;而UDP协议的传输“尽力而为” 3&#xff0c;TCP可以实现流控&#xff0c;但UDP不行;…

怎么找回回收站里删除的XLS文件?5个恢复方法

我们经常会使用到XLS文件来存储和整理数据。然而有时候由于误操作或不小心&#xff0c;我们可能会将重要的XLS文件删除&#xff0c;并且这些文件可能还被清空出了回收站。面对这种情况许多人会感到焦虑和无助。但是不必过于担心&#xff0c;因为有专门的软件可以帮助我们找回这…