返回首页

JavaWeb学习笔记——By Bug

前言

本笔记是Javaweb开发的笔记,需要有一定的前端基础和Java基础 笔记中省略了HTML,CSS,JavaScript,Vue,Ajax相关知识,本笔记中主要记录的是Java相关内容,前端相关笔记,请到本站导航站查阅!

说明: 本笔记为本人学习过程中随手写的笔记,为复习使用,笔记中可能存在遗漏或错误,具体请以官方文档和权威书籍为准!谢谢! 笔记中的一些图片等元素因路径配置问题,可能会发生丢失。 笔记中展示的构造器和方法等的知识点仅为部分内容,完整内容请查阅官方开发文档内容!

 

参考资料

【黑马程序员JavaWeb开发教程,实现javaweb企业开发全流程(涵盖Spring+MyBatis+SpringMVC+SpringBoot等)】 https://www.bilibili.com/video/BV1m84y1w7Tb/?share_source=copy_web&vd_source=ea0cf64e8dac6f0193a7e28187a0fccb

 

Web开发简介

什么是Web? Web即全球广域网,也称万维网,能够通过浏览器访问到的网站

image-20240808182726472

image-20240808182802007

前端web开发

Axios

Axios是对原生的Ajax进行了封装,简化书写

Axios官方文档👇 起步 | Axios中文文档 | Axios中文网 (axios-http.cn)

在vue项目中安装axios

导入axios

 

前端工程化

Vue

见:Vue2+Vue3笔记

当前主流开发模式:前后端分离模式 前端开发前端页面,后端开发后端程序,前端使用数据时使用API获得相应的数据 以接口文档为标准

流程:需求分析→定义接口文档→前后端并行开发(遵循API文档)→测试(前后端分别测试)→前后端联调测试

接口文档管理平台推荐:YApi,POSTMAN,APIFox

前端工程化开发:模块化(js,css),组件化(UI结构,样式,行为),规范化(结构,编码,接口),自动化(构建,部署,测试)

 

Element

Element:是一套为开发者,设计师等准备的基于Vue2.0的桌面端组件库 组件:组成网页的部件,如 超链接,按钮,图片,表格,表单等 官网:https://element.eleme.cn/

element-ui组件安装

  1. 打开终端,输入以下命令

  2. 在main.js中引入element-ui

  3. 访问官网文档,选择需要的组件复制后根据需要进行调整 组件 | Element

 

前端web开发介绍到此结束


下面是后端web开发内容

后端web开发

Maven

Maven是apache旗下的开源项目,用于管理和构建Java项目的工具 官网:Maven – Welcome to Apache Maven

Maven的作用

  1. 依赖管理:方便快捷的管理项目的依赖资源(jar包),避免版本冲突问题

  2. 提供标准、统一的项目结构

  3. 项目构建:标准跨平台的自动化项目构建方式

 

Maven的介绍

Maven是一个项目管理和构建工具,它是基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建。 image-20240810182407607

仓库:用于存储资源,管理各种jar包

Maven的安装

  1. 下载并解压压缩包 下载地址:Maven – Download Apache Maven

  2. 配置本地仓库:修改conf/settings.xml中的<localRepository>为一个指定目录

  3. 配置阿里云私服:修改<mirrors>标签

  4. 配置环境变量:Maven_HOME,并将其Bin目录加入PATH

 

IDEA集成Maven

Maven依赖管理

SpringBoot Web基础

Spring官网:Spring | Home

SpringBoot可以帮助快速构建应用程序,简化开发,提高效率

 

SpringBoot Web入门


补充教程:IDEA专业版 注意:本方法来源于网络,安全性请自行权衡!如果不放心,可前往官网申请学习产品。

如安装了社区版,请先卸载,到官网下载专业版并安装。 Download IntelliJ IDEA – The Leading Java and Kotlin IDE (jetbrains.com)

下载激活脚本:JetBrains 全家桶激活(2024最新).zip - 蓝奏云 (lanzouh.com)

运行激活脚本,并检查是否激活成功

也可以申请学习版,申请地址:JetBrains 学习产品


 

新建第一个springboot应用 需求:使用springBoot开发一个web应用,浏览器发出请求/hello时,返回一个HELLO WORLD字符串

 

HTTP协议

概述

HTTP:即超文本传输协议,规定了浏览器与服务器之间的数据传输规则

image-20240811172524578

特点

  1. 基于TCP协议:面向连接,安全

  2. 基于请求--响应模型的:一次请求对应一次响应

  3. HTTP协议是无状态的协议:对于事务的处理没有记忆能力。每次请求和响应都是独立的 优点:速度快 缺点:多次请求之间不能共享数据

 

请求协议

请求格式:

Get与post请求区别 GET:请求参数在请求行中,没有请求体。 POST:请求参数在请求体中,POST请求大小没有限制。

请求方式

