基于Java+SpringBoot+vue实现图书借阅管理系统

基于Java+SpringBoot+vue实现图书借阅和销售商城一体化系统

🍅 作者主页 程序设计

🍅 欢迎点赞 👍 收藏 ⭐留言 📝
🍅 文末获取源码联系方式 📝

文章目录

  • 基于Java+SpringBoot+vue实现图书借阅和销售商城一体化系统
  • 前言介绍:
  • 系统实现功能:
  • 系统设计:
    • 业务流程分析:
    • 图书信息实体图
    • 系统流程图:
  • 功能截图:
    • 登录注册模块
    • 前台首页
    • 图书信息
    • 图书详情
    • 图书资讯
    • 个人中心
    • 购物车管理
    • 下单模块
    • 后台管理模块
    • 卖家管理
    • 图书类型管理
    • 图书信息管理
    • 图书资讯管理
    • 图书借阅管理
    • 图书归还管理
    • 系统轮播图
    • 订单信息管理
  • 主要代码:
    • yml配置:
    • 文件上传:
    • 图书借阅:
  • 论文参考:
  • 获取源码:

前言介绍:

在Internet高速发展的今天,计算机的应用几乎完全覆盖我们生活的各个领域,互联网在经济,生活等方面有着举足轻重的地位,成为人们资源共享,信息快速传递的重要渠道。在中国,网上管理的兴起也同时飞速发展着。为了适应现代人类强烈的时间观念,对于网上图书商城传统管理方式的缺点,互联网的出现打破了这种局限性,给了广大用户更大的选择空间,促进了网上图书商城管理,有效的避免了网上图书商城管理缭乱的局面,方便用户。本网站中,管理员可以以最方便的形式,在最短的时间内查找最多的网上图书信息。因此,系统无疑给人们的生活带来了极大的方便,网络的应用让时间和距离不再是局限。
通过网上图书商城的研究可以更好地理解系统开发的意义,而且也有利于发展更多的智能系统,解决了人才的供给和需求的平衡问题,网上图书商城的开发建设,由于其开发周期短,维护方便,所以它可以适应网上图书商城体系基本要求。

系统实现功能:

本次设计任务是要设计一个网上图书商城,通过这个系统能够满足网上图书商城的管理功能。系统的主要功能包括首页、个人中心、用户管理、卖家管理、图书类型管理、图书信息管理、图书借阅管理、订单管理、系统管理等功能。
管理员可以根据系统给定的账号进行登录,登录后可以进入网上图书商城,对网上图书商城所有模块进行管理。包括查看和修改自己的个人信息以及登录密码。
该系统为每一个用户都分配了一个用户账号,用户通过账号的登录可以在系统中查看网上图书商城信息及对个人信息进行修改等功能。

系统设计:

业务流程分析:

在系统流程分析当中调查分析它是比较重要的环节,因为在这个系统当中它都涉及到每个环节的业务流程,所以从婚纱摄影网的设计的整体设计上要保证各个信息的正确输入和输出以及对数据储存的完整,并结合实际的操作步骤来绘制出具体的流程图。具体流程图如下图所示:
在这里插入图片描述

图书信息实体图

在这里插入图片描述

系统流程图:

下图是用户进入这个网上图书商城后,基本的操作流程。一进入首页便可以进行各种图书商城信息的浏览,包括图书信息等,用户可以根据自身的需求来找适合自己的图书,如果有合适的图书时,就能进行相应的操作,但前提是必须是登录的用户,不然系统会提示需重新登录才可操作。用户也可通过公告的消息,了解实时的情况,这样有助于结合自身,更好的适应网上图书商城的管理需求,最后用户可以根据自己获得信息的满意程度来进行操作
在这里插入图片描述

功能截图:

登录注册模块

用户注册、用户登录,用户通过输入用户名、密码、姓名、联系电话、邮箱等信息进行注册、登录
在这里插入图片描述
在这里插入图片描述

