<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>JavaWeb on Creat</title><link>/categories/javaweb/</link><description>Recent content in JavaWeb on Creat</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Thu, 16 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="/categories/javaweb/index.xml" rel="self" type="application/rss+xml"/><item><title>web后端实战</title><link>/post/web%E5%90%8E%E7%AB%AF%E5%AE%9E%E6%88%98/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><guid>/post/web%E5%90%8E%E7%AB%AF%E5%AE%9E%E6%88%98/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-16&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="restful"&gt;Restful
&lt;/h1&gt;&lt;p&gt;REST(REpresentational state Transfer)，表述性状态转换，它是一种软件架构风格。
❗它并不是一种标准或协议，而是一组设计原则，旨在让网络服务更加简洁、高效且易于扩展。&lt;/p&gt;
&lt;h2 id="具体请求url"&gt;具体请求url
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;动作&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;完整的 URL 示例&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;语义&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;查询全部&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;GET localhost:8080/books&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;查列表&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;查询单个&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;GET localhost:8080/books/{id}&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;查详情&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;新增&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;POST localhost:8080/books&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;存入新数据&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;更新&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;PUT localhost:8080/books/{id}&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;覆盖旧数据&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;删除&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;DELETE localhost:8080/books/{id}&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;移除数据&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="对应的注解"&gt;对应的注解
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;注解&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;对应的 HTTP 方法&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;REST 语义&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;典型应用场景&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@GetMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;GET&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;查&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;获取列表、查看详情、条件搜索。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@PostMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;POST&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;增&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;提交表单、上传文件、新增部门/员工。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@PutMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;PUT&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;改（整）&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;修改整个对象的信息（如修改员工的所有资料）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@PatchMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;PATCH&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;改（部）&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;修改部分信息（如只修改状态、只重置密码）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@DeleteMapping&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;DELETE&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;删&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;删除单个或批量删除资源。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;POST&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;PUT&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;语义&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;创建 (Create)&lt;/strong&gt;：用于创建子资源。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;更新/替换 (Update/Replace)&lt;/strong&gt;：用于更新或替换指定资源。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;资源标识&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;资源 ID 通常由&lt;strong&gt;服务器&lt;/strong&gt;生成。&lt;/td&gt;
 &lt;td&gt;资源 ID 通常由&lt;strong&gt;客户端&lt;/strong&gt;指定。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;对应 SQL&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;类似于 &lt;code&gt;INSERT&lt;/code&gt;。&lt;/td&gt;
 &lt;td&gt;类似于 &lt;code&gt;UPDATE&lt;/code&gt; (全量) 或 &lt;code&gt;REPLACE INTO&lt;/code&gt;。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;幂等性&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;不幂等&lt;/strong&gt;。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;幂等&lt;/strong&gt;。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//指定请求方式 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;查询全部部门数据&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Dept&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; deptList &lt;span style="color:#f92672"&gt;=&lt;/span&gt; deptService.&lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(deptList); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="优点"&gt;优点
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;轻量级:&lt;/strong&gt; 相比早期的 SOAP 协议，REST 传输的数据量更小。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;易于理解:&lt;/strong&gt; 直接利用 HTTP 语义，开发者上手极快。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;高兼容性:&lt;/strong&gt; 只要支持 HTTP 协议的平台（浏览器、移动端、IoT）都能轻松调用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;利于缓存:&lt;/strong&gt; 良好的 RESTful 设计可以充分利用 HTTP 缓存机制，提升性能。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="数据封装"&gt;数据封装
&lt;/h1&gt;&lt;p&gt;在 MyBatis 中，如果&lt;strong&gt;实体类属性名&lt;/strong&gt;（比如 &lt;code&gt;deptName&lt;/code&gt;）和&lt;strong&gt;数据库字段名&lt;/strong&gt;（比如 &lt;code&gt;name&lt;/code&gt;）对不上，MyBatis 找不到对应关系，封装出来的结果就会是 &lt;code&gt;null&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="手动结果映射results-result"&gt;手动结果映射&lt;code&gt;@Results @Result&lt;/code&gt;
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Mapper&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DeptMapper&lt;/span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Results&lt;/span&gt;({ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Result&lt;/span&gt;(column &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;create_time&amp;#34;&lt;/span&gt;, property &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;createTime&amp;#34;&lt;/span&gt;), 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Result&lt;/span&gt;(column &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;update_time&amp;#34;&lt;/span&gt;, property &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;updateTime&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Select&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;SELECT id, name, create_time, update_time FROM dept ORDER BY update_time DESC&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Dept&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="起别名"&gt;起别名
&lt;/h3&gt;&lt;p&gt;在写 SQL 语句时，利用 SQL 的 &lt;code&gt;AS&lt;/code&gt; 关键字，手动将数据库字段名改成和实体类属性名一致。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点：&lt;/strong&gt; 简单直接。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点：&lt;/strong&gt; 如果字段很多，SQL 语句会变得非常臃肿，且每个查询都要写一遍。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Mysql" data-lang="Mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 id, name, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 dept_name &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; deptName, &lt;span style="color:#75715e"&gt;-- 数据库是 dept_name，实体类是 deptName
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 create_time &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; createTime 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; dept;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="开启驼峰命名自动转换-最推荐"&gt;开启驼峰命名自动转换 (最推荐)
&lt;/h3&gt;&lt;p&gt;这是目前最常用的方案。大部分开发规范中，数据库字段用下划线（&lt;code&gt;dept_name&lt;/code&gt;），Java 属性用小驼峰（&lt;code&gt;deptName&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;只需要在 Spring Boot 的配置文件 &lt;code&gt;application.yml&lt;/code&gt;（或 &lt;code&gt;properties&lt;/code&gt;）中开启一个开关，MyBatis 就会自动帮你转换。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;配置文件设置：&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-YAML" data-lang="YAML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mybatis&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;configuration&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 开启驼峰命名自动映射：a_column -&amp;gt; aColumn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;map-underscore-to-camel-case&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;效果：&lt;/strong&gt; 开启后，&lt;code&gt;dept_name&lt;/code&gt; 会自动映射到 &lt;code&gt;deptName&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="使用-resultmap-最强大最灵活"&gt;使用 ResultMap (最强大、最灵活)
&lt;/h3&gt;&lt;p&gt;如果命名完全不规则（比如数据库叫 &lt;code&gt;d_n&lt;/code&gt;，实体类叫 &lt;code&gt;deptName&lt;/code&gt;），或者需要处理复杂的关联查询，就需要手动定义映射规则。&lt;/p&gt;
&lt;p&gt;在 Mapper 的 XML 文件中定义 &lt;code&gt;&amp;lt;resultMap&amp;gt;&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;resultMap&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;DeptResultMap&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;com.example.pojo.Dept&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;id&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;deptName&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;c_time&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;createTime&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/resultMap&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;findAll&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resultMap=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;DeptResultMap&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 SELECT id, name, c_time FROM dept
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;ResultMap (Join)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;分开查询 (Service组装)&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;开发效率&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;高 (MyBatis 自动化)&lt;/td&gt;
 &lt;td&gt;中 (需要写 Java 逻辑)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;SQL 复杂度&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;高 (涉及多表关联)&lt;/td&gt;
 &lt;td&gt;低 (全是单表操作)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;传输压力&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;较大 (存在冗余字段)&lt;/td&gt;
 &lt;td&gt;小 (按需取数据)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;缓存灵活性&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;差&lt;/td&gt;
 &lt;td&gt;好&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!--自定义结果集--&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;resultMap&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;empResultMap&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;asia.creat.pojo.Emp&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;id&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;username&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;username&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;gender&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;gender&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;phone&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;phone&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;job&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;job&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;salary&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;salary&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;image&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;image&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;entry_date&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;entryDate&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;dept_id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;deptId&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;create_time&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;createTime&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;update_time&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;updateTime&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;!--封装exprList--&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;collection&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;exprList&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ofType=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;asia.creat.pojo.EmpExpr&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;id&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_Id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_company&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;company&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_job&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;job&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_begin&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;begin&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_end&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;end&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;result&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;column=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ee_emp_id&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;empId&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/collection&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/resultMap&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="nginx"&gt;Nginx
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;server{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#e6db74"&gt;listen&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;90&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;# 省略......
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;# ......
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;location&lt;/span&gt; &lt;span style="color:#e6db74"&gt;^~&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/api/&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;# 只要URL 是以 /api/ 开头的请求
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;rewrite&lt;/span&gt; &lt;span style="color:#e6db74"&gt;^~/api/(.*)&lt;/span&gt;$ &lt;span style="color:#e6db74"&gt;/&lt;/span&gt;$1 &lt;span style="color:#e6db74"&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;proxy_pass&lt;/span&gt; &lt;span style="color:#e6db74"&gt;http://localhost:8080&lt;/span&gt;; &lt;span style="color:#75715e"&gt;# 代理转发
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="各种注解"&gt;各种注解
&lt;/h1&gt;&lt;h2 id="httpservletrequest"&gt;HttpServletRequest
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	* 基于HttpServetRequest接收前端请求参数，删除部门数据 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	* */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@DeleteMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(HttpServletRequest request){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String idStr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getParameter&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(idStr); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;根据ID删除部门:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;id); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="requestparam"&gt;@RequestParam
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@DeleteMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestParam&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;) Integer deptId){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;根据ID删除部门:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;deptId); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@DeleteMapping(&amp;quot;/depts&amp;quot;)&lt;/code&gt;&lt;/strong&gt;: 指定该方法处理发送到 &lt;code&gt;/depts&lt;/code&gt; 路径的 &lt;strong&gt;DELETE&lt;/strong&gt; 类型请求。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@RequestParam(&amp;quot;id&amp;quot;)&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;❗明确映射&lt;/strong&gt;：&lt;strong&gt;强制要求&lt;/strong&gt;前端必须传递一个名为 &lt;code&gt;id&lt;/code&gt; 的参数，否则报错&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;默认Request 为 true，设为false 则不传递不会报错&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动转换&lt;/strong&gt;：Spring 会自动将前端传来的字符串（如 &lt;code&gt;&amp;quot;1&amp;quot;&lt;/code&gt;）转换为 Java 的 &lt;code&gt;Integer&lt;/code&gt; 类型。如果前端传了非数字字符，Spring 会直接抛出 &lt;code&gt;400 Bad Request&lt;/code&gt; 错误，无需你手动编写 &lt;code&gt;Integer.parseInt&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Integer deptId&lt;/code&gt;&lt;/strong&gt;: 这里的变量名可以叫 &lt;code&gt;deptId&lt;/code&gt;，因为在注解中明确指定了匹配前端的 &lt;code&gt;id&lt;/code&gt; 字段&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="省略requestparam"&gt;省略@RequestParam
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;如果请求参数名与形参变量名相同，直接定义方法形参即可接收&lt;/strong&gt;
但是此时的形参只能为&lt;strong&gt;前端请求参数名&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@DeleteMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(Integer id){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;根据ID删除部门:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;id); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="指定默认值"&gt;指定默认值
&lt;/h3&gt;&lt;p&gt;使用defaultValue设置默认值&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	* 分页查询 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;	* */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestParam&lt;/span&gt;(defaultValue &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;) Integer page, Integer pageSize){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;分页查询{},{}&amp;#34;&lt;/span&gt;,page,pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; pageResult &lt;span style="color:#f92672"&gt;=&lt;/span&gt; empService.&lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;(page, pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(pageResult); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="requestbody"&gt;@RequestBody
&lt;/h2&gt;&lt;p&gt;当请求进入后端时，&lt;code&gt;@RequestBody&lt;/code&gt; 会告诉 Spring：“不要去 URL 路径或查询参数里找数据，去请求体（HTTP Body）里找。把那段 JSON 字符串拿出来，转换成我定义的这个 Java 对象。”&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Controller:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@PostMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestBody&lt;/span&gt; Dept dept){ &lt;span style="color:#75715e"&gt;//将json数据封装到对象 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;新增部门&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;dept); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 deptService.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(dept);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Service:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(Dept dept) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 dept.&lt;span style="color:#a6e22e"&gt;setCreateTime&lt;/span&gt;(LocalDateTime.&lt;span style="color:#a6e22e"&gt;now&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 dept.&lt;span style="color:#a6e22e"&gt;setUpdateTime&lt;/span&gt;(LocalDateTime.&lt;span style="color:#a6e22e"&gt;now&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 deptMapper.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(dept); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mapper:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Insert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;INSERT INTO dept (name,create_time,update_time)VALUES (#{name},#{creatTime},#{updateTime})&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#960050;background-color:#1e0010"&gt;❗❗❗&lt;/span&gt;注意&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;VALUES后用的是属性名(驼峰命名)而不是字段名(下划线)&lt;span style="color:#960050;background-color:#1e0010"&gt;❗❗❗&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(Dept dept);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="使用前提"&gt;使用前提
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求方式&lt;/strong&gt;：通常用于 &lt;code&gt;POST&lt;/code&gt;、&lt;code&gt;PUT&lt;/code&gt; 或 &lt;code&gt;PATCH&lt;/code&gt;。&lt;code&gt;GET&lt;/code&gt; 请求没有请求体，所以不能使用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Content-Type&lt;/strong&gt;：前端发送请求时，Header 中必须包含 &lt;code&gt;Content-Type: application/json&lt;/code&gt;。否则后端会报 &lt;code&gt;415 Unsupported Media Type&lt;/code&gt; 错误&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;属性匹配&lt;/strong&gt;：JSON 中的键名（Key）必须与 Java 实体类中的属性名完全一致，且实体类必须提供 &lt;strong&gt;Setter 方法&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="pathvariable"&gt;@PathVariable
&lt;/h2&gt;&lt;p&gt;REST 风格提倡“URL 代表资源”。例如，你想访问 ID 为 5 的部门，URL 应该是 &lt;code&gt;.../depts/5&lt;/code&gt;，而不是传统的 &lt;code&gt;.../depts?id=5&lt;/code&gt;。这里的 &lt;code&gt;5&lt;/code&gt; 就是一个路径变量
要让 &lt;code&gt;@PathVariable&lt;/code&gt; 生效，需要两个步骤的配合：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;在路径中使用占位符&lt;/strong&gt;：用 &lt;code&gt;{变量名}&lt;/code&gt; 标注。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;在参数前加注解&lt;/strong&gt;：将占位符的值映射到 Java 变量。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts/{id}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;getInfo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@PathVariable&lt;/span&gt; Integer id){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#960050;background-color:#1e0010"&gt;❗❗❗&lt;/span&gt; 如果占位符名称 {id} 和方法参数名 id 一致&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;可以直接映射&lt;span style="color:#960050;background-color:#1e0010"&gt;❗❗❗&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;根据ID查询部门：&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt; id); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
在URL中可以携带多个路径参数 如 &amp;ldquo;/depts/1/0&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="datetimeformat"&gt;@DateTimeFormat
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;@DateTimeFormat&lt;/code&gt; 是一个非常实用的注解，主要用于 &lt;strong&gt;格式化请求参数&lt;/strong&gt;（也就是从前端传到后端的日期字符串）&lt;/p&gt;
&lt;h3 id="在实体类中使用处理搜索条件"&gt;在实体类中使用（处理搜索条件）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;EmpQueryDTO&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 接收类似 &amp;#34;2024-01-01&amp;#34; 的字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; LocalDate beginDate;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; LocalDate endDate;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="直接在-controller-参数中使用"&gt;直接在 Controller 参数中使用
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;pageByCondition&lt;/span&gt;(String name, Integer gender, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;) LocalDate begin, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;) LocalDate end, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(result); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
如果是普通 GET 请求的参数，用 &lt;code&gt;@DateTimeFormat&lt;/code&gt;；如果是 &lt;code&gt;@RequestBody&lt;/code&gt; 接收的 JSON 数据，用 &lt;code&gt;@JsonFormat&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="options"&gt;@Options
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;@Options&lt;/code&gt; 注解主要用于在使用 &lt;strong&gt;注解开发&lt;/strong&gt;（即直接在 Mapper 接口方法上写 &lt;code&gt;@Insert&lt;/code&gt; 或 &lt;code&gt;@Update&lt;/code&gt;）时，配置一些额外的开关和属性。最常见的用法是 &lt;strong&gt;获取自增主键&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Options&lt;/span&gt;(useGeneratedKeys &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,keyProperty &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//获取到生成的主键 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Insert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;...插入语句...&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;insertEmp&lt;/span&gt;(Emp emp);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;useGeneratedKeys = true&lt;/code&gt;&lt;/strong&gt;：告诉 MyBatis 使用数据库生成的自增主键&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;keyProperty = &amp;quot;id&amp;quot;&lt;/code&gt;&lt;/strong&gt;：告诉 MyBatis 把拿到的主键值，设置到 &lt;code&gt;emp&lt;/code&gt; 对象的哪个属性中
执行后的效果：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	empService.&lt;span style="color:#a6e22e"&gt;insertEmp&lt;/span&gt;(emp); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(emp.&lt;span style="color:#a6e22e"&gt;getId&lt;/span&gt;()); &lt;span style="color:#75715e"&gt;// 这里就能打印出数据库生成的那个新 ID 了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;除了获取主键，&lt;code&gt;@Options&lt;/code&gt; 还可以配置以下内容：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;属性&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;timeout&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;设置这条 SQL 执行的超时时间（单位：秒）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;flushCache&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;设置为 &lt;code&gt;true&lt;/code&gt; 时，只要语句被调用，就会清空一级和二级缓存&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;useCache&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;是否将该查询结果放入二级缓存（默认为 true）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;statementType&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;设置 SQL 执行方式（默认为 &lt;code&gt;PREPARED&lt;/code&gt;，即预编译）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="xml形式的等价写法"&gt;XML形式的等价写法
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;insert id&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;insert&amp;#34;&lt;/span&gt; useGeneratedKeys&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; keyProperty&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 insert into &lt;span style="color:#a6e22e"&gt;emp&lt;/span&gt;(...) values(...)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/&lt;/span&gt;insert&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="将多个参数提取到实体类"&gt;将多个参数提取到实体类
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;代码整洁&lt;/strong&gt;：方法参数由 10 个变成 1 个。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;高复用性&lt;/strong&gt;：这个实体类可以在 Controller、Service、Mapper 之间直接传递。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动封装&lt;/strong&gt;：Spring MVC 会自动根据请求参数的名称（Query Params）与实体类的属性名进行匹配并赋值&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Data&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;EmpQueryParam&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer page &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer pageSize &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 10; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer gender; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String begin; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DateTimeFormat&lt;/span&gt;(pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String end; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="注意事项"&gt;注意事项
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不要加 &lt;code&gt;@RequestBody&lt;/code&gt;&lt;/strong&gt;：&lt;code&gt;@RequestBody&lt;/code&gt; 是用来解析 POST 请求里的 JSON 体的。对于 GET 请求的 URL 参数映射到对象，&lt;strong&gt;直接写参数&lt;/strong&gt;即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;默认值处理&lt;/strong&gt;：在实体类中直接为 &lt;code&gt;page&lt;/code&gt; 和 &lt;code&gt;pageSize&lt;/code&gt; 赋初值，可以省去 Controller 里的 &lt;code&gt;@RequestParam(defaultValue = &amp;quot;...&amp;quot;)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日期处理&lt;/strong&gt;：记得给日期属性加上 &lt;code&gt;@DateTimeFormat&lt;/code&gt;，否则当前端传 &lt;code&gt;2026-05-20&lt;/code&gt; 时，后端会因为无法转换为 &lt;code&gt;LocalDate&lt;/code&gt; 而报错。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="路径抽取"&gt;路径抽取
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;修改前&lt;/strong&gt;：每个方法（如查询、删除、新增）都要在注解里写 &lt;code&gt;@GetMapping(&amp;quot;/depts&amp;quot;)&lt;/code&gt; 或 &lt;code&gt;@DeleteMapping(&amp;quot;/depts/{id}&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;修改后&lt;/strong&gt;：在 &lt;code&gt;public class DeptController&lt;/code&gt; 顶部添加 &lt;strong&gt;&lt;code&gt;@RequestMapping(&amp;quot;/depts&amp;quot;)&lt;/code&gt;&lt;/strong&gt;。这样下方的方法注解就可以简化，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;查询全部简写为：&lt;code&gt;@GetMapping&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;根据 ID 查询简写为：&lt;code&gt;@GetMapping(&amp;quot;/{id}&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//指定请求路径前缀 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DeptController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; DeptService deptService; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(value &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/depts&amp;#34;&lt;/span&gt;,method &lt;span style="color:#f92672"&gt;=&lt;/span&gt; RequestMethod.&lt;span style="color:#a6e22e"&gt;GET&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//指定请求方式 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;(){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@PostMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestBody&lt;/span&gt; Dept dept){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DeleteMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(Integer id){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@GetMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/{id}&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;--&amp;gt;&lt;/span&gt; 即为 &lt;span style="color:#e6db74"&gt;&amp;#34;/depts/{id}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;getInfo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@PathVariable&lt;/span&gt; Integer id){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@PutMapping&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;update&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;@RequestBody&lt;/span&gt; Dept dept){...} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="日志logback"&gt;日志Logback
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JUL (java.util.logging)&lt;/strong&gt;：Java 原生日志框架，虽然配置简单但灵活性和性能较差&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Log4j&lt;/strong&gt;：早期非常流行的第三方日志框架，配置灵活&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Logback&lt;/strong&gt;：由 Log4j 作者开发的升级版，性能更优，也是目前 Spring Boot 默认集成的日志实现&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Slf4j (Simple Logging Facade for Java)&lt;/strong&gt;：重点强调的“&lt;strong&gt;简单日志门面&lt;/strong&gt;”，它不是真正的日志实现，而是一套标准接口，允许你在不修改代码的情况下切换底层的日志框架（如从 Log4j 切换到 Logback）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//logger 来自 SLF4j包&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; Logger log &lt;span style="color:#f92672"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 org.&lt;span style="color:#a6e22e"&gt;slf4j&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;LoggerFactory&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getLogger&lt;/span&gt;(LogTest.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;可替换为注解：@Slf4j&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="日志级别"&gt;日志级别
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;日志级别&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;记录方式&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;trace&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;追踪，记录程序运行轨迹，使用很少&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;log.trace(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;debug&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;调试，记录调试过程中的信息，实际应用中通常视为最低级别&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;log.debug(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;info&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;记录一般信息，描述运行关键事件（如网络连接、IO 操作），使用较多&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;log.info(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;warn&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;警告信息，记录潜在有害情况，使用较多&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;log.warn(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;error&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;错误信息，使用较多&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;log.error(&amp;quot;...&amp;quot;)&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;只有&lt;strong&gt;大于等于&lt;/strong&gt;设定级别的日志才会被输出。&lt;/li&gt;
&lt;li&gt;如果将 &lt;code&gt;root&lt;/code&gt; 级别设为 &lt;strong&gt;&lt;code&gt;info&lt;/code&gt;&lt;/strong&gt;，那么 &lt;code&gt;trace&lt;/code&gt; 和 &lt;code&gt;debug&lt;/code&gt; 级别的日志将&lt;strong&gt;不会&lt;/strong&gt;被记录或显示&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;root&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;level=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;&amp;lt;appender-ref&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ref=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;STDOUT&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;&amp;lt;appender-ref&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ref=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;FILE&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/root&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="pagehelper分页查询"&gt;PageHelper分页查询
&lt;/h1&gt;&lt;h2 id="原理"&gt;原理
&lt;/h2&gt;&lt;p&gt;PageHelper 利用了 MyBatis 的 &lt;strong&gt;拦截器（Interceptor）&lt;/strong&gt; 机制。它的工作流程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;拦截&lt;/strong&gt;：当你调用 Mapper 方法前，PageHelper 会拦截到即将执行的 SQL&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解析&lt;/strong&gt;：自动检测你当前使用的数据库类型（MySQL, Oracle, MariaDB 等）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;改写&lt;/strong&gt;：根据你设置的页码（pageNum）和每页数量（pageSize），动态地在原始 SQL 后面拼接分页子句&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动 Count&lt;/strong&gt;：它还会额外执行一条 &lt;code&gt;SELECT COUNT(0)&lt;/code&gt; 来获取总记录数，方便前端显示总页数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;❗SQL语句结尾不能加分号；&lt;/strong&gt;(PageHelper会追加limit语句)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;❗&lt;strong&gt;PageHelper仅仅能对紧跟在其后的第一个查询语句进行分页处理&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="使用"&gt;使用
&lt;/h2&gt;&lt;p&gt;原始Service层&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;(Integer page, Integer pageSize) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Long total &lt;span style="color:#f92672"&gt;=&lt;/span&gt; empMapper.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; rows &lt;span style="color:#f92672"&gt;=&lt;/span&gt; empMapper.&lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;((page &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1)&lt;span style="color:#f92672"&gt;*&lt;/span&gt;pageSize, pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;(total,rows); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用后&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;(Integer page, Integer pageSize) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//设置分页参数PageHelper &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 PageHelper.&lt;span style="color:#a6e22e"&gt;startPage&lt;/span&gt;(page, pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//执行查询 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; emp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; empMapper.&lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;(page, pageSize); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//解析查询结果并封装数据 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Page&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Page&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;) emp; &lt;span style="color:#75715e"&gt;//多态的实现&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; PageResult&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Emp&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;(p.&lt;span style="color:#a6e22e"&gt;getTotal&lt;/span&gt;(), p.&lt;span style="color:#a6e22e"&gt;getResult&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="web%e5%90%8e%e7%ab%af%e5%ae%9e%e6%88%98-1.png"
 loading="lazy"
 data-pending-gallery
 alt="644"
 &gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="spring事务管理"&gt;Spring&lt;a class="link" href="/MySQL/%e4%ba%8b%e5%8a%a1" &gt;事务管理&lt;/a&gt;
&lt;/h1&gt;&lt;p&gt;Spring 事务的本质是利用 &lt;strong&gt;AOP（面向切面编程）&lt;/strong&gt;。当你给一个方法加上事务注解时，Spring 会为该类创建一个代理对象。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;开启&lt;/strong&gt;：在方法执行前，代理对象关闭自动提交，开启事务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;提交&lt;/strong&gt;：如果方法正常执行完毕，代理对象提交事务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;回滚&lt;/strong&gt;：如果方法执行过程中抛出异常，代理对象捕获异常并回滚数据。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="transactional"&gt;@Transactional
&lt;/h2&gt;&lt;p&gt;这是开发中最常用的方式，通过注解直接管理事务，代码零侵入&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;EmpServiceImpl&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; EmpService {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; EmpMapper empMapper;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; DeptMapper deptMapper;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 开启事务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;deleteDept&lt;/span&gt;(Integer id) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 1. 删除部门&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; deptMapper.&lt;span style="color:#a6e22e"&gt;deleteById&lt;/span&gt;(id);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 模拟异常：一旦报错，上面的删除操作也会撤销&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// int i = 1/0; &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 2. 删除该部门下的所有员工&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; empMapper.&lt;span style="color:#a6e22e"&gt;deleteByDeptId&lt;/span&gt;(id);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;属性&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;描述&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;rollbackFor&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;指定哪些异常触发回滚。默认只回滚 &lt;code&gt;RuntimeException&lt;/code&gt;。建议设置为 &lt;code&gt;Exception.class&lt;/code&gt; 以涵盖所有异常。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;propagation&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;事务传播行为&lt;/strong&gt;：定义当一个事务方法调用另一个事务方法时，事务如何传递。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;readOnly&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;是否为只读事务。查询操作建议设为 &lt;code&gt;true&lt;/code&gt;，可以优化数据库性能。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="rollbackfor"&gt;rollbackFor
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt;&lt;span style="color:#75715e"&gt;//默认出现运行时异常RuntimeException才会回滚&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt;(rollbackFor &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {Exception.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;})&lt;span style="color:#75715e"&gt;//指定所有异常都会回滚&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="propagation"&gt;propagation
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;属性值&lt;/th&gt;
 &lt;th&gt;含义&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;REQUIRED&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;【默认值】需要事务，有则加入，无则创建新事务&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;REQUIRES_NEW&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;需要新事务，无论有无，总是创建新事务&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;SUPPORTS&lt;/td&gt;
 &lt;td&gt;支持事务，有则加入，无则在无事务状态中运行&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;NOT_SUPPORTED&lt;/td&gt;
 &lt;td&gt;不支持事务，在无事务状态下运行；如果当前存在已有事务，则挂起当前事务&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;MANDATORY&lt;/td&gt;
 &lt;td&gt;必须有事务，否则抛异常&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;NEVER&lt;/td&gt;
 &lt;td&gt;必须没事务，否则抛异常&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="readonly"&gt;readOnly
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Transactional&lt;/span&gt;(readOnly &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; User &lt;span style="color:#a6e22e"&gt;getUserById&lt;/span&gt;(Long id) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; userRepository.&lt;span style="color:#a6e22e"&gt;findById&lt;/span&gt;(id);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：告诉数据库这是一个只读事务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;好处&lt;/strong&gt;：数据库可以针对只读操作进行优化（例如在 MySQL 中不分配回滚段），提高查询效率&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;它能防止修改吗？&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;不一定&lt;/strong&gt;。这取决于数据库和驱动。虽然 Hibernate 会跳过脏检查，但如果你在只读事务中强行执行原生 SQL 的 &lt;code&gt;UPDATE&lt;/code&gt;，某些数据库可能仍然允许执行（虽然这会导致语义混乱）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;主从架构（Read/Write Splitting）&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;这是 &lt;code&gt;readOnly&lt;/code&gt; 的&lt;strong&gt;关键应用场景&lt;/strong&gt;。通过 AOP 拦截 &lt;code&gt;readOnly=true&lt;/code&gt; 的方法，可以将请求路由到从库（Read Node），而将其他的路由到主库。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;性能损耗&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;虽然它能优化内存，但开启事务本身也是有开销的（获取连接、上下文切换）。对于极其简单的单条查询，有时不加 &lt;code&gt;@Transactional&lt;/code&gt; 反而更快。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="失效场景"&gt;失效场景
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;非 public 方法&lt;/strong&gt;：&lt;code&gt;@Transactional&lt;/code&gt; 只能用于 &lt;code&gt;public&lt;/code&gt; 方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方法内部调用&lt;/strong&gt;：同一个类中，A 方法调用 B 方法，即使 B 加了注解也不会生效（因为绕过了 AOP 代理）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;异常被捕获&lt;/strong&gt;：如果你在代码里 &lt;code&gt;try...catch&lt;/code&gt; 了异常且没有抛出，Spring 无法感知到报错，就不会回滚。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据库不支持&lt;/strong&gt;：比如 MySQL 的 MyISAM 引擎不支持事务，必须使用 &lt;strong&gt;InnoDB&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="tips"&gt;⭐Tips
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;加在 Service 层&lt;/strong&gt;：不要加在 Controller 层，确保业务逻辑的完整性。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;显式指定回滚范围&lt;/strong&gt;：推荐使用 &lt;code&gt;@Transactional(rollbackFor = Exception.class)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;保持方法短小&lt;/strong&gt;：事务会占用数据库连接，尽量不要在事务方法中进行远程接口调用或耗时操作，防止连接池耗尽&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
&lt;code&gt;@Transactional&lt;/code&gt; 可以加在&lt;strong&gt;方法上、类上、接口&lt;/strong&gt;上
※ 推荐加在方法上 ※&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="文件上传"&gt;文件上传
&lt;/h1&gt;&lt;h1 id="multipartfile"&gt;MultipartFile
&lt;/h1&gt;&lt;p&gt;&lt;code&gt;MultipartFile&lt;/code&gt; 是处理文件上传的核心接口。它代表了 HTML 表单中 &lt;code&gt;multipart/form-data&lt;/code&gt; 类型的文件内容。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@PostMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/upload&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;upload&lt;/span&gt;(String name, Integer age, MultipartFile file){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;接收参数：{},{},{}&amp;#34;&lt;/span&gt;,name,age,file); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;方法&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;getName()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;获取表单中文件参数的名称（如上面例子中的 &amp;ldquo;file&amp;rdquo;）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;getOriginalFilename()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;获取客户端文件系统的原始文件名。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;getContentType()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;获取内容类型（如 &lt;code&gt;image/png&lt;/code&gt;）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;isEmpty()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;判断文件是否为空（没有内容或未选择文件）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;getSize()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;返回文件大小（单位：字节）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;getBytes()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;以字节数组形式读取文件内容。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;getInputStream()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;获取输入流，用于流式读取（适合大文件处理）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;transferTo(File dest)&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;最常用&lt;/strong&gt;：将上传的文件直接保存到目标文件。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="问题及注意事项"&gt;问题及注意事项
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;多文件上传&lt;/strong&gt;： 如果你需要一次上传多个文件，将参数改为数组或列表即可： &lt;code&gt;public String upload(@RequestParam(&amp;quot;files&amp;quot;) MultipartFile[] files)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;文件名冲突&lt;/strong&gt;： 直接使用 &lt;code&gt;getOriginalFilename()&lt;/code&gt; 可能导致重名覆盖。建议使用 &lt;strong&gt;UUID&lt;/strong&gt; 或 &lt;strong&gt;时间戳&lt;/strong&gt; 重命名文件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;临时存储&lt;/strong&gt;： &lt;code&gt;MultipartFile&lt;/code&gt; 在处理时会产生临时文件（存储在操作系统的 &lt;code&gt;tmp&lt;/code&gt; 目录）。一旦请求处理完成，这些临时文件会被自动删除。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安全性&lt;/strong&gt;： 务必校验文件后缀名和文件头（Magic Number），防止用户上传恶意的 &lt;code&gt;.exe&lt;/code&gt; 或 &lt;code&gt;.sh&lt;/code&gt; 脚本文件。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="存储在本地"&gt;存储在本地
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@PostMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/upload&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;upload&lt;/span&gt;(String name, Integer age, MultipartFile file) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; IOException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;接收参数：{},{},{}&amp;#34;&lt;/span&gt;,name,age,file); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//原始文件名 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String fof &lt;span style="color:#f92672"&gt;=&lt;/span&gt; file.&lt;span style="color:#a6e22e"&gt;getOriginalFilename&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//新文件名 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String extension &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fof.&lt;span style="color:#a6e22e"&gt;substring&lt;/span&gt;(fof.&lt;span style="color:#a6e22e"&gt;lastIndexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;.&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String newName &lt;span style="color:#f92672"&gt;=&lt;/span&gt; UUID.&lt;span style="color:#a6e22e"&gt;randomUUID&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; extension; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//保存文件 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 file.&lt;span style="color:#a6e22e"&gt;transferTo&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; File(&lt;span style="color:#e6db74"&gt;&amp;#34;F:/images/&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt; newName)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Spring中默认上传文件最大大小为1MB，超过大小需要在配置文件中配置&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-YML" data-lang="YML"&gt;# 文件上传
Spring:
	servlet: 
	 multipart: 
	 # 最大单个文件大小 
	 max-file-size: 10MB 
	 # 最大请求大小（包含所有文件和表单数据） 
	 max-request-size: 100MB
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="oss"&gt;OSS
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Value&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;${aliyun.oss.endpoint}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String endpoint; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Value&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;${aliyun.oss.bucketName}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String bucketName; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Value&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;${aliyun.oss.region}&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String region;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-YML" data-lang="YML"&gt;# 阿里云 OSS配置 
aliyun: 
 oss: 
 endpoint: https://oss-cn-beijing.aliyuncs.com 
 bucketName: creat-spring-oss 
 region: cn-beijing
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="批量注入值configurationproperties"&gt;批量注入值@ConfigurationProperties
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Component&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AliyunOSSOperator&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; AliyunOSSProperties aliyunOSSProperties; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;upload&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; content, String originalFilename) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; ClientException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String endpoint &lt;span style="color:#f92672"&gt;=&lt;/span&gt; aliyunOSSProperties.&lt;span style="color:#a6e22e"&gt;getEndpoint&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String bucketName &lt;span style="color:#f92672"&gt;=&lt;/span&gt; aliyunOSSProperties.&lt;span style="color:#a6e22e"&gt;getBucketName&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String region &lt;span style="color:#f92672"&gt;=&lt;/span&gt; aliyunOSSProperties.&lt;span style="color:#a6e22e"&gt;getRegion&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 ......
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Data&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Component&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@ConfigurationProperties&lt;/span&gt;(prefix &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;aliyun.oss&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AliyunOSSProperties&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String endpoint; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String bucketName; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String region; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="全局异常处理器"&gt;全局异常处理器
&lt;/h1&gt;&lt;p&gt;无论程序在哪里抛出了异常，都能被这个处理器统一拦截，并返回一个优雅、格式统一的错误信息给前端或客户端&lt;/p&gt;
&lt;h2 id="注解"&gt;注解
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@RestControllerAdvice&lt;/code&gt;&lt;/strong&gt;：标记这是一个增强版的控制器，专门处理全局层面的逻辑&lt;code&gt;(@ControllerAdvice + @ResponseBody)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@ExceptionHandler&lt;/code&gt;&lt;/strong&gt;：指定具体的异常类型，当这种异常发生时，执行对应的方法。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="核心流程"&gt;核心流程：
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;异常发生&lt;/strong&gt;：Controller 或 Service 层抛出一个异常（如 &lt;code&gt;UserNotFoundException&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动捕获&lt;/strong&gt;：Spring 发现该异常未被内部 &lt;code&gt;try-catch&lt;/code&gt;，于是将其向上抛给全局处理器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;匹配处理&lt;/strong&gt;：处理器根据异常类型找到对应的处理方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;返回结果&lt;/strong&gt;：处理器将异常包装成一个通用的 &lt;code&gt;Result&lt;/code&gt; 对象（包含错误码、错误消息），转换成 JSON 返回。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestControllerAdvice&lt;/span&gt; &lt;span style="color:#75715e"&gt;// = @ControllerAdvice + @ResponseBody&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GlobalExceptionHandler&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 处理自定义业务异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt;(BusinessException.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleBusinessException&lt;/span&gt;(BusinessException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(e.&lt;span style="color:#a6e22e"&gt;getCode&lt;/span&gt;(), e.&lt;span style="color:#a6e22e"&gt;getMessage&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 处理参数验证异常 (如 @Valid 校验失败)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt;(MethodArgumentNotValidException.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleValidationException&lt;/span&gt;(MethodArgumentNotValidException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String msg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;getBindingResult&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getFieldError&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getDefaultMessage&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(400, msg);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 兜底：处理所有未知的运行异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt;(Exception.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleException&lt;/span&gt;(Exception e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; log.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;系统崩溃了，救命！&amp;#34;&lt;/span&gt;, e); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(500, &lt;span style="color:#e6db74"&gt;&amp;#34;服务器开小差了，请稍后再试&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;---------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleException&lt;/span&gt;(Exception e) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;发生异常: &amp;#34;&lt;/span&gt;, e); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;服务器发生异常，请稍后再试&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@ExceptionHandler&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Result &lt;span style="color:#a6e22e"&gt;handleDuplicateKeyException&lt;/span&gt;(DuplicateKeyException e) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 log.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;发生异常: &amp;#34;&lt;/span&gt;, e); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String msg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; e.&lt;span style="color:#a6e22e"&gt;getMessage&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; msg.&lt;span style="color:#a6e22e"&gt;indexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Duplicate entry&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String errMsg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; msg.&lt;span style="color:#a6e22e"&gt;substring&lt;/span&gt;(i); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; arr &lt;span style="color:#f92672"&gt;=&lt;/span&gt; errMsg.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; arr&lt;span style="color:#f92672"&gt;[&lt;/span&gt;2&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39; 已存在，请检查数据&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="会话技术"&gt;会话技术
&lt;/h1&gt;&lt;h2 id="cookie"&gt;Cookie
&lt;/h2&gt;&lt;h3 id="工作流程"&gt;工作流程
&lt;/h3&gt;&lt;p&gt;Cookie 的本质是通过 HTTP 响应头和请求头在外部交换数据：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;设置阶段&lt;/strong&gt;：服务器在响应（Response）中加入 &lt;code&gt;Set-Cookie&lt;/code&gt; 头部字段。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;存储阶段&lt;/strong&gt;：浏览器收到响应后，将 Cookie 内容保存在本地（内存或硬盘）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;携带阶段&lt;/strong&gt;：下次请求同一个域名时，浏览器会自动在请求（Request）头中加入 &lt;code&gt;Cookie&lt;/code&gt; 字段。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="缺点"&gt;缺点
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;缺点&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;存储能力&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;容量小&lt;/td&gt;
 &lt;td&gt;单个 Cookie 最大限制约为 &lt;strong&gt;4KB&lt;/strong&gt;，不适合存大数据。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;用户控制&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;可被禁用&lt;/td&gt;
 &lt;td&gt;用户可以在浏览器设置中完全禁止接收 Cookie，导致功能失效。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;安全性&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;不安全&lt;/td&gt;
 &lt;td&gt;默认明文存储在客户端，极易受到 &lt;strong&gt;XSS 攻击&lt;/strong&gt; 窃取或中间人篡改。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;访问限制&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;跨域限制&lt;/td&gt;
 &lt;td&gt;受到同源策略限制，Cookie 无法在不同的一级域名间直接共享。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;网络性能&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;占用带宽&lt;/td&gt;
 &lt;td&gt;每次 HTTP 请求都会自动携带相关 Cookie，增加了请求头体积，浪费流量。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;合规隐私&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;隐私问题&lt;/td&gt;
 &lt;td&gt;常用于行为追踪，可能触犯 GDPR 等隐私法规，令用户反感。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;生命周期&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;时效性&lt;/td&gt;
 &lt;td&gt;默认为会话级别（关闭浏览器即消失），除非开发者手动设置 &lt;code&gt;Max-Age&lt;/code&gt;。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;物理限制&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;无法跨设备&lt;/td&gt;
 &lt;td&gt;数据绑定在特定设备的特定浏览器上，无法实现手机/电脑端同步。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="典型场景与规避方案"&gt;典型场景与规避方案
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;敏感信息处理&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原则&lt;/strong&gt;：绝不在 Cookie 中存储密码、身份证号等敏感数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案&lt;/strong&gt;：仅存储加密后的 Token，并设置 &lt;code&gt;HttpOnly&lt;/code&gt; 属性以防止 JS 脚本读取。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;移动端开发&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;痛点&lt;/strong&gt;：部分原生 App 内置浏览器或某些移动端环境对 Cookie 支持不佳。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案&lt;/strong&gt;：在移动端或前后端分离架构中，优先考虑使用 &lt;strong&gt;JWT (JSON Web Token)&lt;/strong&gt; 并通过自定义 Header 传输。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;分布式/集群环境&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;痛点&lt;/strong&gt;：多台服务器之间无法直接共享保存在各自内存或浏览器关联的传统 Session。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案&lt;/strong&gt;：采用 &lt;strong&gt;分布式会话&lt;/strong&gt;（如 &lt;code&gt;Spring Session + Redis&lt;/code&gt;），将状态数据统一托管在外部缓存中。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="session"&gt;Session
&lt;/h2&gt;&lt;h3 id="工作原理"&gt;工作原理
&lt;/h3&gt;&lt;p&gt;Session 的核心在于服务器与浏览器之间的一个“约定”。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建：&lt;/strong&gt; 当用户第一次访问服务器时，服务器会为该用户创建一个唯一的 &lt;strong&gt;HttpSession&lt;/strong&gt; 对象，并生成一个唯一的 ID（通常称为 &lt;code&gt;JSESSIONID&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;传递：&lt;/strong&gt; 服务器通过 HTTP 响应头，将这个 &lt;code&gt;JSESSIONID&lt;/code&gt; 以 &lt;strong&gt;Cookie&lt;/strong&gt; 的形式发送给浏览器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;识别：&lt;/strong&gt; 当浏览器再次请求该服务器时，会自动在请求头中携带这个 &lt;code&gt;JSESSIONID&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检索：&lt;/strong&gt; 服务器根据收到的 ID，在内存中找到对应的 Session 对象&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="生命周期"&gt;生命周期
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;开始：&lt;/strong&gt; 用户第一次调用 &lt;code&gt;request.getSession()&lt;/code&gt; 时。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;超时：&lt;/strong&gt; 为了节省服务器内存，Session 不会永久存在。如果用户在一段时间内（默认通常是 30 分钟）没有任何操作，Session 会自动销毁。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="缺点-1"&gt;缺点
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;优势&lt;/th&gt;
 &lt;th&gt;劣势&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;开发难度&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;简单易用&lt;/strong&gt;：Java 原生支持，直接调用 &lt;code&gt;getAttribute&lt;/code&gt; 即可，逻辑清晰。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;依赖 Cookie&lt;/strong&gt;：如果客户端禁用了 Cookie，Session 就会失效（需额外处理 URL 重写）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;数据安全&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;安全性高&lt;/strong&gt;：敏感数据留在服务器，客户端只拿一个加密 ID，不容易被篡改。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;会话劫持&lt;/strong&gt;：如果 ID 被窃取，攻击者可以完全冒充用户身份（需 HTTPS 配合）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;性能表现&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;读写极快&lt;/strong&gt;：数据就在本地内存中，无需网络开销，适合单机小型应用。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;内存消耗&lt;/strong&gt;：用户多了会占满服务器内存。用户关浏览器不点退出，数据会白白占用内存直到超时。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;架构扩展&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;无需额外中间件&lt;/strong&gt;：单机部署时非常方便，不需要安装 Redis 等数据库。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;分布式困境&lt;/strong&gt;：多台服务器环境下，Session 不共享，会导致用户登录状态频繁丢失。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;数据类型&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;灵活&lt;/strong&gt;：可以存储复杂的 Java 对象，不需要像 Token 那样进行频繁的序列化转换。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;存储限制&lt;/strong&gt;：不能存太大的东西（如大列表、大图片），否则严重拖慢服务器性能。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="对比cookie"&gt;对比Cookie
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Cookie&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Session&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;存储位置&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;客户端（浏览器）&lt;/td&gt;
 &lt;td&gt;服务器端&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;安全性&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;较低（易被伪造或窃取）&lt;/td&gt;
 &lt;td&gt;较高（敏感数据不发送给客户端）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;存储容量&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;较小（通常单个 4KB）&lt;/td&gt;
 &lt;td&gt;较大（取决于服务器内存）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;数据类型&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;只能存储字符串&lt;/td&gt;
 &lt;td&gt;可以存储任意 Java 对象&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;性能影响&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;几乎不占用服务器资源&lt;/td&gt;
 &lt;td&gt;占用服务器内存，用户多时压力大&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="token令牌主流"&gt;⭐Token令牌（主流）
&lt;/h2&gt;&lt;h3 id="工作原理-1"&gt;工作原理
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1. 签发：&lt;/strong&gt; 当用户通过用户名和密码登录成功后，服务器会根据用户信息（如用户 ID）和一段只有服务器知道的“秘钥”，生成一个加密的字符串（即 Token）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 传输：&lt;/strong&gt; 服务器将这个 Token 作为响应体的一部分发送给浏览器。与 Session 不同，服务器此时&lt;strong&gt;不会&lt;/strong&gt;在自己的内存或数据库中保存这个 Token。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 存储：&lt;/strong&gt; 浏览器接收到 Token 后，通常将其存储在 &lt;code&gt;localStorage&lt;/code&gt;、&lt;code&gt;sessionStorage&lt;/code&gt; 或 &lt;code&gt;Cookie&lt;/code&gt; 中。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. 携带：&lt;/strong&gt; 当浏览器后续请求受保护的资源（如获取订单列表）时，会手动将 Token 放入 HTTP 请求头中（通常放在 &lt;code&gt;Authorization: Bearer &amp;lt;Token&amp;gt;&lt;/code&gt; 字段）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. 校验：&lt;/strong&gt; 服务器接收到请求后，不再去查找数据库或内存，而是直接使用存储在服务器本地的“秘钥”对该 Token 进行解密和签名校验。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. 提取：&lt;/strong&gt; 如果校验通过，服务器就认为该请求是合法的，并直接从 Token 内部解密出用户信息（如该用户是“张三”），从而完成业务处理。&lt;/p&gt;
&lt;h3 id="jwt组成"&gt;JWT组成
&lt;/h3&gt;&lt;h4 id="header头部-说明书"&gt;Header（头部）—— “说明书”
&lt;/h4&gt;&lt;p&gt;这部分用于描述 JWT 的元数据，告诉服务器如何处理这个令牌。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内容：&lt;/strong&gt; 通常包含令牌的类型（&lt;code&gt;typ&lt;/code&gt;: &amp;ldquo;JWT&amp;rdquo;）和所使用的加密算法（&lt;code&gt;alg&lt;/code&gt;: 如 &amp;ldquo;HS256&amp;rdquo; 或 &amp;ldquo;RS256&amp;rdquo;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编码：&lt;/strong&gt; 使用 &lt;strong&gt;Base64URL&lt;/strong&gt; 算法进行编码。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	{ &lt;span style="color:#e6db74"&gt;&amp;#34;alg&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;HS256&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;typ&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;JWT&amp;#34;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="payload有效载荷-货物"&gt;Payload（有效载荷）—— “货物”
&lt;/h4&gt;&lt;p&gt;这是 JWT 的核心部分，包含了实际要传递的用户信息（Claims）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标准字段：&lt;/strong&gt; 如签发人（&lt;code&gt;iss&lt;/code&gt;）、过期时间（&lt;code&gt;exp&lt;/code&gt;）、用户 ID（&lt;code&gt;sub&lt;/code&gt;）等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自定义字段：&lt;/strong&gt; 你可以放入用户的角色、权限、姓名等（例如：&lt;code&gt;&amp;quot;role&amp;quot;: &amp;quot;admin&amp;quot;&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编码：&lt;/strong&gt; 同样使用 &lt;strong&gt;Base64URL&lt;/strong&gt; 编码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 这里的内容只是编码，并不是加密。&lt;strong&gt;绝对不要在此处存放密码或敏感信息&lt;/strong&gt;，因为任何人拿到 Token 都能通过解码看到里面的内容。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#e6db74"&gt;&amp;#34;sub&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;ZhangSan&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#e6db74"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Java-Dev&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#e6db74"&gt;&amp;#34;exp&amp;#34;&lt;/span&gt;: 1746144000 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="signature签名-防伪封条"&gt;Signature（签名）—— “防伪封条”
&lt;/h4&gt;&lt;p&gt;这是保证安全的关键。它用于验证 Token 在传输过程中是否被篡改。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;生成原理：&lt;/strong&gt; 服务器将编码后的 &lt;code&gt;Header&lt;/code&gt; 和 &lt;code&gt;Payload&lt;/code&gt; 用点拼接起来，再加上一个只有服务器知道的&lt;strong&gt;密钥（Secret）&lt;/strong&gt;，按照 Header 中指定的算法进行哈希计算。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt; 如果有人修改了 Payload 里的用户权限（比如把 &lt;code&gt;user&lt;/code&gt; 改成 &lt;code&gt;admin&lt;/code&gt;），由于他没有服务器的密钥，生成的签名就会和原来的不匹配。服务器校验失败，该 Token 立即失效。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-Secret" data-lang="Secret"&gt;	a-string-secret-at-least-256-bits-long
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="总结外观"&gt;总结外观
&lt;/h4&gt;&lt;p&gt;一个完整的 JWT 看起来像这样：
&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.&lt;/code&gt;
&lt;code&gt;eyJzdWIiOiJaaGFuZ3NhbiIsInJvbGUiOiJKYXZhLURldiIsImV4cCI6MTc0NjE0NDAwMH0.&lt;/code&gt;
&lt;code&gt;MJSEga1Hm1wHRnaCKpjSzXcr7DpI3TlhDQoGcIWnXDA&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;xxxxx.yyyyy.zzzzz&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;红色部分 (xxxxx):&lt;/strong&gt; 头部，声明算法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;蓝色部分 (yyyyy):&lt;/strong&gt; 负载，存放用户信息。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;绿色部分 (zzzzz):&lt;/strong&gt; 签名，由前两部分加盐哈希而成&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="jwr生成解析"&gt;JWR生成/解析
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; String SECRET &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;基于base64的字符串（字节数必须大于32）&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; SecretKey KEY &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Keys.&lt;span style="color:#a6e22e"&gt;hmacShaKeyFor&lt;/span&gt;(SECRET.&lt;span style="color:#a6e22e"&gt;getBytes&lt;/span&gt;(StandardCharsets.&lt;span style="color:#a6e22e"&gt;UTF_8&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testGenerateJwt&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Map&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String, Object&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; dataMap &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dataMap.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;userId&amp;#34;&lt;/span&gt;, 1); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dataMap.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String token &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Jwts.&lt;span style="color:#a6e22e"&gt;builder&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;claims&lt;/span&gt;(dataMap) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;expiration&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date(System.&lt;span style="color:#a6e22e"&gt;currentTimeMillis&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 3600 &lt;span style="color:#f92672"&gt;*&lt;/span&gt; 1000)) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;signWith&lt;/span&gt;(KEY) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;compact&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(token); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testParseJwt&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String token &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;JWT得到的Token&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Claims claims &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Jwts.&lt;span style="color:#a6e22e"&gt;parser&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;verifyWith&lt;/span&gt;(KEY) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;() 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;parseSignedClaims&lt;/span&gt;(token) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;getPayload&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(claims); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="cookiesessiontoken对比"&gt;&lt;code&gt;Cookie,Session,Token&lt;/code&gt;对比
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Cookie&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Session&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Token (JWT)&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;定义&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;存储在浏览器端的一段文本。&lt;/td&gt;
 &lt;td&gt;服务器端的一种会话记录机制。&lt;/td&gt;
 &lt;td&gt;一段经过加密/签名的凭证字符串。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;核心位置&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;客户端&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;服务器&lt;/strong&gt;（内存/数据库/Redis）&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;客户端&lt;/strong&gt;（服务器不存储）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;工作逻辑&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;浏览器自动携带。&lt;/td&gt;
 &lt;td&gt;依赖 Session ID 匹配服务器记录。&lt;/td&gt;
 &lt;td&gt;客户端手动放入 Header，服务器解密。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;安全性&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;较低，容易被拦截或伪造。&lt;/td&gt;
 &lt;td&gt;较高，敏感信息存在服务器。&lt;/td&gt;
 &lt;td&gt;高，有签名校验，防篡改。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;扩展性&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;无。&lt;/td&gt;
 &lt;td&gt;差，多台服务器需做数据同步。&lt;/td&gt;
 &lt;td&gt;极佳，天然支持跨服务器、跨域。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;存储压力&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;无（存在用户本地）。&lt;/td&gt;
 &lt;td&gt;较大，用户多时会消耗大量服务器内存。&lt;/td&gt;
 &lt;td&gt;无（存在用户本地）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src="web%e5%90%8e%e7%ab%af%e5%ae%9e%e6%88%98-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="优点对比"&gt;优点对比
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Cookie (客户端存储)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Session (服务端存储)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Token (无状态令牌/JWT)&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;最大优势&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;减轻服务器压力&lt;/strong&gt;：数据存用户本地，服务器不占内存。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;数据最安全&lt;/strong&gt;：敏感信息不发给客户端，只在服务器内部。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;极易水平扩展&lt;/strong&gt;：服务器不存任何数据，非常适合微服务/集群。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;生命周期&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;持久性好&lt;/strong&gt;：可以设置长达数天的有效期，甚至关机后再开也存在。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;控制力强&lt;/strong&gt;：服务器可以随时主动让某个特定用户下线。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;性能均衡&lt;/strong&gt;：不需要查数据库或缓存，服务器解析 Token 即可校验身份。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;开发难度&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;最简单&lt;/strong&gt;：浏览器原生支持，几乎不需要写代码逻辑。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;非常简单&lt;/strong&gt;：成熟的框架（如 Spring）自动处理 ID 传递。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;跨域支持完美&lt;/strong&gt;：不受浏览器跨域限制，App、小程序、H5 通用。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;存储能力&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;随用随取&lt;/strong&gt;：适合存偏好设置（如主题颜色、语言）。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;类型多样&lt;/strong&gt;：可以存复杂的 Java 对象（用户角色、权限列表）。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;自包含&lt;/strong&gt;：Token 内部可以携带用户信息，减少后端查询次数。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="过滤器filter"&gt;过滤器Filter
&lt;/h1&gt;&lt;h2 id="核心作用"&gt;核心作用
&lt;/h2&gt;&lt;p&gt;过滤器主要用于处理一些&lt;strong&gt;通用性&lt;/strong&gt;的横切关注点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;权限校验&lt;/strong&gt;：检查请求头中是否携带有效的 JWT Token。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;字符编码转换&lt;/strong&gt;：统一设置 &lt;code&gt;request&lt;/code&gt; 和 &lt;code&gt;response&lt;/code&gt; 的编码（如 UTF-8）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日志记录&lt;/strong&gt;：统计接口的访问耗时、记录请求来源 IP。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;敏感词过滤&lt;/strong&gt;：对用户提交的内容进行安全扫描。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="工作原理责任链模式"&gt;工作原理：责任链模式
&lt;/h2&gt;&lt;p&gt;过滤器并不是独立存在的，它们通常组成一个&lt;strong&gt;过滤器链 (FilterChain)&lt;/strong&gt;。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;执行前处理&lt;/strong&gt;：请求进入时，过滤器先执行 &lt;code&gt;doFilter&lt;/code&gt; 方法中 &lt;code&gt;chain.doFilter()&lt;/code&gt; 之前的代码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;放行（传递）&lt;/strong&gt;：调用 &lt;code&gt;chain.doFilter(request, response)&lt;/code&gt;。如果有下一个过滤器，就传给下一个；如果没有，就传给 Servlet（或 Controller）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;执行后处理&lt;/strong&gt;：当核心业务处理完返回响应时，代码会回到 &lt;code&gt;chain.doFilter()&lt;/code&gt; 之后，执行后续逻辑。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="执行顺序"&gt;执行顺序
&lt;/h2&gt;&lt;pre&gt;
$$Filter \rightarrow Controller \rightarrow Service \rightarrow Mapper \rightarrow DB$$
$$\uparrow \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \downarrow$$
$$Filter(回程) \leftarrow Controller \leftarrow Service \leftarrow Mapper$$
&lt;/pre&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;[&lt;/span&gt;浏览器请求&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;┌──────&lt;/span&gt; Filter (去程&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;校验Token&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;记录时间) &lt;span style="color:#960050;background-color:#1e0010"&gt;──────┐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;┌────&lt;/span&gt; Controller (解析请求&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;参数校验) &lt;span style="color:#960050;background-color:#1e0010"&gt;────┐&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;┌──&lt;/span&gt; Service (业务逻辑处理) &lt;span style="color:#960050;background-color:#1e0010"&gt;────────┐&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;┌&lt;/span&gt; Mapper (SQL执行) &lt;span style="color:#960050;background-color:#1e0010"&gt;──┐&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt; 数据库 DB &lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; (返回结果) &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└────────────────────────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└──&lt;/span&gt; Service (业务结果组装) &lt;span style="color:#960050;background-color:#1e0010"&gt;────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└────&lt;/span&gt; Controller (封装结果对象) &lt;span style="color:#960050;background-color:#1e0010"&gt;─────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#960050;background-color:#1e0010"&gt;└──────&lt;/span&gt; Filter (回程&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;清理ThreadLocal&lt;span style="color:#960050;background-color:#1e0010"&gt;、&lt;/span&gt;日志打印) &lt;span style="color:#960050;background-color:#1e0010"&gt;┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#f92672"&gt;[&lt;/span&gt;返回响应&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//-- 这种图强调了 Filter 是最外层，它包裹着所有的内部组件：--&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		( ( ( ( &lt;span style="color:#f92672"&gt;[&lt;/span&gt; 数据库 DB &lt;span style="color:#f92672"&gt;]&lt;/span&gt; ) ) ) )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▲&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└─────┴───┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└────&lt;/span&gt; Mapper &lt;span style="color:#960050;background-color:#1e0010"&gt;─────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└───────&lt;/span&gt; Service &lt;span style="color:#960050;background-color:#1e0010"&gt;─────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└──────────&lt;/span&gt; Controller &lt;span style="color:#960050;background-color:#1e0010"&gt;───────────┘&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└─────────────&lt;/span&gt; Filter &lt;span style="color:#960050;background-color:#1e0010"&gt;──────────────────┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;请求进入&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;响应返回&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;去程：&lt;/strong&gt; &lt;code&gt;Client&lt;/code&gt; $\rightarrow$ &lt;code&gt;Filter&lt;/code&gt; $\rightarrow$ &lt;code&gt;Controller&lt;/code&gt; $\rightarrow$ &lt;code&gt;Service&lt;/code&gt; $\rightarrow$ &lt;code&gt;Mapper&lt;/code&gt; $\rightarrow$ &lt;code&gt;DB&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心：&lt;/strong&gt; 数据库执行查询/更新&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;回程：&lt;/strong&gt; &lt;code&gt;DB&lt;/code&gt; $\rightarrow$ &lt;code&gt;Mapper&lt;/code&gt; $\rightarrow$ &lt;code&gt;Service&lt;/code&gt; $\rightarrow$ &lt;code&gt;Controller&lt;/code&gt; $\rightarrow$ &lt;code&gt;Filter&lt;/code&gt; $\rightarrow$ &lt;code&gt;Client&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&amp;mdash;页尾&amp;mdash;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="注意事项-1"&gt;注意事项
&lt;/h1&gt;&lt;h2 id="pathvariable与requestparam"&gt;@PathVariable与@RequestParam
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;方式&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;前端URL&lt;/th&gt;
 &lt;th&gt;后端请求&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;什么时候用？&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;精准定位&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;/clazzs/5&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;/{id}&lt;/code&gt; + &lt;code&gt;@PathVariable&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;删除单个 ID&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;带清单操作&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;/clazzs?ids=1,2,3&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;(无路径)&lt;/code&gt; + &lt;code&gt;@RequestParam&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;批量删除&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;路径串烧&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;/clazzs/1,2,3&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;/{ids}&lt;/code&gt; + &lt;code&gt;@PathVariable&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;极少用，除非有特殊设计需求&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="xml的更新语句"&gt;&lt;code&gt;xml&lt;/code&gt;的更新语句
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;字段类型&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;业务要求&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;&lt;if&gt; 判定表达式&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;避坑指南&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;String&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;必填&lt;/strong&gt; (非空且非空串)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;test=&amp;quot;name != null and name != ''&amp;quot;&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;这样可以防止前端传个空字符串 &lt;code&gt;&amp;quot;&amp;quot;&lt;/code&gt; 导致数据库存入无意义数据。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;String&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;允许置空&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;test=&amp;quot;address != null&amp;quot;&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;注意：&lt;/strong&gt; 这样如果传 &lt;code&gt;&amp;quot;&amp;quot;&lt;/code&gt;，它会判定为非 null，从而把空串插入数据库。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Integer / 数字&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;必填&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;test=&amp;quot;id != null&amp;quot;&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;绝对不要加&lt;/strong&gt; &lt;code&gt;and id != ''&lt;/code&gt;！如果 id 为 0，MyBatis 可能会误判它等于空串，导致 0 存不进去。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Integer / 数字&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;允许置空&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;test=&amp;quot;degree != null&amp;quot;&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;同上，只判断 null 即可。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;操作类型&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;字段类型&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;推荐写法&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;理由&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;SELECT&lt;/strong&gt; (搜索)&lt;/td&gt;
 &lt;td&gt;任何类型&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;!= null and != ''&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;防前端传空搜索框&lt;/strong&gt;导致的“查无数据”。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;UPDATE&lt;/strong&gt; (更新)&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;String&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;!= null and != ''&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;过滤无效空串，保证数据严谨。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;UPDATE&lt;/strong&gt; (更新)&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Integer&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;!= null&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;最安全&lt;/strong&gt;，防止 &lt;code&gt;0&lt;/code&gt; 值无法更新。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;INSERT&lt;/strong&gt; (插入)&lt;/td&gt;
 &lt;td&gt;任何类型&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;!= null&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;通常只为了防止 null 值覆盖数据库默认值。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>Web</title><link>/post/web/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><guid>/post/web/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="springbootweb基础"&gt;SpringBootWeb基础
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;* 请求处理类 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;* */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;HelloController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 响应返回值 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/Hello&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;Hello&lt;/span&gt;(String name){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;name); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; name &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;~&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="http协议"&gt;&lt;a class="link" href="%e5%9f%ba%e7%a1%80#HTTP" &gt;HTTP协议&lt;/a&gt;
&lt;/h1&gt;&lt;p&gt;概念:&lt;code&gt;Hyper Text Transfer Protocol&lt;/code&gt;，超文本传输协议，规定了浏览器和服务器之间数据传输的规则&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点:&lt;/strong&gt;
&lt;ol&gt;
&lt;li&gt;基于TCP协议：面向连接，安全&lt;/li&gt;
&lt;li&gt;基于请求-响应模型的：一次请求对应一次响应&lt;/li&gt;
&lt;li&gt;HTTP协议是&lt;strong&gt;无状态&lt;/strong&gt;的协议：对于事务处理没有记忆能力。每次请求-响应都是独立的。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;li&gt;缺点:多次请求间不能共享数据。&lt;/li&gt;
&lt;li&gt;优点:速度快&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="请求协议"&gt;请求协议
&lt;/h2&gt;&lt;h3 id="请求数据格式"&gt;请求数据格式
&lt;/h3&gt;&lt;p&gt;&lt;img src="Web-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h4 id="请求行-request-line"&gt;请求行 (Request Line)
&lt;/h4&gt;&lt;p&gt;包含三个核心信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求方法&lt;/strong&gt;：&lt;code&gt;GET&lt;/code&gt;、&lt;code&gt;POST&lt;/code&gt;、&lt;code&gt;PUT&lt;/code&gt;、&lt;code&gt;DELETE&lt;/code&gt; 等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;资源路径&lt;/strong&gt;：例如 &lt;code&gt;/api/v1/users&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;协议版本&lt;/strong&gt;：通常是 &lt;code&gt;HTTP/1.1&lt;/code&gt; 或 &lt;code&gt;HTTP/2&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;示例：&lt;code&gt;POST /login HTTP/1.1&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="请求头-request-headers"&gt;请求头 (Request Headers)
&lt;/h4&gt;&lt;p&gt;用键值对（&lt;code&gt;Key: Value&lt;/code&gt;）的形式告知服务器客户端的环境、权限以及&lt;strong&gt;数据格式&lt;/strong&gt;。常见头信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Host&lt;/code&gt;&lt;/strong&gt;: 服务器域名。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;User-Agent&lt;/code&gt;&lt;/strong&gt;: 客户端浏览器或系统信息。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Content-Type&lt;/code&gt;&lt;/strong&gt;: &lt;strong&gt;最重要的字段&lt;/strong&gt;，告诉服务器请求体里装的是什么格式的数据（如 JSON 或表单）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Authorization&lt;/code&gt;&lt;/strong&gt;: 携带 Token 进行登录校验。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="空行-empty-line"&gt;空行 (Empty Line)
&lt;/h4&gt;&lt;p&gt;必须存在的一行空行，用于分隔“报头”和“数据体”。&lt;/p&gt;
&lt;h4 id="请求体-request-body"&gt;请求体 (Request Body)
&lt;/h4&gt;&lt;p&gt;真正传输的数据。注意：&lt;code&gt;GET&lt;/code&gt; 请求通常没有请求体（参数放在 URL 后），而 &lt;code&gt;POST&lt;/code&gt;、&lt;code&gt;PUT&lt;/code&gt; 请求通常将数据放在这里。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="请求数据获取"&gt;请求数据获取
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RequestController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/request&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;request&lt;/span&gt;(HttpServletRequest request) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求方式 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String method &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getMethod&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求方式:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; method); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求url地址 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getRequestURL&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//http://localhost:8080/request &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求url地址:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; url); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String uri &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getRequestURI&lt;/span&gt;();&lt;span style="color:#75715e"&gt;//request &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求uri地址:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; uri); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求协议 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String protocol &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getProtocol&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求协议:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; protocol); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求参数 - name &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getParameter&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getParameter&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;age&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求参数name:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; name &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;,age:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; age); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//获取请求头 - Accept &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String accept &lt;span style="color:#f92672"&gt;=&lt;/span&gt; request.&lt;span style="color:#a6e22e"&gt;getHeader&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;请求头Accept:&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; accept); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;OKK&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;URL (Uniform Resource Locator)&lt;/strong&gt;：资源的&lt;strong&gt;路径&lt;/strong&gt;。它像家庭住址：&lt;code&gt;http://localhost:8080/request&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;URI (Uniform Resource Identifier)&lt;/strong&gt;：资源的&lt;strong&gt;身份证&lt;/strong&gt;。它只关心资源本身：&lt;code&gt;/request&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;面试题：&lt;/strong&gt; 所有的 URL 都是 URI，但不是所有的 URI 都是 URL&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="响应协议"&gt;响应协议
&lt;/h2&gt;&lt;h3 id="响应数据格式"&gt;响应数据格式
&lt;/h3&gt;&lt;p&gt;&lt;img src="Web-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h4 id="响应行"&gt;响应行
&lt;/h4&gt;&lt;p&gt;协议版本 + 状态码 + 状态描述&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例如：&lt;code&gt;HTTP/1.1 200 OK&lt;/code&gt; 或 &lt;code&gt;HTTP/1.1 404 Not Found&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="响应头"&gt;响应头
&lt;/h4&gt;&lt;p&gt;服务器告知客户端的数据元信息。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Content-Type&lt;/code&gt;&lt;/strong&gt;: &lt;strong&gt;最关键&lt;/strong&gt;。告知浏览器数据格式（如 &lt;code&gt;application/json&lt;/code&gt; 或 &lt;code&gt;text/html&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Set-Cookie&lt;/code&gt;&lt;/strong&gt;: 服务器给客户端种下的“小饼干”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="空行"&gt;&lt;strong&gt;空行&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;分隔头部与内容。&lt;/p&gt;
&lt;h4 id="响应体"&gt;响应体
&lt;/h4&gt;&lt;p&gt;真正传回给前端的数据（HTML、JSON、图片字节流等）&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;HTTP 状态码&lt;/th&gt;
 &lt;th&gt;含义说明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;1xx&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;响应中 - 临时状态码，表示请求已经接收，告诉客户端应该继续请求或者如果它已经完成则忽略它。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;2xx&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;成功 - 表示请求已经被成功接收，处理已完成。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;3xx&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;重定向 - 重定向到其他地方；让客户端再发起一次请求以完成整个处理。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;4xx&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;客户端错误 - 处理发生错误，责任在客户端。如：请求了不存在的资源、客户端未被授权、禁止访问等。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;5xx&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;服务器错误 - 处理发生错误，责任在服务端。如：程序抛出异常等。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;最常见状态码：&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;状态码&lt;/th&gt;
 &lt;th&gt;英文描述&lt;/th&gt;
 &lt;th&gt;解释&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;200&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;OK&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;请求成功，服务器正常处理并返回资源&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;404&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;Not Found&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;请求的资源不存在&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;500&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;Internal Server Error&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;服务器内部错误，无法完成请求&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;字段解释：&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;响应头字段&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;含义说明&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;Content-Type&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;表示该响应内容的类型，例如&lt;code&gt;text/html&lt;/code&gt;, &lt;code&gt;application/json&lt;/code&gt;。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;Content-Length&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;表示该响应内容的长度（字节数）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;Content-Encoding&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;表示该响应压缩算法，例如&lt;code&gt;gzip&lt;/code&gt;。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;Cache-Control&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;指示客户端应如何缓存，例如&lt;code&gt;max-age=300&lt;/code&gt;表示可以最多缓存 300 秒。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;Set-Cookie&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;告诉浏览器为当前页面所在的域设置 cookie。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="响应数据设置"&gt;响应数据设置
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ResponseController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/response&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;(HttpServletResponse response) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; IOException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//设置响应状态码 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; response.&lt;span style="color:#a6e22e"&gt;setStatus&lt;/span&gt;(401); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//设置响应头 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; response.&lt;span style="color:#a6e22e"&gt;setHeader&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;itcast&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//设置响应体 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; response.&lt;span style="color:#a6e22e"&gt;getWriter&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;h1&amp;gt;Hello Response&amp;lt;/h1&amp;gt;&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 方法二 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 基于ResponseEntity构建响应对象 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/response2&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; ResponseEntity&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response2&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ResponseEntity 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;status&lt;/span&gt;(401) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;header&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;javaweb&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;h1&amp;gt;Hello ResponseEntity&amp;lt;/h1&amp;gt;&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="案例"&gt;案例
&lt;/h1&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//UserController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 用户信息Controller 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/list&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; FileNotFoundException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//加载并读取user.txt &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; InputStream in &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getClassLoader&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getResourceAsStream&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;user.txt&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; lines &lt;span style="color:#f92672"&gt;=&lt;/span&gt; IoUtil.&lt;span style="color:#a6e22e"&gt;readLines&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (in, StandardCharsets.&lt;span style="color:#a6e22e"&gt;UTF_8&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//解析用户信息，封装为User对象，list集合 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; userList &lt;span style="color:#f92672"&gt;=&lt;/span&gt; lines.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(line &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; parts &lt;span style="color:#f92672"&gt;=&lt;/span&gt; line.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Integer id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String username &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String password &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;2&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;3&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Integer age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;4&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LocalDateTime updateTime &lt;span style="color:#f92672"&gt;=&lt;/span&gt; LocalDateTime.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;5&lt;span style="color:#f92672"&gt;]&lt;/span&gt;, DateTimeFormatter.&lt;span style="color:#a6e22e"&gt;ofPattern&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; User(id, username, password, name, age, updateTime); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;toList&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//返回数据json &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; userList; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//User&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Data&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@NoArgsConstructor&lt;/span&gt; &lt;span style="color:#75715e"&gt;// &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@AllArgsConstructor&lt;/span&gt; &lt;span style="color:#75715e"&gt;//全参 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;User&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer id; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String username; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String password; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Integer age; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; LocalDateTime updateTime; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;1.静态资源文件存放位置&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;resources/static&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2.@ResponseBody 注解的作用&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将 controller 方法的返回值直接写入 HTTP 响应体&lt;/li&gt;
&lt;li&gt;如果是对象或集合，会先转为 json，再响应&lt;/li&gt;
&lt;li&gt;@RestController = @Controller + @ResponseBody&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h1 id="分层解耦"&gt;分层解耦
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;耦合:&lt;/strong&gt; 衡量软件中各个层/各个模块的依赖关联程度。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;内聚:&lt;/strong&gt; 软件中各个功能模块内部的功能联系。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设计原则： 高内聚低耦合&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="三层架构"&gt;三层架构
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;层次名称&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;对应英文&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;核心注解&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;职责描述（通俗理解）&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;控制层&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Controller&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;@RestController&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;门面&lt;/strong&gt;。负责接收请求、校验参数，并把结果响应给前端。它不负责处理业务。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;业务逻辑层&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Service&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;@Service&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;大脑&lt;/strong&gt;。负责所有的计算、逻辑判断、事务管理。它是系统最核心的部分。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;数据访问层&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;dao&lt;/strong&gt;(Data Access Object)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;@Repository&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;搬运工&lt;/strong&gt;。负责与数据库打交道，进行增删改查（CRUD）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="controller"&gt;Controller
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 用户信息Controller 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserServiceImpl(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;多态的实现&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RequestMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/list&amp;#34;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; FileNotFoundException { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService.&lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;多态的实现&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; list; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="service"&gt;Service
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//接口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserService&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; *查询所有用户信息 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//实现类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//带impl就是一个实现类 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserService { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserDao userDao &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserDaoImpl(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;*&lt;/span&gt;多态的实现&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; lines &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userDao.&lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;多态的实现&lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;User&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; userList &lt;span style="color:#f92672"&gt;=&lt;/span&gt; lines.&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(line &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; parts &lt;span style="color:#f92672"&gt;=&lt;/span&gt; line.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Integer id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String username &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String password &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;2&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;3&lt;span style="color:#f92672"&gt;]&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Integer age &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;4&lt;span style="color:#f92672"&gt;]&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LocalDateTime updateTime &lt;span style="color:#f92672"&gt;=&lt;/span&gt; LocalDateTime.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(parts&lt;span style="color:#f92672"&gt;[&lt;/span&gt;5&lt;span style="color:#f92672"&gt;]&lt;/span&gt;, DateTimeFormatter.&lt;span style="color:#a6e22e"&gt;ofPattern&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; User(id, username, password, name, age, updateTime); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;toList&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; userList; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="dao"&gt;Dao
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//接口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserDao&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * 加载用户数据 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * */&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//实现类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserDaoImpl&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserDao { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; List&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;findAll&lt;/span&gt;() { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; InputStream in &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getClassLoader&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getResourceAsStream&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;user.txt&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; lines &lt;span style="color:#f92672"&gt;=&lt;/span&gt; IoUtil.&lt;span style="color:#a6e22e"&gt;readLines&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (in, StandardCharsets.&lt;span style="color:#a6e22e"&gt;UTF_8&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ArrayList&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;()); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; lines; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="Web-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;
&lt;img src="Web-4.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="控制反转ioc-依赖注入di-bean对象"&gt;控制反转（IOC）&amp;amp; 依赖注入（DI）&amp;amp; Bean对象
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;对象的创建控制权由程序自身转移到外部(容器)，这种思想称为控制反转&lt;/li&gt;
&lt;li&gt;容器为应用程序提供运行时，所依赖的资源，称之为依赖注入&lt;/li&gt;
&lt;li&gt;IOC容器中创建、管理的对象，称之为Bean
&lt;img src="Web-5.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;
&lt;img src="Web-6.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ioc详解"&gt;IOC详解
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;如何将一个类交给 IOC 容器管理？&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@Component&lt;/code&gt;（注意：是加在实现类上，而非接口上）&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;如何从 IOC 容器中找到该类型的 bean，然后完成依赖注入？&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@Autowired&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;@Component时声明bean的基础注解
其他三个是@Component的衍生注解&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;注解&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;适用层级&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;语义描述&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@Component&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;通用组件&lt;/td&gt;
 &lt;td&gt;不属于以下三类时，用此注解（如工具类、配置类）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@Controller&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;标注在&lt;strong&gt;控制层类&lt;/strong&gt; (Web)&lt;/td&gt;
 &lt;td&gt;负责处理 HTTP 请求，分发数据。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@Service&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;标注在&lt;strong&gt;业务逻辑层类&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;负责核心业务逻辑处理、事务管理。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@Repository&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;标注在&lt;strong&gt;数据访问层类&lt;/strong&gt; (Dao)&lt;/td&gt;
 &lt;td&gt;负责数据库的增删改查，并能将原生数据库异常转为 Spring 异常。（由于与&lt;a class="link" href="MySQL/JDBC%20&amp;amp;%20Mybatis.md#Mybatis" &gt;mybatis&lt;/a&gt;整合，用的少）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!warning]
❗：@RestController 注解内部已经包含 @Controller&lt;/p&gt;
&lt;p&gt;❗：声明bean的时候，可以通过注解的value属性指定bean的名字，如果没有指定，默认为类名首字母小写&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="Web-7.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="di详解"&gt;DI详解
&lt;/h3&gt;&lt;h4 id="基于autowired进行依赖注入的常见方式"&gt;基于@Autowired进行依赖注入的常见方式
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;①.属性注入&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;这是最常见、最简洁的方式。直接在成员变量上加上 &lt;code&gt;@Autowired&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService; &lt;span style="color:#75715e"&gt;// 直接注入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：代码极其简洁，可读性好。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不能使用 &lt;code&gt;final&lt;/code&gt; 修饰变量&lt;/strong&gt;（因为变量必须在对象实例化后通过反射注入）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;隐藏依赖关系&lt;/strong&gt;：外部不通过反射很难看到这个类到底依赖了谁。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;违背单一职责原则&lt;/strong&gt;：因为写起来太简单，容易导致一个类注入了过多的依赖。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;②.构造器注入&lt;/strong&gt;—Spring官方推荐&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;通过类的构造函数来完成注入。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Service&lt;/span&gt; &lt;span style="color:#75715e"&gt;//将当前类给IOC容器管理 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserService { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; UserDao userDao; &lt;span style="color:#75715e"&gt;//可以是final&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt; &lt;span style="color:#75715e"&gt;//可省略！&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl&lt;/span&gt;(UserDao userDao) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;userDao&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userDao; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;支持 &lt;code&gt;final&lt;/code&gt; 关键字&lt;/strong&gt;：保证了依赖在对象创建后不可变，更加安全。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;完全初始化&lt;/strong&gt;：确保对象在被调用前，所有依赖都已就绪。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;易于测试&lt;/strong&gt;：在写单元测试时，可以直接通过 &lt;code&gt;new&lt;/code&gt; 一个对象并传入 Mock 依赖，不需要启动整个 Spring 容器。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：如果类中只有一个构造函数，Spring 4.3 以后可以省略 &lt;code&gt;@Autowired&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;③.Setter方法注入&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;通过对应的 &lt;code&gt;setXxx&lt;/code&gt; 方法来注入依赖。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setUserService&lt;/span&gt;(UserService userService) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;userService&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：允许依赖在之后被修改（灵活性高）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不能使用 &lt;code&gt;final&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对象在被使用时可能处于“未完全初始化”的状态（如果没调用 set 方法）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;对比：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;注入方式&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;是否推荐&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;支持 final&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;优点&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;缺点&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;属性注入&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;慎用&lt;/td&gt;
 &lt;td&gt;否&lt;/td&gt;
 &lt;td&gt;简单、快&lt;/td&gt;
 &lt;td&gt;依赖关系不透明，不方便单元测试&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;构造器注入&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;强烈推荐&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;是&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;安全、强制初始化、方便测试&lt;/td&gt;
 &lt;td&gt;代码略显冗长&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Setter 注入&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;可选&lt;/td&gt;
 &lt;td&gt;否&lt;/td&gt;
 &lt;td&gt;灵活，可按需注入&lt;/td&gt;
 &lt;td&gt;无法保证对象完整性&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h4 id="当出现多个相同类型的bean就会报错如何解决"&gt;当出现多个相同类型的Bean就会报错，如何解决？
&lt;/h4&gt;&lt;p&gt;&lt;img src="Web-8.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;
&lt;strong&gt;①使用 @Primary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你希望在大多数情况下都使用某个特定的实现类，可以在该类上加上 &lt;code&gt;@Primary&lt;/code&gt; 注解。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;效果&lt;/strong&gt;：当存在多个候选 Bean 时，Spring 会优先注入标注了 &lt;code&gt;@Primary&lt;/code&gt; 的那一个&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JAVA" data-lang="JAVA"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Primary&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl1&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserService { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ... &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserServiceImpl2&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; UserService { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ... &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;②使用@Qualifier(指定具体的名称)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你想在不同的地方注入不同的实现，可以配合 &lt;code&gt;@Autowired&lt;/code&gt; 使用 &lt;code&gt;@Qualifier&lt;/code&gt;，并指定 Bean 的名称。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：Bean 的默认名称是&lt;strong&gt;类名首字母小写&lt;/strong&gt;（如 &lt;code&gt;userServiceImpl1&lt;/code&gt;），你也可以在注解中手动指定名称，如 &lt;code&gt;@Service(&amp;quot;userService2&amp;quot;)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Autowired&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Qualifier&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;userServiceImpl1&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 明确告诉 Spring：我要这一个&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;③使用@Resource(直接按名称查找)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@Resource&lt;/code&gt; 是 JDK 提供的注解（Spring 也支持）。
它与 &lt;code&gt;@Autowired&lt;/code&gt; 的最大区别在于&lt;strong&gt;查找顺序&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@Autowired&lt;/code&gt;&lt;/strong&gt;：先按&lt;strong&gt;类型&lt;/strong&gt;找，如果类型有多个，再按名称找。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@Resource&lt;/code&gt;&lt;/strong&gt;：先按&lt;strong&gt;名称&lt;/strong&gt;找，如果名称找不到，再按类型找。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@RestController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UserController&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Resource&lt;/span&gt;(name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;userServiceImpl2&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 直接通过名字“精准定位”&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;解决方案&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;核心原理&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@Primary&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;权重优先&lt;/td&gt;
 &lt;td&gt;存在一个“绝对主流”的实现类时。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@Qualifier&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;类型&lt;/strong&gt; + 名称辅助&lt;/td&gt;
 &lt;td&gt;需要在不同类中灵活切换不同实现时。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@Resource&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;名称&lt;/strong&gt;优先&lt;/td&gt;
 &lt;td&gt;想减少对 Spring 注解的依赖，或更倾向于按名字查找时。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="问题"&gt;问题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;问：“既然没有代码显式调用构造函数，Spring 是如何实现注入的？”&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这是通过 &lt;strong&gt;IoC 容器&lt;/strong&gt; 的生命周期管理实现的。Spring 启动时会解析 &lt;strong&gt;BeanDefinition&lt;/strong&gt;（Bean 的定义信息）。如果发现是构造器注入，Spring 会通过 &lt;strong&gt;反射&lt;/strong&gt; 查找匹配的参数 Bean，并利用 &lt;code&gt;Constructor.newInstance()&lt;/code&gt; 方法完成实例化。这种方式将对象的创建权交给了容器，实现了真正的控制反转。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;问：“如果你在代码里同时用了 &lt;code&gt;@Primary&lt;/code&gt; 和 &lt;code&gt;@Qualifier&lt;/code&gt;，谁会生效？”&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“&lt;strong&gt;&lt;code&gt;@Qualifier&lt;/code&gt; 的优先级更高&lt;/strong&gt;。因为 &lt;code&gt;@Primary&lt;/code&gt; 定义的是默认的首选 Bean，而 &lt;code&gt;@Qualifier&lt;/code&gt; 是在注入点进行的‘精准指名’。这就好比食堂默认提供大米饭（Primary），但你明确跟打饭阿姨说你要面条（Qualifier），阿姨肯定会给你面条。”&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="附录"&gt;附录
&lt;/h1&gt;&lt;h2 id="状态码大全"&gt;&lt;a class="link" href="https://cloud.tencent.com/developer/article/2138076" target="_blank" rel="noopener"
 &gt;状态码大全&lt;/a&gt;
&lt;/h2&gt;</description></item><item><title>Maven</title><link>/post/maven/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><guid>/post/maven/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-10&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;用于管理和构建Java项目的工具&lt;/li&gt;
&lt;li&gt;拥有本地仓库，中央仓库，远程仓库（私服）&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="-生命周期"&gt;* 生命周期
&lt;/h1&gt;&lt;p&gt;Maven 的工作是有固定逻辑顺序的
&lt;strong&gt;只需要执行一个命令，它会自动执行之前的所有步骤&lt;/strong&gt;：（前提：同一生命周期）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;clean&lt;/strong&gt;：清理旧的编译文件（删掉 &lt;code&gt;target&lt;/code&gt; 目录）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;compile&lt;/strong&gt;：编译源代码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;test&lt;/strong&gt;：运行单元测试&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;package&lt;/strong&gt;：打包（生成可执行的 Jar 包）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;install&lt;/strong&gt;：把打好的包安装到&lt;strong&gt;本地仓库&lt;/strong&gt;，让其他项目也能引用它&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="坐标"&gt;坐标
&lt;/h1&gt;&lt;p&gt;在 Maven 中，&lt;strong&gt;坐标（Coordinates）&lt;/strong&gt; 是用来唯一标识一个 Jar 包（插件或项目）的地址&lt;/p&gt;
&lt;h2 id="坐标的核心组成gav"&gt;坐标的核心组成（GAV）
&lt;/h2&gt;&lt;p&gt;一个最基本的坐标由三个核心部分组成，简称 &lt;strong&gt;GAV&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;groupId&lt;/code&gt; (团体/组织 ID)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;含义&lt;/strong&gt;：定义当前项目隶属的实际项目或组织。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;命名习惯&lt;/strong&gt;：通常是公司域名的倒写。例如：&lt;code&gt;com.google&lt;/code&gt;、&lt;code&gt;org.apache&lt;/code&gt;、&lt;code&gt;com.alibaba&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;artifactId&lt;/code&gt; (项目 ID)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;含义&lt;/strong&gt;：该组织下的某个具体模块或项目的名称。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;命名习惯&lt;/strong&gt;：通常是项目名。例如：&lt;code&gt;spring-boot-starter-web&lt;/code&gt;、&lt;code&gt;mysql-connector-java&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;version&lt;/code&gt; (版本)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;含义&lt;/strong&gt;：当前项目的版本号。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常见格式&lt;/strong&gt;：&lt;code&gt;1.0.0-RELEASE&lt;/code&gt;（正式版）或 &lt;code&gt;2.1.5-SNAPSHOT&lt;/code&gt;（开发快照版）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="在pomxml中的样子"&gt;在&lt;code&gt;pom.xml&lt;/code&gt;中的样子
&lt;/h2&gt;&lt;p&gt;当你去 &lt;strong&gt;Maven 中央仓库&lt;/strong&gt; 搜到一个依赖时，它会给你这样一段坐标代码，你只需把它复制到 &lt;code&gt;dependencies&lt;/code&gt; 标签里：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.mybatis&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;mybatis&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#f92672"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.5.13&lt;span style="color:#f92672"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="坐标与目录结构的逻辑顺序"&gt;坐标与目录结构的逻辑顺序
&lt;/h2&gt;&lt;p&gt;坐标不仅仅是几个字母，它直接决定了 Jar 包在&lt;strong&gt;本地仓库&lt;/strong&gt;中的&lt;strong&gt;物理存放路径&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果本地仓库路径是 &lt;code&gt;D:\maven_repo&lt;/code&gt;，那么上面 MyBatis 的 Jar 包会被存放在：
&lt;code&gt;D:\maven_repo \ org \ mybatis \ mybatis \ 3.5.13 \ mybatis-3.5.13.jar&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;groupId&lt;/code&gt;&lt;/strong&gt;：中的点（&lt;code&gt;.&lt;/code&gt;）会被转换成文件夹斜杠（&lt;code&gt;\&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;artifactId&lt;/code&gt;&lt;/strong&gt;：是下一级文件夹。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;version&lt;/code&gt;&lt;/strong&gt;：是再下一级文件夹。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="依赖配置"&gt;依赖配置
&lt;/h1&gt;&lt;p&gt;在 Maven 项目中，&lt;strong&gt;依赖配置（Dependency Configuration）&lt;/strong&gt; 是通过 &lt;code&gt;pom.xml&lt;/code&gt; 文件来声明项目运行所需的外部库&lt;/p&gt;
&lt;h2 id="依赖传递与排除-exclusions"&gt;依赖传递与排除 (Exclusions)
&lt;/h2&gt;&lt;p&gt;这是 Maven 解决复用性的核心逻辑：如果引入了 A，而 A 依赖了 B，Maven 会自动把 B 也下载下来。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：如果 A 引入的 B 版本太旧，导致项目报错怎么办？
&lt;strong&gt;解决&lt;/strong&gt;：使用 &lt;code&gt;&amp;lt;exclusions&amp;gt;&lt;/code&gt; 手动切断传递&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.example&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;library-a&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span style="color:#f92672"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.slf4j&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;slf4j-log4j12&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/exclusion&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="常见配置逻辑顺"&gt;常见配置逻辑顺
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;确定需求&lt;/strong&gt;：比如需要连接 MySQL。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查找坐标&lt;/strong&gt;：在 &lt;a class="link" href="https://mvnrepository.com/" target="_blank" rel="noopener"
 &gt;MVNrepository&lt;/a&gt; 搜索 &lt;code&gt;mysql-connector-java&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;粘贴配置&lt;/strong&gt;：将代码放入 &lt;code&gt;pom.xml&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;刷新 Maven&lt;/strong&gt;：在 IDEA 中点击刷新图标&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查冲突&lt;/strong&gt;：在 IDEA 右侧 Maven 面板查看 &lt;code&gt;Dependencies&lt;/code&gt; 树，确认没有红色的冲突标识&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING] 警告&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果依赖配置变更了，必须要刷新/重新加载&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="单元测试"&gt;单元测试
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;单元测试 (Unit Testing)&lt;/strong&gt; 是指对软件中的最小可测试单元（在 Java 中通常是一个&lt;strong&gt;类&lt;/strong&gt;或一个&lt;strong&gt;方法&lt;/strong&gt;）进行检查和验证
&lt;img src="Maven-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="为什么要写单元测试"&gt;为什么要写单元测试？
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;快速反馈&lt;/strong&gt;：改完代码秒知对错，不用等启动整个项目或手动点浏览器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;防止回滚&lt;/strong&gt;：当你重构（修改）旧代码时，单元测试能确保你没有改坏原本正常的功能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;文档作用&lt;/strong&gt;：好的测试代码本身就是最好的“功能说明书”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;测试代码与应用程序代码分开,便于维护&lt;/li&gt;
&lt;li&gt;可以自动生成测试报告(通过:绿色，失败:红色)&lt;/li&gt;
&lt;li&gt;一个测试方法执行失败，不会影响其它测试方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="junit"&gt;JUnit
&lt;/h2&gt;&lt;h3 id="测试类要求"&gt;测试类要求
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;要求标准&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;存放路径&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;src/test/java&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;必须与业务代码（&lt;code&gt;src/main/java&lt;/code&gt;）分开存放。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;包名结构&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;与被测类包名一致&lt;/td&gt;
 &lt;td&gt;例如被测类在 &lt;code&gt;com.demo.service&lt;/code&gt;，测试类也应在此包下。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;类名规范&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;以 &lt;code&gt;Test&lt;/code&gt; 结尾&lt;/td&gt;
 &lt;td&gt;例如：&lt;code&gt;UserServiceTest.java&lt;/code&gt;（Surefire 插件默认识别规则）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;依赖配置&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;scope&lt;/code&gt; 设为 &lt;code&gt;test&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;确保测试相关的 Jar 包（如 JUnit）不会被打包到生产环境。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="断言assert"&gt;断言&lt;code&gt;assert&lt;/code&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;本质&lt;/strong&gt;：测试逻辑的“裁判”。它对比 &lt;strong&gt;预期值 (Expected)&lt;/strong&gt; 与 &lt;strong&gt;实际值 (Actual)&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑流&lt;/strong&gt;：&lt;code&gt;执行业务逻辑 -&amp;gt; 获取结果 -&amp;gt; 调用断言方法 -&amp;gt; 判定测试通过/失败&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testGenderWithAssert&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 UserService userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserService(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String gender &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService.&lt;span style="color:#a6e22e"&gt;getGenderByIdCard&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011011&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Assertions.&lt;span style="color:#a6e22e"&gt;assertEquals&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;男&amp;#34;&lt;/span&gt;, gender,&lt;span style="color:#e6db74"&gt;&amp;#34;性别获取逻辑有问题&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;//会检测与结果是否一致&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!PROBLEM]
测试代码中，通常会极力避免手动写 &lt;code&gt;try-catch&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;断言方法&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;assertEquals(exp, act)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;判断两个值是否相等&lt;/td&gt;
 &lt;td&gt;验证计算结果、字符串内容、对象相等。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;assertNotEquals(exp, act)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;判断两个值是否&lt;strong&gt;不&lt;/strong&gt;相等&lt;/td&gt;
 &lt;td&gt;验证更新后的值确实变了。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;assertTrue(condition)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;判断条件是否为 &lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;验证布尔逻辑（如：&lt;code&gt;canAfford&lt;/code&gt; 方法）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;assertFalse(condition)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;判断条件是否为 &lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;验证否定逻辑（如：用户是否未登录）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;assertNull(obj)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;判断对象是否为空&lt;/td&gt;
 &lt;td&gt;验证查询不到数据时的返回。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;assertNotNull(obj)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;判断对象是否不为空&lt;/td&gt;
 &lt;td&gt;验证对象是否成功创建或查询到。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;assertArrayEquals(exp, act)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;判断两个数组是否相等&lt;/td&gt;
 &lt;td&gt;验证列表排序或批量处理后的数组。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@Test&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testGenderWithAssert2&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 UserService userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserService(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 String gender &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService.&lt;span style="color:#a6e22e"&gt;getGenderByIdCard&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011011&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;//当异常发生的时候 测试能否抛出正确的异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 Assertions.&lt;span style="color:#a6e22e"&gt;assertThrows&lt;/span&gt;(IllegalArgumentException.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;,()&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 userService.&lt;span style="color:#a6e22e"&gt;getGenderByIdCard&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;)); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="组合断言"&gt;组合断言
&lt;/h4&gt;&lt;p&gt;当一个测试方法里有多个断言时：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;普通逻辑&lt;/strong&gt;：第一个断言挂了，后面都不跑了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;assertAll 逻辑&lt;/strong&gt;：所有断言都会跑完，最后统一输出哪些挂了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 笔记示例：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	assertAll(&lt;span style="color:#e6db74"&gt;&amp;#34;用户信息校验&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 () &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; assertEquals(&lt;span style="color:#e6db74"&gt;&amp;#34;男&amp;#34;&lt;/span&gt;, gender),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 () &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; assertEquals(36, age)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="注解annotation"&gt;注解&lt;code&gt;Annotation&lt;/code&gt;
&lt;/h3&gt;&lt;h4 id="生命周期钩子"&gt;生命周期钩子
&lt;/h4&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;注解&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;执行时机&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;强制要求&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;典型用途&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@BeforeAll&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;所有测试开始前，&lt;strong&gt;只执行一次&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;必须是 &lt;code&gt;static&lt;/code&gt; 方法&lt;/td&gt;
 &lt;td&gt;初始化数据库连接池、启动 Redis 容器。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@BeforeEach&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;每个&lt;/strong&gt;测试方法执行前都跑一次&lt;/td&gt;
 &lt;td&gt;普通方法&lt;/td&gt;
 &lt;td&gt;重置对象状态、准备 Mock 数据。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@AfterEach&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;每个&lt;/strong&gt;测试方法执行后都跑一次&lt;/td&gt;
 &lt;td&gt;普通方法&lt;/td&gt;
 &lt;td&gt;清理临时文件、撤销数据库更改。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;@AfterAll&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;所有测试结束后，&lt;strong&gt;只执行一次&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;必须是 &lt;code&gt;static&lt;/code&gt; 方法&lt;/td&gt;
 &lt;td&gt;关闭数据库连接、释放系统资源。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;执行顺序逻辑：&lt;/strong&gt; &lt;code&gt;@BeforeAll&lt;/code&gt; $\rightarrow$ (&lt;code&gt;@BeforeEach&lt;/code&gt; $\rightarrow$ &lt;code&gt;@Test&lt;/code&gt; $\rightarrow$ &lt;code&gt;@AfterEach&lt;/code&gt;) $\times$ N次 $\rightarrow$ &lt;code&gt;@AfterAll&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before All
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	男
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	before each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after each
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	after All
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	进程已结束，退出代码为 &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="核心测试与显示"&gt;核心测试与显示
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@Test&lt;/code&gt;&lt;/strong&gt;：最基础的标签，告诉 Maven 这是一个标准的单元测试。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@DisplayName(&amp;quot;描述内容&amp;quot;)&lt;/code&gt;&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：在 IDEA 的运行面板或测试报告中，显示中文或易读的描述，而不是枯燥的方法名。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;复用性&lt;/strong&gt;：让非技术人员（或一个月后的你）一眼看懂这个测试在测什么&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="参数化测试"&gt;参数化测试
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;@ParameterizedTest&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：声明这个方法是一个“参数化测试”，它会多次运行，每次注入不同的值。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：它必须配合“数据源”注解使用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@ValueSource&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：最简单的&lt;strong&gt;数据源&lt;/strong&gt;，提供一组基本类型的值（如 Strings, Ints）&lt;/li&gt;
&lt;li&gt;身份证性别测试：&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ParameterizedTest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@ValueSource&lt;/span&gt;(strings &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 				{&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011021&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 				&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011032&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 				&lt;span style="color:#e6db74"&gt;&amp;#34;100000200010011051&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 			})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@DisplayName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;验证多个男性身份证的识别&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;testGenderWithAssert2&lt;/span&gt;(String idCard){&lt;span style="color:#75715e"&gt;//strings传入idCard&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; UserService userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserService(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; String gender &lt;span style="color:#f92672"&gt;=&lt;/span&gt; userService.&lt;span style="color:#a6e22e"&gt;getGenderByIdCard&lt;/span&gt;(idCard); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Assertions.&lt;span style="color:#a6e22e"&gt;assertEquals&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;男&amp;#34;&lt;/span&gt;,gender); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="总结"&gt;总结
&lt;/h4&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;注解分类&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;注解名称&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;记忆关键词&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;控制流&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;@Before...&lt;/code&gt; / &lt;code&gt;@After...&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;时机控制&lt;/strong&gt;（前置/后置）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;基础&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;@Test&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;入场券&lt;/strong&gt;（标记测试）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;美化&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;@DisplayName&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;别名&lt;/strong&gt;（中文描述）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;高级&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;@ParameterizedTest&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;分身术&lt;/strong&gt;（一法多测）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;数据源&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;@ValueSource&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;数据池&lt;/strong&gt;（提供参数）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;静态限制&lt;/strong&gt;：记住 &lt;code&gt;@BeforeAll&lt;/code&gt; 和 &lt;code&gt;@AfterAll&lt;/code&gt; 必须加 &lt;code&gt;static&lt;/code&gt; 关键字，因为它们在类实例创建之前就要运行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;依赖冲突&lt;/strong&gt;：如果你在 &lt;code&gt;pom.xml&lt;/code&gt; 里用的是 JUnit 4，这些注解（来自 &lt;code&gt;org.junit.jupiter&lt;/code&gt; 包）是无法识别的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不要混用&lt;/strong&gt;：通常一个方法要么标 &lt;code&gt;@Test&lt;/code&gt;，要么标 &lt;code&gt;@ParameterizedTest&lt;/code&gt;，不要两个都标。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="规范"&gt;规范
&lt;/h3&gt;&lt;p&gt;在企业开发规范中，这种写法被称为 &lt;strong&gt;“测试环境准备（Test Fixture Setup）”&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Java" data-lang="Java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; UserService userService; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;@BeforeEach&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setUp&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 userService &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; UserService(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="依赖范围"&gt;依赖范围
&lt;/h1&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;范围 (Scope)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;编译 (main)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;测试 (test)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;运行 (runtime)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;打包&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;典型例子&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;compile&lt;/code&gt;&lt;/strong&gt; (默认)&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;Spring 核心库、Log4j&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;test&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;JUnit 5&lt;/strong&gt;、Mockito&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;provided&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Servlet API&lt;/strong&gt;、Lombok&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;runtime&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;❌&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;JDBC 驱动实现&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;system&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;✅&lt;/td&gt;
 &lt;td&gt;本地磁盘上的 Jar 包，&lt;strong&gt;迁移报错&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="详细范围"&gt;详细范围
&lt;/h2&gt;&lt;h3 id="compile编译范围"&gt;compile（编译范围）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：如果不写 &lt;code&gt;&amp;lt;scope&amp;gt;&lt;/code&gt;，默认就是这个。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特性&lt;/strong&gt;：全能型。你在写代码、跑测试、部署上线时都需要它。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;复用性&lt;/strong&gt;：它具有&lt;strong&gt;传递性&lt;/strong&gt;（如果你依赖 A，A 依赖 B，那么你的项目也会获得 B）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-test测试范围"&gt;🔹 test（测试范围）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：只在 &lt;code&gt;src/test/java&lt;/code&gt; 下的代码中有效。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;为什么要用&lt;/strong&gt;：像 JUnit 这种工具，上线运行代码时根本不需要。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;规范&lt;/strong&gt;：&lt;strong&gt;必须&lt;/strong&gt;给所有测试框架加上 &lt;code&gt;test&lt;/code&gt; 范围，防止线上包由于包含测试类而变得臃肿。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-provided已提供范围"&gt;🔹 provided（已提供范围）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：编译时我需要它，但&lt;strong&gt;打包时请不要带上它&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;典型场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Servlet API&lt;/strong&gt;：你的代码需要它来编译，但你最终要把项目部署到 Tomcat。Tomcat 已经自带了 Servlet 的 Jar 包，如果你的包里也带一个，就会产生版本冲突。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lombok&lt;/strong&gt;：编译时生成 Getter/Setter，编译完后就不再需要了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-runtime运行时范围"&gt;🔹 runtime（运行时范围）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;逻辑&lt;/strong&gt;：写代码（编译）时不需要，但程序跑起来（运行）时必须有。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;典型场景&lt;/strong&gt;：&lt;strong&gt;数据库驱动（如 MySQL Connector）&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我们在代码里通常使用 JDK 自带的 &lt;code&gt;java.sql.Connection&lt;/code&gt;（接口），不需要直接调用 MySQL 的具体实现类。只有在程序运行时，Maven 才会加载驱动包来建立真实连接。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="bom"&gt;BOM
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;BOM&lt;/strong&gt; 的全称是 &lt;strong&gt;Bill of Materials&lt;/strong&gt;（物料清单）&lt;/p&gt;
&lt;p&gt;简单来说，BOM 是一个特殊的 &lt;code&gt;pom.xml&lt;/code&gt; 文件，它的核心逻辑不是为了提供代码，而是为了&lt;strong&gt;统一管理依赖的版本号&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="使用bom"&gt;使用BOM
&lt;/h2&gt;&lt;p&gt;在 &lt;code&gt;pom.xml&lt;/code&gt; 中导入 BOM&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-dependencies&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.2.0&lt;span style="color:#f92672"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span style="color:#f92672"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span style="color:#f92672"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;引入具体依赖（不写版本号）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-web&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;传统方式&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;使用 BOM&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;版本控制&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;每个模块各自维护，易冲突&lt;/td&gt;
 &lt;td&gt;全局统一，一处修改全线更新&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;配置量&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;每个 &lt;code&gt;&amp;lt;dependency&amp;gt;&lt;/code&gt; 都要写版本&lt;/td&gt;
 &lt;td&gt;只在顶层写一次，子模块极简&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;复用性&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;差，需要反复确认版本号&lt;/td&gt;
 &lt;td&gt;极强，确保所有组件完美兼容&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;稳定性&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;容易出现 Jar 包版本不匹配&lt;/td&gt;
 &lt;td&gt;官方认证的“全家桶”组合，最稳定&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;</description></item><item><title>Vue3 &amp; Ajax.md</title><link>/post/vue3--ajax/</link><pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate><guid>/post/vue3--ajax/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-09&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="vue"&gt;Vue
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;Vue.js&lt;/strong&gt; 是一个用于构建用户界面的 &lt;strong&gt;JavaScript 框架&lt;/strong&gt;。
它最核心的价值在于：&lt;strong&gt;不再需要手动操作 DOM。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;框架：就是一套完整的项目解决方案，用于快速构建项目&lt;/li&gt;
&lt;li&gt;优点：大大提升前端项目的开发效率
&lt;img src="Vue3%20&amp;amp;%20Ajax-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;li&gt;引入Vue模块&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;app&amp;#34;&lt;/span&gt;&amp;gt;{{ message }}&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;ref&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;https://unpkg.com/vue@3/dist/vue.esm-browser.js&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;setup&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ref&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Hello Vue!&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }).&lt;span style="color:#a6e22e"&gt;mount&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;#app&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="Vue3%20&amp;amp;%20Ajax-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="指令"&gt;指令
&lt;/h2&gt;&lt;p&gt;&lt;img src="Vue3%20&amp;amp;%20Ajax-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="基础显示指令"&gt;基础显示指令
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;指令&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;v-text&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;更新元素的文本内容&lt;/td&gt;
 &lt;td&gt;类似 &lt;code&gt;innerText&lt;/code&gt;，但通常直接用 &lt;code&gt;{{ }}&lt;/code&gt; 更方便。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;v-html&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;更新元素的 &lt;code&gt;innerHTML&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;内容按 HTML 解析&lt;/strong&gt;。注意：只在信任的内容上使用，防止 XSS 攻击。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;v-once&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;只渲染一次&lt;/td&gt;
 &lt;td&gt;之后即使数据变了，这里也不会更新，用于性能优化。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="条件渲染指令"&gt;条件渲染指令
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;v-if&lt;/code&gt; / &lt;code&gt;v-else-if&lt;/code&gt; / &lt;code&gt;v-else&lt;/code&gt;&lt;/strong&gt;：真正的条件渲染。如果条件为假，元素根本不会被创建（不出现在 DOM 树中）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;:基于条件判断，来控制创建或移除元素节点(条件渲染)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;场景&lt;/strong&gt;:要么显示，要么不显示，不频繁切换的场景&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;v-show&lt;/code&gt;&lt;/strong&gt;：通过修改 CSS 的 &lt;code&gt;display: none&lt;/code&gt; 来切换显隐。元素始终存在于 DOM 中&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;:基于CSS样式display来控制显示与隐藏&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;场景&lt;/strong&gt;:频繁切换显示隐藏的场景&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;场景建议&lt;/strong&gt;：频繁切换显示用 &lt;code&gt;v-show&lt;/code&gt;，运行时条件不大可能改变用 &lt;code&gt;v-if&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="列表渲染指令"&gt;列表渲染指令
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;v-for&lt;/code&gt;&lt;/strong&gt;：基于一个数组来渲染一个列表&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;语法&lt;/strong&gt;：&lt;code&gt;v-for=&amp;quot;(item, index) in list&amp;quot; :key=&amp;quot;item.id&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;item&lt;/code&gt;：当前遍历项&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index&lt;/code&gt;：当前索引（从 0 开始）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;list&lt;/code&gt;：要循环的数组&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:key=&amp;quot;item.id&amp;quot;&lt;/code&gt;：给列表项唯一标识，提升渲染性能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;tbody&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;tr&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-for&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;(e, index) in empList&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;:key&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;e.id&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{index+1}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.name}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.gender == 1?&amp;#34;男&amp;#34;:&amp;#34;女&amp;#34; }}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.job}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.entrydate}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;{{e.updatetime}}&amp;lt;/&lt;span style="color:#f92672"&gt;td&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;tr&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;tbody&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	empList: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 { &amp;#34;id&amp;#34;: 1,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;name&amp;#34;: &amp;#34;姓名&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;gender&amp;#34;: 1,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;job&amp;#34;: &amp;#34;1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;entrydate&amp;#34;: &amp;#34;2023-06-09&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;#34;updatetime&amp;#34;: &amp;#34;2024-07-30T14:59:38&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;关键点&lt;/strong&gt;：使用 &lt;code&gt;v-for&lt;/code&gt; 时&lt;strong&gt;必须&lt;/strong&gt;绑定 &lt;code&gt;:key&lt;/code&gt;。这能帮助 Vue 的 Diff 算法精准识别每个节点，提高更新性能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：遍历的数组，必须在data中定义;要想让哪个标签循环展示多次，就在哪个标签上使用 v-for 指令。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id="属性绑定与事件监听"&gt;属性绑定与事件监听
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;v-bind&lt;/code&gt; (缩写 &lt;code&gt;:&lt;/code&gt;)&lt;/strong&gt;：动态绑定 HTML 属性。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;img&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-bind:src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;imageSrc&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;img&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;:src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;imageSrc&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	插值表达式不能在标签内使用
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;v-on&lt;/code&gt; (缩写 &lt;code&gt;@&lt;/code&gt;)&lt;/strong&gt;：绑定事件监听器。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;完整写法&lt;/strong&gt;：&lt;code&gt;v-on:事件名=&amp;quot;方法名&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;简写形式&lt;/strong&gt;（最常用）：&lt;strong&gt;&lt;code&gt;@事件名=&amp;quot;方法名&amp;quot;&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//HTML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;button type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;button&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;click&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;search&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;查询&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/&lt;/span&gt;button&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;    &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;button type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;reset&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;click&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;clear&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;清空&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/&lt;/span&gt;button&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//JS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;methods&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#a6e22e"&gt;clear&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;job&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="双向绑定指令表单"&gt;双向绑定指令(表单)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;v-model&lt;/code&gt;&lt;/strong&gt;：在表单元素（input, select, textarea）上创建双向数据绑定。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原理&lt;/strong&gt;：它是 &lt;code&gt;v-bind:value&lt;/code&gt; 和 &lt;code&gt;v-on:input&lt;/code&gt; 的语法糖&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;从数据到视图&lt;/strong&gt;：当变量值改变时，输入框的内容自动变&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;从视图到数据&lt;/strong&gt;：当用户在输入框打字时，变量的值实时更新&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;gender&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-model&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;searchForm.gender&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;select&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;job&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-model&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;searchForm.job&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;select&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	searchForm:{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				name:&amp;#39;&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				gender:&amp;#39;&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				job:&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;                },
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="ajax"&gt;Ajax
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Ajax (Asynchronous JavaScript and XML)&lt;/strong&gt; 是让网页实现“局部刷新”的核心技术。它允许网页在不重新加载整个页面的情况下，从服务器请求数据。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;XML:&lt;/strong&gt; (Extensible Markup Language)可扩展标记语言，本质是一种数据格式，可以用来存储复杂的数据结构。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据交换:&lt;/strong&gt; 通过Ajax可以给服务器发送请求，并获取服务器响应的数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异步交互:&lt;/strong&gt; 可以在不重新加载整个页面的情况下，与服务器交换数据并更新部分网页的技术，如:搜索联想、用户名是否可用的校验等等。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="同步异步"&gt;同步异步
&lt;/h3&gt;&lt;h4 id="同步"&gt;同步
&lt;/h4&gt;&lt;p&gt;浏览器页面在发送请求给服务器，在服务器处理请求的过程中，浏览器页面不能做其他的操作。只能等到服务器响应结束后才能，浏览器页面才能继续做其他的操作
&lt;img src="Vue3%20&amp;amp;%20Ajax-5.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h4 id="异步"&gt;异步
&lt;/h4&gt;&lt;p&gt;浏览器页面发送请求给服务器，在服务器处理请求的过程中，浏览器页面还可以做其他的操作。
&lt;img src="Vue3%20&amp;amp;%20Ajax-6.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h3 id="async--await"&gt;async &amp;amp; await
&lt;/h3&gt;&lt;p&gt;可以通过async、await可以让异步变为同步操作。async就是来声明一个异步方法，await是用来等待异步任务执行&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//基于axios发送异步请求，请求http://127.0.0.1:5500/json/simple.json，根据条件查询员工列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;axios&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`http://127.0.0.1:5500/json/simple.json?name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;amp;gender=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;amp;job=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;job&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;empList&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="axios"&gt;&lt;a class="link" href="https://www.axios-http.cn" target="_blank" rel="noopener"
 &gt;Axios&lt;/a&gt;
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;步骤&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;引入Axios的js文件&lt;/li&gt;
&lt;li&gt;使用Axios发送请求，并获取响应结果
&lt;img src="Vue3%20&amp;amp;%20Ajax-4.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;为了方便，Axios已经为所有支持的请求方法提供了别名&lt;/li&gt;
&lt;li&gt;格式：&lt;code&gt;axios.请求方式(url [,data [, config ]])&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;//GET请求
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;    document.&lt;span style="color:#a6e22e"&gt;querySelector&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;#getData&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;onclick&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;        &lt;span style="color:#75715e"&gt;//发出请求后 不会等待服务器返回（异步），而是继续执行后续代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;axios&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://jsonplaceholder.typicode.com/posts/1&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}).&lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;================================&amp;#39;&lt;/span&gt;);&lt;span style="color:#75715e"&gt;//先输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="vue-的生命周期"&gt;Vue 的生命周期
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;阶段&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;状态名 (Vue 2)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Vue 3 (组合式 API)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;状态描述&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;创建&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;beforeCreate&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;setup&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;实例初始化，无数据&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;created&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;setup&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;数据可用&lt;/strong&gt;，无 DOM&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;挂载&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;beforeMount&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;onBeforeMount&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;虚拟 DOM 已准备好&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;mounted&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;onMounted&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;DOM 已渲染&lt;/strong&gt;（最常用）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;更新&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;beforeUpdate&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;onBeforeUpdate&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;数据变了，页面没变&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;updated&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;onUpdated&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;页面更新完成&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;销毁&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;beforeDestroy&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;onBeforeUnmount&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;清理现场&lt;/strong&gt;（防内存泄漏）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;destroyed&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;onUnmounted&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;完全消失&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://unpkg.com/axios/dist/axios.min.js&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 导入 Vue 3 的 createApp 方法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;https://unpkg.com/vue@3/dist/vue.esm-browser.js&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 搜索表单绑定的数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// 姓名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// 性别
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;job&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 职位
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 员工列表，表格渲染的数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;empList&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;methods&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 查询方法，点击“查询”按钮或页面加载时调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 发送 GET 请求到远程接口，带上表单参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;axios&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`https://web-server.itheima.net/emps/list?name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;amp;gender=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;amp;job=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;job&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 将返回的员工数组赋值给 empList，页面自动渲染
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;empList&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 控制台输出分隔线，调试用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;================================&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; result.data：是整个响应体（包含 code、msg、data 等字段）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; result.data.data：才是真正需要的员工数组
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 清空方法，点击“清空”按钮时调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;clear&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 重置表单
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;searchForm&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;gender&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;job&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 重新查询，显示所有数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 生命周期钩子，页面加载完成后自动查询一次，显示所有数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;mounted&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;search&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;mount&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;#container&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>HTML</title><link>/post/htmlcssjs/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>/post/htmlcssjs/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-07&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="html"&gt;HTML
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;HyperText Markup Language&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HTML 不是一种编程语言，而是一种&lt;strong&gt;标记语言&lt;/strong&gt;（Markup Language）。它通过一系列“标签”来描述网页的结构，是构建 Web 页面的基石。&lt;/p&gt;
&lt;h2 id="html-核心标签"&gt;HTML 核心标签
&lt;/h2&gt;&lt;p&gt;HTML 是网页的骨架，用于定义页面内容。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标题标签 (&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; - &lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt;)&lt;/strong&gt;：用于定义 1 到 6 级标题，数字越小级别越高，字体越大。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;超链接标签 (&lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;href&lt;/code&gt; 属性&lt;/strong&gt;：指定资源访问的 URL 地址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;target&lt;/code&gt; 属性&lt;/strong&gt;：指定打开链接的位置。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;_self&lt;/code&gt;：在当前页面打开（默认）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;_blank&lt;/code&gt;：在新的空白页面打开。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="表单"&gt;表单
&lt;/h2&gt;&lt;h3 id="表单容器-form"&gt;表单容器 &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;所有表单控件必须放在 &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; 标签内，它负责定义数据提交的方向和方式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;action&lt;/code&gt;&lt;/strong&gt;: 服务器接收数据的 URL 地址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;method&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;GET&lt;/code&gt;: 数据跟在 URL 后面，适合搜索、查询（安全性低，有长度限制）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;POST&lt;/code&gt;: 数据放在请求体中，适合注册、上传文件（安全性高，无长度限制）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	form表单&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	action&lt;span style="color:#960050;background-color:#1e0010"&gt;：表单数据提交的&lt;/span&gt;url地址
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	method&lt;span style="color:#960050;background-color:#1e0010"&gt;：提交方式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 get&lt;span style="color:#960050;background-color:#1e0010"&gt;：默认，表单数据会出现在&lt;/span&gt;url后面&lt;span style="color:#960050;background-color:#1e0010"&gt;，形式：&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;save&lt;span style="color:#f92672"&gt;?&lt;/span&gt;name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Tom&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;age&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;18&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;特点：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;．如果表单中包含了隐私数据，&lt;/span&gt;get方式并不安全&lt;span style="color:#960050;background-color:#1e0010"&gt;，不推荐使用该方式．&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;．在浏览器中&lt;/span&gt;get请求的大小是有限制的&lt;span style="color:#960050;background-color:#1e0010"&gt;，不适合提交大数据量的表单．&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 post&lt;span style="color:#960050;background-color:#1e0010"&gt;：表单数据会在消息体&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;请求体中提交到服务器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#960050;background-color:#1e0010"&gt;特点：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;．安全．&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;．请求大小没有限制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#960050;background-color:#1e0010"&gt;注意：表单项要想能够采集数据，必须得设置&lt;/span&gt;name属性&lt;span style="color:#960050;background-color:#1e0010"&gt;，表示当前表单项的名字&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="表单项"&gt;表单项
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; 标签 (点击文字也能选中)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;极力推荐使用&lt;/strong&gt;。它能通过 &lt;code&gt;for&lt;/code&gt; 属性绑定到对应的 &lt;code&gt;input&lt;/code&gt; 的 &lt;code&gt;id&lt;/code&gt; 上。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;好处&lt;/strong&gt;：点击“用户名”这三个字，光标也会跳进输入框，对移动端非常友好。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; 属性 (后端唯一标识)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;这是表单项最核心的属性&lt;/strong&gt;。后端程序只认 &lt;code&gt;name&lt;/code&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;em&gt;比喻：&lt;code&gt;name&lt;/code&gt; 是变量名，用户输入的是变量值。没写 &lt;code&gt;name&lt;/code&gt;，后端就收不到这个项的数据。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;code&gt;value&lt;/code&gt; 属性 (初始值/提交值)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;对于文本框：它是默认填好的文字。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对于单选/复选框：它是选中后传给后端的“暗号”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="input"&gt;&lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;
&lt;/h4&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;常用 Type&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;视觉效果&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;text&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;单行输入框&lt;/td&gt;
 &lt;td&gt;用户名、地址&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;password&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;掩盖输入内容&lt;/td&gt;
 &lt;td&gt;密码、敏感信息&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;radio&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;圆形选择点&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;单选&lt;/strong&gt;（必须设置相同 &lt;code&gt;name&lt;/code&gt; 才能互斥）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;checkbox&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;方形勾选框&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;多选&lt;/strong&gt;（如爱好、协议确认）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;file&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;文件选择按钮&lt;/td&gt;
 &lt;td&gt;上传头像、文档&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;submit&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;提交按钮&lt;/td&gt;
 &lt;td&gt;确认并发送整个表单&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="select--option"&gt;&lt;code&gt;&amp;lt;select&amp;gt; &amp;amp; &amp;lt;option&amp;gt;&lt;/code&gt;
&lt;/h4&gt;&lt;p&gt;用于在有限的空间里提供大量选项。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;select&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &amp;lt;&lt;span style="color:#f92672"&gt;option&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;bj&amp;#34;&lt;/span&gt;&amp;gt;北京&amp;lt;/&lt;span style="color:#f92672"&gt;option&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &amp;lt;&lt;span style="color:#f92672"&gt;option&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;sh&amp;#34;&lt;/span&gt;&amp;gt;上海&amp;lt;/&lt;span style="color:#f92672"&gt;option&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;select&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="textarea"&gt;&lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;
&lt;/h4&gt;&lt;p&gt;用于输入大量文字（如自我介绍、评价），支持换行。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="表格"&gt;表格
&lt;/h2&gt;&lt;p&gt;HTML 表格是由行（Row）组成的，行里面再拆分单元格（Cell）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;&lt;/strong&gt;: 表格的容器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt;&lt;/strong&gt; (Table Row): 定义一行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;th&amp;gt;&lt;/code&gt;&lt;/strong&gt; (Table Header): &lt;strong&gt;表头&lt;/strong&gt;单元格。文字默认加粗、居中。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;td&amp;gt;&lt;/code&gt;&lt;/strong&gt; (Table Data): &lt;strong&gt;普通&lt;/strong&gt;单元格。承载具体内容。
为了让长表格更易读、更符合标准，建议使用以下标签：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;标签&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;thead&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;包裹表头部分（通常是第一行）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;tbody&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;包裹表格主体（数据部分）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;tfoot&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;包裹表格页脚（如合计行）。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;caption&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;表格的标题，紧跟在 &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; 之后。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="单元格合并"&gt;单元格合并
&lt;/h3&gt;&lt;p&gt;这是表格布局中最常用的技巧，用于处理复杂的表头或跨行数据。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;colspan&lt;/code&gt; (跨列)&lt;/strong&gt;：将多个单元格水平合并。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;rowspan&lt;/code&gt; (跨行)&lt;/strong&gt;：将多个单元格垂直合并。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="页脚"&gt;页脚
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;code&gt;**&amp;lt;footer&amp;gt;&lt;/code&gt; (页面页脚)**&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;tfoot&amp;gt; &lt;/code&gt;(表格页脚)&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;所属父级&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; 或 &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;主要功能&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;放置版权、导航、作者信息&lt;/td&gt;
 &lt;td&gt;放置表格数据的合计、平均值&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;出现频率&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;一个页面通常只有一个主 &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;每个表格可以有一个 &lt;code&gt;&amp;lt;tfoot&amp;gt;&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;布局技巧&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;常配合 CSS 固定在页面底部&lt;/td&gt;
 &lt;td&gt;常配合 &lt;code&gt;colspan&lt;/code&gt; 合并单元格&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="css"&gt;CSS
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;Cascading Style Sheets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CSS 负责网页的&lt;strong&gt;表现（Presentation）&lt;/strong&gt;。如果说 HTML 是建筑的骨架，那么 CSS 就是装修、油漆和家具布局。它通过选择器定位 HTML 元素，并应用样式属性。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="css-引入方式"&gt;CSS 引入方式
&lt;/h2&gt;&lt;p&gt;CSS 用于美化 HTML 页面，主要有三种引入手段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;行内样式 (Inline Styles)&lt;/strong&gt;：直接写在标签的 &lt;code&gt;style&lt;/code&gt; 属性中，优先级最高但不易维护。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内部样式表 (Internal Style Sheet)&lt;/strong&gt;：写在 &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; 标签内的 &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; 标签中，适用于单页样式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;外部样式表 (External Style Sheet)&lt;/strong&gt;：&lt;strong&gt;推荐做法&lt;/strong&gt;。通过 &lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;路径.css&amp;quot;&amp;gt;&lt;/code&gt; 引入独立的 &lt;code&gt;.css&lt;/code&gt; 文件，实现结构与表现分离。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="颜色表示"&gt;颜色表示
&lt;/h2&gt;&lt;h3 id="十六进制颜色值"&gt;十六进制颜色值
&lt;/h3&gt;&lt;p&gt;这是目前网页开发中最常用的表达方式&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;格式&lt;/strong&gt;：&lt;code&gt;#RRGGBB&lt;/code&gt;（前缀为 &lt;code&gt;#&lt;/code&gt;，后面跟着三组十六进制数）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;原理&lt;/strong&gt;：使用十六进制（0-9, A-F）分别定义红 (Red)、绿 (Green)、蓝 (Blue) 三原色的强度。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;#FFFFFF&lt;/code&gt;：纯白色。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;#000000&lt;/code&gt;：纯黑色。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rgb-与-rgba-模式"&gt;RGB 与 RGBA 模式
&lt;/h3&gt;&lt;p&gt;直接通过数字定义三原色的混合比例，更符合计算机颜色的底层逻辑。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RGB 格式&lt;/strong&gt;：&lt;code&gt;rgb(红色值, 绿色值, 蓝色值)&lt;/code&gt;。每个数值范围是 &lt;code&gt;0-255&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;示例&lt;/em&gt;：&lt;code&gt;rgb(231, 76, 60)&lt;/code&gt; 等同于十六进制的 &lt;code&gt;#e74c3c&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RGBA 格式&lt;/strong&gt;：&lt;code&gt;rgba(r, g, b, alpha)&lt;/code&gt;。多了一个 &lt;code&gt;alpha&lt;/code&gt; 通道用于控制&lt;strong&gt;透明度&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;alpha&lt;/code&gt; 取值范围是 &lt;code&gt;0&lt;/code&gt;（完全透明）到 &lt;code&gt;1&lt;/code&gt;（完全不透明）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;示例&lt;/em&gt;：&lt;code&gt;rgba(52, 152, 219, 0.5)&lt;/code&gt; 表示 50% 透明度的蓝色。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="选择器"&gt;选择器
&lt;/h2&gt;&lt;h3 id="基本选择器"&gt;基本选择器
&lt;/h3&gt;&lt;p&gt;这是最常用、最基础的选择方法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标签选择器 (1)&lt;/strong&gt;：通过 HTML 标签名选择。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;p { color: red; }&lt;/code&gt;（选中页面上所有的 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; 标签）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类选择器 (10)&lt;/strong&gt;：选择具有特定 &lt;code&gt;class&lt;/code&gt; 属性的元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;.highlight { background: yellow; }&lt;/code&gt;（选中所有 &lt;code&gt;class=&amp;quot;highlight&amp;quot;&lt;/code&gt; 的元素）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ID 选择器 (100)&lt;/strong&gt;：选择具有特定 &lt;code&gt;id&lt;/code&gt; 属性的唯一元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;#header { font-size: 24px; }&lt;/code&gt;（选中 &lt;code&gt;id=&amp;quot;header&amp;quot;&lt;/code&gt; 的元素）。&lt;strong&gt;注意：一个 ID 在 HTML 页面中应该是唯一的。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通配符选择器 (0)&lt;/strong&gt;：选择页面上的所有元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;* { margin: 0; padding: 0; }&lt;/code&gt;（常用于重置页面默认边距）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="复合选择器"&gt;复合选择器
&lt;/h3&gt;&lt;p&gt;用于更精确地定位元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;后代选择器 (Descendant Selector)&lt;/strong&gt;：选择某个元素内部的所有指定后代。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;.container p { ... }&lt;/code&gt;（选中 &lt;code&gt;.container&lt;/code&gt; 内部所有的 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; 标签，无论嵌套多深）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;子元素选择器 (Child Selector)&lt;/strong&gt;：仅选择某个元素的直接子元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;.container &amp;gt; p { ... }&lt;/code&gt;（只选中 &lt;code&gt;.container&lt;/code&gt; 下的第一层 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;并集选择器 (Grouping Selector)&lt;/strong&gt;：同时给多个选择器设置相同的样式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;h1, h2, .title { ... }&lt;/code&gt;（用逗号分隔）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="伪类选择器"&gt;伪类选择器
&lt;/h3&gt;&lt;p&gt;用于选择元素的特定&lt;strong&gt;状态&lt;/strong&gt;，常用于交互效果。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;:hover&lt;/code&gt;&lt;/strong&gt;：鼠标悬停在元素上的状态。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;a:hover { text-decoration: underline; }&lt;/code&gt;（鼠标移上去显示下划线）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;:active&lt;/code&gt;&lt;/strong&gt;：元素被激活（鼠标点击按下）的状态。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;:nth-child(n)&lt;/code&gt;&lt;/strong&gt;：选择父元素中的第 n 个子元素。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;li:nth-child(2) { color: blue; }&lt;/code&gt;（选中列表中的第二项）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="属性选择器"&gt;属性选择器
&lt;/h3&gt;&lt;p&gt;根据 HTML 标签的属性来选择，这在处理你之前提到的 &lt;code&gt;contest.xml&lt;/code&gt; 这种结构化数据转换成的 HTML 时非常有用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;写法&lt;/em&gt;：&lt;code&gt;[type=&amp;quot;text&amp;quot;] { border: 1px solid #ccc; }&lt;/code&gt;（选中所有 &lt;code&gt;type&lt;/code&gt; 属性为 &lt;code&gt;text&lt;/code&gt; 的输入框）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="选择器的优先级"&gt;选择器的优先级
&lt;/h3&gt;&lt;p&gt;当多个选择器指向同一个元素并设置相同属性时，浏览器会根据“权重”来决定听谁的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;行内样式 (&lt;code&gt;style=&amp;quot;...&amp;quot;&lt;/code&gt;)&lt;/strong&gt;：权重最高 (1000)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ID 选择器 (&lt;code&gt;#id&lt;/code&gt;)&lt;/strong&gt;：权重高 (100)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;类、伪类、属性选择器 (&lt;code&gt;.class&lt;/code&gt;)&lt;/strong&gt;：权重中 (10)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标签选择器 (&lt;code&gt;div&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt;)&lt;/strong&gt;：权重低 (1)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通配符 (&lt;code&gt;*&lt;/code&gt;)&lt;/strong&gt;：权重最低 (0)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;原则&lt;/strong&gt;：描述得越精准，权重越高。如果权重相同，则&lt;strong&gt;后写的样式&lt;/strong&gt;会覆盖先写的样式。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="正文样式"&gt;正文样式
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;属性&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;功能说明&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;常见取值示例&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;color&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;设置字体颜色&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;#e74c3c&lt;/code&gt; (十六进制), &lt;code&gt;rgba(0,0,0,0.8)&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;设置字体大小&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;16px&lt;/code&gt;, &lt;code&gt;1rem&lt;/code&gt;, &lt;code&gt;1.2em&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;line-height&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;设置行高（行间距）&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;1.5&lt;/code&gt;, &lt;code&gt;1.6&lt;/code&gt; (通常为字号的倍数)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;letter-spacing&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;设置字间距&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;1px&lt;/code&gt;, &lt;code&gt;2px&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;text-indent&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;首行缩进&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;2em&lt;/code&gt; (缩进两个字符)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;text-align&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;文本对齐方式&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;left&lt;/code&gt;, &lt;code&gt;center&lt;/code&gt;, &lt;code&gt;right&lt;/code&gt;, &lt;code&gt;justify&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="盒子模型"&gt;盒子模型
&lt;/h2&gt;&lt;p&gt;在 CSS 中，所有的 HTML 元素都可以看作是一个矩形的“盒子”。
这个盒子由内到外由四个部分（区域）组成。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内容 (Content)&lt;/strong&gt;：盒子的核心，显示文本、图片等实际内容。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内边距 (Padding)&lt;/strong&gt;：内容与边框之间的透明区域。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;边框 (Border)&lt;/strong&gt;：围绕在内边距和内容外的线。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;外边距 (Margin)&lt;/strong&gt;：边框外的区域，用于控制元素与其它元素之间的距离。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;通过 &lt;code&gt;box-sizing&lt;/code&gt; 属性切换计算逻辑，这是最容易出错的地方：&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="标准盒子模型-content-box"&gt;标准盒子模型 (&lt;code&gt;content-box&lt;/code&gt;)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特性&lt;/strong&gt;：&lt;code&gt;width&lt;/code&gt; 只等于 &lt;strong&gt;Content&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;总宽度公式&lt;/strong&gt;：&lt;code&gt;Width + Padding*2 + Border*2&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：加了边框或内边距，盒子会被“撑大”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="怪异盒子模型-border-box"&gt;怪异盒子模型 (&lt;code&gt;border-box&lt;/code&gt;)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;特性&lt;/strong&gt;：&lt;code&gt;width&lt;/code&gt; 等于 &lt;strong&gt;Content + Padding + Border&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;总宽度公式&lt;/strong&gt;：等于你设置的 &lt;code&gt;Width&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：加了边框或内边距，内容区会“向内压缩”，盒子总尺寸不变。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="布局"&gt;布局
&lt;/h2&gt;&lt;h3 id="布局标签"&gt;布局标签
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1.&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; 标签 (Division) —— 块级容器&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; 是 &amp;ldquo;division&amp;rdquo;（部分、分区）的缩写，用于定义文档中的一个区块。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;显示特性&lt;/strong&gt;：&lt;strong&gt;块级元素 (Block-level)&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;默认情况下，它会独占一行（宽度默认铺满父容器 100%）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它可以设置宽度 (&lt;code&gt;width&lt;/code&gt;)、高度 (&lt;code&gt;height&lt;/code&gt;)、内边距 (&lt;code&gt;padding&lt;/code&gt;) 和外边距 (&lt;code&gt;margin&lt;/code&gt;)。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常用场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;划分页面的大区域（如：页眉、导航栏、内容区、页脚）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;作为 CSS 布局（如 Flex 或 Grid）的父容器。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;team-card&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;h2&lt;/span&gt;&amp;gt;Alpha Team&amp;lt;/&lt;span style="color:#f92672"&gt;h2&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;积分：1500&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-2.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; 标签 —— 行内容器&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; 用于组合文档中的行内元素，以便通过 CSS 修改局部样式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;显示特性&lt;/strong&gt;：&lt;strong&gt;行内元素 (Inline)&lt;/strong&gt;。
&lt;ul&gt;
&lt;li&gt;它不会换行，只会占据内容所需的宽度，与其他文本排在同一行。&lt;/li&gt;
&lt;li&gt;默认情况下，设置宽高属性无效。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;修改一段文字中某个词的颜色、字号或字体。&lt;/li&gt;
&lt;li&gt;在一行内放置小图标或状态标签。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;队伍 T001 的状态是 &amp;lt;&lt;span style="color:#f92672"&gt;span&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;color: green;&amp;#34;&lt;/span&gt;&amp;gt;AC&amp;lt;/&lt;span style="color:#f92672"&gt;span&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/th&gt;
 &lt;th&gt;&lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;元素类型&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;块级元素 (Block)&lt;/td&gt;
 &lt;td&gt;行内元素 (Inline)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;占用空间&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;独占一行，默认宽度 100%&lt;/td&gt;
 &lt;td&gt;随内容变化，不换行&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;嵌套规则&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;可以包含其它 &lt;code&gt;div&lt;/code&gt; 或 &lt;code&gt;span&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;只能包含文本或其它行内元素&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;布局用途&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;构建网页骨架、容器&lt;/td&gt;
 &lt;td&gt;局部修饰、修饰行内小部件&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="flex布局"&gt;flex布局
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;flex是flexible Box的缩写，意为&amp;quot;弹性布局&amp;quot;，是一种一维的布局模型。flex布局可以为元素之间提供强大的空间分布和对齐能力。&lt;/li&gt;
&lt;li&gt;通过给&lt;strong&gt;父容器&lt;/strong&gt;添加flex的相关属性,来控制&lt;strong&gt;子元素的位置和排列方式&lt;/strong&gt;，&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;理解 Flex 的关键在于明白它有两个轴：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;主轴 (Main Axis)&lt;/strong&gt;：默认是水平方向（从左到右）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;交叉轴 (Cross Axis)&lt;/strong&gt;：默认是垂直方向（从上到下）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以通过 &lt;code&gt;flex-direction&lt;/code&gt; 来交换这两个轴。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;属性&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;常用取值&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;justify-content&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;控制子元素在 &lt;strong&gt;主轴&lt;/strong&gt;（横向）上的对齐&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;center&lt;/code&gt;, &lt;code&gt;space-between&lt;/code&gt;, &lt;code&gt;flex-end&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;align-items&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;控制子元素在 &lt;strong&gt;交叉轴&lt;/strong&gt;（纵向）上的对齐&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;center&lt;/code&gt;, &lt;code&gt;flex-start&lt;/code&gt;, &lt;code&gt;stretch&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;flex&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;控制子元素如何 &lt;strong&gt;分配剩余空间&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;1&lt;/code&gt; (平分), &lt;code&gt;2&lt;/code&gt; (占两份)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-3.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;flex布局相关的CSS样式&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;属性&lt;/th&gt;
 &lt;th style="text-align: left"&gt;说明&lt;/th&gt;
 &lt;th style="text-align: left"&gt;取值&lt;/th&gt;
 &lt;th style="text-align: left"&gt;含义&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;display&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;模式&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;flex&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;使用 flex 布局&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;flex-direction&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;设置主轴&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;row&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;主轴方向为 x 轴，水平向右（默认）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;column&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;主轴方向为 y 轴，垂直向下&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;justify-content&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;子元素在主轴上的对齐方式&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;flex-start&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;从头开始排列&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;flex-end&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;从尾部开始排列&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;center&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;在主轴居中对齐&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;space-around&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;平分剩余空间&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;space-between&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;先两边贴边，再平分剩余空间&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="html--css总览"&gt;HTML &amp;amp; CSS总览
&lt;/h1&gt;&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-4.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;
&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-5.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="javascript"&gt;JavaScript
&lt;/h1&gt;&lt;h2 id="组成"&gt;组成
&lt;/h2&gt;&lt;h3 id="1-ecmascript-核心语法"&gt;1. ECMAScript (核心语法)
&lt;/h3&gt;&lt;p&gt;这是 JavaScript 的&lt;strong&gt;大脑&lt;/strong&gt;，定义了语言的基础规则。它不涉及浏览器，只规定语法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;包含内容&lt;/strong&gt;：变量声明 (&lt;code&gt;var&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt;)、数据类型、流程控制 (if/else, for)、函数、类 (Class)、对象等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标准制定者&lt;/strong&gt;：由 ECMA 国际组织负责更新（如 ES6, ES2023）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通俗理解&lt;/strong&gt;：就像汉语的语法字典，规定了怎么造句，但不规定这些句子是在书里还是在墙上。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="2-dom-文档对象模型"&gt;2. DOM (文档对象模型)
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;DOM (Document Object Model)&lt;/strong&gt; 是 JavaScript 操作网页内容的&lt;strong&gt;手脚&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;功能&lt;/strong&gt;：将 HTML 页面抽象为一棵“树”。JS 通过 DOM 接口可以增、删、改、查网页上的任何标签、属性和样式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常见操作&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;document.getElementById()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改文字内容 (&lt;code&gt;innerText&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改 CSS 样式 (&lt;code&gt;style.display = 'none'&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通俗理解&lt;/strong&gt;：把 HTML 页面看作一间屋子，DOM 就是家具的控制面板，让你能随时换个沙发或者关上灯。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="3-bom-浏览器对象模型"&gt;3. BOM (浏览器对象模型)
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;BOM (Browser Object Model)&lt;/strong&gt; 是 JavaScript 与浏览器软件本身对话的&lt;strong&gt;窗口&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;功能&lt;/strong&gt;：提供与浏览器窗口交互的对象，不涉及页面内部的具体内容。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;包含内容&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;window&lt;/code&gt;&lt;/strong&gt;: 顶层对象（所有 JS 全局变量都在这里）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;location&lt;/code&gt;&lt;/strong&gt;: 获取或设置当前页面的 URL。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;navigation&lt;/code&gt;&lt;/strong&gt;: 获取浏览器信息（版本、系统等）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;history&lt;/code&gt;&lt;/strong&gt;: 操作浏览器的前进和后退。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;screen&lt;/code&gt;&lt;/strong&gt;: 获取屏幕分辨率。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通俗理解&lt;/strong&gt;：它是浏览器的外壳控制，比如弹出一个警告框 (&lt;code&gt;alert&lt;/code&gt;) 或开启一个新的标签页。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="引入方式"&gt;引入方式
&lt;/h2&gt;&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;h3 id="行内引入"&gt;行内引入
&lt;/h3&gt;&lt;p&gt;直接将 JS 代码写在 HTML 标签的事件属性中（如 &lt;code&gt;onclick&lt;/code&gt;）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;onclick&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;alert(&amp;#39;你点击了按钮！&amp;#39;)&amp;#34;&lt;/span&gt;&amp;gt;点击我&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：简单、快速，用于极少量的交互。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：代码与 HTML 耦合度过高，极难维护，&lt;strong&gt;不推荐使用&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="内部引入"&gt;内部引入
&lt;/h3&gt;&lt;p&gt;将代码写在 HTML 文档的 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签内。通常放在 &lt;code&gt;&amp;lt;/body&amp;gt;&lt;/code&gt; 标签之前。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;代码示例&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;lt;&lt;span style="color:#f92672"&gt;h1&lt;/span&gt;&amp;gt;标题&amp;lt;/&lt;span style="color:#f92672"&gt;h1&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;querySelector&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;h1&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;innerText&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&amp;lt;/&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：不需要额外创建文件，适合单个页面的简短脚本。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：如果脚本过长，会使 HTML 文件变得臃肿，无法在多个页面间复用代码。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="外部引入推荐"&gt;外部引入&amp;ndash;推荐
&lt;/h3&gt;&lt;p&gt;将 JS 代码写在独立的 &lt;code&gt;.js&lt;/code&gt; 文件中，通过 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签的 &lt;code&gt;src&lt;/code&gt; 属性引入。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HTML 部分&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;js/main.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JS 部分 (main.js)&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;alert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;这是来自外部文件的代码&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;代码复用&lt;/strong&gt;：多个网页可以引用同一个 JS 文件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结构清晰&lt;/strong&gt;：HTML 只负责结构，JS 负责逻辑，各司其职。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缓存优化&lt;/strong&gt;：浏览器会缓存外部 JS 文件，提高页面加载速度。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="基础语法"&gt;基础语法
&lt;/h2&gt;&lt;h3 id="1-变量声明-variables"&gt;1. 变量声明 (Variables)
&lt;/h3&gt;&lt;p&gt;在现代 JS 中，我们使用 &lt;code&gt;let&lt;/code&gt; 和 &lt;code&gt;const&lt;/code&gt; 来代替过时的 &lt;code&gt;var&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;const&lt;/code&gt;&lt;/strong&gt;: 声明&lt;strong&gt;常量&lt;/strong&gt;。一旦赋值，不能修改。优先使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;let&lt;/code&gt;&lt;/strong&gt;: 声明&lt;strong&gt;变量&lt;/strong&gt;。值可以被重新覆盖。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pi&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3.14&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 不可变
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;score&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 可变
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;score&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 允许
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="2-数据类型-data-types"&gt;2. 数据类型 (Data Types)
&lt;/h3&gt;&lt;p&gt;JS 的数据分为“简单”和“复杂”两类。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;分类&lt;/th&gt;
 &lt;th style="text-align: left"&gt;数据类型&lt;/th&gt;
 &lt;th style="text-align: left"&gt;英文&lt;/th&gt;
 &lt;th style="text-align: left"&gt;说明 &amp;amp; 示例&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;基本类型&lt;/td&gt;
 &lt;td style="text-align: left"&gt;数字&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;number&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;数字（10, 3.14）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;字符串&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;string&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;字符串&lt;code&gt;(&amp;quot;Hello&amp;quot;, 'Hi')&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;布尔&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;布尔（true, false）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;空值&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;空值,&lt;code&gt;null != Null != NULL&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;未定义&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;该变量未初始化&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;引用类型&lt;/td&gt;
 &lt;td style="text-align: left"&gt;对象&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;object&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;对象，用 {} 表示，存储键值对&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;数组&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;array&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;数组，用 [] 表示，存储有序列表&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;使用&lt;code&gt;typeof&lt;/code&gt;运算符可以获取数据类型
&lt;code&gt;typeof a -&amp;gt; number&lt;/code&gt;
避免使用 &lt;code&gt;var&lt;/code&gt;，否则变量可能在声明前被访问而导致 &lt;code&gt;undefined&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING] 注意&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;由字母、数字、下划线 &lt;code&gt;_&lt;/code&gt;、美元符 &lt;code&gt;$&lt;/code&gt; 组成&lt;/li&gt;
&lt;li&gt;不能以数字开头&lt;/li&gt;
&lt;li&gt;严格区分大小写&lt;/li&gt;
&lt;li&gt;不能是 JavaScript 关键字或保留字&lt;/li&gt;
&lt;li&gt;建议见名知意，语义清晰&lt;/li&gt;
&lt;li&gt;推荐使用小驼峰命名法，第一个单词小写，后面单词首字母大写&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4 id="模板字符串"&gt;模板字符串
&lt;/h4&gt;&lt;p&gt;三种功能&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;变量嵌入
通过 &lt;code&gt;${}&lt;/code&gt; 语法，可以直接在字符串中插入变量或表达式，不再需要用大量的 &lt;code&gt;+&lt;/code&gt; 号&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Gemini&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;version&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 旧版写法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;你好，我是 &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;，当前版本是 &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;version&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 模板字符串写法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`你好，我是 &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;，当前版本是 &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;version&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;多行字符串
在传统字符串中，换行需要使用 &lt;code&gt;\n&lt;/code&gt;。而在模板字符串中，可以直接按回车键换行&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 自动保留换行格式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;htmlTemplate&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	 &amp;lt;div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	 &amp;lt;h1&amp;gt;标题&amp;lt;/h1&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	 &amp;lt;p&amp;gt;内容段落&amp;lt;/p&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	 &amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;	`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;嵌入表达式
&lt;code&gt;${}&lt;/code&gt; 内部不仅可以放变量，还可以进行运算、调用函数或逻辑判断。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;price&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;tax&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`总价是：&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;price&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;tax&lt;/span&gt;)&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; 元`&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 运算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`状态：&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;price&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;50&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;昂贵&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;便宜&amp;#39;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 三元运算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!tip]
如果在模板字符串中需要显示反引号本身，请使用转义符：&lt;code&gt;` \` `&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果在模板字符串中需要显示 &lt;code&gt;${}&lt;/code&gt; 原样字符，也需要转义：&lt;code&gt;\${}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="函数"&gt;函数
&lt;/h2&gt;&lt;p&gt;在 &lt;code&gt;JavaScript&lt;/code&gt; 中，&lt;strong&gt;函数（Function）&lt;/strong&gt; 是执行特定任务的可重复调用的代码块。它是程序中最基本的“逻辑单元”。&lt;/p&gt;
&lt;h3 id="函数声明-function-declaration"&gt;函数声明 (Function Declaration)
&lt;/h3&gt;&lt;p&gt;最传统、最常用的方式。具有“声明提升”特性（可以在声明前调用）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;greet&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`你好, &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;!`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;greet&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;)); &lt;span style="color:#75715e"&gt;// 调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="匿名函数"&gt;匿名函数
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;匿名函数（Anonymous Function）&lt;/strong&gt; 是指在定义时&lt;strong&gt;没有函数名称&lt;/strong&gt;的函数。在 JavaScript 中，它们通常作为“工具人”使用，在需要的地方临时定义并立即执行或传递。&lt;/p&gt;
&lt;h4 id="函数表达式-function-expression"&gt;函数表达式 (Function Expression)
&lt;/h4&gt;&lt;p&gt;将函数赋值给一个变量。没有提升特性。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="箭头函数-arrow-function--现代主流"&gt;箭头函数 (Arrow Function) —— &lt;strong&gt;现代主流&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;ES6 引入的简洁写法。注意：它没有自己的 &lt;code&gt;this&lt;/code&gt;，适合用作回调函数。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;multiply&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) =&amp;gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
由于匿名函数没有名字，在复杂的报错调试（Debug）时，错误堆栈里可能只显示 &lt;code&gt;anonymous&lt;/code&gt;，找起 Bug 来会比具名函数稍微麻烦一点。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="自定义对象"&gt;自定义对象
&lt;/h2&gt;&lt;p&gt;在 JavaScript 中，&lt;strong&gt;自定义对象（Custom Objects）&lt;/strong&gt; 是将相关数据（属性）和行为（方法）组织在一起的容器。它是 JS 模拟现实世界实体（如：用户、商品、订单）的核心方式。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;对象名&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;属性名1&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;属性值1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;属性名2&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;属性值2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;属性名3&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;属性值3&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;方法名&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;形参列表&lt;/span&gt;){}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 调用格式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;对象名&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;属性名&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;对象名&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;方法名&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="字面量方式常用"&gt;字面量方式（常用）
&lt;/h3&gt;&lt;p&gt;直接用大括号 &lt;code&gt;{}&lt;/code&gt; 定义，适合创建一个独立、唯一的对象&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;phone&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;brand&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;华为&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;model&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Mate 60&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;price&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5999&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#75715e"&gt;// 方法：对象中的函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {&lt;span style="color:#75715e"&gt;//不推荐使用箭头函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		 &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;正在拨打电话...&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="构造函数"&gt;构造函数
&lt;/h3&gt;&lt;p&gt;当需要批量创建多个结构相似的对象时（如 100 个学生），使用构造函数
&lt;strong&gt;约定&lt;/strong&gt;：函数名首字母大写&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;age&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;age&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;age&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;study&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; 正在学习`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s1&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;小明&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;18&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Student&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;小红&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;19&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="类"&gt;类
&lt;/h3&gt;&lt;p&gt;ES6 引入的语法糖，逻辑更清晰，接近 Java/C# 的风格&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Car&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;constructor&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;color&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;speed&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;color&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;color&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;speed&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;speed&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;drive&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`这辆&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;color&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;的车正在以&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;speed&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;码行驶`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;myCar&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Car&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;白色&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;120&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="json"&gt;JSON
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;JSON (JavaScript Object Notation)&lt;/strong&gt; 是一种轻量级的&lt;strong&gt;数据交换格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它基于 JavaScript 的一个子集，但它是独立于语言的文本格式，目前几乎所有的编程语言（Python, Java, PHP, Go 等）都支持 JSON&lt;/p&gt;
&lt;h2 id="语法规则"&gt;语法规则
&lt;/h2&gt;&lt;p&gt;JSON 的结构非常简单，主要由&lt;strong&gt;键值对&lt;/strong&gt;组成。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据在键值对中&lt;/strong&gt;：键（Key）必须用&lt;strong&gt;双引号&lt;/strong&gt;包裹。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据由逗号分隔&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;对象&lt;/strong&gt;由大括号 &lt;code&gt;{}&lt;/code&gt; 保存。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数组&lt;/strong&gt;由方括号 &lt;code&gt;[]&lt;/code&gt; 保存。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="数据类型"&gt;数据类型
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;示例&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;字符串&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;&amp;quot;Hello World&amp;quot;&lt;/code&gt; (必须双引号)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;数字&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;123&lt;/code&gt;, &lt;code&gt;45.6&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;布尔值&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;数组&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;[&amp;quot;Apple&amp;quot;, &amp;quot;Orange&amp;quot;]&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;对象&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;{&amp;quot;id&amp;quot;: 1, &amp;quot;name&amp;quot;: &amp;quot;Gemini&amp;quot;}&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;空值&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;⚠️ &lt;strong&gt;注意&lt;/strong&gt;：JSON &lt;strong&gt;不能&lt;/strong&gt;包含函数、日期对象或 &lt;code&gt;undefined&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="javascript-中的-json-操作"&gt;JavaScript 中的 JSON 操作
&lt;/h2&gt;&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-6.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// JSON.parse() 当从服务器收到一段 JSON 字符串时，需要用它将其解析为 JS 对象。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;jsonStr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;{&amp;#34;name&amp;#34;: &amp;#34;小明&amp;#34;, &amp;#34;age&amp;#34;: 18}&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;jsonStr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 输出: 小明
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// JSON.stringify() 当准备把数据发送给服务器时，需要将 JS 对象转换为 JSON 字符串。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;user&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;小明&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;age&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;18&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;jsonString&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;user&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;jsonString&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 输出: &amp;#39;{&amp;#34;name&amp;#34;:&amp;#34;小明&amp;#34;,&amp;#34;age&amp;#34;:18}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="dom"&gt;DOM
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;DOM (Document Object Model)&lt;/strong&gt;，即文档对象模型，是 JavaScript 操作网页内容的“桥梁”
它将 HTML 文档表现为一个&lt;strong&gt;树状结构&lt;/strong&gt;，让我们可以通过脚本动态地修改页面的内容、结构和样式。
&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-7.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="dom操作"&gt;DOM操作
&lt;/h2&gt;&lt;p&gt;根据CSS选择器获取DOM对象&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;document.querySelector('选择器')&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：返回匹配到的&lt;strong&gt;第一个&lt;/strong&gt;对象。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：&lt;code&gt;document.querySelector('.my-class')&lt;/code&gt; 或 &lt;code&gt;document.querySelector('#my-id p')&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;document.querySelectorAll('选择器')&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;：返回匹配到的&lt;strong&gt;所有&lt;/strong&gt;对象。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：一个 &lt;code&gt;NodeList&lt;/code&gt;（类似数组的集合，可以用 &lt;code&gt;forEach&lt;/code&gt; 遍历）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;注意:得到的是一个NodeList节点集合，是一个伪数组(有长度、有索引的数组)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;方法&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;获取依据&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;返回值类型&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;getElementById('id')&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;唯一 ID&lt;/td&gt;
 &lt;td&gt;单个对象&lt;/td&gt;
 &lt;td&gt;速度最快，只能找 ID&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;getElementsByClassName('class')&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;类名&lt;/td&gt;
 &lt;td&gt;动态集合 (HTMLCollection)&lt;/td&gt;
 &lt;td&gt;实时更新的集合&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;getElementsByTagName('标签名')&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;标签名&lt;/td&gt;
 &lt;td&gt;动态集合 (HTMLCollection)&lt;/td&gt;
 &lt;td&gt;比如找所有的 &lt;code&gt;div&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="事件监听"&gt;事件监听
&lt;/h2&gt;&lt;h3 id="三要素"&gt;三要素
&lt;/h3&gt;&lt;p&gt;可以把事件监听想象成一个&lt;strong&gt;报警系统&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;事件源 (Target)&lt;/strong&gt;：谁触发了事件？（比如：一个 &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; 按钮）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;事件源.addEventListener('事件类型',事件触发执行的函数);&lt;/code&gt;可以多次绑定同一事件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;早期版本写法:&lt;code&gt;事件源.on事件=function{}&lt;/code&gt;如果多次绑定同一事件，就会&lt;strong&gt;覆盖&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;事件类型 (Type)&lt;/strong&gt;：发生了什么事？（比如：&lt;code&gt;click&lt;/code&gt; 点击）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;事件处理程序 (Handler)&lt;/strong&gt;：要做什么？（通常是一个&lt;strong&gt;回调函数&lt;/strong&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;分类&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;事件名&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;触发时机&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;鼠标事件&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;click&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;鼠标点击&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;mouseenter&lt;/code&gt; / &lt;code&gt;mouseleave&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;鼠标移入 / 移出&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;键盘事件&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;keydown&lt;/code&gt; / &lt;code&gt;keyup&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;按键按下 / 松开&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;表单事件&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;input&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;输入内容改变时（实时）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;change&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;内容改变并失去焦点时&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;submit&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;表单提交时&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;窗口事件&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;load&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;整个页面加载完成&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;scroll&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;页面滚动&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="js优化"&gt;JS优化
&lt;/h2&gt;&lt;p&gt;&lt;img src="HTML&amp;amp;CSS&amp;amp;JS-8.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;</description></item><item><title>基础</title><link>/post/%E5%9F%BA%E7%A1%80/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>/post/%E5%9F%BA%E7%A1%80/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文更新于 2026-04-09&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="http"&gt;HTTP
&lt;/h1&gt;&lt;p&gt;HTTP 是互联网上应用最为广泛的一种&lt;strong&gt;网络协议&lt;/strong&gt;。它定义了浏览器（客户端）与服务器之间交换数据的格式和规则&lt;/p&gt;
&lt;h2 id="http-的基本特性"&gt;HTTP 的基本特性
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;应用层协议&lt;/strong&gt;：运行在 TCP/IP 协议栈之上（默认端口 80，HTTPS 为 443）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求-响应模型&lt;/strong&gt;：必须由客户端发起请求，服务器给出响应。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无状态 (Stateless)&lt;/strong&gt;：协议本身不保留之前的事务记忆。
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;对策&lt;/em&gt;：在开发中通过 &lt;strong&gt;Cookie/Session&lt;/strong&gt; 或 &lt;strong&gt;JWT (Token)&lt;/strong&gt; 来维持登录状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活&lt;/strong&gt;：允许传输任意类型的数据对象，通过 &lt;code&gt;Content-Type&lt;/code&gt; 加以标记。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src="%e5%9f%ba%e7%a1%80-1.png"
 loading="lazy"
 data-pending-gallery
 
 &gt;&lt;/p&gt;
&lt;h2 id="http-请求报文结构"&gt;HTTP 请求报文结构
&lt;/h2&gt;&lt;p&gt;一个标准的 HTTP 请求由四部分组成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求行 (Request Line)&lt;/strong&gt;：
&lt;code&gt;Method&lt;/code&gt; + &lt;code&gt;URL&lt;/code&gt; + &lt;code&gt;Version&lt;/code&gt; (如 &lt;code&gt;GET /index.html HTTP/1.1&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求头 (Request Headers)&lt;/strong&gt;：键值对格式，描述客户端环境和偏好。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Host&lt;/code&gt;: 目标主机。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;User-Agent&lt;/code&gt;: 浏览器标识。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Accept&lt;/code&gt;: 客户端可接受的内容类型。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;空行&lt;/strong&gt;：必须存在，用于分隔头部和正文。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;请求体 (Request Body)&lt;/strong&gt;：仅 &lt;code&gt;POST/PUT&lt;/code&gt; 等方法使用，存放要提交的数据（如 JSON）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="http-响应报文与状态码"&gt;HTTP 响应报文与状态码
&lt;/h2&gt;&lt;p&gt;响应报文同样由 &lt;strong&gt;状态行&lt;/strong&gt;、&lt;strong&gt;响应头&lt;/strong&gt;、&lt;strong&gt;空行&lt;/strong&gt;、&lt;strong&gt;响应体&lt;/strong&gt; 组成。&lt;/p&gt;
&lt;h4 id="核心状态码分类"&gt;核心状态码分类：
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2xx (成功)&lt;/strong&gt;：&lt;code&gt;200 OK&lt;/code&gt; (请求成功)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3xx (重定向)&lt;/strong&gt;：&lt;code&gt;301&lt;/code&gt; (永久重定向)、&lt;code&gt;302&lt;/code&gt; (临时重定向)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4xx (客户端错误)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;400 Bad Request&lt;/code&gt;: 请求语法错误。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;403 Forbidden&lt;/code&gt;: 服务器拒绝执行。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;404 Not Found&lt;/code&gt;: 资源不存在。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;405 Method Not Allowed&lt;/code&gt;: 方法不支持（如用 GET 访问 POST 接口）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5xx (服务器错误)&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;500 Internal Server Error&lt;/code&gt;: 后端代码抛出未处理的异常。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;502 Bad Gateway&lt;/code&gt;: 网关从后端收到了非法响应（如 Nginx 找不到 Java 服务）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;504 Gateway Timeout&lt;/code&gt;: 后端处理超时。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="长链接与短链接"&gt;长链接与短链接
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;HTTP&lt;/th&gt;
 &lt;th&gt;应用层协议&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;TCP&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;传输层协议&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;ip&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;网络层协议&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;strong&gt;特性&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;短连接 (Short Connection)&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;长连接 (Keep-Alive)&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;底层表现&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;一次请求/响应消耗一个 TCP 连接&lt;/td&gt;
 &lt;td&gt;多次请求/响应复用一个 TCP 连接&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;HTTP 版本&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;HTTP/1.0 默认&lt;/td&gt;
 &lt;td&gt;HTTP/1.1 默认&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;HTTP Header&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;Connection: close&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;Connection: keep-alive&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;握手开销&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;高（每次请求都要三次握手）&lt;/td&gt;
 &lt;td&gt;低（仅首次建立需要）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;服务器压力&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;CPU 压力较大（频繁建立/销毁连接）&lt;/td&gt;
 &lt;td&gt;内存压力较大（需维持空闲连接的 socket）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;偶尔交互的单次请求、请求频率极低的服务&lt;/td&gt;
 &lt;td&gt;Web 页面浏览、前后端高频 API 交互、图片服务器&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;</description></item></channel></rss>