java自学阶段二:JavaWeb开发50(Spring和Springboot学习)

news2024/11/26 12:01:34

Spring、Springboot基础知识学习
目录

  1. 学习目标
  2. Spring基础概念
  3. IOC控制反转
  4. DI依赖注入
  5. 事务管理
  6. AOP面向切面编程
  7. Spring案例说明(Postman使用、Restful开发规范、lombok、Restful、nginx了解)

一:学习目标:
1)了解Spring基础概念,Spring核心特性:IOC控制反转、DI依赖注入、事务管理、AOP面向切面编程;
2)参照老师课程,创建、编写SpringBoot入门Demo;
3)其他工具:Postman使用;

二、Spring基础概念
Spring、SpringMVC、Springboot的概念和区别;
1)Spring就是一个java的开源框架,为你写项目提供很多便利的,其中Spring有一些核心特性是需要去学习了解的:
2)SpringMVC:Spring MVC 是 Spring 框架中的一个模块,用于构建基于 Java 的 Web 应用程序。它实现了 Model-View-Controller(MVC)设计模式,使得应用程序的各部分可以更加清晰地分离和协作。

理解起来就是三层结构,有清晰的请求处理流程:通过前端控制器(DispatcherServlet)、处理器映射(Handler Mapping)、处理器适配器(Handler Adapter)和视图解析器(View Resolver)等组件,实现了一个清晰的请求处理流程。
在这里插入图片描述
在这里插入图片描述
灵活的视图技术:支持 JSP、Thymeleaf、FreeMarker 等多种视图技术。
数据绑定和表单处理:自动将请求参数绑定到 JavaBean 对象,并支持自定义数据绑定和验证。
国际化:支持多语言应用程序的开发。

3)Spring Boot
Spring Boot 是基于 Spring 框架的一个快速开发平台,它旨在简化新 Spring 应用程序的初始搭建和开发过程。通过使用“约定优于配置”(Convention Over Configuration)的原则,Spring Boot 可以快速启动和运行应用程序,而无需编写大量的样板代码和配置。

Spring Boot 的主要特性包括:

自动配置:根据添加的依赖项自动配置应用程序。
内嵌服务器:支持内嵌 Tomcat、Jetty 和 Undertow 等 Web 服务器,无需部署到外部容器中。
简化 Maven 和 Gradle 配置:通过提供一系列预定义的“起步依赖”(Starter Dependencies),简化了 Maven 和 Gradle 的配置。
健康检查和外部配置:提供了监控和管理生产环境中应用程序的工具。
与 Cloud 服务集成:与 Docker、Kubernetes、AWS、Azure 等云服务平台紧密集成。

三、IOC控制反转
控制反转(IOC):对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。设计程序讲究高内聚低耦合,把创建对象交给外部来处理,需要的就去Spring的bean中拿。不需要再自己new了,只需要先定义好是bean对象,Component组件,需要new的时候,Spring框架会自己去IOC容器中找,找到了就直接拿来使用,找不到就再创建(单例模式)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:这里有一个特殊的:@RestController = @ResponseBody+@Controller

  • 依赖注入(Dependency Injection, DI):容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。自动装配就是这里这个类需要使用到别的类,刚好也是bean管理的,就可以直接用这个注解,@Autowired来依赖注入

在这里插入图片描述
四、DI依赖注入
个人理解,为了高内聚,低耦合,通俗讲就是一个类里面,尽量少涉及太多别的类,不然修改就容易牵一发而动全身,所以会有一个依赖注入的说法。通过Spring底层技术,一个类里如果需要别的类(如A、B、C类),可以用依赖注入,@Autowired自动加载,这样就不用自己去new了,但是前提是这个类得是Spring管理的才可以
在这里插入图片描述
Grep Console 高亮日志插件

五、事务处理
java中的事务:所谓事务,是你认为的有哪些操作是务必要一起执行完成的;是一个单元集合
异常的类型,有些是RuntimeException才会回滚,需要自己设置