前台首页

在系统首页可以查看首页、图书信息、图书资讯、个人中心、购物车等内容进行详细操作
在这里插入图片描述

图书信息

在图书信息页面可以查看图书名称、价格、单次购买、库存、店铺名称、图书编号、图书类型、图片、作者、出版社、账号、买家账号、手机、图示介绍等详细内容
在这里插入图片描述

图书详情

并进行添加到购物车,立即购买,评论,等收藏操作
在这里插入图片描述
在这里插入图片描述

图书资讯

在这里插入图片描述
在这里插入图片描述

个人中心

个人中心,在个人中心页面通过填写用户名、密码、姓名、性别、上传图片、邮箱、手机、余额等信息进行更新信息,根据需要对我的订单,我的地址,我的收藏进行详细操作
在这里插入图片描述
在这里插入图片描述

购物车管理

购物车页面可以查看购买商品、价格、数量、总价等信息,还可以进行点击购买和删除操作
在这里插入图片描述

下单模块

在这里插入图片描述

后台管理模块

用户管理:在用户管理页面可以对索引、用户名、姓名、性别、头像、邮箱、手机等信息进行详情,修改和删除等操作
在这里插入图片描述

卖家管理

在卖家管理页面可以对索引、账号、卖家姓名、性别、头像、身份证、手机、邮箱、审核回复、审核状态等内容进行详情,审核,修改和删除等操作
在这里插入图片描述

图书类型管理

在图书类型管理页面可以查看索引、图书类型等内容,并进行新增、修改和删除操作
在这里插入图片描述

图书信息管理

在图书信息管理页面可以查看索引、店铺名称、图书编号、图书名称、图书类型、图片、作者、出版社、账号、买家姓名、手机、价格、单限、库存等内容,
在这里插入图片描述
并进行详情,修改,查看评论和删除操作
在这里插入图片描述

图书资讯管理

在图书资讯可以对索引、标题、图片等内容进行查看,
在这里插入图片描述
还可以对 详情,修改和删除等操作
在这里插入图片描述

图书借阅管理

在这里插入图片描述

图书归还管理

在这里插入图片描述
在这里插入图片描述

系统轮播图

还可以对轮播图管理进行相应的操作
在这里插入图片描述

订单信息管理

在已支付订单页面可以对索引、订单编号、商品名称、商品图片、购买数量、价格/积分、折扣价格、总价格/总积分、折扣总价格、支付类型、状态、地址、电话、收货人、商户名称、下单时间等信息进行详情、发货和删除操作,还可以对已退款订单,已完成订单,已发货订单,未支付订单,已取消订单等进行相应的操作
在这里插入图片描述

主要代码:

yml配置:

# Tomcat
server:tomcat:uri-encoding: UTF-8port: 8080servlet:context-path: /springbootq3ulrspring:datasource:driverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3307/springbootq3ulr?useUnicode=true&characterEncoding=utf-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8username: rootpassword: crit@123456#        driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
#        url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=springbootq3ulr
#        username: sa
#        password: 123456servlet:multipart:max-file-size: 300MBmax-request-size: 300MBresources:static-locations: classpath:static/,file:static/#mybatis
mybatis-plus:mapper-locations: classpath*:mapper/*.xml#实体扫描,多个package用逗号或者分号分隔typeAliasesPackage: com.entityglobal-config:#主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";id-type: 1#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"field-strategy: 1#驼峰下划线转换db-column-underline: true#刷新mapper 调试神器refresh-mapper: true#逻辑删除配置logic-delete-value: -1logic-not-delete-value: 0#自定义SQL注入器sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjectorconfiguration:map-underscore-to-camel-case: truecache-enabled: falsecall-setters-on-nulls: true#springboot 项目mybatis plus 设置 jdbcTypeForNull (oracle数据库需配置JdbcType.NULL, 默认是Other)jdbc-type-for-null: 'null'

文件上传:

 
/*** 上传文件映射表*/
@RestController
@RequestMapping("file")
@SuppressWarnings({"unchecked","rawtypes"})
public class FileController{@Autowiredprivate ConfigService configService;/*** 上传文件*/@RequestMapping("/upload")public R upload(@RequestParam("file") MultipartFile file,String type) throws Exception {if (file.isEmpty()) {throw new EIException("上传文件不能为空");}String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);File path = new File(ResourceUtils.getURL("classpath:static").getPath());if(!path.exists()) {path = new File("");}File upload = new File(path.getAbsolutePath(),"/upload/");if(!upload.exists()) {upload.mkdirs();}String fileName = new Date().getTime()+"."+fileExt;File dest = new File(upload.getAbsolutePath()+"/"+fileName);file.transferTo(dest);/*** 如果使用idea或者eclipse重启项目,发现之前上传的图片或者文件丢失,将下面一行代码注释打开* 请将以下的"D:\\springbootq33sd\\src\\main\\resources\\static\\upload"替换成你本地项目的upload路径,* 并且项目路径不能存在中文、空格等特殊字符*/
//		FileUtils.copyFile(dest, new File("D:\\springbootq33sd\\src\\main\\resources\\static\\upload"+"/"+fileName)); /**修改了路径以后请将该行最前面的//注释去掉**/if(StringUtils.isNotBlank(type) && type.equals("1")) {ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));if(configEntity==null) {configEntity = new ConfigEntity();configEntity.setName("faceFile");configEntity.setValue(fileName);} else {configEntity.setValue(fileName);}configService.insertOrUpdate(configEntity);}return R.ok().put("file", fileName);}/*** 下载文件*/@IgnoreAuth@RequestMapping("/download")public ResponseEntity<byte[]> download(@RequestParam String fileName) {try {File path = new File(ResourceUtils.getURL("classpath:static").getPath());if(!path.exists()) {path = new File("");}File upload = new File(path.getAbsolutePath(),"/upload/");if(!upload.exists()) {upload.mkdirs();}File file = new File(upload.getAbsolutePath()+"/"+fileName);if(file.exists()){/*if(!fileService.canRead(file, SessionManager.getSessionUser())){getResponse().sendError(403);}*/HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);    headers.setContentDispositionFormData("attachment", fileName);    return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);}} catch (IOException e) {e.printStackTrace();}return new ResponseEntity<byte[]>(HttpStatus.INTERNAL_SERVER_ERROR);}}

图书借阅:

 
/*** 图书借阅* 后端接口* @lyy* @date 2022-03-25 17:43:28*/
@RestController
@RequestMapping("/tushujieyue")
public class TushujieyueController {@Autowiredprivate TushujieyueService tushujieyueService;/*** 后端列表*/@RequestMapping("/page")public R page(@RequestParam Map<String, Object> params,TushujieyueEntity tushujieyue,HttpServletRequest request){String tableName = request.getSession().getAttribute("tableName").toString();if(tableName.equals("maijia")) {tushujieyue.setZhanghao((String)request.getSession().getAttribute("username"));}if(tableName.equals("yonghu")) {tushujieyue.setYonghuming((String)request.getSession().getAttribute("username"));}EntityWrapper<TushujieyueEntity> ew = new EntityWrapper<TushujieyueEntity>();PageUtils page = tushujieyueService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, tushujieyue), params), params));return R.ok().put("data", page);}/*** 前端列表*/@IgnoreAuth@RequestMapping("/list")public R list(@RequestParam Map<String, Object> params,TushujieyueEntity tushujieyue, HttpServletRequest request){EntityWrapper<TushujieyueEntity> ew = new EntityWrapper<TushujieyueEntity>();PageUtils page = tushujieyueService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, tushujieyue), params), params));return R.ok().put("data", page);}/*** 列表*/@RequestMapping("/lists")public R list( TushujieyueEntity tushujieyue){EntityWrapper<TushujieyueEntity> ew = new EntityWrapper<TushujieyueEntity>();ew.allEq(MPUtil.allEQMapPre( tushujieyue, "tushujieyue")); return R.ok().put("data", tushujieyueService.selectListView(ew));}/*** 查询*/@RequestMapping("/query")public R query(TushujieyueEntity tushujieyue){EntityWrapper< TushujieyueEntity> ew = new EntityWrapper< TushujieyueEntity>();ew.allEq(MPUtil.allEQMapPre( tushujieyue, "tushujieyue")); TushujieyueView tushujieyueView =  tushujieyueService.selectView(ew);return R.ok("查询图书借阅成功").put("data", tushujieyueView);}/*** 后端详情*/@RequestMapping("/info/{id}")public R info(@PathVariable("id") Long id){TushujieyueEntity tushujieyue = tushujieyueService.selectById(id);return R.ok().put("data", tushujieyue);}/*** 前端详情*/@IgnoreAuth@RequestMapping("/detail/{id}")public R detail(@PathVariable("id") Long id){TushujieyueEntity tushujieyue = tushujieyueService.selectById(id);return R.ok().put("data", tushujieyue);}/*** 后端保存*/@RequestMapping("/save")public R save(@RequestBody TushujieyueEntity tushujieyue, HttpServletRequest request){tushujieyue.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());//ValidatorUtils.validateEntity(tushujieyue);tushujieyueService.insert(tushujieyue);return R.ok();}/*** 前端保存*/@RequestMapping("/add")public R add(@RequestBody TushujieyueEntity tushujieyue, HttpServletRequest request){tushujieyue.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());//ValidatorUtils.validateEntity(tushujieyue);tushujieyueService.insert(tushujieyue);return R.ok();}/*** 修改*/@RequestMapping("/update")public R update(@RequestBody TushujieyueEntity tushujieyue, HttpServletRequest request){//ValidatorUtils.validateEntity(tushujieyue);tushujieyueService.updateById(tushujieyue);//全部更新return R.ok();}/*** 删除*/@RequestMapping("/delete")public R delete(@RequestBody Long[] ids){tushujieyueService.deleteBatchIds(Arrays.asList(ids));return R.ok();}/*** 提醒接口*/@RequestMapping("/remind/{columnName}/{type}")public R remindCount(@PathVariable("columnName") String columnName, HttpServletRequest request, @PathVariable("type") String type,@RequestParam Map<String, Object> map) {map.put("column", columnName);map.put("type", type);if(type.equals("2")) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Calendar c = Calendar.getInstance();Date remindStartDate = null;Date remindEndDate = null;if(map.get("remindstart")!=null) {Integer remindStart = Integer.parseInt(map.get("remindstart").toString());c.setTime(new Date()); c.add(Calendar.DAY_OF_MONTH,remindStart);remindStartDate = c.getTime();map.put("remindstart", sdf.format(remindStartDate));}if(map.get("remindend")!=null) {Integer remindEnd = Integer.parseInt(map.get("remindend").toString());c.setTime(new Date());c.add(Calendar.DAY_OF_MONTH,remindEnd);remindEndDate = c.getTime();map.put("remindend", sdf.format(remindEndDate));}}Wrapper<TushujieyueEntity> wrapper = new EntityWrapper<TushujieyueEntity>();if(map.get("remindstart")!=null) {wrapper.ge(columnName, map.get("remindstart"));}if(map.get("remindend")!=null) {wrapper.le(columnName, map.get("remindend"));}String tableName = request.getSession().getAttribute("tableName").toString();if(tableName.equals("maijia")) {wrapper.eq("zhanghao", (String)request.getSession().getAttribute("username"));}if(tableName.equals("yonghu")) {wrapper.eq("yonghuming", (String)request.getSession().getAttribute("username"));}int count = tushujieyueService.selectCount(wrapper);return R.ok().put("count", count);}}