序号方法描述
1GET从服务器获取资源。用于请求数据而不对数据进行更改。例如,从服务器获取网页、图片等。
2POST向服务器发送数据以创建新资源。常用于提交表单数据或上传文件。发送的数据包含在请求体中。
3PUT向服务器发送数据以更新现有资源。如果资源不存在,则创建新的资源。与 POST 不同,PUT 通常是幂等的,即多次执行相同的 PUT 请求不会产生不同的结果。
4DELETE从服务器删除指定的资源。请求中包含要删除的资源标识符。
5PATCH对资源进行部分修改。与 PUT 类似,但 PATCH 只更改部分数据而不是替换整个资源。
6HEAD类似于 GET,但服务器只返回响应的头部,不返回实际数据。用于检查资源的元数据(例如,检查资源是否存在,查看响应的头部信息)。
7OPTIONS返回服务器支持的 HTTP 方法。用于检查服务器支持哪些请求方法,通常用于跨域资源共享(CORS)的预检请求。
8TRACE回显服务器收到的请求,主要用于诊断。客户端可以查看请求在服务器中的处理路径。
9CONNECT建立一个到服务器的隧道,通常用于 HTTPS 连接。客户端可以通过该隧道发送加密的数据。

常用的HTTP请求头

协议头说明示例状态
Accept可接受的响应内容类型(Content-Types)。Accept: text/plain固定
Accept-Charset可接受的字符集Accept-Charset: utf-8固定
Accept-Encoding可接受的响应内容的编码方式。Accept-Encoding: gzip, deflate固定
Accept-Language可接受的响应内容语言列表。Accept-Language: en-US固定
Accept-Datetime可接受的按照时间来表示的响应内容版本Accept-Datetime: Sat, 26 Dec 2015 17:30:00 GMT临时
Authorization用于表示HTTP协议中需要认证资源的认证信息Authorization: Basic OSdjJGRpbjpvcGVuIANlc2SdDE==固定
Cache-Control用来指定当前的请求/回复中的,是否使用缓存机制。Cache-Control: no-cache固定
Connection客户端(浏览器)想要优先使用的连接类型Connection: keep-alive``Connection: Upgrade固定
Cookie由之前服务器通过Set-Cookie(见下文)设置的一个HTTP协议CookieCookie: $Version=1; Skin=new;固定:标准
Content-Length以8进制表示的请求体的长度Content-Length: 348固定
Content-MD5请求体的内容的二进制 MD5 散列值(数字签名),以 Base64 编码的结果Content-MD5: oD8dH2sgSW50ZWdyaIEd9D==废弃
Content-Type请求体的MIME类型 (用于POST和PUT请求中)Content-Type: application/x-www-form-urlencoded固定
Date发送该消息的日期和时间(以RFC 7231中定义的"HTTP日期"格式来发送)Date: Dec, 26 Dec 2015 17:30:00 GMT固定
Expect表示客户端要求服务器做出特定的行为Expect: 100-continue固定
From发起此请求的用户的邮件地址From: user@itbilu.com固定
Host表示服务器的域名以及服务器所监听的端口号。如果所请求的端口是对应的服务的标准端口(80),则端口号可以省略。Host: www.itbilu.com:80``Host: www.itbilu.com固定
If-Match仅当客户端提供的实体与服务器上对应的实体相匹配时,才进行对应的操作。主要用于像 PUT 这样的方法中,仅当从用户上次更新某个资源后,该资源未被修改的情况下,才更新该资源。If-Match: "9jd00cdj34pss9ejqiw39d82f20d0ikd"固定
If-Modified-Since允许在对应的资源未被修改的情况下返回304未修改If-Modified-Since: Dec, 26 Dec 2015 17:30:00 GMT固定
If-None-Match允许在对应的内容未被修改的情况下返回304未修改( 304 Not Modified ),参考 超文本传输协议 的实体标记If-None-Match: "9jd00cdj34pss9ejqiw39d82f20d0ikd"固定
If-Range如果该实体未被修改过,则向返回所缺少的那一个或多个部分。否则,返回整个新的实体If-Range: "9jd00cdj34pss9ejqiw39d82f20d0ikd"固定
If-Unmodified-Since仅当该实体自某个特定时间以来未被修改的情况下,才发送回应。If-Unmodified-Since: Dec, 26 Dec 2015 17:30:00 GMT固定
Max-Forwards限制该消息可被代理及网关转发的次数。Max-Forwards: 10固定
Origin发起一个针对跨域资源共享的请求(该请求要求服务器在响应中加入一个Access-Control-Allow-Origin的消息头,表示访问控制所允许的来源)。Origin: http://www.itbilu.com固定: 标准
Pragma与具体的实现相关,这些字段可能在请求/回应链中的任何时候产生。Pragma: no-cache固定
Proxy-Authorization用于向代理进行认证的认证信息。Proxy-Authorization: Basic IOoDZRgDOi0vcGVuIHNlNidJi2==固定
Range表示请求某个实体的一部分,字节偏移以0开始。Range: bytes=500-999固定
Referer表示浏览器所访问的前一个页面,可以认为是之前访问页面的链接将浏览器带到了当前页面。Referer其实是Referrer这个单词,但RFC制作标准时给拼错了,后来也就将错就错使用Referer了。Referer: http://itbilu.com/nodejs固定
TE浏览器预期接受的传输时的编码方式:可使用回应协议头Transfer-Encoding中的值(还可以使用"trailers"表示数据传输时的分块方式)用来表示浏览器希望在最后一个大小为0的块之后还接收到一些额外的字段。TE: trailers,deflate固定
User-Agent浏览器的身份标识字符串User-Agent: Mozilla/……固定
Upgrade要求服务器升级到一个高版本协议。Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11固定
Via告诉服务器,这个请求是由哪些代理发出的。Via: 1.0 fred, 1.1 itbilu.com.com (Apache/1.1)固定
Warning一个一般性的警告,表示在实体内容体中可能存在错误。Warning: 199 Miscellaneous warning固定

 

响应协议