程序上面,还有业务这一层。对于不同的业务,事务管理还是很有必要的,例如,删除部门的时候,其实要删除对应部门下的员工才可以。而这时候如果不是同一个事物,就有可能导致员工删了,部门没删;或者部门删了,员工没删;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
六、AOP
所谓的AOP,我理解是代码写了很多了,然后如果统一要对部分类似代码/同包代码进行处理,如果要全部改一遍很麻烦,不好处理。这时候,就产生了AOP的方法,把要处理的逻辑抽象具体为具体的方法,(要实现这种效果,底层是用到了注解、以及动态代理技术的),然后统一对这部分代码进行逻辑增强。
在这里插入图片描述
在这里插入图片描述
底层实现逻辑:
在这里插入图片描述
AOP执行流程:一旦用了AOP,执行的就不再是原来的方法了,而是动态代理对象加强了原来方法后的新方法

AOP的好处:
在这里插入图片描述
AOP使用步骤:
1.引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.定义一个类,使用注解@Aspect,@Component,声明这个类为AOP类,归属于springboot管理;

3.按照模板来写具体要抽取的核心逻辑

@Around("execution(* com.itheima.service.*.*(..))")//这是around的写法
//方法参数是固定的,定义为了proceedingJoinPoint
public Object recordTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    long begin = System.currentTimeMillis();//其他要在这个方法上执行的逻辑
    Object object = proceedingJoinPoint.proceed(); //调用对应匹配到的方法,然后运行
    long end = System.currentTimeMillis();
    log.info(proceedingJoinPoint.getSignature()+"执行耗时: {}ms", end - begin);
    return object;
}

AOP的概念:
在AOP中,通知(Advice)表示要在目标方法上执行的额外逻辑,而切面(Aspect)则负责定义通知应该应用到哪些连接点(Join Point)上。连接点是程序执行过程中的一个点,如方法的调用或异常的处理。
在这里插入图片描述
核心概念:
1.通知:
在这里插入图片描述
记住:只有Around才需要自己调一遍proceed,其他的其实没有必要;
在这里插入图片描述
通知顺序:
在这里插入图片描述
2.切入点表达式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.连接点
在这里插入图片描述
4.切入点
在这里插入图片描述
5.使用案例:将案例中 增、删、改 相关接口的操作日志记录到数据库表中

  • 定义一个切面类、定义好日志表实体类、以及mapper(插入数据库表的操作):
    注意:还要新建一个自定义注解类
    在这里插入图片描述
  • 在切面类中抓取要记录的日志数据:
//    @Around("execution(* com.itheima.service.impl.*.*(..))")
   @Around("@annotation(com.itheima.anno.Log)")
   //这里使用注解类,是为了方便针对具体的方法使用,而不是放到包这个维度,不好管控
    public Object recordTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//        proceedingJoinPoint.getThis();
        //记录操作人ID - 当前登录员工ID
        //获取请求头中的jwt令牌, 解析令牌
        String jwt = httpServletRequest.getHeader("token");
        Claims claims = JwtUtils.parseJwt(jwt);
        Integer operateUser = (Integer) claims.get("id");
        //获取操作时间
        LocalDateTime operateTime = LocalDateTime.now();
        //获取操作的类名
        String className = proceedingJoinPoint.getTarget().getClass().getName();
        //获取操作的方法名
        String methodName = proceedingJoinPoint.getSignature().getName();
        //获取方法参数
        Object[] Params = proceedingJoinPoint.getArgs();
        String methodParams = Arrays.toString(Params);
        //获取返回值
        String returnValue = proceedingJoinPoint.getKind();

        long begin = System.currentTimeMillis();
        Object object = proceedingJoinPoint.proceed(); //调用原始方法运行
        long end = System.currentTimeMillis();
        long costTime = end - begin;
        log.info(proceedingJoinPoint.getSignature()+"执行耗时: {}ms", end - begin);
        OperateLog operateLog = new OperateLog(operateUser,operateTime,className,methodName,methodParams,returnValue,costTime);
        LogMapper.insertLog(operateLog);
        return object;
    }
  • 具体的类中,需要加上@log注解(好像一般都是加在controller的…是因为这是一切的开始吗?)
    在这里插入图片描述