论文参考:

在这里插入图片描述

获取源码:

大家点赞、收藏、关注、评论啦 、查看👇🏻👇🏻获取联系方式👇🏻👇🏻
🍅 查看下方微信号获取联系方式 📝
🚀🚀🚀精彩系列推荐
Java毕设项目精品实战案例《500套》
精彩专栏推荐订阅:在下方专栏👇🏻👇🏻

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

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

相关文章

elasticsearch-hadoop.jar 6.8版本编译异常

## 背景 重新编译 elasticsearch-hadoop 包&#xff1b; GitHub - elastic/elasticsearch-hadoop at 6.8 编译 7.17 版本时很正常&#xff0c;注意设置下环境变量就好&#xff0c;JAVA8_HOME/.... 编译 6.8 版本时&#xff08;要求jdk8 / jdk9&#xff09;&#xff0c;出现…

腾讯云轻量服务器和云服务器CVM该怎么选?区别一览

腾讯云轻量服务器和云服务器CVM该怎么选&#xff1f;不差钱选云服务器CVM&#xff0c;追求性价比选择轻量应用服务器&#xff0c;轻量真优惠呀&#xff0c;活动 https://curl.qcloud.com/oRMoSucP 轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三…

Qt(二):使用udp发送与接收图片

使用Qt来通过UDP协议发送和接收图片可以分为几个步骤。以下是一个基本的指南&#xff1a; 发送图片准备图片数据&#xff1a;首先&#xff0c;你需要将图片转换为可以在网络上传输的数据格式。通常&#xff0c;这涉及到将图片转换为字节数组。设置UDP套接字&#xff1a;在Qt中…