响应组成

响应码介绍

状态码分类

  1. 信息响应 (100199)

  2. 成功响应 (200299)

  3. 重定向消息 (300399)

  4. 客户端错误响应 (400499)

  5. 服务端错误响应 (500599)

分类分类描述
1**信息,服务器收到请求,需要请求者继续执行操作
2**成功,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器在处理请求的过程中发生了错误

状态码解释

状态码状态码英文名称中文描述
100Continue继续。客户端应继续其请求
101Switching Protocols切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
   
200OK请求成功。一般用于GET与POST请求
201Created已创建。成功请求并创建了新的资源
202Accepted已接受。已经接受请求,但未处理完成
203Non-Authoritative Information非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204No Content无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205Reset Content重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206Partial Content部分内容。服务器成功处理了部分GET请求
   
300Multiple Choices多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301Moved Permanently永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302Found临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303See Other查看其它地址。与301类似。使用GET和POST请求查看
304Not Modified未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305Use Proxy使用代理。所请求的资源必须通过代理访问
306Unused已经被废弃的HTTP状态码
307Temporary Redirect临时重定向。与302类似。使用GET请求重定向
   
400Bad Request客户端请求的语法错误,服务器无法理解
401Unauthorized请求要求用户的身份认证
402Payment Required保留,将来使用
403Forbidden服务器理解请求客户端的请求,但是拒绝执行此请求
404Not Found服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405Method Not Allowed客户端请求中的方法被禁止
406Not Acceptable服务器无法根据客户端请求的内容特性完成请求
407Proxy Authentication Required请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408Request Time-out服务器等待客户端发送的请求时间过长,超时
409Conflict服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410Gone客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411Length Required服务器无法处理客户端发送的不带Content-Length的请求信息
412Precondition Failed客户端请求信息的先决条件错误
413Request Entity Too Large由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414Request-URI Too Large请求的URI过长(URI通常为网址),服务器无法处理
415Unsupported Media Type服务器无法处理请求附带的媒体格式
416Requested range not satisfiable客户端请求的范围无效
417Expectation Failed(预期失败)服务器无法满足请求头中 Expect 字段指定的预期行为。
418I'm a teapot状态码 418 实际上是一个愚人节玩笑。它在 RFC 2324 中定义,该 RFC 是一个关于超文本咖啡壶控制协议(HTCPCP)的笑话文件。在这个笑话中,418 状态码是作为一个玩笑加入到 HTTP 协议中的。
   
500Internal Server Error服务器内部错误,无法完成请求
501Not Implemented服务器不支持请求的功能,无法完成请求
502Bad Gateway作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503Service Unavailable由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504Gateway Time-out充当网关或代理的服务器,未及时从远端服务器获取请求
505HTTP Version not supported服务器不支持请求的HTTP协议的版本,无法完成处理

 

常用的HTTP响应头

响应头说明示例状态
Access-Control-Allow-Origin指定哪些网站可以跨域源资源共享Access-Control-Allow-Origin: *临时
Accept-Patch指定服务器所支持的文档补丁格式Accept-Patch: text/example;charset=utf-8固定
Accept-Ranges服务器所支持的内容范围Accept-Ranges: bytes固定
Age响应对象在代理缓存中存在的时间,以秒为单位Age: 12固定
Allow对于特定资源的有效动作;Allow: GET, HEAD固定
Cache-Control通知从服务器到客户端内的所有缓存机制,表示它们是否可以缓存这个对象及缓存有效时间。其单位为秒Cache-Control: max-age=3600固定
Connection针对该连接所预期的选项Connection: close固定
Content-Disposition对已知MIME类型资源的描述,浏览器可以根据这个响应头决定是对返回资源的动作,如:将其下载或是打开。Content-Disposition: attachment; filename="fname.ext"固定
Content-Encoding响应资源所使用的编码类型。Content-Encoding: gzip固定
Content-Language响就内容所使用的语言Content-Language: zh-cn固定
Content-Length响应消息体的长度,用8进制字节表示Content-Length: 348固定
Content-Location所返回的数据的一个候选位置Content-Location: /index.htm固定
Content-MD5响应内容的二进制 MD5 散列值,以 Base64 方式编码Content-MD5: IDK0iSsgSW50ZWd0DiJUi==已淘汰
Content-Range如果是响应部分消息,表示属于完整消息的哪个部分Content-Range: bytes 21010-47021/47022固定
Content-Type当前内容的MIME类型Content-Type: text/html; charset=utf-8固定
Date此条消息被发送时的日期和时间(以RFC 7231中定义的"HTTP日期"格式来表示)Date: Tue, 15 Nov 1994 08:12:31 GMT固定
ETag对于某个资源的某个特定版本的一个标识符,通常是一个 消息散列ETag: "737060cd8c284d8af7ad3082f209582d"固定
Expires指定一个日期/时间,超过该时间则认为此回应已经过期Expires: Thu, 01 Dec 1994 16:00:00 GMT固定: 标准
Last-Modified所请求的对象的最后修改日期(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示)Last-Modified: Dec, 26 Dec 2015 17:30:00 GMT固定
Link用来表示与另一个资源之间的类型关系,此类型关系是在RFC 5988中定义Link:; rel="alternate"固定
Location用于在进行重定向,或在创建了某个新资源时使用。Location: http://www.itbilu.com/nodejs固定
P3PP3P策略相关设置P3P: CP="This is not a P3P policy!固定
Pragma与具体的实现相关,这些响应头可能在请求/回应链中的不同时候产生不同的效果Pragma: no-cache固定
Proxy-Authenticate要求在访问代理时提供身份认证信息。Proxy-Authenticate: Basic固定
Public-Key-Pins用于防止中间攻击,声明网站认证中传输层安全协议的证书散列值Public-Key-Pins: max-age=2592000; pin-sha256="……";固定
Refresh用于重定向,或者当一个新的资源被创建时。默认会在5秒后刷新重定向。Refresh: 5; url=http://itbilu.com 
Retry-After如果某个实体临时不可用,那么此协议头用于告知客户端稍后重试。其值可以是一个特定的时间段(以秒为单位)或一个超文本传输协议日期。示例1:Retry-After: 120示例2: Retry-After: Dec, 26 Dec 2015 17:30:00 GMT固定
Server服务器的名称Server: nginx/1.6.3固定
Set-Cookie设置HTTP cookieSet-Cookie: UserID=itbilu; Max-Age=3600; Version=1固定: 标准
Status通用网关接口的响应头字段,用来说明当前HTTP连接的响应状态。Status: 200 OK 
TrailerTrailer用户说明传输中分块编码的编码信息Trailer: Max-Forwards固定
Transfer-Encoding用表示实体传输给用户的编码形式。包括:chunkedcompressdeflategzipidentityTransfer-Encoding: chunked固定
Upgrade要求客户端升级到另一个高版本协议。Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11固定
Vary告知下游的代理服务器,应当如何对以后的请求协议头进行匹配,以决定是否可使用已缓存的响应内容而不是重新从原服务器请求新的内容。Vary: *固定
Via告知代理服务器的客户端,当前响应是通过什么途径发送的。Via: 1.0 fred, 1.1 itbilu.com (nginx/1.6.3)固定
Warning一般性警告,告知在实体内容体中可能存在错误。Warning: 199 Miscellaneous warning固定
WWW-Authenticate表示在请求获取这个实体时应当使用的认证模式。WWW-Authenticate: Basic固定

 