七、Springboot案例
1.自己在idea新建一个Springboot项目就好。可能会遇到版本的问题,我用的是idea2022的版本,然后jdk是11的,新建的时候会遇到版本的问题,这里不能选择2.多的
在这里插入图片描述
那就只能先新建出来,然后执行启动类,根据报错来修改,印象中是自己修改了pom文件的依赖:
在这里插入图片描述
2.配置Springboot的配置文件,会涉及到Springboot的数据库连接池,springboot默认连接池是HikariCP?我们可以自己改为Druid数据库连接池(常用的,阿里巴巴开发的连接池)。
在这里插入图片描述
pom中加入依赖,修改配置文件:
在这里插入图片描述
在这里插入图片描述

3.Postman的使用:
postman和yapi(接口平台)有啥区别?Postman和YApi在功能和用途上存在一些显著的区别。

*Postman主要是一个接口测试工具,它提供了一套完整的API请求概念,包括API请求的各种组成部分,如请求方法、URL、请求头和请求体等。它支持各种请求方法,如GETPOSTPUTDELETE等,并且具有集成其他工具和服务的能力,如Git、Slack、Newman等,这使得Postman能够更高效地管理和测试API。此外,Postman还提供了环境变量、脚本编写、集合和测试用例等概念,进一步增强了其测试和管理API的能力。通过Postman,用户可以实时监控API性能,及时发现和解决性能问题。
相比之下,YApi是一个高效、易用、功能强大的API管理平台。它的主要目标是为开发、产品和测试人员提供更优雅的接口管理服务。YApi可以帮助开发者轻松创建、发布和维护API,并且提供了优秀的交互体验。用户只需利用平台提供的接口数据写入工具以及简单的点击操作,就可以实现接口的管理。*

Postman更侧重于接口的测试,YApi则更偏向于接口的管理,为开发者提供了便捷的管理平台和交互体验。
使用postman,建立自己的workplace
在这里插入图片描述
2)Restful风格:前后端交互的接口,是基于Restful风格来交互的
在这里插入图片描述
在这里插入图片描述

Restful风格是一种基于HTTP协议设计Web API的软件架构风格,由Roy Fielding在2000年提出。它强调使用HTTP动词来表示对资源的操作(如GETPOSTPUTPATCHDELETE等),并通过URI(统一资源标识符)表示资源的唯一标识符。

Restful风格请求的特点主要包括:
基于资源:数据和功能被抽象成资源,并通过URI来唯一标识这些资源。
HTTP动词:使用HTTP协议中的标准方法(如GETPOSTPUTDELETE等)来表示对资源的操作。
无状态:服务器不保存客户端的状态信息,每次请求都需要包含完整的信息。
以下是一个Restful风格的GET请求示例:
URI:http://example.com/api/users/1
HTTP方法:GET
描述:从http://example.com/api/users/路径下获取ID1的用户信息。

非Restful风格请求:非Restful风格的请求可能不遵循上述原则,例如:

不基于资源:请求可能不直接对应到某个具体的资源。
使用非标准HTTP方法:可能使用自定义的HTTP方法或总是使用GETPOST方法。
有状态:服务器可能保存客户端的状态信息。
以下是一个非Restful风格的请求示例(假设这是一个总是使用POST方法的请求):

URI:http://example.com/api/get_user
HTTP方法:POST(注意这里使用了POST方法而不是GET)
请求体(可能包含):{"id": 1}
描述:这个请求试图从服务器获取ID1的用户信息,但它使用了POST方法,并且请求体中包含了用户ID。在Restful风格中,这种操作应该使用GET方法,并将用户ID包含在URI中。
对比
Restful风格:更简洁、直观,符合HTTP协议的设计初衷。它使得API易于理解、使用和扩展。
非Restful风格:可能更加灵活,但也可能导致API设计混乱、不易于理解和维护。它可能违反了HTTP协议的一些基本原则。
总的来说,Restful风格是一种被广泛接受的Web API设计风格,它使得API更加清晰、一致和易于使用。在设计Web API时,应尽量遵循Restful风格的原则。