Java 缓存中间件

Java 缓存中间件 关键词&#xff1a;Spring Cache、J2Cache、JetCache 一 、JSR 107 JSR107 中制订了 Java 缓存的规范。 因此&#xff0c;在很多缓存框架、缓存库中&#xff0c;其 API 都参考了 JSR 107 规范。 img Java Caching 定义了 5 个核心接口 CachingProvider - 定义…

合并区间(LeetCode 56)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路参考文献 1.问题描述 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输…

MetalLB:本地Kubernetes集群的LoadBalancer负载均衡利器

背景 在本地集群进行测试时&#xff0c;我们常常面临一个棘手的问题&#xff1a;Service Type不支持LoadBalancer&#xff0c;而我们只能选择使用NodePort作为替代。这种情况下&#xff0c;我们通常会配置Service为NodePort&#xff0c;并使用externalIPs将流量导入Kubernetes…

SpringBoot多线程与任务调度总结

一、前言 多线程与任务调度是java开发中必须掌握的技能&#xff0c;在springBoot的开发中&#xff0c;多线程和任务调度变得越来越简单。实现方式可以通过实现ApplicationRunner接口&#xff0c;重新run的方法实现多线程。任务调度则可以使用Scheduled注解 二、使用示例 Slf…

微软发布安卓版Copilot,可免费使用GPT-4、DALL-E 3

12月27日&#xff0c;微软的Copilot助手&#xff0c;可在谷歌应用商店下载。目前&#xff0c;只有安卓版&#xff0c;ios还无法使用。 Copilot是一款类ChatGPT助手支持中文&#xff0c;可生成文本/代码/图片、分析图片、总结内容等&#xff0c;二者的功能几乎没太大差别。 值…

【小程序】如何获取特定页面的小程序码

一、进入到小程序管理后台&#xff0c;进入后点击上方的“工具”》“生成小程序码” 小程序管理后台 二、进入开发者工具&#xff0c;打开对应的小程序项目&#xff0c;复制底部小程序特定页面的路径 三、粘贴到对应位置的文本框&#xff0c;点击确定即可

Starling-LM-7B与GPT-4:开源AI的新纪录