Web服务器

Web服务器是一个软件程序,对HTTP协议的操作进行了封装,使得程序员不需要直接对协议进行操作,使得开发更加便捷。

TomCat介绍

TomCat是一个开源免费的轻量级WEB服务器,支持servlet/jsp少量JavaEE规范

TomCat安装和使用

注意:TomCat已经内置在SpringBoot中,无需再进行下载和安装

TomCat官网:Apache Tomcat® - Welcome!

 

请求响应

请求

POSTMAN

一款功能强大的网页调试与发送请求的chrome插件,常用于进行接口测试 官网:Postman API Platform | Sign Up for Free 其他工具:APIPOST, APIFOX

  1. 下载安装包,并进行安装

  2. 注册账号,并进行登录

  3. 创建工作空间(workspaces)

image-20240812135707259

 

简单参数
SpringBoot方式

简单参数:在方法中设置参数名与形参变量名相同,定义形参接收参数

如果请求参数与方法形参不一致,可以使用注解@RequestParam进行映射

 

实体参数

简单实体对象:请求参数名与形参对象属性名相同,定义一个 类 接收即可

注意:请求参数名要与形参参数名一致

复杂实体对象:请求参数名与形参对象属性名一致,按照对象层次关系即可接收嵌套属性参数

请求格式样例:

image-20240812164530975

数组集合参数

数组参数:请亲参数名与形参数组名称相同,且请求参数有多个,定义一个数组类型的形参即可接收参数

 

日期参数

使用@DateTimeFormat注解完成日期参数格式转换

 

JSON参数

请求方式:POST 接收json数据一般使用对象接收,JSON数据的键名与形参对象的属性名相同。需要使用@RequestBody标识

image-20240812212354407

路径参数

通过请求URL直接传递的参数,使用{...}来表示该路径的参数,需要使用@PathVariavle获取路径参数

 

响应

HttpServletResponse

分层解耦

三层架构

 

分层解耦

 

将使用的对象放在容器中,模块需要使用时,从容器中得到

 

IOC&DI入门

在使用IOC的程序上加入注解:@Component 在使用IOC程序提供的资源上添加注解:@Autowired

 

IOC详解

要把某个对象交给IOC容器管理,需要在对应的类上加入对应注解

注解说明位置
@Component声明bean的基础注解不属于以下三类使用此注解
@Controller@Component的衍生注解标注在控制器类上
@Service@Component的衍生注解标注在业务类上
@Repository@Component的衍生注解标注在数据访问类上

Bean组件扫描

DI详解

由于@Autowired默认是按照类型进行注入的,如果存在多个相同类型的bean,就会报错

解决方案:使用以下注解解决

总结

扩展:@Resource与@Autowired区别

MySQL

MySQL相关笔记请参考本站mysql笔记

 

SpringBoot Mybatis

Mybatis简介

MyBatis 是一款优秀的持久层(数据访问层)框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

MyBatis中文网

 

Mybatis入门

使用Mybatis操作数据库

  1. 创建SpringBoot工程,数据库表和实体类

  2. 引入Mybatis依赖,配置Mybatis image-20240813210350937 在application.properties文件中配置数据库的连接信息

    定义一个持久层的接口,只需要定义接口,不需要重写实现类,在调用方法时

     

  3. 编写SQL语句 案例:使用Mybatis查用户表中的所有数据

     

 

JDBC介绍