基于资源:RESTful风格将数据和功能抽象成资源,并通过URI(统一资源定位符)来唯一标识资源。每一个URI指向一个特定的资源,通过URI来访问资源。
统一接口:RESTful风格使用HTTP动词(如GETPOSTPUTPATCHDELETE等)来表示对资源的操作。这些HTTP动词遵循HTTP协议的标准,使得不同的客户端和服务端可以相互理解和通信。
GETSELECT):从服务器取出资源(一项或多项)。
POSTCREATE):在服务器新建一个资源。
PUTUPDATE):在服务器更新资源(客户端提供完整资源数据)。
PATCHUPDATE):在服务器更新资源(客户端提供需要修改的资源数据)。
DELETEDELETE):从服务器删除资源。
无状态:所有的资源都可以通过URI定位,而且这个定位与其他资源无关。服务端不会保存客户端的状态信息,每次请求都是独立的。这种无状态性使得服务端可以更容易地实现负载均衡和扩展。
URI的设计:RESTful风格的URL应该简洁明了,能够清晰地表示资源的路径和操作。例如,使用http://localhost:8080/users/{id}来表示一个用户资源的URI,其中{id}是用户的唯一标识符。
其他特点:
客户端和服务端之间的通信通常使用JSONXML作为数据交换格式。
RESTful风格支持缓存机制,可以通过HTTP头信息来控制缓存行为。
RESTful风格通常使用HTTP状态码来表示请求的处理结果,如200表示成功,404表示资源未找到等。
总结来说,Restful风格是一种面向资源的API设计方式,它强调使用HTTP协议和URI来标识和操作资源。通过遵循统一接口、无状态等设计原则,Restful风格可以使得Web服务更加简洁、清晰和易于理解。在Spring Boot等框架中,可以方便地实现Restful风格的API