引言 在人工智能的前沿领域&#xff0c;Starling-LM-7B的出现标志着开源大型语言模型&#xff08;LLM&#xff09;的一大突破。与GPT-4的近距离竞争不仅展示了Starling-LM-7B的技术实力&#xff0c;也突显了开源社区在推动AI发展方面的重要作用。 模型特点 Starling-LM-7B&a…

django之drf框架(排序、过滤、分页、异常处理)

排序 排序的快速使用 1.必须是继承GenericAPIView及其子类才能是用排序 导入OrderingFilter类&#xff0c;from rest_framework.filters import OrderingFilter 2.在类中配置类属性 filter_backends[OrderingFilter] 3.类中写属性 ordering_fields [price,id] # 必须是表的…

某后台管理系统加密参数逆向分析

前言 在我们日常的渗透中经常会遇到开局一个登录框的情况&#xff0c;弱口令爆破当然是我们的首选。但是有的网站会对账号密码等登录信息进行加密处理&#xff0c;这一步不由得阻碍了很多人的脚步。前端的加解密是比较常见的&#xff0c;无论是 web 后台还是小程序&#xff0c…

k8s之部署kubeadm

master 20.0.0.71&#xff08;4核8G&#xff09; docker、kubelet、kubectl、kubeadm、flannel node1 20.0.0.73&#xff08;最少2核4G&#xff09; docker、kubelet、kubectl、kubeadm、flannel node2 20.0.0.74&#xff08;最少2核4G&#xff09; docker、kubelet、kube…

检查Excel内容是否符合规范

代码一&#xff1a; package com.ly.cloud.config;import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.f…

【MySQL库的操作】

1.库的操作 1.1 创建数据库 语法&#xff1a; create databases [IF NOT EXISTS] 数据库名;注意&#xff1a; [] 是可选项 1.2 创建数据库案例 创建名为 db1 的数据库 create databases db1;说明&#xff1a;当我们创建数据库没有指定字符集和校验规则时&#xff0c;系统…

docker compose 部署 grafana + loki + vector 监控kafka消息

Centos7 随笔记录记录 docker compose 统一管理 granfana loki vector 监控kafka 信息。 当然如果仅仅是想通过 Grafana 监控kafka&#xff0c;推荐使用 Grafana Prometheus 通过JMX监控kafka 目录 1. 目录结构 2. 前提已安装Docker-Compose 3. docker-compose 自定义服…

Go 泛型之泛型约束

Go 泛型之泛型约束 文章目录 Go 泛型之泛型约束一、引入二、最宽松的约束&#xff1a;any三、支持比较操作的内置约束&#xff1a;comparable四、自定义约束五、类型集合&#xff08;type set&#xff09;六、简化版的约束形式七、约束的类型推断八、小结 一、引入 虽然泛型是…

Keras多分类鸢尾花DEMO

完整的一个小demo&#xff1a; pandas1.2.4 numpy1.19.2 python3.9.2 import numpy as np import pandas as pd import matplotlib.pyplot as plt from pandas import DataFrame from scipy.io import loadmat from sklearn.model_selection import train_test_split impor…

【MYSQL】MYSQL 的学习教程(十)之 InnoDB 锁

数据库为什么需要加锁呢&#xff1f; 如果有多个并发请求存取数据&#xff0c;在数据就可能会产生多个事务同时操作同一行数据。如果并发操作不加控制&#xff0c;不加锁的话&#xff0c;就可能写入了不正确的数据&#xff0c;或者导致读取了不正确的数据&#xff0c;破坏了数…

MySQL数据库多版本并发控制(MVCC)

在数据库中&#xff0c;并发控制是确保多个事务能够同时执行&#xff0c;而不会导致数据不一致或冲突的关键机制。多版本并发控制(MVCC)是一种流行的并发控制方法&#xff0c;它可以允许多个事务同时读取同一数据项的不同版本&#xff0c;而不会相互阻塞。本文将讨论MVCC的原理…