使用Java语言操作关系型数据库的一套API

原始的JDBC程序操作繁琐,浪费计算机性能和资源

在Mybatis中将数据库连接信息配置到了单独的配置文件中,查询的结果会自动进行封装,利用数据库连接池技术避免频繁的连接和释放

 

数据库连接池

数据库连接池的优点

 

lombok

lombok可以简化编写实体类的代码,使得代码更加简洁

lombok是一个实用的Java类库,能通过注解的形式自动生成构造器,getter/setter方法,equals,hashcode,toString等方法,并可以自动化生成日志,简化Java开发,提高效率

lombox提供的部分注解

注解作用
@Getter/@Setter为所有的属性提供get/set方法
@ToString为类自动生成易阅读的tostring方法
@EqualsAndHashCode根据类所拥有的非静态字符串自动重写equals和hashcode方法
@Data提供了综合的生成代码功能(@Getter/@Setter/@ToString@EqualsAndHashCode)
@NoArgsConstructor为实体类生成无参构造器方法
@AllArgsConstructor为实体类生成除了static修饰的字段之外带有各种参数的构造器方法

引入lombok依赖

之前的实体类,代码臃肿

使用lombok简化的代码,简介,一目了然

 

Mybatis增删改查

注释配置SQL

本操作用到的数据库信息

参数占位符

 

XML文件配置SQL语句

规范

  1. XML映射文件的名称要与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名) image-20240815193821702

  2. XML映射文件的namespace属性为Mapper接口全类名一致

  3. XML文件中的SQL语句的id与Mapper接口中的方法名一致,并保持返回类型一致 image-20240815194017128

配置内容

image-20240815202028517

这个插件可以快速定位接口与sql语句直接的关系

image-20240815202524914

点击小鸟可完成快速跳转

 

使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。

选择何种方式来配置映射,以及认为是否应该要统一映射语句定义的形式,完全取决于你和你的团队。 换句话说,永远不要拘泥于一种方式,你可以很轻松的在基于注解和 XML 的语句映射方式间自由移植和切换。

 

Mybatis动态SQL

动态SQL是随着用户输入或外部条件的变化而变化的SQL语句

<if>

 

<foreach>

foreach标签属性介绍

需求:批量删除数据

 

<sql>&&<include>

<sql>用于定义可重用的SQL语句片段

<include>:通过refid属性,引入SQL片段

 

案例:教学辅助系统

开发学习系统的部门管理和员工管理模块

体会前后端交互方式

准备

image-20240816212640458

 

部门管理

 

员工管理

分页查询插件:PageHelper

 

文件上传

指的是将本地图片,视频,音频等文件上传到服务器,供其他用户浏览或下载的过程

 

文件上传表单的三要素

image-20240818153212132

 

服务端接收数据 普通数据依然正常接收,文件使用 MultipartFile 接收 image-20240818155126714

 

存储方式

本地存储

将接受的文件转存到服务器磁盘

在MultipartFile中提供了一个transferTo方法,可以将接收到的文件转存到指定的磁盘目录中 在获取原始文件名时,可以使用MultipartFile中提供的getOriginalFilename()方法获取

为了防止文件名重复问题,可以使用UUID解决

上传文件的默认最大为1MB,可以通过配置属性文件修改允许上传的最大文件大小

 

云存储

使用云服务提供商,提供的对象存储服务OSS

准备

  1. 注册云服务账号

  2. 开通对象存储服务OSS

  3. 创建存储空间

  4. 获取密钥

  5. 参考官网文档进行开发

 

配置文件

参数配置化

可以将阿里云的配置信息配置到SpringBoot的配置文件中,通过外部配置的属性注入方式添加属性

用法@Value("${配置文件中的KEY}")

image-20240819132349022

 

yml配置文件

后缀名可以是yml,也可以是yaml

书写格式KEU:VALUE,并按照层级进行书写

yml配置基本语法

  1. 大小写敏感

  2. 数值前面必须加空格,作为分隔符

  3. 使用缩进表示层级关系,缩进是不允许使用tab,要使用空格(在IDEA中会自动将TAB转化为空格,可忽略)

  4. 缩进空格数目不重要,相同层级缩进数量相同即可

  5. #表示注释

 

@ConfigurationProperties

这个注解可以将配置文件中的数据注入到对象中,要求配置文件的属性名要和对象的属性名相同才能完成自动注入,再将该对象交给IOC容器管理即可,使用时再将此对象对象进行注入。

image-20240819154208430

 

登录功能

基础登录

逻辑:使用输入的用户名和密码在数据库中查找,查找到结果即为登录成功,反之认为登录失败

 

 

登录校验

 

 

 

 

 

过滤器 VS 拦截器

过滤器和拦截器的区别主要体现在以下 5 点:

  1. 出身不同; 过滤器来自于 Servlet,而拦截器来自于 Spring 框架

  2. 触发时机不同; 请求的执行顺序是:请求进入容器 > 进入过滤器 > 进入 Servlet > 进入拦截器 > 执行控制器(Controller)

  3. 实现不同; 过滤器是基于方法回调实现的,拦截器是基于动态代理(底层是反射)实现的

  4. 支持的项目类型不同; 过滤器是 Servlet 规范中定义的,所以过滤器要依赖 Servlet 容器,它只能用在 Web 项目中;而拦截器是 Spring 中的一个组件,因此拦截器既可以用在 Web 项目中,同时还可以用在 Application 或 Swing 程序中。

  5. 使用的场景不同。

    因为拦截器更接近业务系统,所以拦截器主要用来实现项目中的业务判断的,比如:登录判断、权限判断、日志记录等业务。 而过滤器通常是用来实现通用功能过滤的,比如:敏感词过滤、字符集编码设置、响应数据压缩等功能。