3)查看接口文档、新建请求:
在这里插入图片描述
发起请求,请求来到controller,controller请求service
在这里插入图片描述
老师的代码优点:1.新知识点
在这里插入图片描述
lombok快捷方式,名称不一致不能自动封装;
在这里插入图片描述
在这里插入图片描述
2.使用注释/**:方便回忆当时的想法
在这里插入图片描述
service通过实现类,请求mapper(dao),dao是一个接口,调用查询
在这里插入图片描述
在这里插入图片描述
mapper查询数据
在这里插入图片描述
然后写给统一的响应消息集
在这里插入图片描述
感觉像是Springboot自动帮忙拼了结果响应
在这里插入图片描述
2)Nginx的了解:
前后端联调,前端发送的请求是:http://localhost:90/api/depts— 实质上代表请求的是nginx的服务器,nginx接收到这次请求后,会发送给后端的8080端口tomcat,最终是由tomcat来处理这次请求
在这里插入图片描述

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

项目实际:
在这里插入图片描述

老师的nginx重写了配置文件:
在这里插入图片描述
原生本地的是这样的:
在这里插入图片描述

如果你请求的路径是 http://localhost:90/depts,但是经过 Nginx 后变成了 http://localhost:90/api/depts,那么很可能是 Nginx 配置中设置了路径的代理或者重写规则。

在 Nginx 中,可以通过 location 块来匹配特定的请求路径,并使用 proxy_pass 指令将请求转发到后端服务器。如果 Nginx 配置中包含了将 /depts 路径重写或代理到 /api/depts 的规则,那么就会发生你所描述的行为。

以下是一个简单的 Nginx 配置示例,它展示了如何将 /depts 路径代理到后端的 /api/depts 路径:

nginx
server {  
    listen 90;  
    server_name localhost;  
  
    location /depts {  
        proxy_pass http://backend_server/api/depts;  
        # 可能还有其他相关的配置,比如 proxy_set_header 等  
    }  
      
    # 其他配置...  
}
在这个例子中,任何发往 http://localhost:90/depts 的请求都会被 Nginx 代理到 http://backend_server/api/depts。backend_server 应该替换成实际的后端服务器地址。

为了解决这个问题,你需要检查 Nginx 的配置文件,找到相关的 location 块,并修改 proxy_pass 的值,或者移除/修改重写规则,以确保路径正确转发到后端服务器。

如果 Nginx 配置文件中没有明显的代理或重写规则,那么也可能是 Nginx 与其他中间件(如 Lua 脚本、第三方模块等)集成时添加的额外逻辑导致的。

请确保检查 Nginx 的配置文件(通常位于 /etc/nginx/nginx.conf 或 /etc/nginx/sites-available/ 目录下),并查找与你的请求路径相关的配置。如果你对 Nginx 配置不太熟悉,可能需要参考 Nginx 的官方文档或寻求有经验的开发者的帮助。

4)功能接口实现:
1.增:前端可能传的是一个json格式的数据,需要封装到pojo对象中,要加入一个注解才会自动封装。在Spring Boot中,你可以使用@RequestBody注解来自动将请求体中的JSON数据转换为Java对象。
在这里插入图片描述
传的json数据少的,需要自己去类中补到对象里;
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

如何基于 Elasticsearch 实现排序沉底或前置

在搜索场景的应用中&#xff0c;存在希望根据某个或某些字段来调整排序评分&#xff0c;从而实现排序沉底或置顶效果的使用需求。以商机管理中的扫街场景为例&#xff0c;当我们在扫街场景中需要寻找一个商户时&#xff0c;希望这个商户离的近、GMV 潜力大、被他人跟进过的次数…

前端计网面试题(二)

一、在浏览器中输入url并且按下回车之后发生了什么&#xff1f; 首先解析url&#xff0c;判断url是否合法&#xff0c;如果合法再判断是否完整。如果不合法&#xff0c;则使用用户默认的搜索引擎进行搜索。DNS域名解析获取URL对应的ip地址。&#xff08;首先看本地是否有缓存&…

【干货】SaaS出海业务必看的五个海外流量渠道

一、Product Hunt 月访客约500万 Product Hunt拥有巨大的用户流量和影响力&#xff0c;其全球Alexa排名在前四千以内。许多知名的产品&#xff0c;如ChatGPT、Notion等&#xff0c;都在这里成功上线并获得广泛关注。在美国有什么新产品&#xff08;不论网站、APP还是插件&…

ThinkPHP+Bootstrap简约自适应网址导航网站源码

使用 ThinkPHPbootstrap 开发&#xff0c;后台采用全局 ajax 无刷新加载&#xff0c;前后台自适应&#xff0c;前台页面非常简洁适合自己收藏网站或做导航网站。 搭建教程&#xff1a; 1.整个主机 2.绑定解析域名 3.上传源码&#xff0c;解压 把解压出来的 nav.sql 文件导入数…

25.入口点注入

钩子注入是利用SetWindowsHookEx函数这是一个被动的注入方式&#xff0c;入口点注入是一个主动注入&#xff0c;就是做这件事什么都不为就是为了注入&#xff0c;入口点注入有很多优势比如说做一个游戏的多开器&#xff0c;多开的检测事情是在游戏一启动的时候完成的&#xff0…

两种典型的嵌入式系统架构模式

大多数嵌入式系统都具备实时特征&#xff0c;那么&#xff0c;这种嵌入式系统的典型架构可概括为两种模式&#xff0c;即层次化模式架构和递归模式架构。 1.层次化模式架构 为了达到概念一致性&#xff0c;许多系统通过层次化的方法进行搭建。这样做的结果是&#xff1a;位于高…

Offline : How to Leverage Diverse Demonstrations in Offline Imitation Learning

ICML 2024 paper code Intro 文章提出一种从混合质量数据中高效抽取有用状态动作数据用于模仿学习。算法基于一种假设&#xff0c;即使当前状态并非属于专家状态&#xff0c;但是若在该状态下采取动作导致下一状态是专家状态&#xff0c;那么该状态相较于随机状态更有价值。 …

【漏洞复现】海洋CMS /js/player/dmplayer/dmku/ SQL注入漏洞复现(CVE-2024-29275)

0x01 产品简介 海洋CMS是一套专为不同需求的站长而设计的内容管理系统&#xff0c;灵活、方便、人性化设计、内容的专业网站。海洋CMS基于PHPMySql技术开发&#xff0c;完全开源免费、无任何加密代码。简单易用是最大的特色&#xff0c;可快速建立一个海量 0x02 漏洞概述 海…

Redis高并发高可用

1. 复制机制 在分布式系统中&#xff0c;为了解决单点问题&#xff0c;通常会将数据复制多个副本部署到其他机器&#xff0c;以满足故障恢复和负载均衡等需求。Redis提供了复制功能&#xff0c;实现了相同数据的多个Redis副本。复制功能是高可用Redis的基础&#xff0c;后面的…

1224 - 过河卒

题目描述 AA 点有一个过河卒&#xff0c;需要走到目标 BB 点。 卒行走规则&#xff1a;可以向下、或者向右。同时在棋盘上的任一点有一个对方的马&#xff08;如下图的 CC 点&#xff09;&#xff0c;该马所在的点和所有跳跃一步可达的点称为对方马的控制点。 例如&#xff…

LabVIEW RT环境中因字符串拼接导致的系统崩溃问题

在LabVIEW实时操作系统&#xff08;RT&#xff09;环境中运行的应用程序出现字符串拼接后死机的问题&#xff0c;通常涉及内存管理、内存泄漏或其他资源管理问题。以下是一些指导和步骤&#xff0c;帮助解决这个问题&#xff1a; 1. 内存泄漏检测 字符串拼接会在内存中创建新…

Could not resolve dependencies for project XXX

大家好&#xff0c;这里是教授.F 如果项目上使用的是idea ide的多模块话&#xff0c;需要模块之间的依赖&#xff0c;比如说系统管理模块依赖授权模块进行认证和授权&#xff0c;而认证授权模块需要依赖系统管理模块进行&#xff0c;然后&#xff0c;就开始相互依赖&#xff0…

大水文之------端午练练JS好了

最近有点不太知道要干啥了&#xff0c;昨天看了集cocos的介绍&#xff0c;下载了个DashBoard&#xff0c;看了看里面的内容&#xff0c;确实有点小震惊&#xff0c;还有些免费的源码可以学习&#xff0c;挺好的。 昨天学习ts&#xff0c;感觉自己的js水平好像不太行&#xff0c…

【Three.js】知识梳理十一:Three.js高级纹理类型

在使用Three.js创建3D图形时&#xff0c;纹理扮演着重要的角色&#xff0c;它们可以增加模型的视觉效果&#xff0c;使模型看起来更加真实。本文将深入讨论几种高级纹理类型&#xff1a;法线贴图&#xff08;Normal Maps&#xff09;&#xff0c;凹凸贴图&#xff08;Displacem…

CentOS7发送邮件的设置教程?有哪些步骤?

CentOS7发送邮件时如何配置SMTP&#xff1f;怎样设置群发功能&#xff1f; 无论是系统通知、错误警报还是应用程序的邮件发送&#xff0c;邮件服务都是不可或缺的。在CentOS7中&#xff0c;设置邮件服务可能需要一些配置和调整。AokSend将详细介绍如何在CentOS7上设置并配置邮…

树结构的实现

树的概念 树是一种非线性的数据结构&#xff0c;它是由n个有限节点组成一个具有层次关系的集合&#xff0c;它看起来像棵树&#xff0c;所以称其为“树”。如下图&#xff1a; 树可以分为根和子树&#xff0c;而子树又可以被分为根和子树&#xff0c;故我们可以用递归对其进行实…

.NET周刊【6月第2期 2024-06-09】

国内文章 C#开源实用的工具类库&#xff0c;集成超过1000多种扩展方法 https://www.cnblogs.com/Can-daydayup/p/18230586 文章介绍了一个免费的C#工具类库Z.ExtensionMethods&#xff0c;可以通过NuGet包管理器轻松集成。该库支持.NET Standard 2.0和.NET Framework 4.0&am…

低价和低俗

无底线的低价可不就是低俗了吗&#xff1f; O(∩_∩)O哈哈~ AI说的(引导他说的) 以下几个角度可以进行论证: 低价竞争可能导致质量下降:为了达到极低的价格,商家可能会降低产品或服务的质量标准,使用劣质材料或减少投入。这样可能会影响产品的功能、安全性和使用体验,给消费…

clipboard.js(web页面实现点击复制)

文章目录 codeshow 一个很简单的需求&#xff0c;一个单页面需要一个点击复制的功能 后来在线上找到一个clipboard.js可以实现&#xff0c;这里只用到了最基础的用法&#xff0c;页面样式布局基于bootstrap5.2.3 code <div class"d-flex align-items-center justify-co…

从零实现KV存储项目实战

本项目是从零实现一个完整的、兼容Redis协议的KV数据库项目。 通过每一行代码的编写。你会对整个系统了如指拿&#xff0c;这样对自己基本功的锻炼、对编程能力的提升都是很大的 项目提供完整的视频教程代码 下面是关于KV存储项目的技术大纲&#xff1a; 如果你在学习的过程…