总结

过滤器和拦截器都是基于 AOP 思想实现的,用来处理某个统一的功能的,但二者又有 5 点不同:出身不同、触发时机不同、实现不同、支持的项目类型不同以及使用的场景不同。过滤器通常是用来进行全局过滤的,而拦截器是用来实现某项业务拦截的。

 

异常处理

在项目开发中,不可避免的会出现很多异常,出现异常后,返回的结果可能不是API文档中指定的返回数据格式,导致前端页面无法正常解析。

处理方法:全局异常处理器

image-20250216210207155

 

Spring事务管理

事务:是一组操作的集合,它是不可分割的一个工作单位,这些操作要么同时成功,要么同时失败。

需求:删除管理系统中的部门信息时,同时删除该部门下的所有员工

以上代码出现异常后,导致部门信息被删除,但是员工却未被删除,造成数据不一致,不完整问题

 

spring事务管理

 

@Transactional注解的属性

 

 

AOP

AOP概述

面向切面编程(AOP)是一种编程范式,它允许开发者将横切关注点(如日志、事务管理等)与业务逻辑分离,从而提高模块化。AOP 通过在运行时动态地将代码插入到特定的类方法或位置上,实现了对这些横切关注点的集中管理。这种方法不仅降低了模块间的耦合度,还使得代码更易于扩展和维护。

动态代理是面向切面编程最主流的实现。而SpringAOP是Spring框架的高级技术,旨在管理bean对象的过程中,主要通过底层的动态代理机制,对特定的方法进行编程。

 

AOP的优点

  1. 提高代码的模块化:

    • 通过将与核心业务逻辑无关的代码(如日志、性能监控、事务处理等)提取到“切面”中,可以使得业务逻辑更加简洁和清晰,减少代码冗余。

    • 这种方式使得“横切关注点”与业务逻辑代码分离,从而避免了在每个业务方法中都编写相同的辅助代码。

  2. 解耦代码:

    • AOP 可以将横切关注点从核心业务逻辑中解耦,减少了代码的耦合性。

    • 比如,事务管理、缓存、日志等功能,AOP 可以在不修改现有业务代码的情况下,插入相关功能,提高了代码的灵活性和可维护性。

  3. 增强代码重用性:

    • 由于切面是独立于业务逻辑的,可以在多个地方复用相同的切面代码。例如,统一的日志记录或事务管理功能,可以应用于多个模块或服务,而不需要重复编写。

  4. 减少代码重复:

    • AOP 通过切面将公共功能(例如日志记录、性能监控、认证和授权等)集中管理,避免了在多个类或方法中重复编写相同的代码。

    • 这种方式使得系统的维护更加容易,减少了冗余代码。

  5. 提高开发效率:

    • 开发人员可以将重点集中在业务逻辑的实现上,而不需要担心如何处理诸如日志、事务管理等横切关注点。

    • 因为这些横切关注点已经被封装到切面中,开发人员可以直接使用 AOP 提供的功能,而无需手动添加重复的代码。

  6. 增强代码的可测试性:

    • 通过将切面和核心业务逻辑分离,可以更容易地进行单元测试。业务逻辑可以单独进行测试,而切面功能也可以单独进行测试,提升了测试的粒度和独立性。

  7. 动态代理和方法拦截:

    • AOP 通过代理(通常是动态代理)对方法的执行进行拦截,提供了比传统的硬编码拦截更加灵活和动态的方式。

    • 开发人员无需修改原始代码就能为现有方法添加额外的功能。

 

AOP的应用场景

  1. 日志记录:

    • 在方法执行前后自动记录日志,特别适用于调试和监控。

  2. 事务管理:

    • 使用 AOP 可以在方法调用前后自动进行事务的开启、提交和回滚。

  3. 安全控制:

    • 可以在方法执行前检查用户权限,决定是否允许执行该方法。

  4. 性能监控:

    • 可以对方法执行的时间进行计时,监控方法的性能。

  5. 缓存:

    • 在方法执行前检查是否有缓存的结果,如果有直接返回缓存结果,否则执行方法并缓存结果。

 

AOP入门

导入AOP依赖

编写AOP程序

需求:记录每个业务操作的执行时间,优化项目

 

AOP核心概念

  1. 切面(Aspect)

示例:

  1. 连接点(Join Point)

示例:

  1. 切入点(Pointcut)

示例:

  1. 通知(Advice)

示例:

  1. 织入(Weaving)

  1. 目标对象(Target Object)

  1. 代理(Proxy)

  1. 引入(Introduction)

AOP 执行流程

  1. 客户端调用目标对象的方法。

  2. AOP 代理对象拦截方法调用(根据切入点匹配)。

  3. 执行通知(如前置通知、环绕通知等)。

  4. 调用目标方法(如果是环绕通知,可以控制是否调用)。

  5. 方法执行完后,执行相应的后置通知、返回通知或异常通知。

 

image-20250217123043098

 

通知

通知类型

通知有多种类型,根据执行时机的不同可以分为以下几种:

 

抽取切入点表达式

使用@Pointcut注解抽取切入点表达式

 

通知顺序

当有多个切面的切入点都匹配到了目标方法,目标方法运行时,多个通知方法都会被执行。

那么,那个通知先执行,哪个通知后执行?

不同切面类中,默认按照切面类的类名字母排序:

目标方法前的通知方法:字母排名靠前的先执行

目标方法后的通知方法:字母排名靠前的后执行

 

手动控制通知执行顺序方法:

@Order(数字)加在切面类上来控制顺序

目标方法的通知方法:数字执行

目标方法的通知方法:数字执行

 

 

切入点表达式

切入点表达式:描述切入点方法的一种表达式

作用:主要用来决定项目中的哪些方法需要加入通知

常见形式:

  1. execution(...)∶根据方法的签名来匹配

  2. @annotation(....):根据注解匹配

 

切入点通配符

*:单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、任意类型的一个参数,也可以通配包、类、方法名的一部分

Spring--AOP进阶高级版(通知类型、顺序+...)_切入点表达式_08

..:多个连续的任意符号,可以通配任意层级的包,或任意类型、任意个数的参数

Spring--AOP进阶高级版(通知类型、顺序+...)_AOP_09

注意:根据业务需要,可以使用且(&&)、或(||)、非(!)来组合比较复杂的切入点表达式

建议

所有业务方法名在命名时尽量规范,方便切入点表达式快速匹配。如:查询类方法都是find开头,更新类方法都是update开头。

描述切入点方法通常基于接口描述,而不是直接描述实现类,增强拓展性。

在满足业务需要的前提下,尽量缩小切入点的匹配范围。如:包名匹配尽量不使用...,使用*匹配单个包。

 

连接点

在Spring中用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如目标类名、方法名、方法参数等。

Spring--AOP进阶高级版(通知类型、顺序+...)_通知顺序_13

 

案例:记录操作日志

将案例中增、删、改相关接口的操作日志记录到数据库表中

实现方法

 

原理篇

配置优先级

在Spring中支持三种配置文件的格式

三种配置文件的优先级是:

 

SpringBoot除了支持配置文件属性配置外,还支持Java系统属性和命令行参数的方式进行属性配置

image-20250218130058479

image-20250218130302664

 

全部配置优先级排序

  1. 命令行参数;

  2. ava:comp/env的JNDI属性(当前J2EE应用的环境);

  3. JAVA系统的环境属性;

  4. 操作系统的环境变量;

  5. JAR包外部的application-xxx.properties或application-xxx.yml配置文件;

  6. JAR包内部的application-xxx.properties或application-xxx.yml配置文件;

  7. JAR包外部的application.properties或application.yml配置文件;

  8. JAR包内部的application.properties或application.yml配置文件;

  9. @Configuration注解类上的@PropertySource指定的配置文件;

  10. 通过SpringApplication.setDefaultProperties 指定的默认属性;

 

Bean管理

springboot原理

对于spring Framework框架来说,它的繁琐是体现在依赖和配置这个方面上,而springboot的出现

优化了这两个点,那是因为springboot底层提供了非常重要的功能,一个是起步依赖,一个是自动配

置,起步依赖大大的简化pom文件当中依赖的配置,就可以解决spring框架中依赖繁琐的问题,而通过

自动配置的功能就可以大大的简化框架在使用时bean的声明以及bean的配置,我们只需要引入程序开发

时所需要的起步依赖,那么所有项目在开发时常见时的配置就都有了,我们之间使用就可以了。

 

起步依赖

当我们使用spring框架进行web程序开发时,我们就需要引入web程序开发所需要的一些依赖,比如

spring web mvc依赖,这是spring框架进行web程序开发所需要的依赖,还有servlet、jason处理的工具

包jackson、aop相关联的依赖等等,而且引入的这些依赖版本还得匹配,否则就可能出现版本冲突的问题

SpringBoot-起步依赖+自动配置(springboot简单、快捷原因底层实现)_springboot

当我们使用springboot开发时就不需要这么麻烦了,我们只需要引入一个依赖就可以了,web开的的起步依赖

SpringBoot-起步依赖+自动配置(springboot简单、快捷原因底层实现)_springboot_02

这个依赖集成了所有web开发的常见依赖,只要引入这一个依赖,其他的依赖都会通过maven的依赖传递进来

依赖传递指的就是如果a依赖了b,b依赖了c,c依赖的d,那么引入a以后b、c、d这些依赖都会被引入

所以起步依赖的原理的就是maven的依赖传递

 

自动配置

SpringBoot的自动配置就是当spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。

自动配置原理

SpringBoot只能扫描所在包及其子包,扫描不到其他包。

 

 

 

@Conditional 作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到SpringIOc容器中。 位置:方法、类

 

总结

在WEB后端开发中,一般都是基于标准三层架构进行开发。

image-20250219130641924

 

模块功能来源

image-20250219130845554

 

Maven高级

分模块设计与开发

为什么要使用分模块设计与开发?

如果不进行分模块开发时,所有的业务代码都在一个模块中,随着业务越来越强大,这个项目中的业务代码会越来越多。会导致项目难以维护,代码难以复用。

在项目设计是,可以将项目进行分模块设计。

image-20250219131414163

 

分模块开发

需求:将项目中的pojo实体类和utils工具类抽取到响应的模块中

image-20250219131715477

注意!分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分。

完成拆分后,在项目需要用到该模块时,只需要在pom文件中引入即可

image-20250219132607697

image-20250219132634396

 

继承与聚合

继承

在maven中,工程也可以实现继承关系

在项目中,每个模块可能都会使用到一个相同的依赖,如果每个模块导入一次,操作非常繁琐,也不便于管理

image-20250219132904272

继承

介绍:继承描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承。

作用:简化依赖配置、统一管理依赖

image-20250219213131744

实现:使用<parent>...</parent>标签

由于依赖只能单继承,需要让父工程继承SpringBoot依赖,再让子工程继承父工程,通过依赖传递将这个依赖传递到子工程

 

步骤

  1. 创建maven模块tlias-parent,该工程为父工程,设置打包方式pom(默认jar)。 打包方式:

    • jar:普通模块打包,springboot项目基本都是jar包(内嵌tomcat运行)

    • war:普通web程序打包,需要部署在外部的tomcat服务器中运行

    • pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理

    在pom文件中使用标签<packaging>设置打包方式

  2. 在子工程的pom.xml文件中,配置继承关系。

  3. 在父工程中配置各个工程共有的依赖(子工程会自动继承父工程的依赖)。

 

版本锁定

什么是版本锁定?

在真实项目开发中,由于业务非常复杂,一个项目通常都是分模块、多人协作开发的,不可能一个人大包大揽,从头写到尾。必然会出现这样一种场景:crm-dao子模块是由程序员A开发的,crm-service子模块是由程序员B开发的,crm-web子模块是由程序员C开发的,当程序员A开发完crm-dao子模块后,他必然就要编写[JUnit单元测试用例了,这时,他就要在其pom.xml文件中添加JUnit的依赖了,假设添加的依赖如下:

同理,当程序员B开发完crm-service子模块后,他必然也要编写JUnit单元测试用例,这时,他也要在其pom.xml文件中添加JUnit的依赖了,假设添加的依赖如下:

可以发现程序员A与程序员B他俩所使用的junit的版本不一致,这样不是太好。合适的方法是一开始就由技术经理在父工程中统一好所使用的junit的版本。这样,每个程序员开发完自己对应的子模块之后,在编写JUnit单元测试用例时,都将使用统一版本的junit。

所以可以通过版本锁定来统一管理JAR包的版本

面对众多的依赖,有一种方法不用考虑依赖路径、声明顺序等因素而可以采用直接锁定版本的方法确定依赖构件的版本,版本锁定后则不用考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中很常用。

在maven中,可以在父工程的pom文件中通过<dependencyManagement>标签来统一管理依赖版本。

配置示例:

注意

  1. 通过<dependencyManagement>配置,仅仅代表统一管理该依赖版本,而并不会将该依赖加入进来。

  2. 如果在子工程中需要使用到这个依赖,我们需要手动进行引入。

  3. 子工程引l入依赖时,无需指定<version>版本号,父工程统一管理。变更依赖版本,只需在父工程中统一变更。

 

自定义属性/引用属性

大型的项目中,可能需要非常非常多的依赖,这些依赖的版本号分散在POM文件中,不便于查找和管理,可以使用自定义属性/引用属性解决

思考(⭐)

<dependencyManagement><dependencies>的区别是什么?

 

聚合

什么是聚合?

在一个大型项目中,依赖配置可能非常复杂,如果需要对一个模块进行打包发布,需要先打包其父工程和其他依赖模块为jar安装到本地操作,才能完成打包。这样非常麻烦。

image-20250219221608905

可以使用maven聚合来解决以上问题。

聚合:将多个模块组织成一个整体,同时进行项目的构建。

通过聚合工程实现

 

父工程也可以作为聚合工程。

image-20250219222052303

在maven中可以通过<modules>设置当前聚合工程所包含的子模块名称

注意:聚合工程中所包含的模块,在构建时,会自动根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关。

 

总结

私服

如果在公司中多个项目模块中的的公共类用的都是一样的,那么不可能将这些一样的代码写两遍。所以将其中一个项目中的代码打包成私服,然后在另外一个模块中去进行引用。

除此之外,如果大公司中开发人员较多,大家同时去远程仓库将依赖下载到本地,那么对公司的带宽会造成很大的压力。很有可能会造成其他的问题。所以可以在公司的局域网内部去搭建一台服务器,开发人员所有的依赖去这台服务器中去访问,如果该台服务器中也没有该依赖,那么该服务器就去远程仓库查找,然后下载到该服务器,最后在返给开发者。

私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的中央仓库,用于解决团队内部的资源共享与资源同步问题。

 

image-20250219223826905

 

私服配置说明

 

访问私服:http://192.168.150.101:8081

访问密码:admin/admin

 

使用私服,需要在maven的settings.xml配置文件中,做如下配置:

  1. 需要在 servers 标签中,配置访问私服的个人凭证(访问的用户名和密码)

     

  2. mirrors 中只配置我们自己私服的连接地址(如果之前配置过阿里云,需要直接替换掉)

     

  3. 需要在 profiles 中,增加如下配置,来指定snapshot快照版本的依赖,依然允许使用

     

  4. 如果需要上传自己的项目到私服上,需要在项目的pom.xml文件中,增加如下配置,来配置项目发布的地址(也就是私服的地址)

     

  5. 发布项目,直接运行 deploy 生命周期即可 (发布时,建议跳过单元测试)

 

 

总结

课程框架

image-20250219230108305

 

笔记到此结束,谢谢!

笔记最后编辑时间:2025.02.19

笔记字数:24100余字

完结撒花❀❀❀❀❀❀