<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>我的学习小铺</title><description>学习笔记</description><link>https://study-docs-158.pages.dev/</link><templateTheme>Firefly</templateTheme><templateThemeVersion>6.15.3</templateThemeVersion><templateThemeUrl>https://github.com/CuteLeaf/Firefly</templateThemeUrl><lastBuildDate>2026年8月1日 15:18:52</lastBuildDate><item><title>到底什么问题该问同事</title><link>https://study-docs-158.pages.dev/posts/%E5%88%B0%E5%BA%95%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98%E8%AF%A5%E9%97%AE%E5%90%8C%E4%BA%8B/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%88%B0%E5%BA%95%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98%E8%AF%A5%E9%97%AE%E5%90%8C%E4%BA%8B/</guid><description>到底什么问题该问同事</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-27/5e0713b5-1bf6-4b5d-aac2-56dbdd88f0fe.jpg&quot; alt=&quot;哪些问题该问同事&quot; /&gt;&lt;figcaption&gt;哪些问题该问同事&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;刚入职新公司，很多新人会陷入两个极端：要么胆战心惊什么都不敢问，导致进度卡壳；要么事无巨细当个“伸手党”，惹人厌烦。&lt;/p&gt;
&lt;p&gt;到底掌握怎样的提问尺度，才能既快速融入团队，又展现专业素养？请熟记以下三大准则。&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;一、 大胆开口：哪些问题该问同事？&lt;a href=&quot;#一-大胆开口哪些问题该问同事&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;当遇到&lt;strong&gt;公司特有的、缺乏文档说明的、或者涉及业务逻辑&lt;/strong&gt;的问题时，不要自己瞎琢磨，一定要及时向同事请教。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1. 缺乏文档支持的“开发流程”问题&lt;a href=&quot;#1-缺乏文档支持的开发流程问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;如果公司没有提供清晰的文档，以下流程必须问清楚，避免做无用功：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;代码规范：&lt;/strong&gt; 团队的开发规范和 Git 协同开发流程是怎样的？&lt;/li&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;/section&gt;&lt;section&gt;&lt;h3&gt;2. 缺乏文档支持的“环境配置”问题&lt;a href=&quot;#2-缺乏文档支持的环境配置问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&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;strong&gt;版本&lt;/strong&gt;？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;服务器权限：&lt;/strong&gt; 登录公司服务器是使用 xshell 直接连接，还是必须通过堡垒机？如果是堡垒机，具体该如何使用？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置文件与依赖：&lt;/strong&gt; 项目有多个配置文件时，本地启动该激活哪个环境？公司是否使用 Maven 私服？如果是，找同事索要包含私服配置信息的 &lt;code&gt;settings.xml&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3. 公司专属的“业务与需求”问题&lt;a href=&quot;#3-公司专属的业务与需求问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&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;li&gt;&lt;strong&gt;内部平台使用：&lt;/strong&gt; 公司自研的 Bug 管理平台或小众项目管理工具不知道怎么用时，可以请教。（&lt;strong&gt;注意提问方式：&lt;/strong&gt; 明确告诉同事你要做什么具体操作卡住了，而不是丢一句“这系统怎么用”）。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、 职场红线：哪些问题绝对不要问？&lt;a href=&quot;#二-职场红线哪些问题绝对不要问&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;职场不是学校，同事没有义务手把手教你基础知识。以下三类问题，问了就会被打上“不专业”的标签。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1. 随手可查的“懒人问题”&lt;a href=&quot;#1-随手可查的懒人问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;不要把同事当成你的免费搜索引擎。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;百度/谷歌能解决的基础问题：&lt;/strong&gt; 例如“Swagger 怎么使用？”、“&lt;code&gt;@Param&lt;/code&gt; 注解是什么意思？”、“SpringBoot 多配置文件怎么选择生效？”。这些纯技术基础，请自行解决。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公司文档里明文写着的：&lt;/strong&gt; 例如“公司代码仓库地址在哪？”、“Maven 私仓地址是多少？”、“项目怎么启动？”。&lt;strong&gt;提问前，先翻遍新人文档！&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码里写得清清楚楚的：&lt;/strong&gt; 例如“数据库连接信息是什么？”、“启动的服务端口是多少？”、“Redis 连接密码是什么？”。自己去项目的 &lt;code&gt;application.yml&lt;/code&gt; 或 &lt;code&gt;properties&lt;/code&gt; 文件里看！&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2. 宽泛、空洞的“情绪化问题”&lt;a href=&quot;#2-宽泛空洞的情绪化问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;li&gt;&lt;strong&gt;点评：&lt;/strong&gt; 这类问题暴露了你没有经过任何思考。要把问题具体化，说清楚你梳理到了哪一步、哪里看不懂，让别人看到你是在思考的。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3. 同一个问题多次问&lt;a href=&quot;#3-同一个问题多次问&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;好记性不如烂笔头。别人解答过的问题、给过的配置项，&lt;strong&gt;立刻拿小本本或文档记下来&lt;/strong&gt;。同一个坑掉进去两次，是非常消耗同事耐心的行为。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、 提问的艺术：如何高效向同事请教？&lt;a href=&quot;#三-提问的艺术如何高效向同事请教&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;总结来说，一个高质量的职场提问应该包含这三个要素：&lt;strong&gt;背景 + 你的尝试 + 具体的卡点&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;你可以套用这个黄金提问句式：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“（称呼），关于**【具体某个任务/功能】&lt;strong&gt;，我在尝试&lt;/strong&gt;【你做的操作】&lt;strong&gt;时遇到了问题。我已经查阅了&lt;/strong&gt;【某某文档/看了某段代码】&lt;strong&gt;，但我对&lt;/strong&gt;【具体某个细节点】**还是不太理解。请问你有空帮我指点一下这个具体的地方吗？”&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这样提问，既展示了你的独立解决问题能力，又极大地降低了同事解答的成本。&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>定时任务Quartz框架的使用</title><link>https://study-docs-158.pages.dev/posts/%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1quartz%E6%A1%86%E6%9E%B6%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1quartz%E6%A1%86%E6%9E%B6%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>定时任务Quartz框架的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、基础概述&lt;a href=&quot;#一基础概述&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-04-18/51e15cdb-c084-4373-9c81-c4bd9abd672e.png&quot; alt=&quot;分布式定时任务鼻祖Quartz架构图&quot; /&gt;&lt;figcaption&gt;分布式定时任务鼻祖Quartz架构图&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、什么是Quartz？&lt;a href=&quot;#1什么是quartz&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单说：Quartz是一个强大的企业级定时任务框架，用来在指定时间、按照复杂规则自动执行代码。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;生活中的例子：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;每天凌晨2点备份数据库&lt;/li&gt;
&lt;li&gt;每小时同步一次上游系统数据&lt;/li&gt;
&lt;li&gt;每月最后一天晚上23点生成对账报表&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、为什么学Quartz？&lt;a href=&quot;#2为什么学quartz&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;你可能会问：Spring的&lt;code&gt;@Scheduled&lt;/code&gt;不是也能做定时任务吗？&lt;/p&gt;


































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;对比项&lt;/th&gt;&lt;th&gt;@Scheduled&lt;/th&gt;&lt;th&gt;Quartz&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&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;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;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;p&gt;&lt;strong&gt;结论：简单且固定的场景用 &lt;code&gt;@Scheduled&lt;/code&gt;，需要动态管理、怕重启丢任务、有多台服务器集群的场景，必须用 Quartz（或 XXL-Job 等）。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、Quartz三个核心概念&lt;a href=&quot;#3quartz三个核心概念&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;类比&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Job（任务）&lt;/td&gt;&lt;td&gt;具体要干的事&lt;/td&gt;&lt;td&gt;具体的工作内容&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Trigger（触发器）&lt;/td&gt;&lt;td&gt;定义什么时候执行&lt;/td&gt;&lt;td&gt;工作时间表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Scheduler（调度器）&lt;/td&gt;&lt;td&gt;把Job和Trigger组合起来&lt;/td&gt;&lt;td&gt;老板，统筹安排工作&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Plaintext&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Job（做什么） + Trigger（什么时候做） = Scheduler（安排执行）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、快速入门（最简内存版 Demo）&lt;a href=&quot;#二快速入门最简内存版-demo&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;em&gt;这部分用于快速理解 Quartz 的骨架，任务信息保存在内存中，重启后重置。&lt;/em&gt;&lt;/p&gt;&lt;section&gt;&lt;h3&gt;第一步：引入依赖&lt;a href=&quot;#第一步引入依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;只要引入 Spring Boot 的官方 Starter，底层依赖全部帮你搞定。&lt;/p&gt;&lt;p&gt;XML&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.springframework.boot&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;spring-boot-starter-quartz&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;第二步：创建任务类（🔥 优雅写法）&lt;a href=&quot;#第二步创建任务类-优雅写法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;避坑：&lt;/strong&gt; 很多老教程教你实现 &lt;code&gt;Job&lt;/code&gt; 接口，然后告诉你无法使用 &lt;code&gt;@Autowired&lt;/code&gt;。在 Spring Boot 中，&lt;strong&gt;强烈建议继承 &lt;code&gt;QuartzJobBean&lt;/code&gt;&lt;/strong&gt;，这样就可以直接快乐地注入任何 Service 了！&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Java&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import org.quartz.JobExecutionContext;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import org.quartz.JobExecutionException;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import org.springframework.beans.factory.annotation.Autowired;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import org.springframework.scheduling.quartz.QuartzJobBean;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import org.springframework.stereotype.Component;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import java.util.Date;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public class MyJob extends QuartzJobBean {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 继承 QuartzJobBean 后，直接使用 @Autowired 注入，非常优雅！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;private OrderService orderService;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;protected void executeInternal(JobExecutionContext context) throws JobExecutionException {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;System.out.println(&quot;定时任务执行了：&quot; + new Date());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 直接调用你的业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderService.doSomething();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;第三步：创建配置类（老板分配工作）&lt;a href=&quot;#第三步创建配置类老板分配工作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Java&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public class QuartzConfig {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@Bean&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;public JobDetail myJobDetail() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 创建JobDetail，指定任务类&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return JobBuilder.newJob(MyJob.class)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.withIdentity(&quot;myJob&quot;, &quot;group1&quot;)  // 任务名称和分组&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.storeDurably()                    // 即使没有Trigger也保留在调度器中&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.build();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@Bean&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;public Trigger myJobTrigger() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 创建触发器，每10秒执行一次&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return TriggerBuilder.newTrigger()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.forJob(myJobDetail())             // 关联上面的 JobDetail&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.withIdentity(&quot;myTrigger&quot;, &quot;group1&quot;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.withSchedule(SimpleScheduleBuilder.simpleSchedule()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.withIntervalInSeconds(10)  // 每10秒执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.repeatForever())           // 无限重复&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.build();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;启动项目后，任务就会自动每 10 秒执行一次了。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、两种核心 Trigger（触发器）&lt;a href=&quot;#三两种核心-trigger触发器&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、SimpleTrigger（简单触发器）&lt;a href=&quot;#1simpletrigger简单触发器&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;适用场景：&lt;/strong&gt; 简单的重复执行，比如“每隔 X 分钟执行一次”、“延迟 X 秒后执行 10 次”。&lt;/p&gt;&lt;p&gt;Java&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 延迟立即开始，每5秒执行一次，共执行10次&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Trigger trigger = TriggerBuilder.newTrigger()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.startNow()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.withSchedule(SimpleScheduleBuilder.simpleSchedule()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.withIntervalInSeconds(5)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.withRepeatCount(10))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.build();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、CronTrigger（Cron触发器）&lt;a href=&quot;#2crontriggercron触发器&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;适用场景：&lt;/strong&gt; 复杂的时间表达式，比如“每天凌晨2点”、“每周五下午4点”。&lt;/p&gt;&lt;p&gt;Java&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 每天凌晨2点执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Trigger&lt;/span&gt;&lt;span&gt; trigger &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;TriggerBuilder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;newTrigger&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;withSchedule&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;CronScheduleBuilder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;cronSchedule&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;0 0 2 * * ?&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;🚨 注意：Quartz Cron 与 Linux Crontab 的区别&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Quartz 的 Cron 支持&lt;strong&gt;秒级&lt;/strong&gt;（有 6~7 位），而 Linux 通常只有 5 位（没有秒）。&lt;/li&gt;
&lt;li&gt;Quartz 规定**“日”和“周”必须有一个用 &lt;code&gt;?&lt;/code&gt; 隔开**以防冲突，Linux 不支持 &lt;code&gt;?&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;强烈建议使用在线工具生成并测试：&lt;a href=&quot;https://cron.ciding.cc/&quot; target=&quot;_blank&quot;&gt;https://cron.ciding.cc/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、高阶必杀技：并发控制（极度重要）&lt;a href=&quot;#四高阶必杀技并发控制极度重要&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;痛点：&lt;/strong&gt; 假设你的任务是每 5 分钟同步一次大量数据。如果某次同步数据量极大，跑了 8 分钟才跑完，但第 5 分钟的时候，Quartz 又会启动一个新线程去跑同步，&lt;strong&gt;导致两个线程同时操作同一批数据，引发严重的死锁或脏数据！&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;解决方案：加一个 &lt;code&gt;@DisallowConcurrentExecution&lt;/code&gt; 注解。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Java&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import org.quartz.DisallowConcurrentExecution;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@DisallowConcurrentExecution // 🔥加上这个注解，Quartz就会等上一次任务彻底跑完，再跑下一次，绝不并发！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public class SafeDataSyncJob extends QuartzJobBean {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;protected void executeInternal(JobExecutionContext context) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 耗时的业务逻辑...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、动态管理任务（企业级真实场景）&lt;a href=&quot;#五动态管理任务企业级真实场景&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;在真实的开发中，以下这些代码通常会被写在 Service 层，然后暴露成 Controller 接口。前端会画一个漂亮的后台管理页面，运营人员在页面上点击“新增”、“启动”、“暂停”按钮，本质上就是调用了这里的代码，从而实现不重启服务器就能掌控定时任务。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;通过 SpringBoot 自动注入的 &lt;code&gt;Scheduler&lt;/code&gt; 对象，我们可以为所欲为：&lt;/p&gt;&lt;p&gt;Java&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public class QuartzManageService {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;private Scheduler scheduler;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 1. 动态添加任务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;public void addJob(String jobName, String jobGroup, String cronExpression, Class&amp;lt;? extends Job&amp;gt; jobClass) throws Exception {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroup).build();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).build();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;scheduler.scheduleJob(jobDetail, trigger);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 2. 暂停任务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;public void pauseJob(String jobName, String jobGroup) throws Exception {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;scheduler.pauseJob(JobKey.jobKey(jobName, jobGroup));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 3. 恢复任务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;public void resumeJob(String jobName, String jobGroup) throws Exception {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;scheduler.resumeJob(JobKey.jobKey(jobName, jobGroup));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 4. 立刻手动触发执行一次（不管时间到没到，常用于测试或数据紧急补偿）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;public void triggerJob(String jobName, String jobGroup) throws Exception {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;scheduler.triggerJob(JobKey.jobKey(jobName, jobGroup));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、企业级生产实战（持久化配置）&lt;a href=&quot;#六企业级生产实战持久化配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;内存模式的致命弱点：&lt;/strong&gt; 一旦服务器重启，所有动态添加的任务、修改的时间全部丢失！&lt;/p&gt;&lt;p&gt;&lt;strong&gt;企业级做法：&lt;/strong&gt; 开启 JDBC 持久化，让 Quartz 把任务数据、执行状态全部存到 MySQL 里。&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;1、准备数据库表&lt;a href=&quot;#1准备数据库表&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;前往 Quartz 官网下载自带的 SQL 脚本（包含了 &lt;code&gt;QRTZ_JOB_DETAILS&lt;/code&gt;、&lt;code&gt;QRTZ_TRIGGERS&lt;/code&gt; 等十来张表），在你的 MySQL 数据库中执行建表。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、修改 application.yml&lt;a href=&quot;#2修改-applicationyml&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;只要加这几行配置，Spring Boot 会自动接管一切，从内存模式切换为数据库模式：&lt;/p&gt;&lt;p&gt;YAML&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;quartz&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;job-store-type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;jdbc&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 🔥核心：告诉Spring使用数据库存储任务信息&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;jdbc&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;initialize-schema&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;never&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 不让它每次启动建表，我们手动建好了&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;properties&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;org&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;quartz&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;jobStore&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;org.quartz.impl.jdbcjobstore.JobStoreTX&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;driverDelegateClass&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;org.quartz.impl.jdbcjobstore.StdJDBCDelegate&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;isClustered&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 🔥核心：开启集群支持。部署多台机器时，它们会抢数据库锁，保证任务只执行一次！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;clusterCheckinInterval&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;10000&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# 集群心跳检测时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;有了这两步，你的项目就已经具备了&lt;strong&gt;分布式调度、防重跑、防宕机丢失&lt;/strong&gt;的企业级能力！&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、新人避坑指南&lt;a href=&quot;#七新人避坑指南&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;任务类无法注入 Bean，报空指针&lt;/td&gt;&lt;td&gt;不要实现 Job 接口，改为继承 QuartzJobBean，即可完美使用 @Autowired。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;任务执行时间过长，导致互相踩踏&lt;/td&gt;&lt;td&gt;在任务类名上方加上 @DisallowConcurrentExecution 注解，禁止并发。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Linux 和代码的 Cron 语法冲突&lt;/td&gt;&lt;td&gt;Quartz 的 Cron 有秒位，且日和周必须有一个用 ?。拿不准时一定要用在线生成工具，不要盲猜。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;发版重启后，之前加的任务全没了&lt;/td&gt;&lt;td&gt;生产环境务必配置 spring.quartz.job-store-type=jdbc，走数据库持久化。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;业务出了 Bug，导致定时任务彻底停摆&lt;/td&gt;&lt;td&gt;在 executeInternal 方法里，业务逻辑一定要 try-catch 包裹，并打上 log.error。千万别把异常抛给 Quartz 调度器，否则容易导致后续调度卡死。&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;八、技术选型对比（我该用哪个？）&lt;a href=&quot;#八技术选型对比我该用哪个&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;


































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;维度&lt;/th&gt;&lt;th&gt;@Scheduled&lt;/th&gt;&lt;th&gt;Quartz&lt;/th&gt;&lt;th&gt;XXL-Job / Elastic-Job&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;上手难度&lt;/td&gt;&lt;td&gt;极低（1个注解）&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;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;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;td&gt;适合大中型企业、微服务架构，任务海量且需要完善的监控告警&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;💡 终极建议：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;能简单就简单，小项目无脑用 &lt;code&gt;@Scheduled&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;如果项目不能引入重量级的外部框架，但又要防重启、集群防重跑，直接上 &lt;strong&gt;Quartz 持久化模式&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;如果公司体量大、任务多，运维有现成的平台，不要自己造轮子，直接接入 &lt;strong&gt;XXL-Job&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;</content:encoded></item><item><title>定时任务Scheduled注解的使用</title><link>https://study-docs-158.pages.dev/posts/%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1scheduled%E6%B3%A8%E8%A7%A3%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1scheduled%E6%B3%A8%E8%A7%A3%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>定时任务Scheduled注解的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、基础概述&lt;a href=&quot;#一基础概述&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、什么是定时任务？&lt;a href=&quot;#1什么是定时任务&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单说：定时任务就是到点自动执行的代码。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;生活中的例子：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;每天凌晨2点备份数据库&lt;/li&gt;
&lt;li&gt;每小时同步一次第三方数据&lt;/li&gt;
&lt;li&gt;每月1号生成报表&lt;/li&gt;
&lt;/ul&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;/th&gt;&lt;th&gt;执行频率&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/tr&gt;&lt;tr&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;/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;/section&gt;&lt;section&gt;&lt;h3&gt;2、Spring Scheduled是什么？&lt;a href=&quot;#2spring-scheduled是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Spring框架自带的定时任务功能，使用简单，只需要加注解就能实现。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;优点：&lt;/strong&gt;&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;p&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&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;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、快速入门&lt;a href=&quot;#二快速入门&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;第一步：开启定时任务支持&lt;a href=&quot;#第一步开启定时任务支持&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在启动类上加 &lt;code&gt;@EnableScheduling&lt;/code&gt; 注解：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;SpringBootApplication&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;EnableScheduling&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 开启定时任务支持&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Application&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;[] &lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;SpringApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Application&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;, args);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;第二步：创建定时任务&lt;a href=&quot;#第二步创建定时任务&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在方法上加 &lt;code&gt;@Scheduled&lt;/code&gt; 注解：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;MyScheduledTask&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cron&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;0 0 2 * * ?&quot;&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 每天凌晨2点执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;executeTask&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;定时任务执行了：&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 这里写业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;就这样，一个定时任务就完成了！&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、@Scheduled注解参数详解&lt;a href=&quot;#三scheduled注解参数详解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、cron表达式（最常用）&lt;a href=&quot;#1cron表达式最常用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;格式：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;秒 分 时 日 月 周 [年]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;th&gt;特殊字符&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;秒&lt;/td&gt;&lt;td&gt;0-59&lt;/td&gt;&lt;td&gt;, - * /&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;分&lt;/td&gt;&lt;td&gt;0-59&lt;/td&gt;&lt;td&gt;, - * /&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;时&lt;/td&gt;&lt;td&gt;0-23&lt;/td&gt;&lt;td&gt;, - * /&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;日&lt;/td&gt;&lt;td&gt;1-31&lt;/td&gt;&lt;td&gt;, - * ? / L W&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;月&lt;/td&gt;&lt;td&gt;1-12&lt;/td&gt;&lt;td&gt;, - * /&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;周&lt;/td&gt;&lt;td&gt;0-7&lt;/td&gt;&lt;td&gt;, - * ? / L #&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&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;/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;/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;tr&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;范围&lt;/td&gt;&lt;td&gt;0 0 9-17 * * ? 9点到17点每小时&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;,&lt;/td&gt;&lt;td&gt;列举&lt;/td&gt;&lt;td&gt;0 0 9,12,15 * * ? 9点、12点、15点&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/&lt;/td&gt;&lt;td&gt;间隔&lt;/td&gt;&lt;td&gt;0 0/30 * * * ? 每30分钟&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;L&lt;/td&gt;&lt;td&gt;最后&lt;/td&gt;&lt;td&gt;0 0 0 L * ? 每月最后一天&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;常用cron表达式：&lt;/strong&gt;&lt;/p&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;0 0 12 * * ?&lt;/td&gt;&lt;td&gt;每天中午12点&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0 0 0 * * ?&lt;/td&gt;&lt;td&gt;每天凌晨0点&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0 0/30 * * * ?&lt;/td&gt;&lt;td&gt;每30分钟&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0 0 2 * * ?&lt;/td&gt;&lt;td&gt;每天凌晨2点&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0 0 0 1 * ?&lt;/td&gt;&lt;td&gt;每月1号凌晨&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0 0 9-17 * * ?&lt;/td&gt;&lt;td&gt;每天9点到17点每小时&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0 0 9 * * MON-FRI&lt;/td&gt;&lt;td&gt;周一到周五每天9点&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0 0/5 * * * ?&lt;/td&gt;&lt;td&gt;每5分钟&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;在线生成工具：&lt;/strong&gt; &lt;a href=&quot;https://cron.ciding.cc/&quot; target=&quot;_blank&quot;&gt;https://cron.ciding.cc/&lt;/a&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人技巧：&lt;/strong&gt; 不用背cron表达式，用在线工具生成就行。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、fixedDelay（固定延迟）&lt;a href=&quot;#2fixeddelay固定延迟&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;特点：&lt;/strong&gt; 上一次执行完成后，等待指定时间再执行。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fixedDelay&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;5000&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 上次执行完5秒后再执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;task1&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;执行任务：&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 假设执行了3秒&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 那么下次执行是：执行完成时间 + 5秒&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;适合场景：&lt;/strong&gt; 任务执行时间不固定，需要等上次执行完再执行的情况。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、fixedRate（固定频率）&lt;a href=&quot;#3fixedrate固定频率&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;特点：&lt;/strong&gt; 不管上次是否执行完，每隔固定时间执行一次。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fixedRate&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;5000&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 每5秒执行一次&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;task2&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;执行任务：&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;适合场景：&lt;/strong&gt; 需要固定频率执行的任务，如心跳检测。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、initialDelay（首次延迟）&lt;a href=&quot;#4initialdelay首次延迟&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;特点：&lt;/strong&gt; 第一次延迟指定时间后再开始执行。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;initialDelay&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;10000&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fixedRate&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;5000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 启动后10秒开始执行，之后每5秒执行一次&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;task3&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;执行任务：&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;适合场景：&lt;/strong&gt; 项目启动后需要延迟一段时间再执行的任务。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、参数对比&lt;a href=&quot;#5参数对比&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;使用场景&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;cron&lt;/td&gt;&lt;td&gt;精确时间点&lt;/td&gt;&lt;td&gt;每天凌晨、每小时等&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;fixedDelay&lt;/td&gt;&lt;td&gt;上次执行完后再等&lt;/td&gt;&lt;td&gt;执行时间不固定的任务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;fixedRate&lt;/td&gt;&lt;td&gt;固定频率执行&lt;/td&gt;&lt;td&gt;心跳、监控等&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;initialDelay&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;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、实际工作中的示例&lt;a href=&quot;#四实际工作中的示例&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;示例1：每天凌晨同步数据&lt;a href=&quot;#示例1每天凌晨同步数据&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Slf4j&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;DataSyncTask&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;DataService&lt;/span&gt;&lt;span&gt; dataService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cron&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;0 0 2 * * ?&quot;&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 每天凌晨2点执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;syncData&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;开始同步数据&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;dataService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;syncFromThirdParty&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;数据同步完成&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;数据同步失败&quot;&lt;/span&gt;&lt;span&gt;, e);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;示例2：每5分钟检查超时订单&lt;a href=&quot;#示例2每5分钟检查超时订单&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Slf4j&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderTimeoutTask&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; orderService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cron&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;0 0/5 * * * ?&quot;&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 每5分钟执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;checkTimeout&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;开始检查超时订单&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;count&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;cancelTimeoutOrders&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;取消了{}个超时订单&quot;&lt;/span&gt;&lt;span&gt;, count);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;示例3：定时清理临时文件&lt;a href=&quot;#示例3定时清理临时文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Slf4j&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FileCleanTask&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cron&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;0 0 3 * * ?&quot;&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 每天凌晨3点执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cleanTempFiles&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;开始清理临时文件&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 删除7天前的临时文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;File&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tempDir&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;File&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/tmp&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 清理逻辑...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;临时文件清理完成&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;示例4：带有任务开关的定时任务（真实工作场景必备）&lt;a href=&quot;#示例4带有任务开关的定时任务真实工作场景必备&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;业务痛点：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;本地开发抢数据：&lt;/strong&gt; 本地启动项目时，如果不小心触发了定时任务，会把测试环境的数据处理掉，影响测试同事。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;线上紧急止血：&lt;/strong&gt; 线上定时任务出现严重 Bug，如果代码里没有开关，只能紧急发版或者直接停机。&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt; 结合配置文件（配合 Nacos / Apollo 等动态配置中心使用效果最佳）实现任务的动态控制。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;application.yml 配置：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;YAML&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 定时任务开关配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;task&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;user-sync&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;enabled&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 生产环境设为 true，本地开发环境设为 false&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Java 代码实现：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Java&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Slf4j&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserSyncTask&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 从配置文件中读取开关状态。冒号后面的 false 是默认值（防备没配报错）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 如果公司使用了 Nacos 或 Apollo，修改配置后这里的值会动态生效，无需重启服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;${task.user-sync.enabled:false}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; isTaskEnabled&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cron&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;0 0/10 * * * ?&quot;&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 每10分钟执行一次&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;syncUser&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 任务开关判断（核心防御逻辑）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;isTaskEnabled) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;【用户同步定时任务】全局开关已关闭，本次跳过执行...&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;【用户同步定时任务】开始执行...&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 2. 执行核心业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;syncUserData&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;【用户同步定时任务】执行成功&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 3. 异常捕获，防止单次报错导致后续不再调度&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;【用户同步定时任务】执行发生异常&quot;&lt;/span&gt;&lt;span&gt;, e);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;🔥 进阶写法（更优雅的 Spring 原生方式）：&lt;/strong&gt; 如果你希望在本地环境&lt;strong&gt;彻底不加载&lt;/strong&gt;这个定时任务（连 Bean 都不创建），可以使用 &lt;code&gt;@ConditionalOnProperty&lt;/code&gt; 注解代替代码里的 &lt;code&gt;if&lt;/code&gt; 判断：&lt;/p&gt;&lt;p&gt;Java&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Slf4j&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 只有当配置文件中 task.user-sync.enabled=true 时，这个定时任务才会生效&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;ConditionalOnProperty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;task.user-sync.enabled&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;havingValue&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;true&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserSyncTask&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cron&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;0 0/10 * * * ?&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;syncUser&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 直接写业务逻辑，不需要再做 if 判断了&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;注意：@ConditionalOnProperty的方式只能在项目启动时决定是否开启，不支持不重启服务动态切换。真实工作中可根据实际需求选择这两种开关方式。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、多线程配置（进阶）&lt;a href=&quot;#五多线程配置进阶&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;问题：默认单线程&lt;a href=&quot;#问题默认单线程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cron&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;0/5 * * * * ?&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;task1&lt;/span&gt;&lt;span&gt;() throws InterruptedException {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Thread&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sleep&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10000&lt;/span&gt;&lt;span&gt;&lt;span&gt;);&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 执行10秒&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;任务1&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cron&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;0/5 * * * * ?&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;task2&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;任务2&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// task2要等task1执行完才能执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;解决方案：配置线程池&lt;a href=&quot;#解决方案配置线程池&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;EnableScheduling&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ScheduleConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SchedulingConfigurer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;configureTasks&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ScheduledTaskRegistrar&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;taskRegistrar&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 配置10个线程&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;taskRegistrar&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setScheduler&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Executors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;newScheduledThreadPool&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;配置后，多个定时任务可以并行执行。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、常见问题&lt;a href=&quot;#六常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、定时任务不执行？&lt;a href=&quot;#1定时任务不执行&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;检查：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;启动类有没有加 &lt;code&gt;@EnableScheduling&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;类有没有加 &lt;code&gt;@Component&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;cron表达式是否正确&lt;/li&gt;
&lt;li&gt;定时任务注解@Scheduled修饰的方法不能有入参&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、任务执行时间过长影响其他任务？&lt;a href=&quot;#2任务执行时间过长影响其他任务&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;解决：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;配置线程池，让任务并行执行&lt;/li&gt;
&lt;li&gt;或者优化任务执行效率&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、多台服务器都会执行怎么办？&lt;a href=&quot;#3多台服务器都会执行怎么办&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Scheduled不支持集群，每台服务器都会执行。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;使用XXL-Job等分布式任务调度框架&lt;/li&gt;
&lt;li&gt;或者用数据库锁让只有一台服务器执行&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、注意事项&lt;a href=&quot;#七注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;记得打日志&lt;/strong&gt;：定时任务要记录执行情况&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异常处理&lt;/strong&gt;：加try-catch，避免异常导致任务停止&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行时间&lt;/strong&gt;：避免任务执行时间超过间隔时间&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;集群问题&lt;/strong&gt;：Scheduled不支持集群，每台机器都会执行&lt;/li&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;li&gt;&lt;strong&gt;方法签名的硬性要求&lt;/strong&gt;：被@Scheduled修饰的方法&lt;strong&gt;必须且只能返回 &lt;code&gt;void&lt;/code&gt;&lt;/strong&gt;，且&lt;strong&gt;不能有任何入参&lt;/strong&gt;。如果加了入参或者返回值，Spring 容器在初始化调度器时会直接报错或忽略。&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;</content:encoded></item><item><title>该如何正确处理异常信息</title><link>https://study-docs-158.pages.dev/posts/%E8%AF%A5%E5%A6%82%E4%BD%95%E6%AD%A3%E7%A1%AE%E5%A4%84%E7%90%86%E5%BC%82%E5%B8%B8%E4%BF%A1%E6%81%AF/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E8%AF%A5%E5%A6%82%E4%BD%95%E6%AD%A3%E7%A1%AE%E5%A4%84%E7%90%86%E5%BC%82%E5%B8%B8%E4%BF%A1%E6%81%AF/</guid><description>该如何正确处理异常信息</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;异常处理是 Java 开发中非常重要的一个知识点。&lt;/p&gt;
&lt;p&gt;很多新人在处理异常的时候，要么不知道什么时候该 try-catch、什么时候该抛出异常，要么 try-catch 里面什么都不做，直接把异常”吞掉”。&lt;/p&gt;
&lt;p&gt;这两种做法都是不对的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么时候抛异常、什么时候 try-catch 处理异常，然后 try-catch 处理异常该怎么处理？&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;section&gt;&lt;h2&gt;一、什么时候 try-catch&lt;a href=&quot;#一什么时候-try-catch&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;当你不想让调用方察觉到异常时，就用 try-catch 悄悄接住：只把日志写足，别把异常抛出去。&lt;/p&gt;&lt;p&gt;同样，当你不想让一次异常中断整个流程、导致后续代码无法运行时，也用 try-catch 把它拦下来。&lt;/p&gt;&lt;p&gt;更进一步，把 try-catch 当成异常场景下的”降级开关”：一旦出事，立刻捕获，记录日志、返回默认值或缓存数据，让用户依旧能看到页面，让业务流程继续走下去。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、隐藏异常，不让调用者感知异常，并做降级处理&lt;a href=&quot;#1隐藏异常不让调用者感知异常并做降级处理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;典型的场景是：一个页面有核心数据和推荐数据两部分，推荐数据来自一个不太稳定的外部服务。如果推荐服务挂了，不应该让整个页面都报错，而是返回空列表，确保核心功能正常。&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Slf4j&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RecommendService&lt;/span&gt;&lt;span&gt; recommendService&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 可能不稳定的推荐服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductDetail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getProductDetail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;productId&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;ProductDetail&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;detail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;productDao&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getById&lt;/span&gt;&lt;span&gt;(productId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 获取商品推荐列表（非核心功能）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;recommendations&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;recommendService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getRecommendations&lt;/span&gt;&lt;span&gt;(productId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;detail&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setRecommendations&lt;/span&gt;&lt;span&gt;(recommendations);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 核心：捕获所有异常，确保详情页主功能不受影响&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;warn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;获取商品[{}]推荐列表失败，将返回空推荐列表&quot;&lt;/span&gt;&lt;span&gt;, productId, e);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;detail&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setRecommendations&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Collections&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;emptyList&lt;/span&gt;&lt;span&gt;()); &lt;/span&gt;&lt;span&gt;// 降级：返回空列表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; detail; &lt;/span&gt;&lt;span&gt;// 主商品信息一定正常返回&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;这种写法的关键是：&lt;strong&gt;日志要写足，降级逻辑要合理，不要什么都不做。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、对原始异常进行包装&lt;a href=&quot;#2对原始异常进行包装&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;当需要对原始异常信息进行包装的时候，也需要使用 try-catch。&lt;/p&gt;&lt;p&gt;这个时候在 try-catch 里面抛出的异常，应该是自定义异常。因为自定义异常返回的信息是清晰明了的，能告诉用户目前出现了什么情况，而不是直接把原始异常信息暴露给用户。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;直接把原始异常信息暴露出去，有两个问题：&lt;/strong&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;：原始异常可能包含数据库 IP、表名、SQL 语句等敏感信息&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;错误的示例：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;login&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; username&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; password) throws SQLException {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 直接调用 DAO，可能抛出 SQLException&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userDao&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;findByUsernameAndPassword&lt;/span&gt;&lt;span&gt;(username, password);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;如果数据库连接失败，前端可能收到包含&lt;strong&gt;数据库 IP、表名、SQL 语句片段&lt;/strong&gt;的错误信息，体验极差且不安全。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;正确的做法：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 1. 首先，定义一个业务异常&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AuthenticationException&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;extends&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RuntimeException&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AuthenticationException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Throwable&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cause&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;super&lt;/span&gt;&lt;span&gt;(message, cause);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 2. 在 Service 层进行包装&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;login&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; username&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; password) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; user &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userDao&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;findByUsernameAndPassword&lt;/span&gt;&lt;span&gt;(username, password);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; user&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) { &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// Spring 对 SQLException 等的包装&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 关键：记录原始异常，供后续排查&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;用户[{}]登录时数据访问异常&quot;&lt;/span&gt;&lt;span&gt;, username, e);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 关键：抛出一个对上游和用户友好的业务异常&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AuthenticationException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;系统繁忙，请稍后再试！&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;这种写法的关键是：&lt;strong&gt;原始异常记到日志里，给用户和上游抛出友好的业务异常。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、什么时候抛出异常&lt;a href=&quot;#二什么时候抛出异常&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;在程序执行过程中，遇到&lt;strong&gt;核心业务前提条件不满足&lt;/strong&gt;或&lt;strong&gt;关键流程出现不可恢复的错误&lt;/strong&gt;，导致后续所有操作变得无意义或不可能成功时，此时就应该抛出异常并终止当前执行流。&lt;/p&gt;&lt;p&gt;简单来说：&lt;strong&gt;条件不满足就别往下走了，直接抛异常。&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;payOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; order&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Payment&lt;/span&gt;&lt;span&gt; payment) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 条件1：订单状态检查&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;PENDING&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getStatus&lt;/span&gt;&lt;span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 后续支付逻辑已无意义，立即抛出！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;IllegalOrderStateException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;订单[id=&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;]当前状态为&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getStatus&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;，无法支付。&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 条件2：支付金额校验&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;payment&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getAmount&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;compareTo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getTotalAmount&lt;/span&gt;&lt;span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 金额不匹配，支付必然失败，立即抛出！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PaymentAmountMismatchException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;支付金额[&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;payment&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getAmount&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;]与订单总额[&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getTotalAmount&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;]不符。&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 条件3：执行核心支付（只有所有前提满足，才执行到这里）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;paymentGateway&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;execute&lt;/span&gt;&lt;span&gt;(payment);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;BankGatewayException&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 支付本身失败，同样抛出业务异常&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PaymentFailedException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;银行支付处理失败，请重试&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 更新状态（只有一切成功，才执行到这里）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setStatus&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;PAID&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;orderRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;抛异常的核心原则：&lt;strong&gt;后续代码已经没有意义执行了，就立刻抛出，不要继续往下走。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、总结&lt;a href=&quot;#三总结&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;/td&gt;&lt;td&gt;try-catch + 降级&lt;/td&gt;&lt;td&gt;日志写足，返回默认值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;原始异常不友好&lt;/td&gt;&lt;td&gt;try-catch + 自定义异常&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;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;/section&gt;</content:encoded></item><item><title>该以什么心态面对工作中的困难</title><link>https://study-docs-158.pages.dev/posts/%E8%AF%A5%E4%BB%A5%E4%BB%80%E4%B9%88%E5%BF%83%E6%80%81%E9%9D%A2%E5%AF%B9%E5%B7%A5%E4%BD%9C%E4%B8%AD%E7%9A%84%E5%9B%B0%E9%9A%BE/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E8%AF%A5%E4%BB%A5%E4%BB%80%E4%B9%88%E5%BF%83%E6%80%81%E9%9D%A2%E5%AF%B9%E5%B7%A5%E4%BD%9C%E4%B8%AD%E7%9A%84%E5%9B%B0%E9%9A%BE/</guid><description>该以什么心态面对工作中的困难</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;该以什么心态面对工作中的困难&lt;a href=&quot;#该以什么心态面对工作中的困难&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;在工作中遇到困难是非常正常的事情。 尤其是刚进入公司的新人，在面对项目代码、业务逻辑、系统架构时，很多内容都是第一次接触。&lt;/p&gt;&lt;p&gt;所以首先要明确一件事：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;遇到困难是正常的，不遇到困难反而是不正常的。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;遇到困难时，第一步不是慌，也不是急着否定自己，而是：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;先让自己沉下心来，认真思考，不要浮躁。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果刚进入公司就什么问题都没有，往往说明你接触的事情还不够复杂，或者你还没有真正开始承担核心任务。&lt;/p&gt;&lt;p&gt;关键不是“有没有困难”，而是：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;遇到困难时，你是如何面对和处理的。&lt;/strong&gt;&lt;/p&gt;&lt;hr /&gt;&lt;section&gt;&lt;h2&gt;一、先接受困难是工作的一部分&lt;a href=&quot;#一先接受困难是工作的一部分&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;很多新人在刚进入公司时，会产生一种错觉：&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;p&gt;但实际上，真实的工作环境中：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;老员工也会遇到问题&lt;/strong&gt;&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;p&gt;区别只是：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（1）老员工遇到问题时更冷静&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（2）更知道从哪里入手解决&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;所以，当你遇到困难时，首先要做的是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;接受困难是工作的一部分，而不是能力不足的证明。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;二、不要一遇到问题就自我否定&lt;a href=&quot;#二不要一遇到问题就自我否定&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;新人在遇到困难时，最容易陷入的一种状态就是：&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、容易陷入自我否定的状态&lt;a href=&quot;#1容易陷入自我否定的状态&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;p&gt;这种状态其实对解决问题是没有任何帮助的，只会让自己越来越焦虑。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、很多问题的产生并不一定是因为你能力不够&lt;a href=&quot;#2很多问题的产生并不一定是因为你能力不够&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;需要明白的是，很多问题的产生，可能来自：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（1）项目本身的问题&lt;/strong&gt;&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;p&gt;&lt;strong&gt;（2）沟通和理解的问题&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;需求描述不够清晰&lt;/li&gt;
&lt;li&gt;业务逻辑比较绕&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以，当你遇到问题的时候，不要第一时间否定自己。&lt;/p&gt;&lt;p&gt;更合理的做法是：&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;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;三、学会拆解问题，而不是被问题压住&lt;a href=&quot;#三学会拆解问题而不是被问题压住&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;面对困难时，一个非常重要的能力就是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;把一个看起来很大的问题拆解成多个小问题。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;1、拆解问题的例子&lt;a href=&quot;#1拆解问题的例子&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;例如，你可能会遇到这样的情况：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“这个需求我完全不会做。”&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;但如果进一步拆解，你会发现问题可能是：&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;li&gt;不知道数据库表结构&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、一步步解决小问题&lt;a href=&quot;#2一步步解决小问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;当你把问题拆解之后，就可以一步一步解决：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;先理解需求&lt;/li&gt;
&lt;li&gt;找相关代码&lt;/li&gt;
&lt;li&gt;看接口逻辑&lt;/li&gt;
&lt;li&gt;查数据库结构&lt;/li&gt;
&lt;li&gt;再开始写代码&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;很多看起来很复杂的问题，其实都是由很多小问题组成的。&lt;/p&gt;&lt;p&gt;只要一步一步解决，小问题解决完，大问题自然也就解决了。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;四、不要长时间自己硬扛&lt;a href=&quot;#四不要长时间自己硬扛&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;新人还有一个非常常见的问题：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;卡住很久，也不愿意问别人。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;1、不愿意问别人的原因&lt;a href=&quot;#1不愿意问别人的原因&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;原因通常是：&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;/section&gt;&lt;section&gt;&lt;h3&gt;2、不会问问题比问问题更严重&lt;a href=&quot;#2不会问问题比问问题更严重&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;但实际上，在工作中：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;不会问问题，比问问题更严重。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为如果你一直卡住：&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;/section&gt;&lt;section&gt;&lt;h3&gt;3、更好的处理方式&lt;a href=&quot;#3更好的处理方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;更好的方式是：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;先自己尝试解决&lt;/li&gt;
&lt;li&gt;查资料、查代码、查日志&lt;/li&gt;
&lt;li&gt;如果一段时间仍然没有进展，就及时沟通&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;在提问的时候，也尽量做到：&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;p&gt;这样别人也更容易帮你。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;五、把困难当成学习机会&lt;a href=&quot;#五把困难当成学习机会&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;很多新人在工作中会有一种想法：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“怎么这么多问题，太难了。”&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;但从另一个角度来看：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;困难越多，成长也越快。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;1、真正让你成长的是困难&lt;a href=&quot;#1真正让你成长的是困难&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;因为真正让你成长的，往往不是那些简单的任务，而是那些：&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;/section&gt;&lt;section&gt;&lt;h3&gt;2、每解决一个问题就是一次成长&lt;a href=&quot;#2每解决一个问题就是一次成长&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;每解决一个问题，你都会多掌握一部分知识。&lt;/p&gt;&lt;p&gt;慢慢地，你就会发现：&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;p&gt;这就是成长的过程。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;六、保持耐心，不要急于求成&lt;a href=&quot;#六保持耐心不要急于求成&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;技术能力的提升，本身就是一个长期过程。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、新人常见的心态&lt;a href=&quot;#1新人常见的心态&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;很多新人在刚进入行业时，会希望：&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;/section&gt;&lt;section&gt;&lt;h3&gt;2、技术成长需要积累&lt;a href=&quot;#2技术成长需要积累&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;但现实是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;技术成长是一个积累的过程，不可能一蹴而就。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;所以，在面对困难时，不要太着急，也不要因为短时间的挫折就否定自己。&lt;/p&gt;&lt;p&gt;只要你：&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;p&gt;随着时间的积累，你的能力一定会慢慢提升。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>该以什么样的心态面对新公司</title><link>https://study-docs-158.pages.dev/posts/%E8%AF%A5%E4%BB%A5%E4%BB%80%E4%B9%88%E6%A0%B7%E7%9A%84%E5%BF%83%E6%80%81%E9%9D%A2%E5%AF%B9%E6%96%B0%E5%85%AC%E5%8F%B8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E8%AF%A5%E4%BB%A5%E4%BB%80%E4%B9%88%E6%A0%B7%E7%9A%84%E5%BF%83%E6%80%81%E9%9D%A2%E5%AF%B9%E6%96%B0%E5%85%AC%E5%8F%B8/</guid><description>该以什么样的心态面对新公司</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、先认可自己&lt;a href=&quot;#一先认可自己&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;首先，要先认可自己。&lt;/p&gt;&lt;p&gt;能够在现在这样的就业环境下，靠自己的学习拿到 offer，本身就说明你并不是完全不行。 公司在招聘时，不可能只面试你一个人，而是会在多个候选人里做筛选。你能够最终拿到 offer，说明你在当时的面试过程中，至少有一些地方是被认可的。&lt;/p&gt;&lt;p&gt;所以，进入新公司之后，不要一上来就把自己放得特别低，觉得自己什么都不行。 你可以承认自己经验不足、基础不够扎实，但也要承认：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;既然能够通过面试进入公司，就说明自己具备一定的能力基础。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这种认可自己，不是盲目自信，而是建立一个比较正常的起点。 如果一开始就完全否定自己，后面遇到一点问题，就会很容易陷入自我怀疑。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、认清现实&lt;a href=&quot;#二认清现实&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;面对新公司，既不能盲目乐观，也不能过度自卑。 更重要的是，要认清现实：&lt;strong&gt;既要看到有利的一面，也要看到自己真实存在的短板。&lt;/strong&gt;&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、有利的一面&lt;a href=&quot;#1有利的一面&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;（1）能拿到 offer，说明你已经通过了一轮筛选&lt;a href=&quot;#1能拿到-offer说明你已经通过了一轮筛选&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;公司在招聘时，通常会面试不止一个人。 你能够从这些候选人中脱颖而出，被最终录用，说明你在某些方面已经得到了面试官的认可。这是你应该自豪的，比较你是通过短短几个月的学习，就能够跟很多真实工作几年的人在一个起点了。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;（2）把你招进来的人，也希望你能尽快进入状态&lt;a href=&quot;#2把你招进来的人也希望你能尽快进入状态&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;一般来说，能够参与面试并拍板录用你的人，在团队里至少是有一定话语权的。 既然他决定把你招进来，那他通常也希望你后面能尽快上手、稳定下来，而不是希望你一进来就表现很差。如果，你表现的不好，别人也会怀疑他的能力，他面子上也挂不住。所以，招你进来的人，包括HR，天然的是会希望你也表现好的。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;（3）你是带薪学习，学习的过程，又有工资拿&lt;a href=&quot;#3你是带薪学习学习的过程又有工资拿&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;如果你目前不具备完整的真实开发经验，那么进入公司之后，其实就是一个“带着工作去学习”的过程。&lt;/p&gt;&lt;p&gt;你一边在赚工资，一边在积累真正的项目经验、沟通经验、推进经验。&lt;/p&gt;&lt;p&gt;所以，只要这个公司还能让你学到东西，就不要因为一时遇到困难，就立刻想着离职。 因为很多时候，离开并不能解决问题，只是把当前的问题延后了。 如果底层能力和方法没有建立起来，换到下一个公司，类似的问题大概率还会继续出现。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、不利的一面&lt;a href=&quot;#2不利的一面&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;（1）缺少真实工作经验，容易犯低级错误&lt;a href=&quot;#1缺少真实工作经验容易犯低级错误&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;很多刚入职的新人，虽然已经通过学习进入了行业，但在真正写业务代码时，仍然容易出现一些低级问题，比如：&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;li&gt;容易写出 bug&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这很正常，不要因为这些问题就否定了自己。要清楚的知道，这些都是正常的。当前最应该做的是，要知道自己该做什么，而不是陷入到内耗的情绪之中。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;（2）知识储备还不够扎实&lt;a href=&quot;#2知识储备还不够扎实&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;能够进入这个行业，并不代表自己已经什么都会了。 很多时候，我们只是通过一段时间的集中学习，具备了进入岗位的基本能力，但很多知识其实还是一知半解。&lt;/p&gt;&lt;p&gt;所以，拿到工作之后，不要产生“终于上岸了，以后不用学了”的错觉。 真正开始工作以后，学习才刚刚开始。 它是什么，它怎么用&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;（3）不熟悉职场沟通和推进方式，容易陷入内耗&lt;a href=&quot;#3不熟悉职场沟通和推进方式容易陷入内耗&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;新人刚进公司时，很多问题并不是技术本身，而是：&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;li&gt;一卡住就只会自己焦虑&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果这些问题处理不好，就很容易陷入内耗，看起来每天很忙，实际上推进得很慢。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、正确的心态应该是什么？&lt;a href=&quot;#三正确的心态应该是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;面对新公司，最好的心态不是“我很牛，我肯定没问题”， 也不是“我太菜了，我肯定不行”， 而是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;先认可自己有进入这个岗位的基础，同时也承认自己目前还有很多不足，然后用一种愿意学习、愿意适应、愿意推进的态度去面对新环境。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;也就是说：&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;li&gt;再一点点把工作能力补起来&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;</content:encoded></item><item><title>工作中Dubbo的使用</title><link>https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADdubbo%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADdubbo%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>工作中Dubbo的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、什么是Dubbo？&lt;a href=&quot;#一什么是dubbo&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Dubbo是阿里巴巴开源的Java RPC框架，用于实现服务的远程调用和治理。在微服务架构中，不同的服务部署在不同的机器上，服务之间需要相互调用，Dubbo就是帮你完成这件事的。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单说：Dubbo就是让一个服务能调用另一个服务的方法，就像调用本地方法一样简单。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;1、为什么需要Dubbo？&lt;a href=&quot;#1为什么需要dubbo&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;场景&lt;/th&gt;&lt;th&gt;不用Dubbo&lt;/th&gt;&lt;th&gt;用Dubbo&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;服务间调用&lt;/td&gt;&lt;td&gt;自己写HTTP请求，手动处理序列化&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;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;/section&gt;&lt;section&gt;&lt;h3&gt;2、Dubbo的核心角色&lt;a href=&quot;#2dubbo的核心角色&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;类比&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Provider（提供者）&lt;/td&gt;&lt;td&gt;暴露服务的应用，提供服务接口的实现&lt;/td&gt;&lt;td&gt;餐厅的厨师，负责做菜&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Consumer（消费者）&lt;/td&gt;&lt;td&gt;调用远程服务的应用&lt;/td&gt;&lt;td&gt;顾客，点菜消费&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Registry（注册中心）&lt;/td&gt;&lt;td&gt;服务注册与发现的地方&lt;/td&gt;&lt;td&gt;餐厅的菜单，告诉你有哪些菜&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Monitor（监控中心）&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;/section&gt;&lt;section&gt;&lt;h3&gt;3、Dubbo的调用流程&lt;a href=&quot;#3dubbo的调用流程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;1. Provider启动 → 向Registry注册自己的服务地址&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;2. Consumer启动 → 向Registry订阅需要的服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;3. Registry → 把Provider的地址列表推送给Consumer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;4. Consumer → 根据地址列表，直接调用Provider（不再经过Registry）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;5. Monitor → 统计调用信息&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-16/fc256743-745a-40ec-879d-783c223a2771.png&quot; alt=&quot;dubbo调用关系&quot; /&gt;&lt;figcaption&gt;dubbo调用关系&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、注册中心的选择&lt;a href=&quot;#二注册中心的选择&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Dubbo支持多种注册中心，&lt;strong&gt;不仅限于Zookeeper&lt;/strong&gt;，你可以根据项目实际情况选择合适的注册中心：&lt;/p&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;Zookeeper&lt;/td&gt;&lt;td&gt;Apache开源的分布式协调服务，Dubbo最经典的注册中心&lt;/td&gt;&lt;td&gt;传统项目，团队对ZK比较熟悉&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Nacos&lt;/td&gt;&lt;td&gt;阿里开源的注册中心和配置中心，同时支持AP和CP模式&lt;/td&gt;&lt;td&gt;Spring Cloud Alibaba技术栈项目，需要同时做配置管理&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Redis&lt;/td&gt;&lt;td&gt;基于Redis实现的注册中心&lt;/td&gt;&lt;td&gt;轻量级项目，已有Redis基础设施&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;工作中最常用的是Zookeeper和Nacos两种&lt;/strong&gt;，下面以这两种为例进行整合演示。具体用哪个取决于你们公司的技术栈，入职后问一下同事即可。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、SpringBoot整合Dubbo&lt;a href=&quot;#三springboot整合dubbo&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、引入依赖&lt;a href=&quot;#1引入依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;父工程引入依赖：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- Dubbo --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.apache.dubbo&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;dubbo-bom&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;${dubbo.version}&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&amp;gt;pom&amp;lt;/&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;scope&lt;/span&gt;&lt;span&gt;&amp;gt;import&amp;lt;/&lt;/span&gt;&lt;span&gt;scope&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;各个子模块引入依赖——根据注册中心选择对应的依赖：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;使用Zookeeper作为注册中心：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- dubbo --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.apache.dubbo&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;dubbo-spring-boot-starter&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;3.0.9&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.apache.dubbo&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;dubbo-dependencies-zookeeper-curator5&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&amp;gt;pom&amp;lt;/&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;exclusions&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;exclusion&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;slf4j-reload4j&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.slf4j&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;exclusion&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;exclusions&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;3.0.9&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;使用Nacos作为注册中心：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- dubbo --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.apache.dubbo&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;dubbo-spring-boot-starter&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;3.0.9&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- nacos作为注册中心 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.apache.dubbo&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;dubbo-registry-nacos&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;3.0.9&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;com.alibaba.nacos&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;nacos-client&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;2.2.3&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、定义公共接口&lt;a href=&quot;#2定义公共接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Provider和Consumer之间需要一个公共的接口模块，双方都依赖这个模块。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TestDubboService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sayHello&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;ZhuoYe&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getZuoYe&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、服务提供者（Provider）&lt;a href=&quot;#3服务提供者provider&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;3.1 配置文件&lt;a href=&quot;#31-配置文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;使用Zookeeper作为注册中心：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;dubbo-springboot-demo-provider&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;protocol&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;-1&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# -1表示自动分配端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;address&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;zookeeper://192.168.190.129:2181&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;60000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;使用Nacos作为注册中心：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;dubbo-springboot-demo-provider&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;protocol&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;-1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;address&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;nacos://127.0.0.1:8848&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;60000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# 如果nacos配置了命名空间，需要指定namespace&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# parameters:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;#   namespace: your-namespace-id&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;区别就只是 &lt;code&gt;registry.address&lt;/code&gt; 的协议头不同&lt;/strong&gt;：Zookeeper是 &lt;code&gt;zookeeper://&lt;/code&gt;，Nacos是 &lt;code&gt;nacos://&lt;/code&gt;，其他配置完全一样。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2 启动类添加注解&lt;a href=&quot;#32-启动类添加注解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;SpringBootApplication&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;EnableDubbo&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 开启Dubbo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProviderApp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;[] &lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;SpringApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ProviderApp&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;, args);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.3 实现服务接口&lt;a href=&quot;#33-实现服务接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboService&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 标记为Dubbo服务，会自动注册到注册中心&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TestDubboServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TestDubboService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sayHello&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;hello,&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; name;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ZhuoYe&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getZuoYe&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;ZhuoYe&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zuoYe&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ZhuoYe&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;zuoYe&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;zhuoye-1&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setDescription&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;帅呆了！！！&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; zuoYe;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、服务消费者（Consumer）&lt;a href=&quot;#4服务消费者consumer&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;4.1 配置文件&lt;a href=&quot;#41-配置文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;使用Zookeeper作为注册中心：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;dubbo-springboot-demo-consumer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;protocol&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;-1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;address&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;zookeeper://192.168.190.129:2181&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;60000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;使用Nacos作为注册中心：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;dubbo-springboot-demo-consumer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;protocol&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;-1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;address&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;nacos://127.0.0.1:8848&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;60000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4.2 启动类添加注解&lt;a href=&quot;#42-启动类添加注解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;SpringBootApplication&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;EnableDubbo&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 开启Dubbo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ConsumerApp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;[] &lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;SpringApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ConsumerApp&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;, args);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4.3 调用远程服务&lt;a href=&quot;#43-调用远程服务&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RestController&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequestMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;dubbo&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TestDubboController&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 注入远程服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TestDubboService&lt;/span&gt;&lt;span&gt; testDubboService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;hello&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hello&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;testDubboService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sayHello&lt;/span&gt;&lt;span&gt;(name);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;getZhuoye&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ZhuoYe&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getZhuoye&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;testDubboService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getZuoYe&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、核心注解说明&lt;a href=&quot;#四核心注解说明&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;@EnableDubbo&lt;/td&gt;&lt;td&gt;启动类&lt;/td&gt;&lt;td&gt;开启Dubbo自动配置&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;@DubboService&lt;/td&gt;&lt;td&gt;Provider的服务实现类&lt;/td&gt;&lt;td&gt;标记为Dubbo服务，自动注册到注册中心&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;@DubboReference&lt;/td&gt;&lt;td&gt;Consumer的属性&lt;/td&gt;&lt;td&gt;注入远程服务的代理对象&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;版本说明：&lt;/strong&gt; 在 Dubbo 2.7.x 及更早版本中，使用的是 &lt;code&gt;@Service&lt;/code&gt; 和 &lt;code&gt;@Reference&lt;/code&gt; 注解（来自 &lt;code&gt;org.apache.dubbo.config.annotation.Service&lt;/code&gt; 或 &lt;code&gt;com.alibaba.dubbo.config.annotation.Service&lt;/code&gt;）。从 Dubbo 2.7.7 开始，官方推荐使用 &lt;code&gt;@DubboService&lt;/code&gt; 和 &lt;code&gt;@DubboReference&lt;/code&gt; 替代，目的是避免与 Spring 的 &lt;code&gt;@Service&lt;/code&gt; 注解产生冲突和混淆。如果你在公司的老项目中看到 &lt;code&gt;@Service&lt;/code&gt; 注解标注的服务类，那就是早期版本的写法，功能上和 &lt;code&gt;@DubboService&lt;/code&gt; 是一样的。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、常用配置说明&lt;a href=&quot;#五常用配置说明&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、超时设置&lt;a href=&quot;#1超时设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 方式一：在注解上设置（推荐，精确控制）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboService&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;5000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 方式二：在消费端设置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、重试设置&lt;a href=&quot;#2重试设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;retries&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 重试2次，总共执行3次&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 涉及写操作（新增、修改、删除）的方法不要设置重试，避免重复执行。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、负载均衡策略&lt;a href=&quot;#3负载均衡策略&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;Random&lt;/td&gt;&lt;td&gt;随机（默认）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RoundRobin&lt;/td&gt;&lt;td&gt;轮询&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LeastActive&lt;/td&gt;&lt;td&gt;最少活跃调用数&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ConsistentHash&lt;/td&gt;&lt;td&gt;一致性Hash&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;loadbalance&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;roundrobin&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、版本控制&lt;a href=&quot;#4版本控制&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;当服务接口有不兼容升级时，可以通过版本来区分：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// Provider：提供不同版本的服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboService&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserServiceImplV1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboService&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;2.0&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserServiceImplV2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// Consumer：指定调用哪个版本&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、项目中如何使用Dubbo&lt;a href=&quot;#六项目中如何使用dubbo&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、项目中首次使用Dubbo&lt;a href=&quot;#1项目中首次使用dubbo&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;按照上面”三、SpringBoot整合Dubbo”的步骤操作即可。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、项目中非首次使用Dubbo&lt;a href=&quot;#2项目中非首次使用dubbo&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;直接使用 &lt;code&gt;Ctrl + Shift + R&lt;/code&gt; 全局搜索 &lt;code&gt;@DubboService&lt;/code&gt;、&lt;code&gt;@DubboReference&lt;/code&gt;、&lt;code&gt;@Service&lt;/code&gt;、&lt;code&gt;@Reference&lt;/code&gt;（后两个是早期版本的注解，老项目中会用到），参考同事的代码，照葫芦画瓢即可。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、常见使用场景&lt;a href=&quot;#七常见使用场景&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、跨服务调用&lt;a href=&quot;#1跨服务调用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户服务 → 调用订单服务获取用户订单&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;订单服务 → 调用商品服务获取商品信息&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、公共服务抽取&lt;a href=&quot;#2公共服务抽取&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;短信服务、邮件服务、文件上传服务 → 独立部署，其他服务通过Dubbo调用&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;八、常见问题排查&lt;a href=&quot;#八常见问题排查&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、服务调用失败：No provider available&lt;a href=&quot;#1服务调用失败no-provider-available&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;可能原因：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Provider未启动或未注册到注册中心&lt;/li&gt;
&lt;li&gt;网络不通，Provider端口未开放&lt;/li&gt;
&lt;li&gt;接口类路径不一致（Provider和Consumer的接口包名必须一致）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;排查步骤：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 1. 检查注册中心（Zookeeper）是否启动&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 2. 检查Provider日志，确认服务已注册&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 3. 检查Consumer和Provider的接口包名是否一致&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、服务调用超时&lt;a href=&quot;#2服务调用超时&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;可能原因：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Provider处理慢（数据库查询慢、业务逻辑复杂）&lt;/li&gt;
&lt;li&gt;网络延迟高&lt;/li&gt;
&lt;li&gt;并发量大，Provider处理不过来&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 增加超时时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;10000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、注册中心连不上&lt;a href=&quot;#3注册中心连不上&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;可能原因：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;注册中心未启动（Zookeeper或Nacos）&lt;/li&gt;
&lt;li&gt;地址或端口配置错误&lt;/li&gt;
&lt;li&gt;防火墙未放行端口&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;排查命令：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 测试Zookeeper连通性&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;telnet&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;192.168.190.129&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2181&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 测试Nacos连通性（默认8848端口）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;http://127.0.0.1:8848/nacos/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、本地改了代码但没有生效（新人高频问题）&lt;a href=&quot;#4本地改了代码但没有生效新人高频问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;现象：&lt;/strong&gt; 本地修改了Provider的代码并重启，但调用接口后发现行为没有变化，打的断点也不进。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;原因：&lt;/strong&gt; 注册中心里注册了多个同名的服务实例（线上环境 + 你本地的），Consumer通过负载均衡调用时，实际走的是线上的服务实例，而不是你本地的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;排查步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;打开注册中心的管理控制台（Zookeeper用PrettyZoo等客户端，Nacos用Web控制台）&lt;/li&gt;
&lt;li&gt;查看该服务名下有几个实例，确认你的本地实例是否在里面&lt;/li&gt;
&lt;li&gt;检查Consumer调用的到底是哪个实例&lt;/li&gt;
&lt;/ol&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;/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;/td&gt;&lt;td&gt;Consumer配置 @DubboReference(url = “dubbo://127.0.0.1&amp;lt;20880&amp;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;本地Provider注册一个独立的版本号，Consumer指定调用该版本&lt;/td&gt;&lt;td&gt;推荐，不影响其他实例&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;只启动本地Provider&lt;/td&gt;&lt;td&gt;把线上的Provider停掉，只保留本地的实例&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;&lt;strong&gt;关于直连端口：&lt;/strong&gt; &lt;code&gt;20880&lt;/code&gt; 是Provider的Dubbo协议端口，对应配置文件中的 &lt;code&gt;dubbo.protocol.port&lt;/code&gt;。如果配置的是固定端口（如 &lt;code&gt;port: 20880&lt;/code&gt;），直接填即可；如果配置的是 &lt;code&gt;-1&lt;/code&gt;（自动分配），实际端口会在Provider启动日志中打印出来，需要去日志里查找。&lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 方式一：注解直连本地（调试时临时使用，用完记得去掉）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 20880是Provider的dubbo协议端口，即配置文件中 dubbo.protocol.port 的值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;dubbo://127.0.0.1:20880&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 方式二：配置文件指定直连（不影响代码）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// application.yml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;consumer&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; dubbo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;//127.0.0.1:20880&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 方式三：通过版本区分（推荐）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// Provider端：本地启动时指定一个测试版本&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboService&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;local-dev&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// Consumer端：指定调用本地测试版本&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;local-dev&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 直连方式会绕过注册中心，仅用于本地调试，上线前必须去掉。版本区分方式的好处是：你本地注册的服务和线上的服务通过版本号隔离开，Consumer明确指定调用 &lt;code&gt;local-dev&lt;/code&gt; 版本，不会误打到线上实例。排查问题的思路就是：&lt;strong&gt;先确认你的请求到底打到了哪个实例上&lt;/strong&gt;。确认方式可以在后端对应调用Provider的服务上打个断点，走到断点就说明请求走的是本地，也可以通过这种方式来验证走本地服务的时候，逻辑是否正确的。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;九、注意事项&lt;a href=&quot;#九注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;接口包名必须一致&lt;/strong&gt;：Provider和Consumer引用的接口类，包路径必须完全一致，否则找不到服务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实体类必须实现Serializable&lt;/strong&gt;：Dubbo传输的对象必须实现序列化接口&lt;/li&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;li&gt;&lt;strong&gt;检查注册中心状态&lt;/strong&gt;：注册中心挂了，新的服务无法注册和发现&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;</content:encoded></item><item><title>工作中ES的使用</title><link>https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADes%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADes%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>工作中ES的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、ES到底是什么？&lt;a href=&quot;#一es到底是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、什么是ES（Elasticsearch）？&lt;a href=&quot;#1什么是eselasticsearch&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单说：ES是一个搜索引擎，擅长在海量数据中快速搜索。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;为什么需要ES？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;你可能会问：MySQL也能查询啊，为什么还要ES？&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;对比项&lt;/th&gt;&lt;th&gt;MySQL&lt;/th&gt;&lt;th&gt;ES&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;模糊查询&lt;/td&gt;&lt;td&gt;LIKE ‘%xxx%‘，很慢&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;tr&gt;&lt;td&gt;复杂搜索&lt;/td&gt;&lt;td&gt;写复杂SQL&lt;/td&gt;&lt;td&gt;简单API调用&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;p&gt;&lt;strong&gt;结论：搜索功能、大量数据的查询，用ES。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、ES和MySQL概念对比&lt;a href=&quot;#2es和mysql概念对比&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;


































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;MySQL&lt;/th&gt;&lt;th&gt;ES&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;/td&gt;&lt;td&gt;索引（Index）&lt;/td&gt;&lt;td&gt;数据的集合&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;表&lt;/td&gt;&lt;td&gt;类型（Type）&lt;/td&gt;&lt;td&gt;7.x后已废弃，一个索引就是一个表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;行&lt;/td&gt;&lt;td&gt;文档（Document）&lt;/td&gt;&lt;td&gt;一条数据&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;列&lt;/td&gt;&lt;td&gt;字段（Field）&lt;/td&gt;&lt;td&gt;一个属性&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;表结构&lt;/td&gt;&lt;td&gt;映射（Mapping）&lt;/td&gt;&lt;td&gt;字段定义&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、什么时候用ES？&lt;a href=&quot;#3什么时候用es&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;




























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;场景&lt;/th&gt;&lt;th&gt;是否用ES&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/tr&gt;&lt;tr&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;否，用MySQL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;事务操作&lt;/td&gt;&lt;td&gt;否，用MySQL&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、核心概念&lt;a href=&quot;#二核心概念&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、索引（Index）&lt;a href=&quot;#1索引index&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;就是数据库，存放数据的地方。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;商品索引：product_index&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户索引：user_index&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;订单索引：order_index&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、文档（Document）&lt;a href=&quot;#2文档document&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;就是一条数据，JSON格式。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;iPhone 15&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;5999&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;category&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;手机&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、映射（Mapping）&lt;a href=&quot;#3映射mapping&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;就是表结构，定义字段类型。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;mappings&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;properties&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;type&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;long&quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;type&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;text&quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;type&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;integer&quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;category&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;type&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;keyword&quot;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;/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;text&lt;/td&gt;&lt;td&gt;可分词的文本&lt;/td&gt;&lt;td&gt;商品描述&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;keyword&lt;/td&gt;&lt;td&gt;精确匹配&lt;/td&gt;&lt;td&gt;品牌、状态&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;integer/long&lt;/td&gt;&lt;td&gt;整数&lt;/td&gt;&lt;td&gt;价格、数量&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;double&lt;/td&gt;&lt;td&gt;小数&lt;/td&gt;&lt;td&gt;金额&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;date&lt;/td&gt;&lt;td&gt;日期&lt;/td&gt;&lt;td&gt;创建时间&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;boolean&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;/section&gt;&lt;section&gt;&lt;h3&gt;4、倒排索引&lt;a href=&quot;#4倒排索引&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;原理：&lt;/strong&gt; 把内容分词，建立 词→文档ID 的映射。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;文档1：苹果手机很好用&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;文档2：华为手机性价比高&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;分词后：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;苹果 → [文档1]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;手机 → [文档1, 文档2]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;很好用 → [文档1]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;华为 → [文档2]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;性价比高 → [文档2]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;搜索&quot;手机&quot;，直接找到文档1和文档2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、SpringBoot整合ES&lt;a href=&quot;#三springboot整合es&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;方案选择&lt;a href=&quot;#方案选择&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;推荐度&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Spring Data Elasticsearch&lt;/td&gt;&lt;td&gt;像用JPA一样用ES&lt;/td&gt;&lt;td&gt;推荐，简单&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RestHighLevelClient&lt;/td&gt;&lt;td&gt;官方客户端（7.x）&lt;/td&gt;&lt;td&gt;推荐，灵活&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Elasticsearch Java Client&lt;/td&gt;&lt;td&gt;官方新客户端（8.x）&lt;/td&gt;&lt;td&gt;ES 8.x用这个&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;新人建议：先学Spring Data Elasticsearch，最简单。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、Spring Data Elasticsearch（推荐）&lt;a href=&quot;#四spring-data-elasticsearch推荐&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;第一步：引入依赖&lt;a href=&quot;#第一步引入依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.springframework.boot&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;spring-boot-starter-data-elasticsearch&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;第二步：配置连接&lt;a href=&quot;#第二步配置连接&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;elasticsearch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;uris&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;http://127.0.0.1:9200&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;username&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;elastic&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;123456&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;第三步：定义实体类&lt;a href=&quot;#第三步定义实体类&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Document&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;indexName&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;product&quot;&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 索引名称&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Id&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Field&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;FieldType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Text&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;analyzer&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;ik_max_word&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; name&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 商品名称，支持分词&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Field&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;FieldType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Keyword&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; category&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 分类，精确匹配&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Field&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;FieldType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Double&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Double&lt;/span&gt;&lt;span&gt; price&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 价格&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Field&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;FieldType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; stock&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 库存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;第四步：定义Repository&lt;a href=&quot;#第四步定义repository&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Repository&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductRepository&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;extends&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ElasticsearchRepository&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 按名称模糊查询&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;findByName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 按分类查询&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;findByCategory&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;category&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 价格区间查询&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;findByPriceBetween&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Double&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;min&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Double&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;max&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 自定义查询：名称包含关键字&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Query&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;{&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;match&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;?0&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;}}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;searchByName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;第五步：使用&lt;a href=&quot;#第五步使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Slf4j&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductRepository&lt;/span&gt;&lt;span&gt; productRepository&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 1. 新增/更新文档&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;save&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;product&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;save&lt;/span&gt;&lt;span&gt;(product);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;保存成功&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 2. 批量新增&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;saveAll&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;products&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;saveAll&lt;/span&gt;&lt;span&gt;(products);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 3. 根据ID查询&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;findById&lt;/span&gt;&lt;span&gt;(id).&lt;/span&gt;&lt;span&gt;orElse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 4. 查询所有&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;getAll&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Iterable&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;findAll&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ArrayList&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;forEach&lt;/span&gt;&lt;span&gt;(list&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;add);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; list;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 5. 删除&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deleteById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 6. 按名称搜索&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;searchByName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;findByName&lt;/span&gt;&lt;span&gt;(name);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 7. 价格区间查询&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;searchByPriceRange&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Double&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;min&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Double&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;max&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;findByPriceBetween&lt;/span&gt;&lt;span&gt;(min, max);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、复杂查询&lt;a href=&quot;#五复杂查询&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;使用ElasticsearchRestTemplate&lt;a href=&quot;#使用elasticsearchresttemplate&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Slf4j&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductSearchService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ElasticsearchRestTemplate&lt;/span&gt;&lt;span&gt; esTemplate&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 多条件搜索&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 支持关键字搜索 + 分类筛选 + 价格区间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;search&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;category&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Double&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;minPrice&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Double&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;maxPrice&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 构建查询条件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;NativeSearchQueryBuilder&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;queryBuilder&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;NativeSearchQueryBuilder&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// bool查询（组合查询）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;BoolQueryBuilder&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolQuery&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;boolQuery&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 关键字搜索（must：必须满足）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;StringUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isNotBlank&lt;/span&gt;&lt;span&gt;(keyword)) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;boolQuery&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;must&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;matchQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;, keyword));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 分类筛选（filter：过滤，不参与评分）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;StringUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isNotBlank&lt;/span&gt;&lt;span&gt;(category)) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;boolQuery&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;filter&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;termQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;category&quot;&lt;/span&gt;&lt;span&gt;, category));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 价格区间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (minPrice &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; maxPrice &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;boolQuery&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;filter&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;rangeQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gte&lt;/span&gt;&lt;span&gt;(minPrice)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;lte&lt;/span&gt;&lt;span&gt;(maxPrice));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;queryBuilder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;withQuery&lt;/span&gt;&lt;span&gt;(boolQuery);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 执行查询&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;SearchHits&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;hits&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;esTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;search&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;queryBuilder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 3. 处理结果&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hits&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getSearchHits&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;stream&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(SearchHit&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;getContent)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;collect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Collectors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toList&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 分页查询&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;49&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;50&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Page&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;searchPage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;page&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;51&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;NativeSearchQueryBuilder&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;queryBuilder&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;NativeSearchQueryBuilder&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;52&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;53&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 关键字搜索&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;54&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;StringUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isNotBlank&lt;/span&gt;&lt;span&gt;(keyword)) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;55&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;queryBuilder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;withQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;matchQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;, keyword));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;56&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;57&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;58&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 分页&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;59&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;queryBuilder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;withPageable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;PageRequest&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;(page, size));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;60&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;61&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 排序（按价格升序）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;62&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;queryBuilder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;withSort&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;SortBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fieldSort&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;SortOrder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ASC&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;63&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;64&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;SearchHits&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;hits&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;esTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;search&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;queryBuilder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;65&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;66&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 转换结果&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;67&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;hits&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getSearchHits&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;stream&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;68&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(SearchHit&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;getContent)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;69&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;collect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Collectors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toList&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;70&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;71&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PageImpl&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;(list, &lt;/span&gt;&lt;span&gt;PageRequest&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;(page, size), &lt;/span&gt;&lt;span&gt;hits&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getTotalHits&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;72&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;73&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、常用查询类型&lt;a href=&quot;#六常用查询类型&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;match&lt;/td&gt;&lt;td&gt;分词匹配&lt;/td&gt;&lt;td&gt;搜索”苹果手机”会分词&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;term&lt;/td&gt;&lt;td&gt;精确匹配&lt;/td&gt;&lt;td&gt;搜索”iPhone15”必须完全一致&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;range&lt;/td&gt;&lt;td&gt;范围查询&lt;/td&gt;&lt;td&gt;价格100-500&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bool&lt;/td&gt;&lt;td&gt;组合查询&lt;/td&gt;&lt;td&gt;多条件组合&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;wildcard&lt;/td&gt;&lt;td&gt;通配符&lt;/td&gt;&lt;td&gt;”apple*“&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// match查询（分词）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;matchQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;苹果手机&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// term查询（精确）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;termQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;category&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;手机&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// range查询（范围）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;rangeQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;gte&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;lte&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;500&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// bool查询（组合）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;BoolQueryBuilder&lt;/span&gt;&lt;span&gt; boolQuery &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;boolQuery&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;boolQuery&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;must&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;matchQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;手机&quot;&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;boolQuery&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;filter&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;QueryBuilders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;termQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;category&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;手机&quot;&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、ES和MySQL数据同步&lt;a href=&quot;#七es和mysql数据同步&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;实际工作中，数据存MySQL，搜索用ES，需要保持同步。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;常见方案&lt;a href=&quot;#常见方案&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;优缺点&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;同步双写&lt;/td&gt;&lt;td&gt;写MySQL同时写ES&lt;/td&gt;&lt;td&gt;简单，但可能不一致&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;异步消息&lt;/td&gt;&lt;td&gt;写MySQL发MQ，消费写ES&lt;/td&gt;&lt;td&gt;解耦，推荐&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Canal监听&lt;/td&gt;&lt;td&gt;监听MySQL binlog&lt;/td&gt;&lt;td&gt;无侵入，复杂&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;简单示例：同步双写&lt;a href=&quot;#简单示例同步双写&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Transactional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductMapper&lt;/span&gt;&lt;span&gt; productMapper&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// MySQL&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductRepository&lt;/span&gt;&lt;span&gt; productRepository&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// ES&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 新增商品&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;addProduct&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;product&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 存MySQL&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(product);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 存ES&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;save&lt;/span&gt;&lt;span&gt;(product);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 更新商品&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;updateProduct&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Product&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;product&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 更新MySQL&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;updateById&lt;/span&gt;&lt;span&gt;(product);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 更新ES&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;save&lt;/span&gt;&lt;span&gt;(product);  &lt;/span&gt;&lt;span&gt;// ES的save是新增或更新&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 删除商品&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deleteProduct&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 删除MySQL&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deleteById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 删除ES&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deleteById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;八、新人避坑指南&lt;a href=&quot;#八新人避坑指南&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;连不上ES&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;tr&gt;&lt;td&gt;中文搜索不准&lt;/td&gt;&lt;td&gt;安装IK分词器&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;字段类型错误&lt;/td&gt;&lt;td&gt;text支持分词，keyword精确匹配&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;数据不同步&lt;/td&gt;&lt;td&gt;写MySQL后记得同步到ES&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;/section&gt;
&lt;section&gt;&lt;h2&gt;九、问同事的问题&lt;a href=&quot;#九问同事的问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;刚入职用ES时，可以问同事：&lt;/p&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;”ES地址是什么？“&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;tr&gt;&lt;td&gt;”用的哪个客户端？“&lt;/td&gt;&lt;td&gt;确认技术方案&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;”有IK分词器吗？“&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;/section&gt;
&lt;section&gt;&lt;h2&gt;十、注意事项&lt;a href=&quot;#十注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ES不是数据库&lt;/strong&gt;：主要用来搜索，不是用来存数据&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分词器很重要&lt;/strong&gt;：中文要用IK分词器&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;字段类型要选对&lt;/strong&gt;：text分词，keyword精确匹配&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据要同步&lt;/strong&gt;：MySQL和ES数据要一致&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要深度分页&lt;/strong&gt;：from+size不要超过10000&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;十一、ES 8.x 新客户端（了解）&lt;a href=&quot;#十一es-8x-新客户端了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;如果项目用的是ES 8.x，要用新的Java Client：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;co.elastic.clients&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;elasticsearch-java&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;8.11.0&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;用法类似，只是API略有不同。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;十二、终极建议&lt;a href=&quot;#十二终极建议&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;ES不难，关键是理解它和MySQL的区别，知道什么时候用ES。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;使用步骤记住五步：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;确认ES地址和版本&lt;/li&gt;
&lt;li&gt;引入依赖&lt;/li&gt;
&lt;li&gt;定义实体类（加@Document注解）&lt;/li&gt;
&lt;li&gt;定义Repository（继承ElasticsearchRepository）&lt;/li&gt;
&lt;li&gt;直接调用方法使用&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;记住：搜索功能、大量数据查询用ES，普通CRUD用MySQL！&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>工作中git的使用</title><link>https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADgit%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADgit%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>工作中git的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h3&gt;一、git是什么？为什么需要git？&lt;a href=&quot;#一git是什么为什么需要git&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、git是什么&lt;a href=&quot;#1git是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;简单的说，Git就 是一个分布式版本控制系统。&lt;/p&gt;&lt;p&gt;分布式：&lt;strong&gt;每个人的电脑上都有一个完整的仓库，包含了全部的历史记录。&lt;/strong&gt; 这样你可以在自己的电脑上独立工作（提交代码、创建分支），不需要随时联网。等完成了一个功能后，再把自己的修改推送到一个大家约定的“中央服务器”上（比如 GitHub, Gitee）进行共享和协作。&lt;/p&gt;&lt;p&gt;版本控制：&lt;strong&gt;Git 就是帮你自动化、智能化地管理这个过程的工具。&lt;/strong&gt; 它就像一个“时光机器”，记录你对项目文件所做的每一次修改（我们称之为“提交”）。你可以随时回溯到任何一个过去的版本，看看某一行代码是谁、在什么时候、为什么而修改的。&lt;/p&gt;&lt;p&gt;Git 的四个工作区域：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;workspace：工作区&lt;/p&gt;
&lt;p&gt;就是平时存放项目代码的地方。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;index：暂存区&lt;/p&gt;
&lt;p&gt;在将工作区内容加入到本地仓库，在加入到本地仓库前，是先放置在暂存区的&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Repository：本地仓库&lt;/p&gt;
&lt;p&gt;位于自己的机器，本地仓库保存了被提交过的各个版本，比起工作区和暂存区的内容，它更旧一些。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remote：远程仓库&lt;/p&gt;
&lt;p&gt;位于托管代码的服务器，就比如gitee、github、gitlab，远程仓库的内容能够被分布在多个地点的处于协作关系的本地仓库修改。比起本地仓库，远程仓库通常旧一些，因此本地仓库修改完之后需要同步到远程仓库.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、为什么需要git?&lt;a href=&quot;#2为什么需要git&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;二、git的安装&lt;a href=&quot;#二git的安装&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;1、安装过程基本直接下一步就可以&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;2、安装完成后，打开cmd，输入如下命令，能够查看到git版本，便是安装成功&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span&gt;git --version&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;3、配置用户名和邮箱&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;1）配置全局&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;git config --global user.name zy&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;git config --global user.email 736173273@qq.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;2）配置项目级别&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;切换到项目根目录下执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;git config  user.name   fengqingyang&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;git config  user.email  fengqingyang@zcloud.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;4、查看是否配置成功&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;1)查看全局配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;git config --global user.name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;git config --global user.email&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;2）查看项目级配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;切换到项目根目录下执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;git config  user.name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;git config  user.email&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、git常用命令&lt;a href=&quot;#三git常用命令&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在你需要操作的目录打开鼠标右击当前目录空白区域，选择git bash命令窗口打开&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/2ef551cf-6fb3-48b5-b826-fd70f4d23bd9.png&quot; alt=&quot;git-bash打开&quot; /&gt;&lt;figcaption&gt;git-bash打开&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;1、克隆代码&lt;a href=&quot;#1克隆代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;克隆远程仓库代码到本地&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git clone  [远程仓库地址]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;克隆远程仓库指定分支代码到本地&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git clone -b  [分支名]   [远程仓库地址]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;指定用户名密码克隆远程仓库代码到本地&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;指定账户密码只能是http/https地址&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git clone http://&amp;lt;用户名&amp;gt;:&amp;lt;密码&amp;gt;@&amp;lt;远程仓库地址&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;指定用户名密码的时候，是因为本地有缓存其他git的凭据信息，所以，需要指定此次克隆地址的用户名和密码。或者使用下面命令清除本地缓存的git凭据信息&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git config --global --unset credential.helper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;再次克隆若出现如下界面，则填写对应你克隆仓库的账号密码即可。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/6e9e8a9b-a51d-41fb-a1ec-f20839f1b579.png&quot; alt=&quot;git-输入账号密码&quot; /&gt;&lt;figcaption&gt;git-输入账号密码&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;4）开启2FA双重认证的git仓库代码克隆&lt;/p&gt;&lt;p&gt;对于开启2FA双重认证的git仓库的克隆，此时使用账号密码是克隆不下来代码的，需要在平台获取访问令牌。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/b7821dc0-c87e-4fa0-8fb3-8bb89767b3bd.png&quot; alt=&quot;gitlab-创建访问令牌&quot; /&gt;&lt;figcaption&gt;gitlab-创建访问令牌&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击&lt;strong&gt;创建个人访问令牌&lt;/strong&gt;之后，出现如下界面：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/5418ce4a-6d7f-4a45-bdcc-73bcc36f3606.png&quot; alt=&quot;gitlab-token&quot; /&gt;&lt;figcaption&gt;gitlab-token&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;拿到token,使用token克隆即可：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git clone http://&amp;lt;用户名&amp;gt;:&amp;lt;token&amp;gt;@&amp;lt;远程仓库地址&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;使用示例：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git clone http://zhuoye:glpat-HaQ_A4ejLRP1Jx-12yXz@192.168.3.3:9000/zCloud/study-platform/zy-cloud.git&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/8eb137dc-69c5-4a37-a749-fdfec1dabdcf.png&quot; alt=&quot;git带token克隆&quot; /&gt;&lt;figcaption&gt;git带token克隆&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;注意：克隆代码的远程仓库地址可以使用http/https或者ssh地址，http/https地址直接使用就行，ssh地址需要本地生成密钥，然后远程仓库添加这个密钥。&lt;/p&gt;&lt;p&gt;ssh密钥配置流程：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;生成本地密钥&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ssh-keygen -t ed25519 -C &quot;736170173@qq.com&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/37841f4a-c86e-49e8-a70c-949b3135a6da.png&quot; alt=&quot;生成ssh密钥&quot; /&gt;&lt;figcaption&gt;生成ssh密钥&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;默认生成在C:\Users\Administrator\ .ssh 其中Administrator是登录电脑的用户名，换成对应自己登录电脑的名字即可！&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;git上添加密钥&lt;/p&gt;
&lt;p&gt;在个人资料里面添加上述步骤生成的公钥，以.pub结尾的那个文件就是公钥。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/67c00521-bd1a-4442-b340-db3bc8514495.png&quot; alt=&quot;添加密钥&quot; /&gt;&lt;figcaption&gt;添加密钥&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;配置完成后，便可以使用git中的ssh地址来进行克隆！&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、将代码从工作区添加到暂存区&lt;a href=&quot;#2将代码从工作区添加到暂存区&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#添加单个文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git add  filename.txt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#添加多个文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git add file1.txt file2.js file3.css&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#添加当前目录所有更改（最常用）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git add .&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#添加特定类型的文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git add *.js      # 添加所有js文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git add src/*.ts  # 添加src目录下所有ts文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、提交代码到本地仓库&lt;a href=&quot;#3提交代码到本地仓库&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#提交暂存区里面的代码到本地仓库&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git commit -m &quot;提交说明&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#提交并添加所有更改（跳过 git add 步骤）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git commit -am &quot;提交说明&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、更新远程仓库代码到本地&lt;a href=&quot;#4更新远程仓库代码到本地&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#拉取当前分支对应的远程分支代码并自动合并&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git pull&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#拉取远程特定分支并合并到当前分支&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git pull origin 分支名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5、推送代码到远程仓库&lt;a href=&quot;#5推送代码到远程仓库&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#推送当前分支到与之关联的远程分支&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git push&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#首次推送时需要设置上游分支&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git push -u origin 分支名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 推送当前分支到远程的指定分支&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git push origin 本地分支名:远程分支名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 强制推送，覆盖远程历史&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git push --force&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6、其它命令&lt;a href=&quot;#6其它命令&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#新建分支&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git branch  分支名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#切换分支&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git checkout  分支名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#合并指定分支到当前分支&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git merge 分支名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、git集成idea的使用&lt;a href=&quot;#三git集成idea的使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、使用git开发前的注意事项&lt;a href=&quot;#1使用git开发前的注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;git操作需谨慎！！！在进行不熟悉的git的操作或者复杂的git操作前，可以把代码做一个整体备份，一是防止误操作导致代码丢失，二是，这样的话你就放心的可以基于现在这份代码来试错了。备份的方式就是ctrl c ctrl v 粘贴复制保存一份未操作之前的代码，或者打个压缩包来保存也行。&lt;/li&gt;
&lt;li&gt;开发前，确定是在哪个分支开发，还是基于新的分支开发，如果基于新的分支开发，要确认清楚，基于哪个分支新建。&lt;/li&gt;
&lt;li&gt;推送代码之前，先把本地代码commit，然后再pull代码更新远程仓库代码，最后push&lt;/li&gt;
&lt;li&gt;切换分支之前，记得把当前分支没有commit的代码commit后再切换分支。&lt;/li&gt;
&lt;li&gt;合并分支代码之前，要问清楚你们是直接自己手动合并，还是要在git仓库管理平台发起合并请求。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、idea集成git&lt;a href=&quot;#2idea集成git&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;idea的settings里面找到Version Control里面的Git下配置本地安装的git&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/34baf2cf-0a7e-4255-b57e-b2824bfa2d9a.png&quot; alt=&quot;idea集成git&quot; /&gt;&lt;figcaption&gt;idea集成git&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、克隆代码&lt;a href=&quot;#3克隆代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;idea也可以克隆代码，克隆之后，就可以直接打开克隆的代码，这种方式还是很方便的。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/a072f070-64a0-4399-98e4-e99f828cae2f.png&quot; alt=&quot;image-20250908184030482&quot; /&gt;&lt;figcaption&gt;image-20250908184030482&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;URL就是代码仓库地址，Directory就是代码要克隆的目录。填写完成后，点击Clone按钮即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/e90351cb-8656-405f-9d6e-06d0f1fc8d79.png&quot; alt=&quot;idea克隆代码&quot; /&gt;&lt;figcaption&gt;idea克隆代码&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;有时候，idea可能会出现如下无法克隆的问题。确保idea已经集成git的情况下，还是有如下问题的话，便可以使用git bash命令窗口通过git clone命令来把代码克隆下来，然后再用idea打开克隆下来的代码。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/80bd10af-23f9-4440-a39e-99f093e21204.jpg&quot; alt=&quot;idea克隆代码报错&quot; /&gt;&lt;figcaption&gt;idea克隆代码报错&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、常见操作&lt;a href=&quot;#3常见操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img /&gt;&lt;figcaption&gt;idea中git常见操作&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;​ 图 3-1&lt;/p&gt;&lt;section&gt;&lt;h5&gt;3.3.1 提交代码&lt;a href=&quot;#331-提交代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;点击图 3-1 的提交代码按钮，便会出现如下界面，按照图中描述的进行操作即可！&lt;strong&gt;注意，我们在工作中的时候，同事之间经常说的你有没有提交代码，其实是口语化的表达，并不是说你有没有commit，而是问你有没有push到远程仓库&lt;/strong&gt;！commit只是把代码commit到你的本地仓库，只有把代码push到远程仓库，他那边才能从远程仓库更新代码到他的本地仓库！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/58da61ad-6243-45e2-8b83-60b6cb0ad5a8.png&quot; alt=&quot;idea-提交代码&quot; /&gt;&lt;figcaption&gt;idea-提交代码&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;3.3.2 更新代码&lt;a href=&quot;#332-更新代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;点击 图 3-1 中的 Update Project,即可将远程分支代码更新到当前分支(建议更新代码先把代码commit一下，避免出现代码冲突误操作导致代码丢失的话，也可以进行回滚)&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;3.3.3 推送代码&lt;a href=&quot;#333-推送代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;点击 图 3-1 中的 Push就会出现如下界面，点击下图对应按钮进行推送。一般情况点击Push正常推送即可！除非你本地代码和远程代码不一致，你又想要远程仓库代码和你本地代码保持一致，才使用Force Push进行强制推送！&lt;strong&gt;强制推送要谨慎&lt;/strong&gt;！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/77e9e156-904a-4fd4-b099-590741bb29e9.png&quot; alt=&quot;推送代码&quot; /&gt;&lt;figcaption&gt;推送代码&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;3.3.4 分支相关操作&lt;a href=&quot;#334-分支相关操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;如下图，当我们点击分支后右尖括号的时候便可以针对当前分支进行对应操作。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/bc9a7951-864e-4282-870e-409d5d3c49e1.png&quot; alt=&quot;新建分支&quot; /&gt;&lt;figcaption&gt;新建分支&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;​ 图 3-3-4-1&lt;/p&gt;&lt;section&gt;&lt;h6&gt;3.3.4.1 新建分支&lt;a href=&quot;#3341-新建分支&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;新建分支，如 图3-3-4-1，点击 &lt;strong&gt;new branch from main&lt;/strong&gt; ,从而基于当前分支进行新建。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/a77d0113-00cd-4c12-a9ca-ec0ad7de11a4.png&quot; alt=&quot;idea-新建分支&quot; /&gt;&lt;figcaption&gt;idea-新建分支&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h6&gt;3.3.4.2 切换分支&lt;a href=&quot;#3342-切换分支&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;点击 图3-3-4-1 的CheckOut将代码切换到当前选中分支，切换代码前，如果当前分支有未commit的代码，可能会出现如下提示：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/7a7f46dc-3b8a-44d9-a84e-6fb2a1348428.png&quot; alt=&quot;idea-切换分支提示&quot; /&gt;&lt;figcaption&gt;idea-切换分支提示&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;此时应点击 &lt;strong&gt;Don’t Checkout&lt;/strong&gt; 暂不切换！可经过以下两种处理方式之后，再进行切换！需要注意的是，即使没有弹出该界面，最好也要手动commit或者暂存未commit的代码再切换分支！&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;把当前未commit的代码进行commit&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;把未提交的代码进行commit，然后再切换分支。再次切换回来之后，如果不想保留这个commit记录。可以使用&lt;strong&gt;undo commit&lt;/strong&gt;来撤销commit！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/c915cd49-71f0-4938-84fe-5cf1413dbd1f.png&quot; alt=&quot;idea-撤销提交&quot; /&gt;&lt;figcaption&gt;idea-撤销提交&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;暂存当前未commit的代码&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如下图，鼠标右击任一空白区域，然后点击 &lt;strong&gt;Stash Changes&lt;/strong&gt; 暂存当前分支修改的文件！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/369c4cfa-f6f2-472a-8b6c-23546fc332e5.png&quot; alt=&quot;idea-暂存代码&quot; /&gt;&lt;figcaption&gt;idea-暂存代码&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击 &lt;strong&gt;Stash Changes&lt;/strong&gt; 后出现如下界面，按下图指引进行操作即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/b08fce08-37e7-4240-ac79-e6a75b709bdf.png&quot; alt=&quot;idea-输入暂存消息&quot; /&gt;&lt;figcaption&gt;idea-输入暂存消息&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;再次切换回来之后，把暂存的代码恢复，如下点击 &lt;strong&gt;Unstash Changes&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/80118679-a67a-4d6c-8eb3-5beeacdfe59f.png&quot; alt=&quot;idea-恢复暂存&quot; /&gt;&lt;figcaption&gt;idea-恢复暂存&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h6&gt;3.3.4.3 合并代码&lt;a href=&quot;#3343-合并代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;分支代码合并，有&lt;strong&gt;本地合并&lt;/strong&gt;和&lt;strong&gt;平台合并&lt;/strong&gt;两种方式。具体哪种合并方式，要确认清楚。一般往重要分支合并都是需要平台发起合并请求，让有权限的人来审核你的代码，看是否合并。正常情况下，我们在源分支往子分支合并代码的话本地合并就行，而子分支代码往源分支合并的时候，则需要平台发起合并请求来进行合并。源分支一般都是受保护的，是不允许直接推送代码的！&lt;/p&gt;&lt;p&gt;需要注意的是，在平台发起合并请求的时候，也就是将子分支合并到源分支之前，最好按照下面本地合并的步骤，把源分支的更新合并到你的子分支。这样做的目的，就是把可能出现的冲突提前在本地解决掉。否则，如果有冲突的话，平台上是无法合并的！&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1、本地合并&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;本地合并代码，如图 3-3-4-1点击你要合并的分支后的左尖括号后，点击 &lt;strong&gt;Merge ‘main’ into ‘dev’&lt;/strong&gt; 。这个意思就是将main分支代码合并到当前dev分支。dev分支就是你当前的分支，mian分支就是你要合并代码过来的分支。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）源分支合并到子分支&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;注意的是，如果你点击的是合并本地main分支的话，一定要先切换到main分支更新一下你本地main分支的代码，保证本地main分支代码是最新的。然后，再切换回你的dev分支，按上述说的，来将main分支代码合并到你当前dev分支。如果，你是点击的远程分支，则直接合并即可！当然，如果dev分支，并不是你一个人的分支，合并之前，也要更新一下dev分支代码，保证dev分支代码也是最新的！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/29c722ad-a8f6-4946-8c45-0ef3aa444a04.png&quot; alt=&quot;idea-合并代码-1&quot; /&gt;&lt;figcaption&gt;idea-合并代码-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）子分支合并到源分支&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;子分支合并到源分支，最好先按照 源分支合并到子分支的步骤合并完，再切换到源分支后，将子分支合并到源分支。合并完成之后，将代码推送到远程仓库即可！&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2、平台合并&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;平台合并就是在git管理平台发起合并请求，待对应审核人员来进行审核，审核通过，同意合并，则合并成功。这里以gitlab为例，流程如下：&lt;/p&gt;&lt;p&gt;首先进入需要发起合并请求的代码仓库里，点击左侧合并请求选项（注意需要合并的代码未push的要push上去）&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/63f88d7a-1a31-459e-a484-2a5799705258.png&quot; alt=&quot;gitlab-合并请求-1&quot; /&gt;&lt;figcaption&gt;gitlab-合并请求-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;然后会出现如下界面，点击新建合并请求&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/93ee0111-7a2e-491f-b22c-6592b7ea95f6.png&quot; alt=&quot;gitlab-新建合并请求&quot; /&gt;&lt;figcaption&gt;gitlab-新建合并请求&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;然后出现如下界面，选择对应需要合并的分支，点击 &lt;strong&gt;比较分支并继续&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/3a4fdb71-13c1-4f56-b8ad-0508f450e6fd.png&quot; alt=&quot;gitlab-合并分支-选择分支&quot; /&gt;&lt;figcaption&gt;gitlab-合并分支-选择分支&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;然后出现如下界面，按照下图注释填写对应内容即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/32589900-c5b4-474b-a29b-78c8b189a0e2.png&quot; alt=&quot;gitlab-合并请求&quot; /&gt;&lt;figcaption&gt;gitlab-合并请求&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;3.3.5 回退代码&lt;a href=&quot;#335-回退代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;section&gt;&lt;h6&gt;3.3.5.1 本地仓库代码回退&lt;a href=&quot;#3351-本地仓库代码回退&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;本地仓库代码回退指的是你还没有将提交推送到远程仓库，或者你只想在本地回退代码。如下选择你要回退的版本进行回退。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/45829fac-f512-460c-93c1-8a18ce9388d2.png&quot; alt=&quot;回退代码&quot; /&gt;&lt;figcaption&gt;回退代码&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;会有如下四个选项:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/9f21ae50-5b31-467b-b8f4-95e547208d09.png&quot; alt=&quot;git-回退选项&quot; /&gt;&lt;figcaption&gt;git-回退选项&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Soft&lt;/p&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;/li&gt;
&lt;li&gt;
&lt;p&gt;Mixed&lt;/p&gt;
&lt;p&gt;提交历史回退到了 &lt;strong&gt;提交一&lt;/strong&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;Hard&lt;/p&gt;
&lt;p&gt;提交历史回退到了 &lt;strong&gt;提交一&lt;/strong&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;Keep&lt;/p&gt;
&lt;p&gt;提交历史回退到了 &lt;strong&gt;提交一&lt;/strong&gt;，但之前提交 &lt;strong&gt;提交二&lt;/strong&gt; 中所做的所有更改会丢失。之前暂存区的内容也会回退到工作区，工作区的内容保持不变。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;总结表格如下：&lt;/p&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;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;—soft&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;—mixed（默认）&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;—hard&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;—keep&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;/section&gt;&lt;section&gt;&lt;h6&gt;3.3.5.2 远程仓库代码回退&lt;a href=&quot;#3352-远程仓库代码回退&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;远程仓库代码回退指的是你已经将提交推送到了远程仓库，现在需要将远程仓库的代码也回退到之前的某个版本。此时回退的方法有如下两个方式：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1） 不需要强制推送（推荐）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;此方式不需要强制推送，会保留原有提交记录，并生成一条新的撤销记录，用于对应需要回退的那条记录。主要方式如下:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/c8583d32-f3ef-488b-a03a-e2c4069ffc26.png&quot; alt=&quot;非强制推送-1&quot; /&gt;&lt;figcaption&gt;非强制推送-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击后会生成一条新的提交记录，该记录仅回滚你选中的那次提交所引入的代码修改。因此，它不会影响中间其他提交记录的代码。但是，如果中间的某次提交与你回滚的提交修改了同一个文件，则可能会产生冲突，需要手动解决。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/85d49b65-73fa-4dc9-91ad-b63d6d82354d.png&quot; alt=&quot;非强制推送-3&quot; /&gt;&lt;figcaption&gt;非强制推送-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;需要注意的是，点击&lt;strong&gt;Revert Commit&lt;/strong&gt; 回退之前需要将未提交的代码提交或者暂存，如果没有提交或者暂存Idea右下角会有如下提示&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/353bea4b-5432-45eb-86d0-a5ac57fdaf1f.png&quot; alt=&quot;非强制推送-2&quot; /&gt;&lt;figcaption&gt;非强制推送-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）需要强制推送 (谨慎)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;步骤就是，先按照本地仓库的回退步骤进行本地回退，然后再推送代码的时候选择强制推送即可。此时，如果强制推送即 &lt;strong&gt;Force Push&lt;/strong&gt; 置灰不可点击，则说明该分支是受保护，不允许强制推送的！那么远程仓库代码该分支就是不允许做回滚的！那么就只能使用方式一。请注意，&lt;strong&gt;强制推送仅建议用于个人分支&lt;/strong&gt;。如果该分支是公共的，那么强制回退该分支远程仓库代码可能会给其他人带来麻烦。因此，如果你要回退远程仓库公共分支代码之前，最好通知团队中的其他成员。&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/f7730917-946d-4a97-a7f1-07d4958bfd89.png&quot; alt=&quot;git-强制推送&quot; /&gt;&lt;figcaption&gt;git-强制推送&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;3.3.6 其他常见操作&lt;a href=&quot;#336-其他常见操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;section&gt;&lt;h6&gt;3.3.6.1 查看代码行提交人&lt;a href=&quot;#3361-查看代码行提交人&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;鼠标右击代码的左侧栏（也是打断点的地方），然后选择 &lt;strong&gt;Annotate with Git Blame&lt;/strong&gt; ，便可查看每行代码是谁写的！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/4565e3a3-ed7d-4b18-b52f-29b7ad91d54c.png&quot; alt=&quot;idea-查看每行代码谁写的&quot; /&gt;&lt;figcaption&gt;idea-查看每行代码谁写的&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h6&gt;3.3.6.2 git日志窗口&lt;a href=&quot;#3362-git日志窗口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;使用快捷键 &lt;strong&gt;Alt + 9&lt;/strong&gt; 可以唤出git的日志窗口，在这里我们除了可以查看git提交的提交人、提交信息、提交时间等提交相关信息之外。还可以针对提交记录，做很多操作，比如上面说的&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;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/2798d8e0-8ca7-46cb-a79e-c6b658201d20.png&quot; alt=&quot;idea-git日志窗口&quot; /&gt;&lt;figcaption&gt;idea-git日志窗口&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h6&gt;3.3.6.3 合并指定提交记录代码&lt;a href=&quot;#3363-合并指定提交记录代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;当你只需要合并某个分支的某个提交记录的时候，则在git日志窗口，选择对应分支之后，鼠标右击你需要合并的提交记录之后，点击 &lt;strong&gt;Cherry-Pick&lt;/strong&gt; 把该记录合并过来。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/c811fd7f-730f-44be-852c-2aff41f388d6.png&quot; alt=&quot;idea-cherry-pick&quot; /&gt;&lt;figcaption&gt;idea-cherry-pick&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h6&gt;3.3.6.4 更改远程仓库地址&lt;a href=&quot;#3364-更改远程仓库地址&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;当我们公司的远程仓库地址变更后，我们本地的项目中的远程地址也需要同步更改！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/70e21f0d-53e4-46e9-9c19-e02bf600ffdc.png&quot; alt=&quot;更改远程仓库地址&quot; /&gt;&lt;figcaption&gt;更改远程仓库地址&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出现如下界面修改远程仓库地址后，点击 &lt;strong&gt;OK&lt;/strong&gt; 即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/f74e34eb-7ce8-45fd-846d-463b2b40bb5e.png&quot; alt=&quot;更改远程仓库地址-2&quot; /&gt;&lt;figcaption&gt;更改远程仓库地址-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h6&gt;3.3.6.5 新增变更列表&lt;a href=&quot;#3365-新增变更列表&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;在我们打开commit窗口的时候，默认是，有一个名为Changes的默认更改列表。所有新更改都会自动放入这个更改列表中。还有一个未版本控制的文件更改列表，用于对尚未添加到 暂存区中的新创建的文件进行分组。你可以根据需要创建任意数量的更改列表。比如，当我们需要根据本地环境更改一些配置文件的时候，而这些配置文件是不需要提交的，那么我们就可以新建一个更改列表，然后，把这些不需要提交的配置文件放到这个更改列表里面，这样后续，提交代码的时候，这些更改的配置文件就不会出现在默认的更改列表Changes中了。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/efe12686-4f9a-4fd7-aa96-a5572ed0e59d.png&quot; alt=&quot;idea-新增变更列表-1&quot; /&gt;&lt;figcaption&gt;idea-新增变更列表-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出现如下界面填写变更列表名称，点击 &lt;strong&gt;OK&lt;/strong&gt; ，便新建一个变更列表！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/c0a390ea-9c61-4a68-8e4c-ebf15b1b2f1b.png&quot; alt=&quot;idea-新增变更列表-1&quot; /&gt;&lt;figcaption&gt;idea-新增变更列表-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;把不需要提交的文件，使用鼠标拖到该变更列表即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/927837d9-e87d-45fb-b219-00af2780bd1c.png&quot; alt=&quot;idea-新增变更列表-3&quot; /&gt;&lt;figcaption&gt;idea-新增变更列表-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h6&gt;3.3.6.6 合并提交记录&lt;a href=&quot;#3366-合并提交记录&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;在开发过程中，我们常常会遇到需要将多个提交记录整合为单一提交的情况。比如，在我们平时开发的时候，怕代码丢失，可能会频繁的多次提交。但是，正常情况下，我们应该完成某个功能之后，才应该算一个提交。所以，在完成该功能的开发时，我们可以采用合并提交记录的方式，把分散的多次提交整合成一个统一的提交，这样不仅有助于保持提交历史的清晰和简洁，也便于后续的代码审查与维护。需要注意的是，这些提交必须是尚未推送到远程仓库的本地提交。如果已经推送，再尝试压缩并重新推送的话，可能需要使用强制推送（force push），而&lt;strong&gt;强制推送通常是不推荐的&lt;/strong&gt;，因为它可能会覆盖其他人的代码或导致不必要的冲突！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/48573b9f-24be-4028-9667-18a23bc5c75a.png&quot; alt=&quot;idea-合并提交记录&quot; /&gt;&lt;figcaption&gt;idea-合并提交记录&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出现如下界面，进行提交记录合并&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/f401a648-8ca0-4fd5-94be-289208065c53.png&quot; alt=&quot;idea-合并提交记录-1&quot; /&gt;&lt;figcaption&gt;idea-合并提交记录-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;除此之外也可以按住Ctrl键 鼠标右击你选中的提交记录，点击 &lt;strong&gt;Squash Commits&lt;/strong&gt; 来快速合并多条提交记录为一条&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/55f04832-6fd1-4599-be56-75c72e6112c3.png&quot; alt=&quot;合并提交记录-2&quot; /&gt;&lt;figcaption&gt;合并提交记录-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h6&gt;3.3.6.7 修改提交信息&lt;a href=&quot;#3367-修改提交信息&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h6&gt;&lt;p&gt;对于已经提交到本地仓库但没有push到远程仓库的提交记录，我们可以通过如下操作来修改提交信息。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/b9695db7-b828-4551-b0ce-6fadaf928038.png&quot; alt=&quot;idea-修改提交信息&quot; /&gt;&lt;figcaption&gt;idea-修改提交信息&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出现如下界面，填写修改后的提交信息，点击 &lt;strong&gt;OK&lt;/strong&gt; 即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/d9f13ef2-98f8-4e5e-8284-805c667f713e.png&quot; alt=&quot;idea-修改提交信息-2&quot; /&gt;&lt;figcaption&gt;idea-修改提交信息-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、常见问题&lt;a href=&quot;#4常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;section&gt;&lt;h5&gt;3.4.1 git代码冲突&lt;a href=&quot;#341-git代码冲突&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;当你在合并代码或者更新代码的时候，就有可能会出现冲突，发生文件冲突的时候，idea会出现如下界面：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/80318193-cc5e-4468-955c-5b8bc0ab2395.png&quot; alt=&quot;idea-git冲突&quot; /&gt;&lt;figcaption&gt;idea-git冲突&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;有时候，出现冲突的时候是先出现如下界面，当你点击 &lt;strong&gt;Merge&lt;/strong&gt;之后进入上图界面&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/1d4cc7f1-895b-45c9-aab0-6c917106cc2d.png&quot; alt=&quot;idea-git-合并冲突&quot; /&gt;&lt;figcaption&gt;idea-git-合并冲突&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;注意，出现该问题一定&lt;strong&gt;不要直接叉掉不处理&lt;/strong&gt;，这样会出现后面3.4.5的问题，并且可能会导致&lt;strong&gt;你没有提交的代码丢失&lt;/strong&gt;！&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;3.4.2 代码无法克隆&lt;a href=&quot;#342-代码无法克隆&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;​ 当出现代码无法克隆的时候，可以按照如下步骤进行排查，若以下步骤排查之后，还是不行，则直接可问同事！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/8b9facf5-5d8a-4e06-bf71-a87cd005bec1.png&quot; alt=&quot;代码无法克隆&quot; /&gt;&lt;figcaption&gt;代码无法克隆&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;3.4.3 代码无法推送&lt;a href=&quot;#343-代码无法推送&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;当出现代码无法推送的时候，可以按照如下步骤进行排查，若以下步骤排查之后，还是不行，则直接可问同事！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/a8611374-0acf-478b-adca-0de5141d717a.png&quot; alt=&quot;代码无法推送&quot; /&gt;&lt;figcaption&gt;代码无法推送&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;3.4.4 idea使用git的过程，弹出填写token界面&lt;a href=&quot;#344-idea使用git的过程弹出填写token界面&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;出现如下界面，随便填写一个token，然后点击 &lt;strong&gt;Log In&lt;/strong&gt; 登录&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/f9e99112-1caa-467c-b718-8c9b2c01a16d.png&quot; alt=&quot;idea-token登录-1&quot; /&gt;&lt;figcaption&gt;idea-token登录-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出现如下界面点击，Log in via Git&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/9b7a2bdd-6b75-4d07-bfc2-203d5767bb05.png&quot; alt=&quot;idea-token登录-2&quot; /&gt;&lt;figcaption&gt;idea-token登录-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出现如下界面，输入你git的账号密码登录即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/f6e54e88-0b26-40af-923e-04a01fa12153.png&quot; alt=&quot;idea-token登录-3&quot; /&gt;&lt;figcaption&gt;idea-token登录-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;还有一种方式就是把idea默认安装的gitlab插件给禁用，这样后续需要登录的时候就会直接弹出账号密码的登录，而不会是用Token登录！&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;3.4.5 当前分支名前出现Rebasing或者Merging&lt;a href=&quot;#345-当前分支名前出现rebasing或者merging&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;如下图，有时候我们会发现自己当前的分支名前，会出现 &lt;strong&gt;Rebasing&lt;/strong&gt; 或者 &lt;strong&gt;Merging&lt;/strong&gt;，出现这个的原因，往往是你因为你进行了合并或者更新等可能引起冲突的操作，但是却没有对冲突文件进行处理，导致对应操作未实际完成的原因！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/a7d9cbc9-f742-4433-a9ad-672b3bdfb7be.png&quot; alt=&quot;idea-分支名前出现Rebasing&quot; /&gt;&lt;figcaption&gt;idea-分支名前出现Rebasing&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;或者&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/134c82d3-2d4e-4b3d-8140-66769f47e668.png&quot; alt=&quot;idea-分支前出现Merging&quot; /&gt;&lt;figcaption&gt;idea-分支前出现Merging&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击 &lt;strong&gt;Resolve Conflicts&lt;/strong&gt; 处理冲突！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/97e5df42-c7ab-4e13-b28b-f6e7b59b576f.png&quot; alt=&quot;idea-分支名前出现Rebasing-2&quot; /&gt;&lt;figcaption&gt;idea-分支名前出现Rebasing-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>工作中Mybatis动态SQL的使用</title><link>https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADmybatis%E5%8A%A8%E6%80%81sql%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADmybatis%E5%8A%A8%E6%80%81sql%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>工作中Mybatis动态SQL的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、基础概述&lt;a href=&quot;#一基础概述&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、什么是动态SQL？&lt;a href=&quot;#1什么是动态sql&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单说：动态SQL就是根据条件自动拼接SQL语句。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;为什么要用动态SQL？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;举个例子：查询用户列表时，用户可能只输入用户名，也可能同时输入用户名和手机号，还可能什么都不输入。如果不用动态SQL，你就得写多个方法：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 不用动态SQL，要写多个方法&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;listAll&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;                           &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 查全部&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;listByName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; userName)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;         &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 按用户名查&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;listByPhone&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; phone)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 按手机号查&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;listByNameAndPhone&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; userName&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; phone)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 按用户名和手机号查&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;用动态SQL，只需要一个方法：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 用动态SQL，一个方法搞定&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;UserQueryDto&lt;/span&gt;&lt;span&gt;&lt;span&gt; query)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、动态SQL能解决什么问题？&lt;a href=&quot;#2动态sql能解决什么问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;




















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;问题&lt;/th&gt;&lt;th&gt;动态SQL解决方案&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;条件不确定&lt;/td&gt;&lt;td&gt;根据参数有无动态拼接条件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SQL拼接繁琐&lt;/td&gt;&lt;td&gt;自动处理AND、OR、逗号等&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;代码冗余&lt;/td&gt;&lt;td&gt;一个SQL搞定多种情况&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、常用动态SQL标签&lt;a href=&quot;#二常用动态sql标签&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、if标签 - 条件判断&lt;a href=&quot;#1if标签---条件判断&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;最常用的标签！&lt;/strong&gt; 用于判断参数是否满足条件。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;基本语法&lt;a href=&quot;#基本语法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;判断条件&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SQL语句&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;使用示例&lt;a href=&quot;#使用示例&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;list&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;User&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT * FROM t_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&amp;lt;!-- 如果userName不为空，就拼接这个条件 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND user_name = #{userName}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&amp;lt;!-- 如果phone不为空，就拼接这个条件 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null and phone != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND phone = #{phone}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&amp;lt;!-- 如果status不为空，就拼接这个条件 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;status != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND status = #{status}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;不同类型的判断方式&lt;a href=&quot;#不同类型的判断方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;Integer类型&lt;/td&gt;&lt;td&gt;只判断null&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;String类型&lt;/td&gt;&lt;td&gt;判断null和空串&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;List类型&lt;/td&gt;&lt;td&gt;判断null和size&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Boolean类型&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;&lt;strong&gt;新人注意：Integer类型判断时不要加空字符串判断！值为0时会被误判为空。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 错误：Integer类型加了空字符串判断 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;status != null and status != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND status = #{status}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 当status=0时，这个条件不会生效！ --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 正确：Integer类型只判断null --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;status != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND status = #{status}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、where标签 - 智能处理WHERE&lt;a href=&quot;#2where标签---智能处理where&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;where标签的作用：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;自动添加WHERE关键字&lt;/li&gt;
&lt;li&gt;自动去除多余的AND或OR&lt;/li&gt;
&lt;/ol&gt;&lt;section&gt;&lt;h4&gt;使用示例&lt;a href=&quot;#使用示例-1&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;list&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;User&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT * FROM t_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND user_name = #{userName}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null and phone != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND phone = #{phone}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;/th&gt;&lt;th&gt;生成的SQL&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;两个条件都有&lt;/td&gt;&lt;td&gt;SELECT * FROM t_user WHERE user_name = ? AND phone = ?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;只有userName&lt;/td&gt;&lt;td&gt;SELECT * FROM t_user WHERE user_name = ?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;条件都为空&lt;/td&gt;&lt;td&gt;SELECT * FROM t_user&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; where标签会自动去掉第一个AND，所以if里面的AND写在前面没问题。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、set标签 - 智能处理UPDATE&lt;a href=&quot;#3set标签---智能处理update&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;set标签的作用：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;自动添加SET关键字&lt;/li&gt;
&lt;li&gt;自动去除多余的逗号&lt;/li&gt;
&lt;/ol&gt;&lt;section&gt;&lt;h4&gt;使用示例&lt;a href=&quot;#使用示例-2&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;update&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;UPDATE t_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user_name = #{userName},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null and phone != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;phone = #{phone},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;email != null and email != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;email = #{email},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE id = #{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;效果：&lt;/strong&gt; 只更新传入的字段，没传的不更新。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、choose/when/otherwise - 多选一&lt;a href=&quot;#4choosewhenotherwise---多选一&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;类似Java的switch-case，只执行第一个满足条件的分支。&lt;/strong&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;使用示例&lt;a href=&quot;#使用示例-3&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;query&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;User&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT * FROM t_user WHERE 1=1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;choose&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;when&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND user_name = #{userName}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;when&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;when&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null and phone != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND phone = #{phone}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;when&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;otherwise&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND status = 1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;otherwise&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;choose&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;效果说明：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;如果userName有值，只按userName查&lt;/li&gt;
&lt;li&gt;如果userName没值但phone有值，只按phone查&lt;/li&gt;
&lt;li&gt;如果都没有，就查status=1的数据&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、foreach标签 - 遍历集合&lt;a href=&quot;#5foreach标签---遍历集合&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;用于批量操作：批量插入、批量更新、IN查询等。&lt;/strong&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;基本语法&lt;a href=&quot;#基本语法-1&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;集合名&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;元素名&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;separator&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;分隔符&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;开始符号&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;close&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;结束符号&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;#{元素名}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;collection&lt;/td&gt;&lt;td&gt;集合参数名&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;item&lt;/td&gt;&lt;td&gt;遍历时每个元素的变量名&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;separator&lt;/td&gt;&lt;td&gt;元素之间的分隔符&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;open&lt;/td&gt;&lt;td&gt;以什么开始&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;close&lt;/td&gt;&lt;td&gt;以什么结束&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;使用场景&lt;a href=&quot;#使用场景&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;（1）IN查询&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;listByIds&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;User&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT * FROM t_user WHERE id IN&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;ids&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;separator&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;(&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;close&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;)&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;#{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;生成的SQL：&lt;code&gt;SELECT * FROM t_user WHERE id IN (1, 2, 3)&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（2）批量插入&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;insertBatch&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;INSERT INTO t_user (user_name, phone, status)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;VALUES&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;list&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;user&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;separator&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(#{user.userName}, #{user.phone}, #{user.status})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;（3）批量更新&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;updateBatch&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;list&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;user&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;separator&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;UPDATE t_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;user.userName != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user_name = #{user.userName},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;user.phone != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;phone = #{user.phone},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE id = #{user.id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6、trim标签 - 自定义处理&lt;a href=&quot;#6trim标签---自定义处理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;更灵活地处理前缀后缀。&lt;/strong&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;使用示例&lt;a href=&quot;#使用示例-4&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 等价于where标签 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;prefix&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;WHERE&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;prefixOverrides&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;AND&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND user_name = #{userName}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null and phone != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND phone = #{phone}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 等价于set标签 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;prefix&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;SET&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;suffixOverrides&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user_name = #{userName},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null and phone != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;phone = #{phone},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、实际工作中的使用场景&lt;a href=&quot;#三实际工作中的使用场景&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、查询列表（最常用）&lt;a href=&quot;#1查询列表最常用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;list&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;UserVo&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT * FROM t_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND user_name LIKE CONCAT(&apos;%&apos;, #{userName}, &apos;%&apos;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null and phone != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND phone = #{phone}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;status != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND status = #{status}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;startTime != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND cr_time &amp;gt;= #{startTime}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;endTime != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND cr_time &amp;lt;= #{endTime}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ORDER BY cr_time DESC&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、动态更新&lt;a href=&quot;#2动态更新&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;updateSelective&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;UPDATE t_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user_name = #{userName},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;phone = #{phone},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;email != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;email = #{email},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;up_time = NOW(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE id = #{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、动态插入&lt;a href=&quot;#3动态插入&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;insertSelective&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;INSERT INTO t_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;prefix&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;(&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;suffix&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;)&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;suffixOverrides&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user_name,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;phone,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;email != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;email,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;cr_time,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;prefix&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;VALUES (&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;suffix&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;)&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;suffixOverrides&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;#{userName},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;#{phone},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;email != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;#{email},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;NOW(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、新人常见错误&lt;a href=&quot;#四新人常见错误&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、Integer类型判断错误&lt;a href=&quot;#1integer类型判断错误&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 错误：Integer类型加了空字符串判断 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;status != null and status != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND status = #{status}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 正确 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;status != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND status = #{status}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、忘记加AND或逗号&lt;a href=&quot;#2忘记加and或逗号&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 错误：忘记加AND --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user_name = #{userName}  &lt;/span&gt;&lt;span&gt;&amp;lt;!-- 少了AND --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND phone = #{phone}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 正确：第一个条件也要加AND，where标签会自动去掉 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND user_name = #{userName}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND phone = #{phone}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;where&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、批量操作没处理好&lt;a href=&quot;#3批量操作没处理好&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 错误：批量插入格式不对 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;insertBatch&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;INSERT INTO t_user (user_name, phone) VALUES&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;list&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;user&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(#{user.userName}, #{user.phone})  &lt;/span&gt;&lt;span&gt;&amp;lt;!-- 没有分隔符 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 正确：加上separator --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;insertBatch&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;INSERT INTO t_user (user_name, phone) VALUES&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;list&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;user&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;separator&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(#{user.userName}, #{user.phone})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、foreach没有判空&lt;a href=&quot;#4foreach没有判空&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人常见错误！如果list为空，&lt;code&gt;&amp;lt;foreach&amp;gt;&lt;/code&gt; 不会生成任何内容，SQL就会变成不合法的语法，直接报错。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 错误：没有判空，list为空时SQL变成 INSERT INTO t_user (user_name, phone) VALUES  ← 后面啥都没有，语法错误！ --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;insertBatch&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;INSERT INTO t_user (user_name, phone) VALUES&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;list&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;user&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;separator&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;(#{user.userName}, #{user.phone})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 错误：同样的问题，list为空时SQL变成 WHERE id IN  ← 后面没有值，语法错误！ --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;listByIds&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;User&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT * FROM t_user WHERE id IN&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;ids&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;separator&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;(&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;close&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;)&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;#{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;正确做法：在Service层判空，list为空时不调用Mapper方法：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insertBatch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;UserDto&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; userList) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 在Service层判空，避免传空集合到Mapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;CollectionUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isEmpty&lt;/span&gt;&lt;span&gt;&lt;span&gt;(userList)&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 分批处理，每批不超过1000条&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; batchSize &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userList&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;&lt;span&gt;();&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; batchSize) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; end &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Math&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;min&lt;/span&gt;&lt;span&gt;&lt;span&gt;(i &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; batchSize, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userList&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insertBatch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;userList&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;subList&lt;/span&gt;&lt;span&gt;(i, end));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;总结：&lt;code&gt;&amp;lt;foreach&amp;gt;&lt;/code&gt; 一定要配合判空使用。建议在Service层判断，集合为空直接return或抛异常，不要让空集合传到Mapper里。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、新人避坑指南&lt;a href=&quot;#五新人避坑指南&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;Integer判断加空字符串&lt;/td&gt;&lt;td&gt;Integer只判断null&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;String判断只判断null&lt;/td&gt;&lt;td&gt;还要判断空字符串&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;第一个if条件不加AND&lt;/td&gt;&lt;td&gt;要加AND，where标签会自动去掉&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;set里最后没逗号&lt;/td&gt;&lt;td&gt;要加逗号，set标签会自动去掉&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;foreach没写separator&lt;/td&gt;&lt;td&gt;批量操作要加分隔符&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;foreach没有判空&lt;/td&gt;&lt;td&gt;在Service层判空，集合为空时不调用Mapper，避免SQL语法错误&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;/section&gt;
&lt;section&gt;&lt;h2&gt;六、调试技巧&lt;a href=&quot;#六调试技巧&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、开启SQL日志&lt;a href=&quot;#1开启sql日志&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;MyBatis项目：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;application.yml&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;mybatis&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;configuration&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;log-impl&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;org.apache.ibatis.logging.stdout.StdOutImpl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;MyBatis-Plus项目：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;application.yml&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;mybatis-plus&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;configuration&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;log-impl&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;org.apache.ibatis.logging.stdout.StdOutImpl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意区分：&lt;/strong&gt; MyBatis和MyBatis-Plus只是配置前缀不同，一个是&lt;code&gt;mybatis:&lt;/code&gt;，一个是&lt;code&gt;mybatis-plus:&lt;/code&gt;。看看项目用的是哪个就配哪个。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;开启日志后，控制台会打印实际执行的SQL，检查是否符合预期。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、使用MyBatis Log Free插件（推荐）&lt;a href=&quot;#2使用mybatis-log-free插件推荐&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;在IDEA中安装 &lt;strong&gt;MyBatis Log Free&lt;/strong&gt; 插件，可以把MyBatis日志中带&lt;code&gt;?&lt;/code&gt;占位符的SQL直接还原成&lt;strong&gt;完整的、可执行的SQL&lt;/strong&gt;，复制到Navicat里直接运行排查问题。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;安装方式：&lt;/strong&gt; IDEA → Settings → Plugins → 搜索 &lt;code&gt;MyBatis Log Free&lt;/code&gt; → Install&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-07/09005bf5-05ef-4cb7-b1a2-7ed23217ee91.png&quot; alt=&quot;mybatislogfree-1&quot; /&gt;&lt;figcaption&gt;mybatislogfree-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;如果安装失败：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-07/9c3bf93b-615f-4684-ac07-6fa8971ff8d9.png&quot; alt=&quot;mybatislogfree-2&quot; /&gt;&lt;figcaption&gt;mybatislogfree-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;​ 在 Appearance &amp;amp; Behavior&lt;code&gt;-&amp;gt;&lt;/code&gt;System Settings&lt;code&gt;-&amp;gt;&lt;/code&gt;HTTP Proxy 路径中勾选 &lt;strong&gt;Auto-detect proxy settings&lt;/strong&gt; 后再重新 install 插件 &lt;code&gt;MyBatis Log Free&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-07/7c4335b1-f576-439e-8d62-9669ab22cda9.png&quot; alt=&quot;mybatislogfree-3&quot; /&gt;&lt;figcaption&gt;mybatislogfree-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;使用步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;开启SQL日志（上面的第1步）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;调用接口后，控制台会打印类似这样的日志：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;==&amp;gt; Preparing: SELECT * FROM t_user WHERE user_name = ? AND status = ?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;==&amp;gt; Parameters: 张三(String), 1(Integer)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;打开IDEA底部的 &lt;strong&gt;MyBatis Log Free&lt;/strong&gt; 面板（Tools → MyBatis Log Free）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;插件会自动还原成完整SQL：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;SELECT&lt;/span&gt;&lt;span&gt; * &lt;/span&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;span&gt; t_user &lt;/span&gt;&lt;span&gt;WHERE&lt;/span&gt;&lt;span&gt;&lt;span&gt; user_name &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;张三&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AND&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-07/98e3e78e-c07b-47d3-8537-efc3c788c585.png&quot; alt=&quot;mybatislogfree-4&quot; /&gt;&lt;figcaption&gt;mybatislogfree-4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;复制这条SQL，直接粘贴到Navicat执行，排查数据和条件是否正确&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人必装！&lt;/strong&gt; 不装这个插件的话，你需要手动把&lt;code&gt;?&lt;/code&gt;和参数一一对应替换，参数多了很容易搞错。有了这个插件一键还原，效率提升很多。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、终极建议&lt;a href=&quot;#七终极建议&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;工作中90%的动态SQL就是if + where的组合，把这个练熟就够了。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;遇到不确定的情况，开启SQL日志，看实际生成的SQL是什么样的，然后调整。&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>工作中Redis的使用</title><link>https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADredis%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADredis%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>工作中Redis的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、什么是Redis？&lt;a href=&quot;#一什么是redis&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Redis是一个开源的内存数据结构存储系统，可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构，如字符串、哈希、列表、集合、有序集合等。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、Redis的特点&lt;a href=&quot;#1redis的特点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;/td&gt;&lt;td&gt;数据存储在内存中，读写速度极快，QPS可达10万+&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;丰富的数据类型&lt;/td&gt;&lt;td&gt;支持String、Hash、List、Set、ZSet等多种数据结构&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;持久化&lt;/td&gt;&lt;td&gt;支持RDB和AOF两种持久化方式，防止数据丢失&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;tr&gt;&lt;td&gt;原子性&lt;/td&gt;&lt;td&gt;所有操作都是原子性的，支持事务&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、Redis的五种基本数据类型&lt;a href=&quot;#2redis的五种基本数据类型&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;适用场景&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;最基本的类型，可以存储字符串、整数、浮点数&lt;/td&gt;&lt;td&gt;缓存、计数器、分布式锁&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Hash&lt;/td&gt;&lt;td&gt;键值对集合，适合存储对象&lt;/td&gt;&lt;td&gt;用户信息、商品信息&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;List&lt;/td&gt;&lt;td&gt;有序列表，支持从两端插入和弹出&lt;/td&gt;&lt;td&gt;消息队列、最新列表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Set&lt;/td&gt;&lt;td&gt;无序集合，元素唯一&lt;/td&gt;&lt;td&gt;标签、共同关注&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ZSet&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;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、项目中如何使用Redis&lt;a href=&quot;#二项目中如何使用redis&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、项目中首次使用Redis&lt;a href=&quot;#1项目中首次使用redis&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1.1 引入依赖&lt;a href=&quot;#11-引入依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.springframework.boot&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;spring-boot-starter-data-redis&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.2 配置Redis信息&lt;a href=&quot;#12-配置redis信息&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;基础配置：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;redis&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;host&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;127.0.0.1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;6379&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;123456&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;database&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;完整配置（推荐）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;redis&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;host&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;127.0.0.1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;6379&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;123456&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;database&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;10000ms&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;lettuce&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;pool&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;max-active&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# 连接池最大连接数&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;max-wait&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;-1ms&lt;/span&gt;&lt;span&gt;       &lt;/span&gt;&lt;span&gt;# 连接池最大阻塞等待时间（负值表示无限制）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;max-idle&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;# 连接池最大空闲连接&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;min-idle&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;# 连接池最小空闲连接&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.3 配置RedisTemplate&lt;a href=&quot;#13-配置redistemplate&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedisConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Bean&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedisTemplate&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;RedisConnectionFactory&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;factory&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;RedisTemplate&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;template&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedisTemplate&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;template&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setConnectionFactory&lt;/span&gt;&lt;span&gt;(factory);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Jackson2JsonRedisSerializer&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;jackson2JsonRedisSerializer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Jackson2JsonRedisSerializer&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;ObjectMapper&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mapper&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ObjectMapper&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;mapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setVisibility&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;PropertyAccessor&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ALL&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;JsonAutoDetect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Visibility&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ANY&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;mapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;activateDefaultTyping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;LaissezFaireSubTypeValidator&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;instance&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;ObjectMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;DefaultTyping&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;NON_FINAL&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;jackson2JsonRedisSerializer&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setObjectMapper&lt;/span&gt;&lt;span&gt;(mapper);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 使用StringRedisSerializer来序列化和反序列化redis的key值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;StringRedisSerializer&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;stringRedisSerializer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StringRedisSerializer&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// key采用String的序列化方式&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;template&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setKeySerializer&lt;/span&gt;&lt;span&gt;(stringRedisSerializer);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// hash的key也采用String的序列化方式&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;template&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setHashKeySerializer&lt;/span&gt;&lt;span&gt;(stringRedisSerializer);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// value序列化方式采用jackson&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;template&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setValueSerializer&lt;/span&gt;&lt;span&gt;(jackson2JsonRedisSerializer);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// hash的value序列化方式采用jackson&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;template&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setHashValueSerializer&lt;/span&gt;&lt;span&gt;(jackson2JsonRedisSerializer);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;template&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;afterPropertiesSet&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; template;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.4 写Redis工具类&lt;a href=&quot;#14-写redis工具类&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedisUtils&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedisTemplate&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; redisTemplate&lt;/span&gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// =============================String类型操作=============================&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 设置缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;time&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForValue&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(key, value, time, &lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SECONDS&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 获取缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; key &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForValue&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 判断key是否存在&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hasKey&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;hasKey&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 删除缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 批量删除&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Collection&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;keys&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(keys);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 设置过期时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;expire&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;time&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;expire&lt;/span&gt;&lt;span&gt;(key, time, &lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SECONDS&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;49&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;50&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;51&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;52&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 获取过期时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;53&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;54&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getExpire&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;55&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getExpire&lt;/span&gt;&lt;span&gt;(key, &lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SECONDS&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;56&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;57&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;58&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;59&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 自增&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;60&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;61&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;increment&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;62&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForValue&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;increment&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;63&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;64&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;65&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;66&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 自增指定值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;67&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;68&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;increment&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delta&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;69&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForValue&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;increment&lt;/span&gt;&lt;span&gt;(key, delta);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;70&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;71&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;72&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;73&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 自减&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;74&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;75&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;decrement&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;76&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForValue&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;decrement&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;77&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;78&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;79&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// =============================Hash类型操作=============================&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;80&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;81&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;82&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 获取Hash中的值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;83&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;84&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hGet&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;field&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;85&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForHash&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(key, field);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;86&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;87&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;88&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;89&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 设置Hash中的值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;90&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;91&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hSet&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;field&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;92&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForHash&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;put&lt;/span&gt;&lt;span&gt;(key, field, value);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;93&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;94&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;95&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;96&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 获取Hash中所有值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;97&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;98&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Map&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;hGetAll&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;99&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForHash&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;entries&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;100&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;101&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;102&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;103&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 设置整个Hash&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;104&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;105&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hSetAll&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Map&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;106&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForHash&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;putAll&lt;/span&gt;&lt;span&gt;(key, map);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;107&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;108&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;109&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;110&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 删除Hash中的字段&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;111&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;112&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hDelete&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt;... &lt;/span&gt;&lt;span&gt;fields&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;113&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForHash&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(key, fields);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;114&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;115&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;116&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;117&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 判断Hash中是否存在该字段&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;118&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;119&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hHasKey&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;field&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;120&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForHash&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;hasKey&lt;/span&gt;&lt;span&gt;(key, field);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;121&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;122&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;123&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// =============================List类型操作=============================&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;124&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;125&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;126&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 获取List中的值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;127&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;128&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lGet&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;129&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForList&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span&gt;(key, index);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;130&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;131&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;132&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;133&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 获取List指定范围内的值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;134&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;135&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lGet&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;start&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;end&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;136&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForList&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;range&lt;/span&gt;&lt;span&gt;(key, start, end);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;137&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;138&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;139&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;140&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 从右边插入&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;141&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;142&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lPush&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;143&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForList&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;rightPush&lt;/span&gt;&lt;span&gt;(key, value);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;144&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;145&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;146&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;147&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 从右边弹出&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;148&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;149&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rPop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;150&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForList&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;rightPop&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;151&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;152&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;153&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;154&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 获取List长度&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;155&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;156&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lSize&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;157&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForList&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;158&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;159&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.5 使用Redis工具类&lt;a href=&quot;#15-使用redis工具类&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedisUtils&lt;/span&gt;&lt;span&gt; redisUtils&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userId&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 先从缓存获取&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cached&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (cached &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; (User) cached;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 缓存没有，从数据库查询&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectById&lt;/span&gt;&lt;span&gt;(userId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 存入缓存，设置1小时过期&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (user &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId, user, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;3600&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; user;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;updateUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 更新数据库&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;updateById&lt;/span&gt;&lt;span&gt;(user);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 删除缓存（保证一致性）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、项目中非首次使用Redis&lt;a href=&quot;#2项目中非首次使用redis&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;直接可以使用 &lt;code&gt;Ctrl + Shift + R&lt;/code&gt; 全局搜索redis，参考别人的代码是如何使用的，照葫芦画瓢（这个技能很重要）。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、项目中使用Redis的常见场景&lt;a href=&quot;#三项目中使用redis的常见场景&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、缓存热点数据&lt;a href=&quot;#1缓存热点数据&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;有些图表数据来源的表数据较多，处理过程复杂，导致接口响应慢，可以使用Redis缓存。&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;DataVO&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;getChartData&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; type) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; cacheKey &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;chart:data:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 先查缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; cached &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(cacheKey);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (cached &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;DataVO&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;) cached&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 查询数据库并处理&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;DataVO&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; data &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;processData&lt;/span&gt;&lt;span&gt;&lt;span&gt;(type)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 存入缓存，5分钟过期&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(cacheKey, data, &lt;/span&gt;&lt;span&gt;300&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; data&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、存储验证码/Token&lt;a href=&quot;#2存储验证码token&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 存储验证码，5分钟过期&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;saveVerifyCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; phone&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; code) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;verify:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; phone, code, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;300&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 验证验证码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;verifyCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; phone&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; code) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; cached &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;verify:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; phone);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;code&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;(cached);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、分布式锁&lt;a href=&quot;#3分布式锁&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;使用Redis实现分布式锁，防止重复操作：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tryLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; lockKey&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; requestId&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; expireTime) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForValue&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setIfAbsent&lt;/span&gt;&lt;span&gt;(lockKey, requestId, expireTime, &lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SECONDS&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TRUE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;(result);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;releaseLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; lockKey&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; requestId) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; script &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;if redis.call(&apos;get&apos;, KEYS[1]) == ARGV[1] then return redis.call(&apos;del&apos;, KEYS[1]) else return 0 end&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RedisScript&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; redisScript &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;RedisScript&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;(script, &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;execute&lt;/span&gt;&lt;span&gt;(redisScript, &lt;/span&gt;&lt;span&gt;Collections&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;singletonList&lt;/span&gt;&lt;span&gt;(lockKey), requestId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;1L&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;推荐使用Redisson实现分布式锁：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.redisson&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;redisson-spring-boot-starter&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;3.23.4&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedissonClient&lt;/span&gt;&lt;span&gt; redissonClient&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;doSomething&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;RLock&lt;/span&gt;&lt;span&gt; lock &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redissonClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;myLock&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 尝试获取锁，最多等待10秒，锁30秒后自动释放&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;30&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SECONDS&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 执行业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;finally&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isHeldByCurrentThread&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unlock&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、计数器&lt;a href=&quot;#4计数器&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 点赞数增加&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;likeArticle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; articleId) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;increment&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;article:like:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; articleId);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 获取点赞数&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getLikeCount&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; articleId) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; count &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;article:like:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; articleId);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; count &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0L&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;parseLong&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;count&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toString&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、限流&lt;a href=&quot;#5限流&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;使用Redis实现简单的限流：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;allowRequest&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; userId&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&lt;span&gt; maxCount&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; seconds) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; key &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;rate:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; count &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;increment&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (count &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;expire&lt;/span&gt;&lt;span&gt;(key, seconds);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; count &lt;/span&gt;&lt;span&gt;&amp;lt;=&lt;/span&gt;&lt;span&gt; maxCount&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、缓存三大问题&lt;a href=&quot;#四缓存三大问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、缓存穿透&lt;a href=&quot;#1缓存穿透&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;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;/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;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; userId) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; cached &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (cached &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;&quot;NULL&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;&lt;span&gt;(cached)&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 命中空值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; (User) cached&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; user &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectById&lt;/span&gt;&lt;span&gt;(userId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (user &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId, user, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;3600&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 缓存空值，5分钟过期&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;NULL&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;300&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; user&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、缓存击穿&lt;a href=&quot;#2缓存击穿&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：某个热点key过期，此时大量请求同时查询这个key，全部穿透到数据库。&lt;/p&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;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserWithLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; userId) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; cached &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (cached &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; (User) cached&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 获取分布式锁&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; lockKey &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;lock:user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;tryLock&lt;/span&gt;&lt;span&gt;&lt;span&gt;(lockKey&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;)) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 再次检查缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;cached &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (cached &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; (User) cached&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 查询数据库&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; user &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectById&lt;/span&gt;&lt;span&gt;(userId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (user &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;user:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; userId, user, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;3600&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; user&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 获取锁失败，等待后重试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;Thread&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sleep&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;50&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserWithLock&lt;/span&gt;&lt;span&gt;&lt;span&gt;(userId)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;finally&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;releaseLock&lt;/span&gt;&lt;span&gt;&lt;span&gt;(lockKey&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、缓存雪崩&lt;a href=&quot;#3缓存雪崩&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：大量缓存key在同一时间集中过期，导致所有请求都落到数据库上。&lt;/p&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;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;使用多级缓存，如本地缓存 + Redis&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;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 过期时间加随机值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;setWithRandomExpire&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; key&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt; baseTime) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt; randomTime &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; baseTime &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Random&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;nextInt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;300&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;redisUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;(key, value, randomTime);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、缓存一致性策略&lt;a href=&quot;#五缓存一致性策略&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;对于缓存一致性问题，直接先更新数据库，再删除缓存就能满足大部分的场景。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;更新数据库 -&amp;gt; 删除缓存 -&amp;gt; 下次查询时重新写入缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;/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;/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;p&gt;&lt;strong&gt;延时双删策略&lt;/strong&gt;（更高一致性要求）：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;删除缓存 -&amp;gt; 更新数据库 -&amp;gt; 延时几百毫秒 -&amp;gt; 再次删除缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、Redis常用命令&lt;a href=&quot;#六redis常用命令&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、String类型&lt;a href=&quot;#1string类型&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;SET key value&lt;/td&gt;&lt;td&gt;设置键值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GET key&lt;/td&gt;&lt;td&gt;获取值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DEL key&lt;/td&gt;&lt;td&gt;删除键&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;EXPIRE key seconds&lt;/td&gt;&lt;td&gt;设置过期时间&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SETNX key value&lt;/td&gt;&lt;td&gt;不存在时才设置&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;INCR key&lt;/td&gt;&lt;td&gt;自增1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DECR key&lt;/td&gt;&lt;td&gt;自减1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、Hash类型&lt;a href=&quot;#2hash类型&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;HSET key field value&lt;/td&gt;&lt;td&gt;设置Hash字段值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HGET key field&lt;/td&gt;&lt;td&gt;获取Hash字段值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HGETALL key&lt;/td&gt;&lt;td&gt;获取Hash所有字段和值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HDEL key field&lt;/td&gt;&lt;td&gt;删除Hash字段&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HEXISTS key field&lt;/td&gt;&lt;td&gt;判断字段是否存在&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、List类型&lt;a href=&quot;#3list类型&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;LPUSH key value&lt;/td&gt;&lt;td&gt;从左边插入&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RPUSH key value&lt;/td&gt;&lt;td&gt;从右边插入&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LPOP key&lt;/td&gt;&lt;td&gt;从左边弹出&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RPOP key&lt;/td&gt;&lt;td&gt;从右边弹出&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LRANGE key start stop&lt;/td&gt;&lt;td&gt;获取指定范围元素&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、通用命令&lt;a href=&quot;#4通用命令&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;KEYS pattern&lt;/td&gt;&lt;td&gt;查找匹配的键（生产环境慎用）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TTL key&lt;/td&gt;&lt;td&gt;查看剩余过期时间&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TYPE key&lt;/td&gt;&lt;td&gt;查看键的类型&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;EXISTS key&lt;/td&gt;&lt;td&gt;判断键是否存在&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;FLUSHDB&lt;/td&gt;&lt;td&gt;清空当前数据库&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、常见问题排查&lt;a href=&quot;#七常见问题排查&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、连接超时&lt;a href=&quot;#1连接超时&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;可能原因：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Redis服务未启动&lt;/li&gt;
&lt;li&gt;防火墙未放行端口&lt;/li&gt;
&lt;li&gt;配置的IP或端口错误&lt;/li&gt;
&lt;li&gt;密码错误&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;排查命令：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 测试端口连通性&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;telnet&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;127.0.0.1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;6379&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 使用redis-cli连接测试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;redis-cli&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-h&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;127.0.0.1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;6379&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-a&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、内存占用过高&lt;a href=&quot;#2内存占用过高&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;排查方法：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 查看Redis内存使用情况&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;redis-cli&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;memory&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 查看大key&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;redis-cli&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--bigkeys&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、响应慢&lt;a href=&quot;#3响应慢&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;可能原因：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;执行了慢查询（如KEYS *）&lt;/li&gt;
&lt;li&gt;存在大key&lt;/li&gt;
&lt;li&gt;网络延迟&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>工作中SVN的使用</title><link>https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADsvn%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%B7%A5%E4%BD%9C%E4%B8%ADsvn%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>工作中SVN的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h3&gt;一、svn是什么？&lt;a href=&quot;#一svn是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;集中式版本控制（Centralized VCS）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;所有历史版本集中存放在一台服务器，本地只保留当前工作副本。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;核心概念：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;中央仓库：SVN 采用客户端-服务器模式。所有文件的历史版本都集中存储在一个中央服务器上。&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;工作副本：开发者从中央服务器“检出”一份文件到自己的本地电脑，这份本地的文件就是工作副本。&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;版本记录：SVN 会记录每一次文件提交，包括：谁、在什么时候、修改了哪些内容、以及为什么修改。每个版本都有一个唯一的版本号。&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;提交与更新：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;提交：当你修改完本地代码后，通过“提交”操作将变更同步到中央服务器，从而创建一个新的版本。&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;更新：通过“更新”操作，将本地工作副本与中央服务器的最新版本同步，获取其他同事的修改。&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;二、有了git，为啥还需要svn?&lt;a href=&quot;#二有了git为啥还需要svn&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;历史原因&lt;/strong&gt;：大量现存的老项目跑在 SVN 上，迁移成本和风险高。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;场景需求&lt;/strong&gt;：对于需要&lt;strong&gt;严格目录级权限控制&lt;/strong&gt;和&lt;strong&gt;频繁处理大型二进制文件&lt;/strong&gt;（如游戏美术资源）的团队，SVN 的方案可能更简单、更稳定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;团队习惯&lt;/strong&gt;：对于非技术背景成员较多或团队习惯已定的情况，SVN 的统一、简单的工作流更容易管理和维护。&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;结论就是：工具没有绝对的好坏，只有是否适合当前的团队和项目。&lt;/strong&gt; Git 在绝大多数软件开发场景下是更优的选择，但 SVN 在它的特定领域内，依然是一个可靠、甚至是更合适的选择。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、svn的安装&lt;a href=&quot;#三svn的安装&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;svn是分为服务端和客户端的。对于我们使用者来说只用安装svn的客户端就行。就像git一样我们本地也是需要安装git的客户端，而服务端比如gitlab是不需要我们安装的。svn客户端的安装很简单，除了下图需要单独设置一下，其他的只要一直点击下一步即可！只有安装的时候选择下面这个 Command Line Client Tools 的时候，你的安装目录的bin目录下面才有svn.exe文件。这样，后续，在idea中集成svn的时候才可以选择它。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/4274e732-f4b3-4593-ac26-2692b4254a07.png&quot; alt=&quot;svn客户端安装&quot; /&gt;&lt;figcaption&gt;svn客户端安装&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;四、SVN的基本操作&lt;a href=&quot;#四svn的基本操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、检出操作&lt;a href=&quot;#1检出操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;拿到仓库地址URL ,鼠标右击空白区域-点击SVN检出&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/0eb9460d-f930-4f2a-993c-27de6fb30fe8.png&quot; alt=&quot;右击空白区域&quot; /&gt;&lt;figcaption&gt;右击空白区域&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;在检出界面，填仓库地址URL ，默认检出地址，就是你点击的空白区域所在目录&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/70e46616-6cf4-4815-9bf8-9ebf5f4c3356.png&quot; alt=&quot;检出&quot; /&gt;&lt;figcaption&gt;检出&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;认证界面，填写用户名/密码&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/aaac1995-3d61-4448-8263-9d3a29ca18a8.png&quot; alt=&quot;认证界面&quot; /&gt;&lt;figcaption&gt;认证界面&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;出现如下界面，便是检出成功&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/b2c5b061-0e85-4f6d-96c4-6d4a53cef747.png&quot; alt=&quot;检出成功&quot; /&gt;&lt;figcaption&gt;检出成功&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、提交文件&lt;a href=&quot;#2提交文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;新增文件需要add之后，才能commit到远程仓库，或者在commit的时候选择未add的文件进行提交，修改的文件commit的时候默认是勾选的。当前目录空白区域鼠标右击，然后点击commit的时候，是commit当前目录下未commit的文件。如果点击某个文件右击的话，commit的就是当前文件。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/0dc243b9-c546-490f-b2aa-c6cecce4b3c7.png&quot; alt=&quot;commit&quot; /&gt;&lt;figcaption&gt;commit&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出现如下界面，填写提交信息后点击Ok提交：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/b7761884-85b0-4f8e-aa68-38a5b877f3a4.png&quot; alt=&quot;commit信息&quot; /&gt;&lt;figcaption&gt;commit信息&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、更新文件&lt;a href=&quot;#3更新文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/5ea081d0-75b4-4707-8e1a-ebdc7519ba96.png&quot; alt=&quot;更新&quot; /&gt;&lt;figcaption&gt;更新&lt;/figcaption&gt;&lt;/figure&gt;4、查看历史版本&lt;a href=&quot;#4查看历史版本&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;通过查看历史版本，可以看到别人的提交记录，以及提交了什么文件。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/20f78b7a-e892-49a2-be22-9f4c6165de73.png&quot; alt=&quot;查看历史日志&quot; /&gt;&lt;figcaption&gt;查看历史日志&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击之后出现如下历史提交记录界面&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/631ca99d-1623-4933-83ce-c7eb035d1c3f.png&quot; alt=&quot;提交日志&quot; /&gt;&lt;figcaption&gt;提交日志&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5、回滚&lt;a href=&quot;#5回滚&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;点击下面按钮，进入回滚界面&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/886de3b8-015b-4495-88e9-5b925533db74.png&quot; alt=&quot;回退版本&quot; /&gt;&lt;figcaption&gt;回退版本&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;进入回退版本界面，点击Show log查看历史提交记录，查看要回退的版本号&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/631ca99d-1623-4933-83ce-c7eb035d1c3f.png&quot; alt=&quot;提交日志&quot; /&gt;&lt;figcaption&gt;提交日志&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;填写要回退的版本的版本号进行回退&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/2f27b5eb-999f-434c-acc6-4adee36c3635.png&quot; alt=&quot;回退版本2&quot; /&gt;&lt;figcaption&gt;回退版本2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6、分支操作&lt;a href=&quot;#6分支操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;​ 正常情况需要进行分支操作的时候，我们需要建立如下三个目录：&lt;/p&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;trunk&lt;/td&gt;&lt;td&gt;主开发线，存放最新的稳定代码&lt;/td&gt;&lt;td&gt;便于集中开发、持续集成&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;branches&lt;/td&gt;&lt;td&gt;用于并行开发、功能分支、修复分支等&lt;/td&gt;&lt;td&gt;支持多人协作、功能隔离、风险控制&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;tags&lt;/td&gt;&lt;td&gt;用于标记发布版本（如 v1.0、v2.0），通常只读，不修改&lt;/td&gt;&lt;td&gt;便于版本回溯、发布管理、归档&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;section&gt;&lt;h5&gt;6.1 新建分支&lt;a href=&quot;#61-新建分支&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;基于主干新建分支的时候，右击主干分支，按下图选择新建分支。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/fb9140c1-b7af-4397-a6f3-23b64dd88bc7.png&quot; alt=&quot;新建分支&quot; /&gt;&lt;figcaption&gt;新建分支&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;进入如下界面，填写对应信息，新建分支&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/a04fe030-c11c-4428-8684-644bf9c56810.png&quot; alt=&quot;新建分支-详情&quot; /&gt;&lt;figcaption&gt;新建分支-详情&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;需要注意的是，新建完分支之后，需要在update一下，本地对应目录才会有对应分支代码。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;6.2 合并分支&lt;a href=&quot;#62-合并分支&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;将分支内容合并到主干（branch =&amp;gt; trunk），按如下步骤进行合并：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;右击主干目录，点击 &lt;strong&gt;Merge&lt;/strong&gt; 进行合并&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/d92756af-4680-476b-8f3e-87ad8d3f5fe2.png&quot; alt=&quot;合并1&quot; /&gt;&lt;figcaption&gt;合并1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;进入如下界面直接点击下一步即可&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/a5178630-f0d0-4d2a-b43a-102cf86a93c9.png&quot; alt=&quot;合并2&quot; /&gt;&lt;figcaption&gt;合并2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;进入如下界面，填写对应合并信息后，点击Next&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9150ef05-8345-4d6f-a856-cab0e6e79c6a.png&quot; alt=&quot;合并3&quot; /&gt;&lt;figcaption&gt;合并3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;一般按照默认就好 先点击 &lt;strong&gt;Test merge&lt;/strong&gt; ，进行合并测试，合并测试没问题，再点击 &lt;strong&gt;Merge&lt;/strong&gt; 合并&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/1bb09968-71ff-4bbc-b586-0e56f22b5a3f.png&quot; alt=&quot;合并4&quot; /&gt;&lt;figcaption&gt;合并4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;需要注意的是，合并仅仅是合并到本地文件夹目录，所以合并完成后，记得要Commit提交到SVN。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/3853fcda-b926-4f80-81ca-770b0801e5e7.png&quot; alt=&quot;合并5&quot; /&gt;&lt;figcaption&gt;合并5&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;6.3 切换分支&lt;a href=&quot;#63-切换分支&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;右击需要切换分支的工作目录，选择 &lt;strong&gt;Switch&lt;/strong&gt; 进入切换分支模块&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/3bbb3a59-b587-4c98-914e-634e74c0d708.png&quot; alt=&quot;切换分支&quot; /&gt;&lt;figcaption&gt;切换分支&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;进入切换分支界面之后，选择要切换的分支，点击 &lt;strong&gt;OK&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/2185a8a3-d752-4fc6-b5dc-af81119f8ba3.png&quot; alt=&quot;切换分支2&quot; /&gt;&lt;figcaption&gt;切换分支2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;7、文件冲突&lt;a href=&quot;#7文件冲突&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;当你在合并代码或者更新代码的时候，就有可能会出现冲突，发生文件冲突的时候，会出现如下界面：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/fc6aaefb-443f-4416-8bec-95ba694552c6.png&quot; alt=&quot;冲突1&quot; /&gt;&lt;figcaption&gt;冲突1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;右击冲突文件，选择 &lt;strong&gt;Edit conflicts&lt;/strong&gt;，编辑冲突文件&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/b2e6fdad-3946-4386-af93-08e2261bdac4.png&quot; alt=&quot;冲突2&quot; /&gt;&lt;figcaption&gt;冲突2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;进入如下界面后，按照图示进行冲突处理：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/3a0847fd-1807-46b0-980d-bdf3deb030d6.png&quot; alt=&quot;冲突3&quot; /&gt;&lt;figcaption&gt;冲突3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;冲突处理完成之后，点击 Save 保存&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/3f5bfacf-91bf-4a09-92d5-de923d8589ab.png&quot; alt=&quot;冲突4&quot; /&gt;&lt;figcaption&gt;冲突4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;如果冲突处理完成，并且 点击的 Mark as resolved ，即标记为已解决，则之前文件前的冲突标识消失。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/4b326cd6-456f-4b86-96ee-c7dd483c9630.png&quot; alt=&quot;冲突5&quot; /&gt;&lt;figcaption&gt;冲突5&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;五、idea集成SVN的基本使用&lt;a href=&quot;#五idea集成svn的基本使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、idea集成svn&lt;a href=&quot;#1idea集成svn&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;idea的&lt;strong&gt;settings&lt;/strong&gt;里面找到&lt;strong&gt;Version Control&lt;/strong&gt;里面的 &lt;strong&gt;Subversion&lt;/strong&gt;下配置本地安装的svn路径&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/3c1fc237-140b-4414-b30a-7eef0bbeda08.png&quot; alt=&quot;idea集成svn&quot; /&gt;&lt;figcaption&gt;idea集成svn&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;idea上方工具栏出现 &lt;strong&gt;SVN&lt;/strong&gt;，则说明idea集成SVN成功!&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/69c82e53-1f2e-42e6-80e0-7f70b119f778.png&quot; alt=&quot;idea集成svn2&quot; /&gt;&lt;figcaption&gt;idea集成svn2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、提交、更新代码&lt;a href=&quot;#2提交更新代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;点击下图对应按钮，即可提交代码、更新代码。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/f8abab72-76db-45c3-90bc-ce5833173088.png&quot; alt=&quot;idea-提交更新&quot; /&gt;&lt;figcaption&gt;idea-提交更新&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击提交代码，会出现如下界面，选择要提交的文件以及填写提交信息，之后点击 &lt;strong&gt;Commit&lt;/strong&gt; 提交代码。需要注意的是SVN是没有&lt;/p&gt;&lt;p&gt;本地仓库的概念的，提交就是直接提交到远程仓库，类似GIT的提交界面中的 &lt;strong&gt;Commit and Push&lt;/strong&gt; ！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9f948a4a-d091-4dfc-8c31-ad6cf3cee1d5.png&quot; alt=&quot;idea-提交详情&quot; /&gt;&lt;figcaption&gt;idea-提交详情&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;idea右下角弹出如下界面就是提交成功！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/0c948c36-72c5-4b53-b8a9-2324aa39eeac.png&quot; alt=&quot;idea-提交成功&quot; /&gt;&lt;figcaption&gt;idea-提交成功&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击更新代码会出现如下界面，直接点击 &lt;strong&gt;OK&lt;/strong&gt; 便是更新当前分支代码。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/6de6c984-6903-4657-b75b-b7e5168aef68.png&quot; alt=&quot;idea-更新代码&quot; /&gt;&lt;figcaption&gt;idea-更新代码&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、查看历史版本&lt;a href=&quot;#3查看历史版本&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;SVN查看历史版本需要选中你要查看的文件，如果是要查看当前工程的历史提交记录，则右击工程目录。如果没有，选中任何文件，则查看的默认是你当前编辑区域窗口打开的文件的历史记录。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/1de07c87-5e7a-4ac6-8b76-4f71ad8f5734.png&quot; alt=&quot;idea-历史记录&quot; /&gt;&lt;figcaption&gt;idea-历史记录&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击 Show History之后便会出现如下历史记录界面。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/85974bb5-da77-453e-abd3-094f3388b507.png&quot; alt=&quot;idea-历史记录2&quot; /&gt;&lt;figcaption&gt;idea-历史记录2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、回滚&lt;a href=&quot;#4回滚&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;回滚也是点击更新代码的按钮，然后，进入如下界面之后就不能直接点击 OK了，而是按照下图步骤进行操作：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/69fa4dc4-4055-48f3-ac0d-a079acbb6e2c.png&quot; alt=&quot;idea-回滚&quot; /&gt;&lt;figcaption&gt;idea-回滚&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5、分支操作&lt;a href=&quot;#5分支操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;section&gt;&lt;h5&gt;5.1 新建分支&lt;a href=&quot;#51-新建分支&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;SVN → Subversive → Branch or Tag 创建新的分支&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/97732a42-f180-4ef6-a916-16402ec402f4.png&quot; alt=&quot;idea-创建分支1&quot; /&gt;&lt;figcaption&gt;idea-创建分支1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击新建分支，出现如下界面，可按图示进行分支创建&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/94ca340a-9844-46b3-b767-63f0ce671270.png&quot; alt=&quot;idea-创建分支2&quot; /&gt;&lt;figcaption&gt;idea-创建分支2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;5.2 切换分支&lt;a href=&quot;#52-切换分支&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;如果上面我们没有勾选，切换分支，那么此时我们也可以通过如下操作来切换分支。同样，切换分支也是点击更新代码的按钮，然后，按照下图进行操作：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/6307a989-81a2-4c25-acea-abcdfa89f5f2.png&quot; alt=&quot;idea-切换分支&quot; /&gt;&lt;figcaption&gt;idea-切换分支&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;5.3 合并分支&lt;a href=&quot;#53-合并分支&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;按照下图操作，进入选择分支界面。下面的操作是将其他分支代码合并到当前分支。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9bc50053-18a2-4cfd-9334-989ae6411b74.png&quot; alt=&quot;idea-合并分支&quot; /&gt;&lt;figcaption&gt;idea-合并分支&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;进入选择分支界面，选择需要合并过来的分支。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/d5e7fbd9-7e74-4281-82cb-ec9d096f95d0.png&quot; alt=&quot;idea-合并分支2&quot; /&gt;&lt;figcaption&gt;idea-合并分支2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击 &lt;strong&gt;Merge All&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/833dc3a3-135c-457c-821a-3afebf12eb83.png&quot; alt=&quot;idea-合并分支3&quot; /&gt;&lt;figcaption&gt;idea-合并分支3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击 &lt;strong&gt;Continue merge&lt;/strong&gt; 完成合并！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/75afdc8c-ed88-4b2c-8162-a0ba56080b6a.png&quot; alt=&quot;idea-合并分支4&quot; /&gt;&lt;figcaption&gt;idea-合并分支4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6、文件冲突&lt;a href=&quot;#6文件冲突&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;idea里面的冲突文件会爆红，如下图，右击冲突文件，按照下图点击 &lt;strong&gt;Resolve Text Conflict&lt;/strong&gt; 解决冲突&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/140dc21a-8cff-4fb5-9045-ffac6146deb5.png&quot; alt=&quot;idea-解决冲突&quot; /&gt;&lt;figcaption&gt;idea-解决冲突&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出现如下界面，根据需要按照下图示进行对应操作&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/4a4219a1-0cf8-4f47-b7cb-77aa73d696e5.png&quot; alt=&quot;idea-解决冲突2&quot; /&gt;&lt;figcaption&gt;idea-解决冲突2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;当选则手动合并的时候，会出现如下界面，可根据需求按照下图示做对应操作&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/a245b332-f0ea-427a-bf60-dbb9641c7481.png&quot; alt=&quot;idea-解决冲突3&quot; /&gt;&lt;figcaption&gt;idea-解决冲突3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;处理冲突之后，文件变蓝色，成待commit文件&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/b30ed388-4b55-4357-8ee5-b65b87b9f9df.png&quot; alt=&quot;idea-解决冲突4&quot; /&gt;&lt;figcaption&gt;idea-解决冲突4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>基本的网络知识</title><link>https://study-docs-158.pages.dev/posts/%E5%9F%BA%E6%9C%AC%E7%9A%84%E7%BD%91%E7%BB%9C%E7%9F%A5%E8%AF%86/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%9F%BA%E6%9C%AC%E7%9A%84%E7%BD%91%E7%BB%9C%E7%9F%A5%E8%AF%86/</guid><description>基本的网络知识</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、为什么 Java 开发要学网络知识？&lt;a href=&quot;#一为什么-java-开发要学网络知识&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;很多刚入职的同学会觉得： “我是写 Java 的，又不是搞运维的，为什么还要学网络？”&lt;/p&gt;&lt;p&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;li&gt;运维说：&lt;strong&gt;服务端口没开&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;你自己发现：&lt;strong&gt;数据库连不上、Redis 连不上、调用其他服务超时&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这些问题表面上看像“代码问题”，实际上很多时候是&lt;strong&gt;网络、环境、端口、配置&lt;/strong&gt;的问题。&lt;/p&gt;&lt;p&gt;所以，作为 Java 开发，网络知识不需要学得特别深，但一定要掌握&lt;strong&gt;最基础、最常用、工作中最容易遇到的部分&lt;/strong&gt;。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、网络区域划分&lt;a href=&quot;#二网络区域划分&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;2.1 什么是网络区域划分？&lt;a href=&quot;#21-什么是网络区域划分&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;网络区域划分是将网络按照安全级别和访问权限划分为不同的区域，每个区域有不同的安全策略和访问控制规则。这种划分可以有效保护内网核心资源，同时为外部用户提供必要的服务。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2.2 三大网络区域&lt;a href=&quot;#22-三大网络区域&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;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;/td&gt;&lt;td&gt;Intranet&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;Public Internet&lt;/td&gt;&lt;td&gt;公共互联网，连接到组织网络的最外层区域&lt;/td&gt;&lt;td&gt;最低&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DMZ区&lt;/td&gt;&lt;td&gt;Demilitarized Zone&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;/section&gt;&lt;section&gt;&lt;h3&gt;2.3 各区域详细说明&lt;a href=&quot;#23-各区域详细说明&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;2.3.1 内网（Intranet）&lt;a href=&quot;#231-内网intranet&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;ul&gt;
&lt;li&gt;位于防火墙内部，与外网隔离&lt;/li&gt;
&lt;li&gt;存放核心业务数据、数据库、内部应用服务器&lt;/li&gt;
&lt;li&gt;使用私有IP地址（如：10.x.x.x、172.16.x.x、192.168.x.x）&lt;/li&gt;
&lt;li&gt;安全性最高，外部用户无法直接访问&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;访问方式&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;VPN（Virtual Private Network）&lt;/strong&gt;：虚拟专用网络，通过加密通道从外网安全访问内网&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;堡垒机&lt;/strong&gt;：统一的安全入口，所有对内网的访问都需要通过堡垒机进行审计&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：VPN 和堡垒机不是必须一起使用的。不同公司安全策略不同，有的只需要 VPN，有的需要 VPN + 堡垒机双重认证。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;典型应用场景&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;场景一：只需 VPN&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;在家办公 → 连接VPN → 访问内网资源&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;场景二：VPN + 堡垒机&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;在家办公 → 连接VPN → 通过堡垒机认证 → 访问内网资源&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.3.2 外网（Public Internet）&lt;a href=&quot;#232-外网public-internet&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;ul&gt;
&lt;li&gt;任何人都可以访问&lt;/li&gt;
&lt;li&gt;安全风险最高，容易受到攻击&lt;/li&gt;
&lt;li&gt;使用公网IP地址&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.3.3 DMZ区域（了解）&lt;a href=&quot;#233-dmz区域了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：DMZ是介于内网和外网之间的隔离区域，用于放置对外提供服务的服务器。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;从外网可以访问DMZ区&lt;/li&gt;
&lt;li&gt;从DMZ区不能直接访问内网（需要特殊授权）&lt;/li&gt;
&lt;li&gt;即使DMZ区被攻破，内网仍然安全&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;典型架构&lt;/strong&gt;：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/944cb601-47bd-44cf-87f0-f20faca1267a.png&quot; alt=&quot;3&quot; /&gt;&lt;figcaption&gt;3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;DMZ区常见服务&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Web服务器（Nginx、Apache等）&lt;/li&gt;
&lt;li&gt;API网关&lt;/li&gt;
&lt;li&gt;邮件服务器&lt;/li&gt;
&lt;li&gt;FTP服务器&lt;/li&gt;
&lt;li&gt;VPN服务器&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、IP、端口、域名等&lt;a href=&quot;#三ip端口域名等&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;3.1 IP&lt;a href=&quot;#31-ip&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;IP地址&lt;/strong&gt;是网络上设备（网络接口）的唯一标识，类似于我们的家庭地址。通过IP地址，可以找到网络中的某台具体设备。严格来说，IP地址对应的是设备上的&lt;strong&gt;网络接口&lt;/strong&gt;，一台设备可以有多个网卡、多个IP地址。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;简单理解&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;一台主机可以有多个网卡&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;就像一栋楼可以有多个门&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;每个网卡对应一个IP地址&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;就像每个门有一个门牌号&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;通过门牌号找到门，通过门进入大楼&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;IP地址分类&lt;/strong&gt;：&lt;/p&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;IPv4&lt;/td&gt;&lt;td&gt;32位地址，常用格式&lt;/td&gt;&lt;td&gt;192.168.1.100&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;IPv6&lt;/td&gt;&lt;td&gt;128位地址，新一代&lt;/td&gt;&lt;td&gt;2001:0db8:85a3:0000:0000:8a2e:0370&amp;lt;7334&amp;gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;私有IP地址范围&lt;/strong&gt;（内网使用）：&lt;/p&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;10.0.0.0 - 10.255.255.255&lt;/td&gt;&lt;td&gt;A类私有地址&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;172.16.0.0 - 172.31.255.255&lt;/td&gt;&lt;td&gt;B类私有地址&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;192.168.0.0 - 192.168.255.255&lt;/td&gt;&lt;td&gt;C类私有地址（最常见）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3.2 端口&lt;a href=&quot;#32-端口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;端口&lt;/strong&gt;是应用程序与网络通信的通道，一个IP地址可以有65535个端口（范围是0-65535，其中0是保留端口，实际常用的是1024以上的端口）。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;简单理解&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;一个IP地址对应一台主机&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;一台主机可以运行多个应用&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;每个应用使用不同的端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;通过IP+端口可以找到具体的应用&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;生活类比&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;IP地址 = 公司地址（如：北京市朝阳区xx大厦）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;端口   = 部门/房间号（如：8080房间）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;要找到具体的人，需要：地址 + 房间号&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;要访问具体的应用，需要：IP + 端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;/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;MySQL&lt;/td&gt;&lt;td&gt;3306&lt;/td&gt;&lt;td&gt;数据库服务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Redis&lt;/td&gt;&lt;td&gt;6379&lt;/td&gt;&lt;td&gt;缓存服务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Tomcat&lt;/td&gt;&lt;td&gt;8080&lt;/td&gt;&lt;td&gt;Java Web服务器&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Nginx&lt;/td&gt;&lt;td&gt;80/443&lt;/td&gt;&lt;td&gt;Web服务器/反向代理&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SSH&lt;/td&gt;&lt;td&gt;22&lt;/td&gt;&lt;td&gt;远程登录服务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HTTP&lt;/td&gt;&lt;td&gt;80&lt;/td&gt;&lt;td&gt;超文本传输协议&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HTTPS&lt;/td&gt;&lt;td&gt;443&lt;/td&gt;&lt;td&gt;加密的超文本传输协议&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3.3 域名&lt;a href=&quot;#33-域名&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;域名就是给 IP 起的更容易记忆的名字。&lt;/p&gt;&lt;p&gt;例如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;www.baidu.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;api.test.company.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;因为用户和开发都不方便记 IP，所以通常通过域名访问服务。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3.4 DNS&lt;a href=&quot;#34-dns&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;DNS 的作用就是： &lt;strong&gt;把域名解析成 IP 地址。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;比如你访问：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;api.test.company.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;系统会先通过 DNS 找到它对应的 IP，然后再去访问目标机器。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;DNS 解析顺序&lt;/strong&gt;（了解）：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;浏览器缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 未命中&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;操作系统缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 未命中&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;hosts 文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 未命中&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;本地 DNS 服务器&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 未命中&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;上级 DNS 服务器（递归查询）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 最终返回&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;拿到 IP 地址，发起访问&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;当 &lt;strong&gt;ping 域名不通，但 ping IP 能通&lt;/strong&gt; 时，就可能是域名解析有问题。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3.5 hosts 文件&lt;a href=&quot;#35-hosts-文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;hosts 文件可以手动指定“某个域名对应哪个 IP”。&lt;/p&gt;&lt;p&gt;例如：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;192.168.1.20 api.test.company.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;意思是：访问这个域名时，直接去找这个 IP，不再走 DNS。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;常见作用&lt;/strong&gt;：&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;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：如果 hosts 配错了，会导致你访问到错误的服务。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、127.0.0.1、localhost、0.0.0.0 的区别&lt;a href=&quot;#四127001localhost0000-的区别&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;这个是 Java 开发必须知道的基本点，必须弄清楚。&lt;/p&gt;&lt;p&gt;理解这三个地址，要从&lt;strong&gt;两个角度&lt;/strong&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;section&gt;&lt;h3&gt;4.1 127.0.0.1&lt;a href=&quot;#41-127001&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;表示本机回环地址，只能本机访问自己。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;服务端角度 — 监听：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果服务监听在 &lt;code&gt;127.0.0.1:8080&lt;/code&gt;，那么只有当前机器自己能访问，其他机器访问不了。 A mysql 127.0.0.1 B&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;服务监听：127.0.0.1:8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;本机能访问：✅&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;其他机器访问：❌&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;客户端角度 — 访问本地服务：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在本地开发时，你的代码需要连接本机的服务，地址就填 &lt;code&gt;127.0.0.1&lt;/code&gt;。这是最常见的用法：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# application.yml 连接本地数据库&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;datasource&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;jdbc:mysql://127.0.0.1:3306/mydb&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 连接本地 Redis&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;redis&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;host&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;127.0.0.1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;6379&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4.2 localhost&lt;a href=&quot;#42-localhost&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;通常表示本机，本质上一般会解析到 &lt;code&gt;127.0.0.1&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;所以大多数情况下，&lt;code&gt;localhost&lt;/code&gt; 和 &lt;code&gt;127.0.0.1&lt;/code&gt; 可以理解成一样。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;客户端角度 — 访问本地服务：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;localhost&lt;/code&gt; 和 &lt;code&gt;127.0.0.1&lt;/code&gt; 在使用上基本等价，都可以用来访问本机服务：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;http://localhost:8080/api/test&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;http://127.0.0.1:8080/api/test&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;jdbc:mysql://localhost:3306/mydb&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;jdbc:mysql://127.0.0.1:3306/mydb&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;细微区别（了解即可）&lt;/strong&gt;：&lt;code&gt;localhost&lt;/code&gt; 需要经过 DNS 解析，而 &lt;code&gt;127.0.0.1&lt;/code&gt; 是直接写死的 IP。极少数情况下 &lt;code&gt;localhost&lt;/code&gt; 可能解析失败，写 &lt;code&gt;127.0.0.1&lt;/code&gt; 更稳妥。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4.3 0.0.0.0&lt;a href=&quot;#43-0000&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;表示监听所有网卡地址。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;服务端角度 — 监听：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果服务监听在 &lt;code&gt;0.0.0.0:8080&lt;/code&gt;，那就意味着：&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;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;服务监听：0.0.0.0:8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;本机能访问：✅&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;局域网其他机器访问：✅（前提：防火墙放行）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;外部机器访问：取决于防火墙、安全组等&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4.4 两个角度的总结&lt;a href=&quot;#44-两个角度的总结&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;客户端访问本机服务时&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;127.0.0.1&lt;/td&gt;&lt;td&gt;只允许本机访问&lt;/td&gt;&lt;td&gt;填这个地址，连接本机服务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;localhost&lt;/td&gt;&lt;td&gt;同 127.0.0.1&lt;/td&gt;&lt;td&gt;和 127.0.0.1 基本等价&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0.0.0.0&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;&lt;strong&gt;注意&lt;/strong&gt;：&lt;code&gt;0.0.0.0&lt;/code&gt; 是&lt;strong&gt;监听地址&lt;/strong&gt;，不是访问地址。你不会在配置文件里写 &lt;code&gt;host: 0.0.0.0&lt;/code&gt; 去连接某个服务，它只在服务端启动时指定”监听所有网卡”。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、常见网络工具&lt;a href=&quot;#五常见网络工具&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;/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;/td&gt;&lt;td&gt;ping&lt;/td&gt;&lt;td&gt;检测 IP/域名是否能通&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;测试端口是否开放&lt;/td&gt;&lt;td&gt;telnet&lt;/td&gt;&lt;td&gt;检测目标端口是否能连通&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;测试 HTTP 接口是否可用&lt;/td&gt;&lt;td&gt;curl&lt;/td&gt;&lt;td&gt;模拟 HTTP 请求，查看响应&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;查看数据包路由路径&lt;/td&gt;&lt;td&gt;tracert / traceroute&lt;/td&gt;&lt;td&gt;排查网络中间节点问题&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;查看端口监听情况&lt;/td&gt;&lt;td&gt;netstat&lt;/td&gt;&lt;td&gt;确认服务是否在监听&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;查看端口占用详情&lt;/td&gt;&lt;td&gt;lsof&lt;/td&gt;&lt;td&gt;确认哪个进程占用了端口&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;查看 Java 进程&lt;/td&gt;&lt;td&gt;jps / ps&lt;/td&gt;&lt;td&gt;确认 Java 服务是否启动&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;结束进程&lt;/td&gt;&lt;td&gt;kill&lt;/td&gt;&lt;td&gt;停止异常进程&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;section&gt;&lt;h3&gt;5.1 ping&lt;a href=&quot;#51-ping&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;作用：测试目标 IP 是否可达。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ping 192.168.1.10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ping www.baidu.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;能 ping 通：说明网络层大概率可达&lt;/li&gt;
&lt;li&gt;不能 ping 通：说明网络可能不通、被禁 ping、域名解析失败等&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;ping 通 ≠ 服务可用&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;因为 ping 只说明 IP 层可能通，不代表应用端口一定通。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5.2 telnet&lt;a href=&quot;#52-telnet&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;作用：测试某个端口能不能连通。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;telnet 192.168.1.10 3306&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;telnet 192.168.1.20 8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;连得上：说明这个端口是通的&lt;/li&gt;
&lt;li&gt;连不上：可能是服务没启动、端口没监听、防火墙没放行&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Windows开启telnet功能&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;控制面板 → 程序 → 启用或关闭Windows功能&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;→ 勾选&quot;Telnet客户端&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;→ 确定并等待安装完成&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/f7c897b6-7243-4079-ba47-f1346a6cf15e.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5.3 curl（了解）&lt;a href=&quot;#53-curl了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;作用：测试 HTTP 接口是否可用。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：日常开发中推荐使用 Postman 等图形化工具测试接口。curl 的主要使用场景是 &lt;strong&gt;SSH 到服务器上排查问题时&lt;/strong&gt;，服务器上没有 Postman，只能用命令行。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：Windows 10 及以上系统自带 curl，较老系统可安装 Git Bash 后使用。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;测试 HTTP 接口是否能访问&lt;/li&gt;
&lt;li&gt;查看响应头、响应体&lt;/li&gt;
&lt;li&gt;模拟 GET/POST 请求&lt;/li&gt;
&lt;/ul&gt;&lt;section&gt;&lt;h4&gt;5.3.1 访问一个 GET 接口&lt;a href=&quot;#531-访问一个-get-接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;curl http://127.0.0.1:8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.3.2 查看响应头&lt;a href=&quot;#532-查看响应头&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;curl -i http://127.0.0.1:8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.3.3 发送 POST 请求&lt;a href=&quot;#533-发送-post-请求&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;curl -X POST -H &quot;Content-Type: application/json&quot; -d &apos;{&quot;id&quot;:1}&apos; http://127.0.0.1:8080/api/test&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.3.4 查看详细请求过程&lt;a href=&quot;#534-查看详细请求过程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;curl -v http://127.0.0.1:8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;可以看到完整的请求头、响应头、TLS 握手等信息，排查问题非常有用。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.3.5 只看 HTTP 状态码&lt;a href=&quot;#535-只看-http-状态码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;curl -o /dev/null -s -w &apos;%{http_code}&apos; http://127.0.0.1:8080/api/test&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;输出示例：&lt;code&gt;200&lt;/code&gt;、&lt;code&gt;404&lt;/code&gt;、&lt;code&gt;500&lt;/code&gt;，快速判断接口是否正常。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ping&lt;/code&gt; 看 IP 通不通&lt;/li&gt;
&lt;li&gt;&lt;code&gt;telnet&lt;/code&gt; 看端口通不通&lt;/li&gt;
&lt;li&gt;&lt;code&gt;curl&lt;/code&gt; 看 HTTP 接口是否真的可用&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5.4 tracert / traceroute（了解）&lt;a href=&quot;#54-tracert--traceroute了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;作用：查看数据包经过哪些路由节点到达目标机器。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt; A B&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tracert www.baidu.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Linux&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;traceroute www.baidu.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;场景&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;当你怀疑网络路径中间某一跳出了问题时，可以用它做辅助排查。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5.5 netstat&lt;a href=&quot;#55-netstat&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;作用：查看端口监听情况。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;netstat -ano | findstr 8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Linux&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;netstat -tunlp | grep 8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;场景&lt;/strong&gt;&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;/section&gt;&lt;section&gt;&lt;h3&gt;5.6 lsof&lt;a href=&quot;#56-lsof&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Linux 中查看端口占用、文件占用很常用。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;lsof -i :8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：&lt;code&gt;lsof&lt;/code&gt; 是 Linux 专属命令，Windows 上没有对应工具，可使用 &lt;code&gt;netstat -ano | findstr 端口号&lt;/code&gt; 代替。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;场景&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;排查：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;端口被谁占用了&lt;/li&gt;
&lt;li&gt;某服务是不是在监听该端口&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5.7 ps / jps&lt;a href=&quot;#57-ps--jps&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;ps&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;查看 Linux 进程&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ps -ef | grep java&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;jps&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;查看 Java 进程&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;jps&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;场景&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;确认 Java 服务是否启动&lt;/li&gt;
&lt;li&gt;找到对应进程 ID&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5.8 kill&lt;a href=&quot;#58-kill&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;结束进程。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;kill -15 12345&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;kill -9 12345&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kill -15&lt;/code&gt;：正常停止&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kill -9&lt;/code&gt;：强制杀死，谨慎使用&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、访问控制：防火墙、安全组、白名单与中间链路策略&lt;a href=&quot;#六访问控制防火墙安全组白名单与中间链路策略&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;6.1 访问控制&lt;a href=&quot;#61-访问控制&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;访问控制可以理解为：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;控制“谁可以访问谁”、“通过什么方式访问”、“哪些访问要被拦截”的一整套规则。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;对于 Java 开发来说，访问控制并不只是“服务器上有没有开端口”这么简单。 一个请求从源头到目标服务，中间可能会经过多层限制，例如：&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;li&gt;中间链路上的网络设备或安全策略&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以你要建立一个意识：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;服务访问不了，不一定是代码问题，也不一定只是目标机器本身的问题，访问链路上的任意一层控制策略都可能拦住请求。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6.2 常见的访问控制位置&lt;a href=&quot;#62-常见的访问控制位置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;实际工作中，常见的访问控制可能出现在以下几个位置：&lt;/p&gt;&lt;section&gt;&lt;h4&gt;6.2.1 服务器本机防火墙&lt;a href=&quot;#621-服务器本机防火墙&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;（1）firewalld&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这是很多 CentOS 7 / RHEL 7 系统默认使用的防火墙管理工具。 特点是：&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;p&gt;&lt;strong&gt;常用命令&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#查看防火墙状态&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl status firewalld&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#关闭防火墙&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl stop firewalld&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#重启防火墙&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl restart firewalld&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#永久开放端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd --permanent --zone=public --add-port=161/udp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd --permanent --zone=public --add-port=3306/tcp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#永久关闭端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd --zone=public --remove-port=3306/tcp --permanent&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#刷新配置，立即生效&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd --reload&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#查看防火墙&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd --zone=public --list-all&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;（2）iptables&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这是 Linux 里更底层、更经典的防火墙工具。 特点是：&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;p&gt;很多老项目、老服务器，或者某些运维场景里仍然会看到它。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;常用命令&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#查看防火墙状态&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl status iptables&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#关闭防火墙&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl stop iptables&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#重启防火墙&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl restart iptables&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#查看防火墙策略&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;iptables -L&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#编辑防火墙策略&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;vim /etc/sysconfig/iptables&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#允许访问3306端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-A INPUT -p tcp  --dport 3306 -j ACCEPT&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-A OUTPUT -p tcp --sport 3306 -j ACCEPT&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：iptables 修改后需要保存并重启才能永久生效：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 保存规则&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;service&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;iptables&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;save&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 或&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;iptables-save&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;/span&gt;&lt;span&gt;/etc/sysconfig/iptables&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 重启 iptables 使配置生效&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;restart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;iptables&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6.2.2 云平台安全组&lt;a href=&quot;#622-云平台安全组&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;如果服务部署在云服务器上，还可能有云平台提供的安全组策略。 即使服务器本机已经开放端口，如果安全组没放开，外部仍然访问不了。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/3e991f78-5bf2-4a4f-a2a7-e16befb3aa8c.png&quot; alt=&quot;2&quot; /&gt;&lt;figcaption&gt;2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6.2.3 白名单&lt;a href=&quot;#623-白名单&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;白名单就是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;只允许特定来源访问，其他来源一律拒绝。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;常见于：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;数据库&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;MQ&lt;/li&gt;
&lt;li&gt;第三方接口回调&lt;/li&gt;
&lt;li&gt;管理后台&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;典型现象&lt;/strong&gt;&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;p&gt;这种情况就要考虑是不是来源限制导致的。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6.2.4 中间链路策略&lt;a href=&quot;#624-中间链路策略&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;很多同学一想到访问控制，只会想到服务器上的 firewalld 或 iptables。 但真实公司网络里，中间链路也可能有访问控制。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;常见中间链路策略&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;网络防火墙设备&lt;/li&gt;
&lt;li&gt;路由器 ACL&lt;/li&gt;
&lt;li&gt;交换机访问控制策略&lt;/li&gt;
&lt;li&gt;网关访问策略&lt;/li&gt;
&lt;li&gt;负载均衡访问控制&lt;/li&gt;
&lt;li&gt;WAF 拦截规则&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6.3 作为 Java 开发，你最该记住什么&lt;a href=&quot;#63-作为-java-开发你最该记住什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;这一节你不用去背复杂规则，但至少要记住下面这几点：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）服务访问不了，不一定是代码问题&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有可能是：&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;li&gt;白名单没加&lt;/li&gt;
&lt;li&gt;中间链路有墙&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;p&gt;&lt;strong&gt;2）先确认服务是否真的启动、端口是否监听&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;比如先查：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;netstat -tunlp | grep 8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;lsof -i :8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;如果服务都没监听，那就不是防火墙问题，而是服务本身没起来。&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;strong&gt;3）防火墙和安全组可能同时限制访问&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;你不能只看服务器本机。 如果在云环境里，还要考虑云平台的安全组规则。如果网络中间经过其他有墙的设备，也要考虑这个中间链路设备的墙。&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;strong&gt;4）生产环境不要随便改防火墙&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;线上环境改防火墙规则一般要按公司流程走，很多公司由运维统一处理。 你要做的是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;能意识到这是排查方向&lt;/li&gt;
&lt;li&gt;知道怎么和运维沟通&lt;/li&gt;
&lt;li&gt;能提供清楚的信息：IP、端口、协议、环境&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6.4 和运维沟通时怎么说更专业&lt;a href=&quot;#64-和运维沟通时怎么说更专业&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;比如你可以这样说：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“服务已经正常启动，8080 端口也在监听，本机访问正常。麻烦帮忙确认一下测试环境这台机器的防火墙/安全组是否已放行 8080 端口。”&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;或者：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“我这边怀疑不是代码问题，可能是网络访问策略限制，麻烦帮忙看下目标机器的端口开放情况和白名单配置。”&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这样沟通会比“接口不通，帮我看看”更专业很多。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、服务访问与网络连通性问题的排查顺序（重要）&lt;a href=&quot;#七服务访问与网络连通性问题的排查顺序重要&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;遇到下面这类问题时：&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;li&gt;服务间调用失败&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;建议优先按下面这个顺序查，不要一上来就怀疑代码，也不要一上来就只看网络。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第一步：先确认目标信息是否正确&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;先确认最基础的信息有没有写错：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;IP 对不对&lt;/li&gt;
&lt;li&gt;端口对不对&lt;/li&gt;
&lt;li&gt;域名对不对&lt;/li&gt;
&lt;li&gt;接口路径对不对&lt;/li&gt;
&lt;li&gt;当前是不是对应环境（dev / test / pre / prod）&lt;/li&gt;
&lt;li&gt;配置文件里填的是不是正确地址&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;很多问题其实在这一步就能发现，比如：&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;li&gt;域名写错&lt;/li&gt;
&lt;li&gt;调错接口路径&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;第二步：确认目标服务/应用是否真的存在、是否正常运行&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这是非常关键的一步。如果服务本身都没启动，后面的网络排查意义就不大。&lt;/p&gt;&lt;p&gt;使用第五章介绍的 &lt;code&gt;netstat&lt;/code&gt;、&lt;code&gt;lsof&lt;/code&gt;、&lt;code&gt;ps&lt;/code&gt;、&lt;code&gt;jps&lt;/code&gt; 命令，确认两件事：&lt;/p&gt;&lt;ol&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;/ol&gt;&lt;p&gt;如果服务没启动或端口没监听，那问题优先就不是网络，而是服务本身。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第三步：看网络是否可达&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;使用第五章 5.1 介绍的 &lt;code&gt;ping&lt;/code&gt; 命令：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ping IP&lt;/code&gt;：看目标机器网络层是否可达&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ping 域名&lt;/code&gt;：看域名解析和网络是否正常&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果 &lt;strong&gt;ping IP 通，但 ping 域名不通&lt;/strong&gt;，优先怀疑 DNS 或 hosts 配置问题（见第三章 3.4、3.5）。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：ping 通不代表服务一定可用。ping 只说明 IP 层大概率可达，不代表目标端口一定开放。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;第四步：看端口是否可达&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果目标机器可达，使用第五章 5.2 介绍的 &lt;code&gt;telnet&lt;/code&gt; 命令测试目标端口：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;telnet IP 端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;如果端口不通，常见原因有：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;服务没启动或没监听该端口（回到第二步确认）&lt;/li&gt;
&lt;li&gt;服务只监听了 &lt;code&gt;127.0.0.1&lt;/code&gt;，外部无法访问（见第四章）&lt;/li&gt;
&lt;li&gt;本机防火墙拦住了（见第六章）&lt;/li&gt;
&lt;li&gt;云安全组没放开（见第六章）&lt;/li&gt;
&lt;li&gt;白名单没加（见第六章）&lt;/li&gt;
&lt;li&gt;中间链路策略拦截了访问（见第六章）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果确认是端口被其他进程占用，可参考&lt;strong&gt;第八章&lt;/strong&gt;的方法解决。&lt;/p&gt;&lt;p&gt;此时可以找运维人员，确认一下端口是否放开，然后再继续后续排查。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;记住：本机能访问，不代表别人机器也能访问。&lt;/strong&gt; 检查服务是否监听在 &lt;code&gt;0.0.0.0&lt;/code&gt; 而非 &lt;code&gt;127.0.0.1&lt;/code&gt;（见第四章）。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;第五步：看 HTTP 接口是否真的可用（仅限 Web 服务 / HTTP 接口）&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：如果目标是数据库、Redis、MQ 等非 HTTP 服务，端口通了就说明连通性没问题，可以跳过这一步。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;如果是 Web 服务或 HTTP 接口，最好不要只停留在”端口通不通”，使用第五章 5.3 介绍的 &lt;code&gt;curl&lt;/code&gt; 命令继续确认接口本身是否可用：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;curl http://IP:端口/接口路径&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;如果 curl 不通，要继续排查：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;服务日志&lt;/li&gt;
&lt;li&gt;Nginx 配置&lt;/li&gt;
&lt;li&gt;网关配置&lt;/li&gt;
&lt;li&gt;服务监听地址&lt;/li&gt;
&lt;li&gt;接口路径 / 请求方式是否正确（GET / POST）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;第六步：最后结合应用日志进一步判断&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;很多问题表面上像“网络不通”，实际上可能是应用内部问题。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;常见情况&lt;/strong&gt;&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;li&gt;Redis/MQ 连接异常&lt;/li&gt;
&lt;li&gt;应用内部抛异常&lt;/li&gt;
&lt;li&gt;Nginx/网关转发失败&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以排查时一定不要脱离日志。 &lt;strong&gt;网络排查和日志排查通常要结合起来看。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;八、常见端口占用问题排查&lt;a href=&quot;#八常见端口占用问题排查&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;blockquote&gt;&lt;p&gt;以下涉及的命令（&lt;code&gt;netstat&lt;/code&gt;、&lt;code&gt;lsof&lt;/code&gt;、&lt;code&gt;ps&lt;/code&gt;、&lt;code&gt;jps&lt;/code&gt;、&lt;code&gt;kill&lt;/code&gt;）用法详见第五章。&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;8.1 Windows 系统&lt;a href=&quot;#81-windows-系统&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;第一步：查看端口占用情况&lt;/strong&gt;（使用 5.5 介绍的 netstat）&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;netstat -ano | findstr 8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;输出结果最后一列数字就是进程ID（PID）。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第二步：查看进程详情&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tasklist | findstr 12345&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第三步：结束占用端口的进程&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;方式1：使用taskkill强制结束&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;taskkill /PID 12345 /F&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;方式2：打开任务管理器 → “详细信息”标签页 → 找到对应PID → 右键结束任务&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/49b035e9-47f2-4cb5-9512-3cbfd99e5aa8.png&quot; alt=&quot;4&quot; /&gt;&lt;figcaption&gt;4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;8.2 Linux 系统&lt;a href=&quot;#82-linux-系统&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;第一步：查看端口占用情况&lt;/strong&gt;（使用 5.5 的 netstat 或 5.6 的 lsof）&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;netstat -tunlp | grep 8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 或（推荐）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;lsof -i :8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第二步：查看进程详情&lt;/strong&gt;（使用 5.7 的 ps / jps）&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ps -ef | grep 12345&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 或查看Java进程&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;jps&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第三步：结束占用端口的进程&lt;/strong&gt;（使用 5.8 的 kill）&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;kill 12345        # 优雅结束（推荐）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;kill -9 12345     # 强制结束&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>开发流程及开发中的术语</title><link>https://study-docs-158.pages.dev/posts/%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B%E5%8F%8A%E5%BC%80%E5%8F%91%E4%B8%AD%E7%9A%84%E6%9C%AF%E8%AF%AD/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B%E5%8F%8A%E5%BC%80%E5%8F%91%E4%B8%AD%E7%9A%84%E6%9C%AF%E8%AF%AD/</guid><description>开发流程及开发中的术语</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;开发流程及开发中的术语&lt;a href=&quot;#开发流程及开发中的术语&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;section&gt;&lt;h2&gt;一、一般开发流程&lt;a href=&quot;#一一般开发流程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-24/55bcef58-dcd0-4ee3-ba7e-c9b07a23ce91.png&quot; alt=&quot;开发流程&quot; /&gt;&lt;figcaption&gt;开发流程&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;二、开发流程关键步骤解释&lt;a href=&quot;#二开发流程关键步骤解释&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;需求评审&lt;/p&gt;
&lt;p&gt;评审需求是否&lt;strong&gt;清晰、可行、可验收&lt;/strong&gt;。重点确认：&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;li&gt;&lt;strong&gt;技术评估&lt;/strong&gt;：能不能做、有没有更简单的实现方式、是否需要提出替代方案，以及技术上的风险和依赖&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;建议&lt;/strong&gt;：需求评审时建议录音（线下会议）或录屏（线上会议），方便后续回顾。会上讨论的东西可能很多，光靠脑子记容易遗漏关键细节，尤其是新人，有录音/录屏回头听一遍，理解会更到位。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;举个例子&lt;/strong&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;li&gt;&lt;strong&gt;验收标准&lt;/strong&gt;：大屏能显示操作记录，延迟不超过1分钟&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;技术评估&lt;/strong&gt;：实时同步开发成本高、容易出 bug、对服务器压力大。可以提出替代方案：“每5秒刷新一次”，既满足业务展示需求，又大幅降低实现难度和风险&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;项目经理分配任务&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;项目经理会把需求拆分成任务，分给不同角色（后端/前端/测试等）。有些项目经理会在分配任务时顺便问你“多久能做完”。这个时候不要为了显得厉害就当场拍时间，可以更稳妥地说： &lt;strong&gt;“我先把需求理解清楚，把实现方案和影响面梳理一下，再给你一个更准确的时间。”&lt;/strong&gt; 这样既专业，也能避免因为信息不全导致估时不准。&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;根据任务进行排期&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;如果项目经理只分配了任务、没有给具体排期，那就需要开发人员自己先做排期。排期时不要只算写代码的时间，至少要把下面这些都算进去：&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;li&gt;联调（和前端/其他服务对接）&lt;/li&gt;
&lt;li&gt;修 bug + 回归验证&lt;/li&gt;
&lt;li&gt;部署测试环境/提测沟通（如果你负责） 你可以给出一个&lt;strong&gt;拆解后的时间&lt;/strong&gt;，而不是一句“我估计两天”。这样项目经理更容易判断整体排期是否合理。&lt;/li&gt;
&lt;/ul&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;确认任务能否按时完成，有没有疑问&lt;/p&gt;
&lt;p&gt;如果项目经理在分配任务时已经给了排期，那么在排期发出来之后，你要第一时间判断：这个时间是否合理、有没有卡点。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&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;ol&gt;
&lt;li&gt;
&lt;p&gt;根据需求进行设计开发&lt;/p&gt;
&lt;p&gt;有些公司在开发前要求写设计文档（方案文档），那就按规范写并参与评审。不会写时可以找同事要一份模板参考。 如果公司不强制要求，你也可以在需求复杂时自己简单写一版方案，目的不是走形式，而是通过设计，能够对需求有更深刻的理解。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;当然，开发过程中如果对需求有疑问，仍然要及时跟产品经理沟通，避免做偏。&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;自测&lt;/p&gt;
&lt;p&gt;代码写完后，先自己测一遍，把低级问题消灭掉。至少要验证：主流程、关键边界、常见异常，以及日志/错误码是否符合预期。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;举个例子&lt;/strong&gt;：假设你写了一个”根据用户ID查询订单”的接口，自测时至少要验证：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主流程&lt;/strong&gt;：传入正常用户ID，能返回订单列表&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键边界&lt;/strong&gt;：用户ID为空、用户ID不存在、用户有0条/1条/多条订单&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常见异常&lt;/strong&gt;：参数格式错误（如ID传了字符串）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志/错误码&lt;/strong&gt;：正常返回日志是否记录、异常时错误码和提示信息是否清晰&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;与前端联调&lt;/p&gt;
&lt;p&gt;自测通过后，与前端进行联调，重点是把”各自能跑”变成”整体能跑”。要对齐：&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;p&gt;联调过程中前端往往也会发现一些问题（字段不一致、边界漏测、错误码不匹配、后端异常报错等），这些都需要你配合修复。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;提测&lt;/p&gt;
&lt;p&gt;联调完成后，将个人分支的代码合并到&lt;strong&gt;测试分支&lt;/strong&gt;（如 &lt;code&gt;test&lt;/code&gt; 或 &lt;code&gt;develop&lt;/code&gt;），部署到测试环境，提交给测试团队验证。&lt;/p&gt;
&lt;p&gt;测试过程中大概率会发现 bug，你需要在个人分支上修复，修复后再次合并到测试分支、部署测试环境，让测试同学重新验证。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：不要在测试通过之前就合并到主分支，避免有问题的代码污染主分支。&lt;/p&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;代码评审（CR）与上线发布&lt;/p&gt;
&lt;p&gt;测试全部通过后，将代码推送到远程仓库，提交&lt;strong&gt;合并请求&lt;/strong&gt;（MR/PR）到&lt;strong&gt;主分支&lt;/strong&gt;（如 &lt;code&gt;master&lt;/code&gt; 或 &lt;code&gt;main&lt;/code&gt;），等待同事进行代码评审。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为什么 CR 放在这个阶段？&lt;/strong&gt; 因为测试过程中会反复修复 bug，如果提前做 CR，这些修复的代码就没有被 review。在合并到主分支时做 CR，审的就是最终稳定版本，所有改动都包含在内。&lt;/p&gt;
&lt;p&gt;CR 的目的不是挑毛病，而是：&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;li&gt;&lt;strong&gt;统一规范&lt;/strong&gt;：确保代码风格、命名、结构符合团队标准&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人必做&lt;/strong&gt;：入职后先搞清楚团队&lt;strong&gt;有没有代码评审&lt;/strong&gt;、&lt;strong&gt;有没有相关的开发规范&lt;/strong&gt;（命名规则、代码风格、分层结构、注释要求等）。如果有，写代码的时候就按规范来，别等 CR 的时候被指出一堆规范问题——逻辑问题可以理解，但规范问题全是本可以避免的，既浪费评审人的时间，也显得自己不够专业。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;CR 一般关注：逻辑是否正确、是否有更好的实现方式、是否有遗漏的异常处理、SQL 是否有性能问题、是否有安全风险等。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;新人对待 CR 意见的态度&lt;/strong&gt;：虚心接受，不懂就问。CR 意见不是质疑你的能力，而是帮你快速成长的途径。有不同看法可以讨论，但不要把意见当成针对个人，本能地反驳或找借口。&lt;/p&gt;
&lt;p&gt;CR 通过后，合并代码到主分支，部署到生产环境。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上线后要做的事&lt;/strong&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;li&gt;&lt;strong&gt;回滚优先于修复&lt;/strong&gt;：线上出问题时，先恢复服务（回滚到上一版本），再排查根因，避免长时间影响用户&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;部分公司会采用&lt;strong&gt;灰度发布&lt;/strong&gt;，先让小部分用户使用新版本，确认没问题后再全量放开。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;三、常见术语&lt;a href=&quot;#三常见术语&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;下面列出的是通用术语。实际工作中，每个公司、每个项目还会有自己的内部术语或业务术语。遇到不认识的术语，可以先百度或问大模型，如果查不到，大概率就是内部术语，直接问同事即可。&lt;/p&gt;&lt;p&gt;但要注意：通用术语不能靠临时查，必须提前掌握。如果连这些基本术语都不知道，和同事沟通时很容易懵，甚至露馅。&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;3.1 测试相关&lt;a href=&quot;#31-测试相关&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;/td&gt;&lt;td&gt;测试人员编写的测试方案与步骤，包含预期结果&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;自测&lt;/td&gt;&lt;td&gt;开发完成后自己先测一遍，减少低级 bug（详见第二章第6步）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;提测&lt;/td&gt;&lt;td&gt;开发把版本交给测试验证（详见第二章第8步）&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;tr&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;/tr&gt;&lt;tr&gt;&lt;td&gt;回归测试&lt;/td&gt;&lt;td&gt;修复 bug 后再测一遍，确认问题解决且未引入新问题&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;tr&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;/tr&gt;&lt;tr&gt;&lt;td&gt;灰度测试&lt;/td&gt;&lt;td&gt;小范围先发布给部分用户试用，逐步扩大使用面，边用边观察问题（与”灰度发布”含义接近，侧重验证阶段）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;缺陷（Bug）&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;tr&gt;&lt;td&gt;优先级&lt;/td&gt;&lt;td&gt;修复处理的先后顺序（P0-P3 等）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3.2 环境与设备相关&lt;a href=&quot;#32-环境与设备相关&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;/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;tr&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;轻量级运行环境（如 Docker），便于部署&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;tr&gt;&lt;td&gt;环境&lt;/td&gt;&lt;td&gt;开发中常说的环境一般是指系统运行所依赖的全部外部条件的总和，包括硬件（服务器）和软件（操作系统、MySQL、Redis等）&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;tr&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;/tr&gt;&lt;tr&gt;&lt;td&gt;生产环境&lt;/td&gt;&lt;td&gt;真实用户使用的环境，变更需谨慎&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;VPN&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;tr&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;/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;/section&gt;&lt;section&gt;&lt;h3&gt;3.3 项目管理相关&lt;a href=&quot;#33-项目管理相关&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;PRD&lt;/td&gt;&lt;td&gt;产品需求文档（需求背景/范围/验收标准）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;需求评审&lt;/td&gt;&lt;td&gt;团队对需求范围与可行性的统一确认（详见第二章第1步）&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;tr&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;/tr&gt;&lt;tr&gt;&lt;td&gt;排期&lt;/td&gt;&lt;td&gt;对任务的时间估算与交付计划（详见第二章第3步）&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;tr&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;/tr&gt;&lt;tr&gt;&lt;td&gt;合并请求（MR/PR）&lt;/td&gt;&lt;td&gt;将分支代码合并到主分支的申请流程&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;代码评审（CR）&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;tr&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;前后端对接接口并修正联调问题的过程（详见第二章第7步）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;上线/发布&lt;/td&gt;&lt;td&gt;将功能部署到生产环境对外提供（详见第二章第9步）&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;tr&gt;&lt;td&gt;灰度发布&lt;/td&gt;&lt;td&gt;按比例逐步开放新版本，控制风险&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3.4 技术相关&lt;a href=&quot;#34-技术相关&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;/td&gt;&lt;td&gt;日常开发中说的”接口”通常指 API 接口（即一个可访问的 URL 地址，前端通过它与后端交互数据）。Java 语法中的 interface 是另一种概念，指的是类的行为抽象&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;tr&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;/tr&gt;&lt;tr&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;/tr&gt;&lt;tr&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;/tr&gt;&lt;tr&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;/tr&gt;&lt;tr&gt;&lt;td&gt;HTTP/HTTPS&lt;/td&gt;&lt;td&gt;常用 Web 传输协议，HTTPS 更安全（详见《基本的网络知识》）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;JSON&lt;/td&gt;&lt;td&gt;常用接口数据格式&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RPC&lt;/td&gt;&lt;td&gt;远程过程调用，服务间通信方式&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ES&lt;/td&gt;&lt;td&gt;Elasticsearch，基于 Lucene 的分布式搜索引擎&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SSO&lt;/td&gt;&lt;td&gt;单点登录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;消息队列&lt;/td&gt;&lt;td&gt;用于在服务间异步传递消息的中间件，可以实现削峰填谷、系统解耦（如 Kafka）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;缓存&lt;/td&gt;&lt;td&gt;将数据存储在高速存储层（如 Redis），以减少对数据库的访问，提升读取速度&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;tr&gt;&lt;td&gt;ping&lt;/td&gt;&lt;td&gt;测试两端 IP 是否可达（详见《基本的网络知识》）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;telnet&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;tr&gt;&lt;td&gt;监控/告警&lt;/td&gt;&lt;td&gt;系统指标采集与异常通知&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;CI/CD&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;/section&gt;&lt;section&gt;&lt;h3&gt;3.5 敏捷与协作相关&lt;a href=&quot;#35-敏捷与协作相关&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;/td&gt;&lt;td&gt;以短周期迭代、快速交付、持续反馈为核心的开发方式&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;站会&lt;/td&gt;&lt;td&gt;每天15分钟左右的短会，同步昨天做了什么、今天计划做什么、有什么阻塞&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;tr&gt;&lt;td&gt;复盘/回顾&lt;/td&gt;&lt;td&gt;迭代或项目结束后，总结做得好的和需要改进的&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Owner&lt;/td&gt;&lt;td&gt;某个功能或模块的主要负责人&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;四、新人常见误区&lt;a href=&quot;#四新人常见误区&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;以下是新人入职后容易踩的坑，提前了解可以少走弯路：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）自测只走正常流程&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;只测”happy path”（正常流程），不测异常和边界，结果提测后被测试同学打回来一堆 bug，反而耽误时间。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;正确做法：自测至少覆盖——正常流程、参数为空/非法、权限不足、数据不存在等常见异常场景。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;2）不看现有代码就动手改&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;拿到需求直接写新代码，不先了解现有逻辑，结果改出新 bug 或者重复造轮子。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;正确做法：先通读相关代码，理解现有逻辑和设计思路，再动手。不懂的地方问同事。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;3）上线完就不管了&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;代码部署到生产环境后就去做别的事，不看监控、不看日志，出了问题都不知道。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;正确做法：上线后至少观察15-30分钟，关注错误日志、监控告警、接口响应时间，确认服务稳定运行。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;4）估时只算写代码的时间&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;排期时只算了编码时间，漏掉了自测、联调、修 bug、写文档的时间，导致实际交付时间远超预期。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;正确做法：排期时按”编码占40%-50%“来估算，留出自测、联调、修 bug、 buffer 的时间。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>浏览器控制台：怎么看？看什么？</title><link>https://study-docs-158.pages.dev/posts/%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8E%A7%E5%88%B6%E5%8F%B0%E6%80%8E%E4%B9%88%E7%9C%8B%E7%9C%8B%E4%BB%80%E4%B9%88/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8E%A7%E5%88%B6%E5%8F%B0%E6%80%8E%E4%B9%88%E7%9C%8B%E7%9C%8B%E4%BB%80%E4%B9%88/</guid><description>浏览器控制台：怎么看？看什么？</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;浏览器控制台：怎么看？看什么？&lt;a href=&quot;#浏览器控制台怎么看看什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;​ vx: nb887722 可进自学交流群 微信公众号: 拙野 学习平台：zystudy.cn csdn: 拙野&lt;/p&gt;&lt;section&gt;&lt;h3&gt;一、怎么看？&lt;a href=&quot;#一怎么看&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;先说怎么打开。&lt;/strong&gt; 最快的方式是按 &lt;code&gt;F12&lt;/code&gt;，Chrome、Edge、Firefox 都通用。如果 F12 不灵（比如被输入法占了快捷键），还有两个备选：在页面任意位置右键选「检查」；或者按 &lt;code&gt;Ctrl + Shift + I&lt;/code&gt;（Mac 是 &lt;code&gt;Cmd + Option + I&lt;/code&gt;）。记住 F12 就够了，其他是兜底。&lt;/p&gt;&lt;p&gt;打开以后，顶部一排标签页就是各种”面板”。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Elements（元素）&lt;/strong&gt;：页面的 HTML 结构，前端调样式用的，后端基本不碰。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Console（控制台）&lt;/strong&gt;：前端 JS 打印的日志和报错都堆这里，页面白屏、按钮没反应，先来这里找红色错误。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Network（网络）&lt;/strong&gt;：所有接口请求都在这——请求地址、参数、状态码、返回内容，&lt;strong&gt;这是后端用得最多的面板&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Application（应用）&lt;/strong&gt;：Cookie、LocalStorage、SessionStorage 存放的地方，后端偶尔看，排查登录态问题时可能用到。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sources（源代码）&lt;/strong&gt;：用来调试 JS 源码的，后端不用管。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-13/4e8115fd-61f5-4912-8cdc-fa1f805e06e4.png&quot; alt=&quot;F12控制台&quot; /&gt;&lt;figcaption&gt;F12控制台&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;二、看什么？&lt;a href=&quot;#二看什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、每个面板看什么信息&lt;a href=&quot;#1每个面板看什么信息&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;Network：一条请求点开后，重点看三样东西。&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;状态码（Status）&lt;/strong&gt;：200 是正常；4xx 是请求有问题，常见 400（参数格式错）、401（没登录）、403（没权限）；5xx 是服务端的问题，500 是代码报错，502/503 是服务没起来或网关有问题。记住一个大概规律：&lt;strong&gt;4xx 多半是前端的事，5xx 多半是后端的事&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求参数（Payload）&lt;/strong&gt;：前端到底传了什么给你。这是排查必看的——很多时候接口返回空或报错，不是你代码错了，是前端传的参数本身就不对。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;响应内容（Response）&lt;/strong&gt;：接口返回了什么。是空数组 &lt;code&gt;[]&lt;/code&gt;，还是报错信息，还是一坨 HTML（说明请求被拦截跳到登录页了）。&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;点开请求后会有几个子标签：Headers 是请求头，Payload 是请求参数，Response 是原始返回内容，Preview 是格式化后的预览。后端排查主要看 Payload 和 Response 这两个。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Console：看红色报错。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Console 里前端 JS 打印的日志和报错都堆这里。红色的就是报错，一般会写哪个 JS 文件第几行出了什么错。后端不用看懂 JS，但你要知道：&lt;strong&gt;红色报错 = 前端代码出了问题，不是你的锅&lt;/strong&gt;，截图发给前端就行。偶尔也有黄色的警告（Warning），那些一般不影响功能，可以忽略。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、遇到 bug 看什么信息&lt;a href=&quot;#2遇到-bug-看什么信息&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-13/3f193a3c-1bdb-4f9b-8d8e-363658a06766.png&quot; alt=&quot;F12控制台-3&quot; /&gt;&lt;figcaption&gt;F12控制台-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;排查的顺序就一条原则：&lt;strong&gt;先确认接口发没发、对不对，再回头看前端报没报错。&lt;/strong&gt; 因为后端的职责到接口为止，接口没问题，大概率就不是你的事。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第一步：先开 F12，再去操作页面触发请求。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果先操作再开 F12，那之前的请求 Network 是抓不到的，你只能看到一个空列表干瞪眼。所以排查问题第一件事就是先按 F12，然后再去复现问题。&lt;/p&gt;&lt;p&gt;怎么触发请求，取决于问题出在哪个操作上：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;列表页空白 → 直接 &lt;code&gt;F5&lt;/code&gt; 刷新当前页面，列表查询接口就会重新发一次&lt;/li&gt;
&lt;li&gt;点某个按钮没反应 → 重新点那个按钮&lt;/li&gt;
&lt;li&gt;提交表单报错 → 重新填一遍提交&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果怀疑是缓存导致的问题（比如代码改了但页面还是老样子），普通刷新可能不灵，得按 &lt;code&gt;Ctrl + F5&lt;/code&gt; 或 &lt;code&gt;Ctrl + Shift + R&lt;/code&gt; 强制刷新，绕过浏览器缓存重新加载。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第二步：在 Network 里找到那个接口，对照状态码判断。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;请求发出去后，Network 里就会列出所有请求。怎么从一堆请求里找到你要的那个？先点 Network 左上角的 🚫（清除）按钮，把之前的旧请求全清掉，然后再去操作页面触发接口。这样 Network 里只剩下刚刚触发的几个请求，找起来干净多了。如果清完还是很多，分两种情况：知道接口名关键词，就在筛选框里输入（比如 &lt;code&gt;user&lt;/code&gt;）直接搜；不知道接口名，就逐个点开看 Payload，哪个的传参是你刚才操作时填的内容，那个就是你要找的接口。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-13/cd655c3a-b047-4377-8757-c6bd500a098b.png&quot; alt=&quot;F12控制台-2&quot; /&gt;&lt;figcaption&gt;F12控制台-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;找到接口后，根据状态码会有三种结果：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;结果一：状态码 200，但返回的是空数据。&lt;/strong&gt; 这时候不是接口报错，是查询逻辑或数据的问题。在控制台能做的只有一件事：看 Payload 里前端传的参数对不对——比如分页参数是不是传了 &lt;code&gt;pageSize=0&lt;/code&gt;，查询条件是不是传了不存在的值。入参不对，先用 Postman 把参数传对了再调一次接口：结果对了，说明是前端传错参数，前端的锅；结果还是不对，那后端也有问题，回后端查日志里的 SQL、条件拼得对不对、库里确实有没有这条数据。入参没问题，控制台的任务就完成了，直接回后端查。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;结果二：状态码是 4xx 或 5xx。&lt;/strong&gt; 这才是接口真的有问题。但别急着查自己的代码，同样先看 Payload 里前端传的参数对不对——参数格式错、必填项没传、类型不对，都会导致 400。入参不对，按结果一的办法用 Postman 传对参数再验一次，判断锅归谁。入参没问题，再点开 Response 看错误信息，4xx 的往参数和权限上查，5xx 的往代码报错和服务状态上查，拿到具体信息再去查日志或代码。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;结果三：Network 里压根没有这个请求。&lt;/strong&gt; 页面空白，但接口根本没被调用——说明问题出在前端，请求就没发出来。这种情况切到 Console 看红色报错，截图发给前端处理就行。&lt;/p&gt;&lt;p&gt;还有个坑要注意：Network 默认会在页面跳转时清空。如果你点了某个按钮页面刷新了，之前的请求就没了，你可能以为”接口没发”，其实是被清掉了。勾选 Network 顶部的「Preserve log」（保留日志），请求就不会被清掉，方便你回头对比。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第三步：遇到 401/403，回到 Network 看请求头。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果接口返回了 401 或 403，说明登录态出了问题——要么 Token 没带、要么 Token 过期了。这时候不用切别的面板，直接点开那个 401 的请求，看 Headers 里的 Request Headers，找 &lt;code&gt;Authorization&lt;/code&gt; 或 &lt;code&gt;Cookie&lt;/code&gt; 字段——这才是请求&lt;strong&gt;实际发出去时带的&lt;/strong&gt;，最准。&lt;/p&gt;&lt;p&gt;判断逻辑：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;请求头里没带 Token → 前端没把登录态塞进请求，是前端的锅，让前端处理登录态。&lt;/li&gt;
&lt;li&gt;请求头里带了 Token、接口还是返回 401 → Token 过期或后端鉴权逻辑有问题，这才是你的锅，得查你的拦截器或权限校验代码。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>拿到接口地址，如何找到对应代码</title><link>https://study-docs-158.pages.dev/posts/%E6%8B%BF%E5%88%B0%E6%8E%A5%E5%8F%A3%E5%9C%B0%E5%9D%80%E5%A6%82%E4%BD%95%E6%89%BE%E5%88%B0%E5%AF%B9%E5%BA%94%E4%BB%A3%E7%A0%81/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E6%8B%BF%E5%88%B0%E6%8E%A5%E5%8F%A3%E5%9C%B0%E5%9D%80%E5%A6%82%E4%BD%95%E6%89%BE%E5%88%B0%E5%AF%B9%E5%BA%94%E4%BB%A3%E7%A0%81/</guid><description>拿到接口地址，如何找到对应代码</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;拿到接口地址，如何找到对应代码？&lt;a href=&quot;#拿到接口地址如何找到对应代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;​ vx: nb887722 可进自学交流群 微信公众号: 拙野 学习平台：zystudy.cn&lt;/p&gt;&lt;section&gt;&lt;h3&gt;一、单体项目&lt;a href=&quot;#一单体项目&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;单体项目里所有代码都在一个工程里，接口地址和代码之间没有中间层，搜起来最直接。&lt;/p&gt;&lt;p&gt;例如搜索如下接口：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/api/admin/feedback/leaderboard&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;方法一：IDE 全局搜索（最快）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在 IDEA 里按 &lt;code&gt;Ctrl + Shift + R&lt;/code&gt;（Mac 是 &lt;code&gt;Cmd + Shift + R&lt;/code&gt;），打开全局搜索。搜路径里&lt;strong&gt;有辨识度的那一段&lt;/strong&gt;，比如接口地址是 &lt;code&gt;/api/order/pageList&lt;/code&gt;，就搜 &lt;code&gt;pageList&quot;&lt;/code&gt;（带个引号，能直接匹配注解里的字符串字面量，过滤掉无关结果），不要搜完整的 &lt;code&gt;/api/order/pageList&lt;/code&gt;——因为类上面的 &lt;code&gt;@RequestMapping&lt;/code&gt; 和方法上面的 &lt;code&gt;@PostMapping&lt;/code&gt; 是分开写的，搜完整路径反而搜不到。&lt;/p&gt;&lt;p&gt;搜到之后，看哪个是 &lt;code&gt;@GetMapping&lt;/code&gt;、&lt;code&gt;@PostMapping&lt;/code&gt;、&lt;code&gt;@RequestMapping&lt;/code&gt; 这类注解修饰的方法，那就是你要找的接口。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-26/eba722c5-421d-4068-8384-12bcaa45c3f4.png&quot; alt=&quot;接口定位代码-1&quot; /&gt;&lt;figcaption&gt;接口定位代码-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方法二：通过 ApiFox 插件搜索（推荐，但需要外网）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;IDEA 可以安装 ApiFox 插件，装好之后直接把接口路径贴进去搜索，它能直接定位到对应的 Controller 方法，比全局搜索更快更准。&lt;strong&gt;如果公司网络环境允许访问外网、且能装插件，推荐优先用这种方式。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;但很多公司是内网开发，IDEA 装不了插件、也访问不了外网，这种情况下就只能用方法一的全局搜索。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-26/f2f508aa-86ad-49bf-a8d7-e44138706e8b.png&quot; alt=&quot;接口定位代码-2&quot; /&gt;&lt;figcaption&gt;接口定位代码-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方法三：顺着项目结构找&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果你对项目结构已经有点了解，可以不搜，直接按包结构找。大部分 Java 项目的 Controller 放在固定的包下（比如 &lt;code&gt;com.xxx.controller&lt;/code&gt; 或 &lt;code&gt;com.xxx.web&lt;/code&gt;），打开对应的包，根据接口路径里的关键词（比如 &lt;code&gt;order&lt;/code&gt;）找到对应的 Controller 类（&lt;code&gt;OrderController&lt;/code&gt;），再在里面找具体方法。这个方法适合你已经熟悉项目之后日常使用，比每次全局搜索效率更高。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;二、微服务项目&lt;a href=&quot;#二微服务项目&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;微服务项目里，接口路径和代码之间隔了一层——请求先到网关，网关根据规则转发到对应的服务，服务里才有 Controller 代码。所以找接口代码要分两步：&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;/p&gt;&lt;p&gt;配置一般在网关服务的 &lt;code&gt;application.yml&lt;/code&gt; 里，长这样：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;cloud&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;gateway&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;routes&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;order-service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;lb://order-service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;predicates&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;Path=/api/order/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;user-service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;lb://user-service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;predicates&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;Path=/api/user/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;接口地址是 &lt;code&gt;/api/order/pageList&lt;/code&gt;，匹配到 &lt;code&gt;Path=/api/order/**&lt;/code&gt;，对应的 &lt;code&gt;uri&lt;/code&gt; 是 &lt;code&gt;lb://order-service&lt;/code&gt;，所以这个接口在 &lt;code&gt;order-service&lt;/code&gt; 这个服务里。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第二步：定位到服务之后，找接口方法就跟单体项目一样了。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;找到服务之后，去那个服务的代码工程里，用单体项目的三种方法找接口：&lt;code&gt;Ctrl + Shift + R&lt;/code&gt; 搜路径关键词、通过 ApiFox 插件搜索、或者顺着项目包结构直接找。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>拿到需求该干什么</title><link>https://study-docs-158.pages.dev/posts/%E6%8B%BF%E5%88%B0%E9%9C%80%E6%B1%82%E8%AF%A5%E5%B9%B2%E4%BB%80%E4%B9%88/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E6%8B%BF%E5%88%B0%E9%9C%80%E6%B1%82%E8%AF%A5%E5%B9%B2%E4%BB%80%E4%B9%88/</guid><description>拿到需求该干什么</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、理解需求&lt;a href=&quot;#一理解需求&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、理解需求的注意事项&lt;a href=&quot;#1理解需求的注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;拿到需求后，不要急着开始开发。 如果一个需求分到你手里，你几乎没有任何疑问就直接开始做，结果做完之后发现和真实需求不一致，那返工几乎是必然的。&lt;/p&gt;&lt;p&gt;开发过程中要建立一个很重要的意识：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;需求来了，没有问题，不代表你很厉害；很多时候，反而说明你还没有真正理解清楚。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;对于需求中的疑问，一定要敢问，也必须要问。 因为理解需求，是后续开发不偏离方向的前提，也是避免后续返工和背锅的前提。&lt;/p&gt;&lt;p&gt;对于产品描述不清楚、原型图表达不明确、边界不完整的地方，都要及时确认清楚，最好拿到明确答复。 这样做的目的，一方面是为了保证自己理解正确，另一方面也是为了避免后续出现“当时大家理解不一致”的扯皮情况。&lt;/p&gt;&lt;p&gt;另外还要有一个意识：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;需求文档和原型图并不一定完全正确。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这些内容通常是由产品经理整理和输出的，而产品经理本身的经验和能力也存在差异。 有些需求文档或原型图本身就可能存在问题，例如：&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;li&gt;边界情况遗漏&lt;/li&gt;
&lt;li&gt;字段定义不明确&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以，不要一看到自己没看懂，就立刻怀疑是自己能力不行。 很多时候，不是你理解能力有问题，而是文档本身就存在问题。&lt;/p&gt;&lt;p&gt;正确的做法是：&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;li&gt;把关键结论对齐清楚后再开始开发&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、理解需求时，重点要确认什么？&lt;a href=&quot;#2理解需求时重点要确认什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;2.1 需求目标&lt;a href=&quot;#21-需求目标&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;首先要明确，这次需求到底要解决什么问题，以及做完之后要达到什么效果。&lt;/p&gt;&lt;p&gt;重点确认：&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;li&gt;这个需求的优先级和紧急程度如何&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.2 需求类型&lt;a href=&quot;#22-需求类型&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;拿到需求后，要先判断这次需求属于哪一类。 因为不同类型的需求，后续分析方式和影响范围往往不一样。&lt;/p&gt;&lt;p&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;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;p&gt;先判断需求类型，有助于你更快判断：&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;/section&gt;&lt;section&gt;&lt;h4&gt;2.3 影响范围&lt;a href=&quot;#23-影响范围&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在明确需求类型之后，要进一步分析这次需求会影响哪些内容。&lt;/p&gt;&lt;p&gt;重点可以从下面几个方面去看：&lt;/p&gt;&lt;section&gt;&lt;h5&gt;（1）数据影响&lt;a href=&quot;#1数据影响&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;是否需要新建表&lt;/li&gt;
&lt;li&gt;是否需要修改已有表&lt;/li&gt;
&lt;li&gt;如果要改表，需要改哪些表&lt;/li&gt;
&lt;li&gt;是否需要新增字段、索引或状态值&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;（2）数据来源&lt;a href=&quot;#2数据来源&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&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;/section&gt;&lt;section&gt;&lt;h5&gt;（3）接口影响&lt;a href=&quot;#3接口影响&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;是否需要新增接口&lt;/li&gt;
&lt;li&gt;还是修改现有接口&lt;/li&gt;
&lt;li&gt;如果修改现有接口，需要改哪些参数或返回值&lt;/li&gt;
&lt;li&gt;修改后会不会影响前端或其他系统调用&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;（4）业务流程影响&lt;a href=&quot;#4业务流程影响&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&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;p&gt;分析影响范围的目的，是避免只盯着当前这一个改动点，结果后面联调或测试时才发现漏改了很多地方。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;理解需求，不是只看懂需求文档写了什么，而是要先搞清楚：这个需求属于什么类型、会影响哪些地方、后面应该从哪里开始下手。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.4 验收标准&lt;a href=&quot;#24-验收标准&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;需要明确：&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;li&gt;筛选条件要支持哪些值&lt;/li&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;p&gt;&lt;strong&gt;验收标准不清楚，后面做完了也不一定算完成&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.5 边界条件&lt;a href=&quot;#25-边界条件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;除了主流程，还要重点确认边界情况，例如：&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;li&gt;没权限时怎么处理&lt;/li&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;p&gt;&lt;strong&gt;主流程大家通常都会想到，真正容易出问题的，往往是边界情况&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.6 依赖关系&lt;a href=&quot;#26-依赖关系&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;理解需求时，还要判断这次需求是否依赖其他角色或系统配合，例如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;是否需要前端同步修改&lt;/li&gt;
&lt;li&gt;是否需要测试提前准备场景和数据&lt;/li&gt;
&lt;li&gt;是否需要 DBA 执行脚本&lt;/li&gt;
&lt;li&gt;是否依赖其他系统提供数据或接口支持&lt;/li&gt;
&lt;li&gt;是否需要产品进一步确认某些边界&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;有些需求不是你会写代码就能按时完成，关键在于你有没有提前发现依赖。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、根据需求进行设计&lt;a href=&quot;#二根据需求进行设计&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;根据需求进行设计，主要有两个目的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第一，进一步加深对需求的理解&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;很多时候，需求在刚看的时候，好像大概明白了。 但真正开始设计的时候，才会发现很多细节还没有想清楚，比如：&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;li&gt;有没有遗漏的影响点&lt;/li&gt;
&lt;li&gt;有没有边界情况需要补充考虑&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;也就是说，&lt;strong&gt;设计的过程，本身也是再次梳理和深化需求理解的过程。&lt;/strong&gt; 通过设计，可以在正式开发之前，把需求尽可能想得更清楚一些，减少后续返工。&lt;/p&gt;&lt;p&gt;当然，也要有一个意识：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;即使前面已经做了设计，真正开发过程中，仍然有可能出现新的疑问。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;如果开发过程中发现需求还有不明确的地方，仍然需要及时沟通确认，而不是自己猜着做。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第二，很多公司本身就要求先设计再开发&lt;/strong&gt;&lt;/p&gt;&lt;p&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;p&gt;对于那种一眼就能看出来怎么做、影响范围也非常小的需求，例如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;新增一个普通字段&lt;/li&gt;
&lt;li&gt;增加一个简单筛选条件&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这类需求可以不一定单独写完整设计文档。&lt;/p&gt;&lt;p&gt;但是对于&lt;strong&gt;稍微复杂一点的需求&lt;/strong&gt;，例如：&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;li&gt;涉及老逻辑兼容&lt;/li&gt;
&lt;li&gt;涉及风险点较多&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;都建议先整理一版设计方案。 如果公司有要求，就按公司的规范来写；如果不知道怎么写，可以先找同事要一份模板参考。 如果公司没有强制要求，也建议至少自己写一个简版设计，帮助自己把思路梳理清楚。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、业务流程梳理&lt;a href=&quot;#1业务流程梳理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;设计时，首先要梳理这次需求涉及的业务流程。&lt;/p&gt;&lt;p&gt;也就是要先想清楚：&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;li&gt;哪一步会新增逻辑&lt;/li&gt;
&lt;li&gt;哪一步会修改原有逻辑&lt;/li&gt;
&lt;li&gt;最终结果会落到哪里&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果流程稍微复杂，建议直接画一个简单流程图。 因为很多时候，&lt;strong&gt;流程一画出来，问题就更容易暴露出来。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;例如，你可能会发现：&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;li&gt;原来某个异常场景没有覆盖到&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以，业务流程梳理的目的，不只是为了“画图”，而是为了让自己真正把主流程和关键节点想清楚。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、表设计&lt;a href=&quot;#2表设计&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;如果需求涉及数据库设计，就需要先根据业务场景分析： 这次需求会涉及哪些核心业务对象，这些对象之间是什么关系，最终应该如何落到数据库表中。&lt;/p&gt;&lt;p&gt;需要注意的是，&lt;strong&gt;业务对象并不一定都必须单独设计成一张表&lt;/strong&gt;。 是否需要单独建表，要结合实际业务场景、数据存储需求、查询方式以及后续扩展性综合判断。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;2.1 先分析业务对象之间的关系&lt;a href=&quot;#21-先分析业务对象之间的关系&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&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;li&gt;&lt;strong&gt;多对多&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;例如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;一个用户可以有多个订单，这通常是一对多&lt;/li&gt;
&lt;li&gt;一个订单可以包含多个商品，一个商品也可以出现在多个订单中，这通常是多对多&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;对于多对多关系，通常需要增加一张&lt;strong&gt;中间关系表&lt;/strong&gt;来维护两边的关联关系。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.2 表与表之间通过关联字段建立关系&lt;a href=&quot;#22-表与表之间通过关联字段建立关系&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在设计表结构时，如果一张表需要关联另一张表，通常通过：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;主键&lt;/li&gt;
&lt;li&gt;业务唯一标识字段&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;来建立关系。&lt;/p&gt;&lt;p&gt;一般情况下，一张表中只需要保存另一张表的&lt;strong&gt;关联字段&lt;/strong&gt;，而不需要重复存储另一张表的所有信息。 需要使用对方信息时，可以通过关联字段进行查询。&lt;/p&gt;&lt;p&gt;这样设计的好处是：&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;p&gt;当然，如果某些场景对查询性能要求较高，或者出于业务快照的考虑，也可能会适当做冗余字段设计，这要结合具体业务判断。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.3 表设计时需要重点注意的内容&lt;a href=&quot;#23-表设计时需要重点注意的内容&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;（1）优先遵循公司已有的建表规范&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在正式设计表之前，首先要了解公司内部是否有统一的建表规范。 如果有，就必须优先按照公司规范来设计表名、字段名、注释、公共字段等内容。&lt;/p&gt;&lt;p&gt;例如，有些公司会要求每张表都必须包含公共字段：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cr_time&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cr_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;up_time&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;up_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rm_time&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rm_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;removed&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;属于建表时最基础的规范，必须掌握：&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;li&gt;多个英文单词之间使用下划线分隔&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;（2）字段不要无节制堆积&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;一张表的字段不宜过多。 如果字段过多，通常说明：&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;p&gt;如果确实字段很多，可以结合业务场景考虑是否拆成：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;主表 + 扩展表&lt;/li&gt;
&lt;li&gt;主表 + 明细表&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;但是否拆表，也不能只看字段数量，还要结合查询方式、更新频率和业务职责一起判断。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（3）字段类型要选择合适&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;字段类型设计要尽量合理，不要随意选择。&lt;/p&gt;&lt;p&gt;例如：&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;li&gt;时间类字段要统一规范&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;不过也要注意： 如果某个字段的数据类型在当前阶段不够稳定，或者后续扩展可能较大，可以在合理范围内选择兼容性更强的类型，但不要为了“省事”全部都用字符串。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（4）表注释和字段注释尽量补齐&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;建表时，最好同时补上：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;表注释&lt;/li&gt;
&lt;li&gt;字段注释&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;因为后续无论是你自己看表，还是别人接手项目，注释都能明显降低理解成本。 尤其是状态字段、业务标识字段、枚举值字段，如果没有注释，后面维护起来会非常痛苦。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（5） 索引要结合查询场景来设计&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;建表时，不建议一上来就给很多字段随意加索引，但也不能完全不考虑索引。&lt;/p&gt;&lt;p&gt;更合理的做法是：&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;li&gt;数据量上来后，再结合实际 SQL 和执行情况优化索引&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;也就是说：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;索引不是越多越好，而是要根据实际查询场景来设计。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.4 表设计的核心目标&lt;a href=&quot;#24-表设计的核心目标&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;表设计最终要达到的目标，不只是“能存数据”，还要尽量做到：&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;li&gt;方便查询&lt;/li&gt;
&lt;li&gt;方便扩展&lt;/li&gt;
&lt;li&gt;方便维护&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;表设计不是简单地把需求字段堆到数据库里，而是要先理清业务对象、对象关系和数据存储方式，再结合公司规范、字段类型、注释和索引等因素，设计出合理、可维护的表结构。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、接口设计&lt;a href=&quot;#3接口设计&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;如果需求涉及接口，就要考虑接口设计。&lt;/p&gt;&lt;p&gt;接口设计时，也要优先遵循项目现有的接口规范，而不是自己随意发挥。 因为你后面真正写接口时，最重要的不是“写出来”，而是要&lt;strong&gt;和项目现有风格保持一致&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;设计接口时，建议重点考虑这些内容：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;接口地址如何命名&lt;/li&gt;
&lt;li&gt;是否遵循 RESTful 风格&lt;/li&gt;
&lt;li&gt;请求方式使用 GET、POST、PUT 还是 DELETE&lt;/li&gt;
&lt;li&gt;请求参数如何封装&lt;/li&gt;
&lt;li&gt;返回值是否使用统一响应类&lt;/li&gt;
&lt;li&gt;错误码是否有统一规范&lt;/li&gt;
&lt;li&gt;分页参数和分页返回结构是否统一&lt;/li&gt;
&lt;li&gt;参数校验怎么处理&lt;/li&gt;
&lt;li&gt;异常处理方式是否和现有项目一致&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这时候，就可以结合你前面在“熟悉项目”时总结出来的内容来看：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;别人之前的接口是怎么写的，这个项目平时的接口风格是什么。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;然后尽量按照现有规范来设计和实现，而不是自己重新搞一套风格。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;一句话总结&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;根据需求进行设计，不只是为了画一份文档，更重要的是在正式开发之前，把业务流程、表设计、接口设计和风险点尽可能想清楚。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、评估工时&lt;a href=&quot;#三评估工时&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;在需求理解清楚、设计思路也基本明确之后，下一步通常就需要进行工时评估。&lt;/p&gt;&lt;p&gt;工时评估，说白了，就是判断：&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;li&gt;是否存在会影响进度的风险点&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;很多新人在这一步最容易犯的错，就是&lt;strong&gt;只算写代码的时间&lt;/strong&gt;。 但真实工作里，一个需求真正完成，远远不只是“把代码写完”这么简单。&lt;/p&gt;&lt;p&gt;一个需求的工时，通常至少要包括下面这些部分：&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;li&gt;自测&lt;/li&gt;
&lt;li&gt;联调&lt;/li&gt;
&lt;li&gt;修 bug&lt;/li&gt;
&lt;li&gt;提测和沟通成本&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;也就是说，&lt;strong&gt;工时评估不能只看开发时间，还要看整个交付过程。&lt;/strong&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;工时评估时，重点看什么？&lt;a href=&quot;#工时评估时重点看什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;section&gt;&lt;h5&gt;（1）需求本身复杂度&lt;a href=&quot;#1需求本身复杂度&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;先判断这个需求本身复杂不复杂，例如：&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;li&gt;还是会影响多个模块和上下游系统&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;需求越复杂，工时自然越长。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;（2）改动范围&lt;a href=&quot;#2改动范围&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;要看这次需求具体会改哪些地方，例如：&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;li&gt;是否影响导出、报表、详情页、缓存、定时任务等联动功能&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;改动范围越大，评估时间时越要保守一些。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;（3）自己对项目的熟悉程度&lt;a href=&quot;#3自己对项目的熟悉程度&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;同样一个需求，不同人做，时间可能差很多。&lt;/p&gt;&lt;p&gt;比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;对项目很熟的人，定位代码和改动点会很快&lt;/li&gt;
&lt;li&gt;刚接手项目的人，可能花很多时间在找代码、看表、理解流程上&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以评估工时时，也要客观考虑自己当前对项目的熟悉程度，不要按照“理想状态”去估。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;（4）是否依赖其他人配合&lt;a href=&quot;#4是否依赖其他人配合&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;有些需求，不是你一个人把代码写完就结束了，还可能依赖：&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;li&gt;其他系统同步改动&lt;/li&gt;
&lt;li&gt;调用其他系统接口&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果有这些依赖，就要考虑进去，不然很容易出现： 代码写完了，但整体推进不了。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;（5）是否存在风险点&lt;a href=&quot;#5是否存在风险点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;如果需求里存在这些情况，评估时间时就要适当留余量：&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;li&gt;接口联动较多&lt;/li&gt;
&lt;li&gt;可能有性能问题&lt;/li&gt;
&lt;li&gt;可能牵扯缓存、MQ、第三方系统&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;有风险点的需求，不适合估得太满。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;工时评估时，不要只给一个“拍脑袋时间”&lt;a href=&quot;#工时评估时不要只给一个拍脑袋时间&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;更推荐的做法是：&lt;strong&gt;拆开估。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;例如，可以拆成这样：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;需求确认：0.5h&lt;/li&gt;
&lt;li&gt;方案梳理：1h&lt;/li&gt;
&lt;li&gt;编码实现：3h&lt;/li&gt;
&lt;li&gt;自测：1h&lt;/li&gt;
&lt;li&gt;联调：1h&lt;/li&gt;
&lt;li&gt;修 bug + 提测：1h&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这样比直接说“我估计一天”要更专业，也更方便后面解释为什么需要这些时间。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;如果项目经理马上问你多久能做完，怎么回答更稳妥？&lt;a href=&quot;#如果项目经理马上问你多久能做完怎么回答更稳妥&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;如果你刚拿到需求，还没把改动点和影响面想清楚，这时候不要急着直接报时间。&lt;/p&gt;&lt;p&gt;更稳妥的表达方式是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;我先把需求理解清楚，把改动点和方案梳理一下，再给你一个更准确的时间。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这句话的好处是：&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;/section&gt;&lt;section&gt;&lt;h4&gt;工时评估的注意事项&lt;a href=&quot;#工时评估的注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;不要只算写代码时间&lt;/li&gt;
&lt;li&gt;不要忽略自测、联调、修 bug 的时间&lt;/li&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;p&gt;&lt;strong&gt;工时评估，不是简单地猜一个时间，而是根据需求复杂度、改动范围、项目熟悉程度、依赖关系和风险点，对整个交付过程做一个相对合理的预估。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>如何进行前后端联调</title><link>https://study-docs-158.pages.dev/posts/%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E5%89%8D%E5%90%8E%E7%AB%AF%E8%81%94%E8%B0%83/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E5%89%8D%E5%90%8E%E7%AB%AF%E8%81%94%E8%B0%83/</guid><description>如何进行前后端联调</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、新人必看&lt;a href=&quot;#一新人必看&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;很多新人会问：&lt;strong&gt;“接口我不是写好了吗？为什么还要联调？”&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为你的接口写好了，不代表前端能正常调用。可能字段名对不上、数据格式不对、返回值有问题……&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;联调就是让前端调你的接口，发现问题后一起解决的过程。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;1、什么是前后端联调？&lt;a href=&quot;#1什么是前后端联调&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;简单说就是：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;后端写好接口&lt;/li&gt;
&lt;li&gt;前端来调接口&lt;/li&gt;
&lt;li&gt;发现问题，后端改&lt;/li&gt;
&lt;li&gt;再调，再改，直到没问题&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、联调流程图&lt;a href=&quot;#2联调流程图&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-10/7fed97f8-037b-405c-a43d-2b2914bf66c6.png&quot; alt=&quot;前后端联调流程图&quot; /&gt;&lt;figcaption&gt;前后端联调流程图&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、联调前的准备&lt;a href=&quot;#二联调前的准备&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、一定要先自测！（重要！）&lt;a href=&quot;#1一定要先自测重要&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人最容易犯的错：接口写完直接给前端调，结果一堆问题。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&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;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;接口能不能通&lt;/td&gt;&lt;td&gt;用Postman调一下，不报错再说&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;tr&gt;&lt;td&gt;返回值对不对&lt;/td&gt;&lt;td&gt;数据格式、字段名是否符合预期&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Token传了没&lt;/td&gt;&lt;td&gt;需要登录的接口要传Token&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;p&gt;&lt;strong&gt;自测工具：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Postman&lt;/li&gt;
&lt;li&gt;Apifox&lt;/li&gt;
&lt;li&gt;Swagger&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、准备接口文档&lt;a href=&quot;#2准备接口文档&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;/th&gt;&lt;th&gt;示例&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;GET /api/user/list&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;请求参数&lt;/td&gt;&lt;td&gt;userName(可选)、pageNum(默认1)、pageSize(默认10)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;返回参数&lt;/td&gt;&lt;td&gt;code、message、data(列表+总数)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;枚举说明&lt;/td&gt;&lt;td&gt;status: 0-禁用, 1-启用&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;接口文档工具：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Word文档（简单粗暴）&lt;/li&gt;
&lt;li&gt;Swagger/Knife4j（自动生成）&lt;/li&gt;
&lt;li&gt;Apifox（在线协作）&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、部署后端服务&lt;a href=&quot;#三部署后端服务&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;前端要调你的接口，你得把服务部署起来。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、方式一：本地部署&lt;a href=&quot;#1方式一本地部署&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;就是把你本地的IDEA启动，让前端来连你电脑。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;前提条件：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;前后端在同一个局域网（同一个WiFi）&lt;/li&gt;
&lt;li&gt;电脑防火墙要关闭&lt;/li&gt;
&lt;li&gt;端口没有被占用&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;操作步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;查看自己的IP地址&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# Windows&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ipconfig&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 找到 IPv4 地址，比如 192.168.3.10 ,可以让前端Ping一下，能够Ping通就没问题&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-10/71ab8373-3833-4bdb-8562-85ef3de83219.png&quot; alt=&quot;前后端联调-2&quot; /&gt;&lt;figcaption&gt;前后端联调-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;关闭防火墙&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;控制面板 → Windows Defender 防火墙 → 启用或关闭Windows Defender防火墙 → 关闭&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;告诉前端你的地址&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;192.168.3.10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、方式二：测试环境部署&lt;a href=&quot;#2方式二测试环境部署&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;直接把服务部署到测试服务器上，前端访问测试环境。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;常见部署方式：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Jenkins自动部署&lt;/li&gt;
&lt;li&gt;手动打包上传&lt;/li&gt;
&lt;li&gt;Docker部署&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;问同事：&lt;/strong&gt; “我们项目怎么部署到测试环境？“&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、验证服务是否正常&lt;a href=&quot;#3验证服务是否正常&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 本地测试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;http://localhost:8080/api/test&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、联调过程中常见问题&lt;a href=&quot;#四联调过程中常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、跨域问题&lt;a href=&quot;#1跨域问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;现象：&lt;/strong&gt; 前端控制台报错 &lt;code&gt;CORS policy&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;/p&gt;&lt;p&gt;后端添加跨域配置：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;CorsConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Bean&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;CorsFilter&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;corsFilter&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;CorsConfiguration&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;CorsConfiguration&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addAllowedOriginPattern&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;*&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addAllowedMethod&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;*&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addAllowedHeader&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;*&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setAllowCredentials&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;UrlBasedCorsConfigurationSource&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;source&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UrlBasedCorsConfigurationSource&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;source&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;registerCorsConfiguration&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/**&quot;&lt;/span&gt;&lt;span&gt;, config);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;CorsFilter&lt;/span&gt;&lt;span&gt;(source);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、前端收不到参数&lt;a href=&quot;#2前端收不到参数&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;现象：&lt;/strong&gt; 前端传了参数，后端收到是null&lt;/p&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;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;请求方式&lt;/td&gt;&lt;td&gt;GET用@RequestParam，POST用@RequestBody&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Content-Type&lt;/td&gt;&lt;td&gt;POST请求要设置 application/json&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;tr&gt;&lt;td&gt;参数位置&lt;/td&gt;&lt;td&gt;Query参数在URL里，Body参数在请求体里&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;常见错误：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 错误：POST请求用了@RequestParam&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/add&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; name) {  &lt;/span&gt;&lt;span&gt;// 收不到！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 正确：POST请求用@RequestBody&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/add&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDto&lt;/span&gt;&lt;span&gt; dto) {  &lt;/span&gt;&lt;span&gt;// 正确&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、返回字段名不对&lt;a href=&quot;#3返回字段名不对&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;现象：&lt;/strong&gt; 前端要userName，你返回的是user_name&lt;/p&gt;&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserVo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;JsonProperty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;userName&quot;&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 指定返回的字段名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; userName&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、日期格式问题&lt;a href=&quot;#4日期格式问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;JsonFormat&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pattern&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;yyyy-MM-dd HH:mm:ss&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt; createTime&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、Token失效&lt;a href=&quot;#5token失效&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;现象：&lt;/strong&gt; 接口返回401&lt;/p&gt;&lt;p&gt;&lt;strong&gt;排查：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Token有没有传&lt;/li&gt;
&lt;li&gt;Token格式对不对（Bearer xxx）&lt;/li&gt;
&lt;li&gt;Token有没有过期&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、联调的正确姿势&lt;a href=&quot;#五联调的正确姿势&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、与前端沟通的技巧&lt;a href=&quot;#1与前端沟通的技巧&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;不要这样说：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“接口没问题啊，你自己检查下”&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;应该这样说：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“我这边用Postman测是正常的，我们一起看看是什么问题，你把请求参数和返回结果发我一下”&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、问题定位方法&lt;a href=&quot;#2问题定位方法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;1. 让前端把请求参数发给你&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;2. 你用同样的参数在Postman测试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;3. 如果Postman正常，说明可能是跨域或前端问题&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;4. 如果Postman也有问题，那就是后端问题&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、改接口要注意&lt;a href=&quot;#3改接口要注意&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;建议&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&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;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;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、联调完成的标准&lt;a href=&quot;#六联调完成的标准&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;/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;tr&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;/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;/section&gt;
&lt;section&gt;&lt;h2&gt;七、新人避坑指南&lt;a href=&quot;#七新人避坑指南&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;/td&gt;&lt;td&gt;先自己用Postman测一遍&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;不写接口文档&lt;/td&gt;&lt;td&gt;至少写个简单的Word文档&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;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;八、常见问题&lt;a href=&quot;#八常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Q：前端说接口调不通怎么办？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;A：让前端把报错截图发你，看是跨域问题还是接口问题。自己用Postman再测一遍确认。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q：前端说字段名不对要改怎么办？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;A：如果只是改字段名，加个@JsonProperty注解就行，不影响数据库字段。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q：联调时前端不在怎么办？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;A：先把接口文档给前端，让前端先看着，等都在了再联调。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Q：一个接口前端调了一直有问题怎么办？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;A：和前端一起看，打开F12看请求和响应，一起分析问题在哪。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;九、注意事项&lt;a href=&quot;#九注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ol&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;li&gt;&lt;strong&gt;记录问题&lt;/strong&gt;：把遇到的问题记下来，下次就不会踩坑&lt;/li&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;/ol&gt;&lt;/section&gt;</content:encoded></item><item><title>如何看线上日志</title><link>https://study-docs-158.pages.dev/posts/%E5%A6%82%E4%BD%95%E7%9C%8B%E7%BA%BF%E4%B8%8A%E6%97%A5%E5%BF%97/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%A6%82%E4%BD%95%E7%9C%8B%E7%BA%BF%E4%B8%8A%E6%97%A5%E5%BF%97/</guid><description>如何看线上日志</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、日志路径怎么找&lt;a href=&quot;#一日志路径怎么找&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;方法一：看配置文件&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Java 项目的日志路径通常写在日志框架的配置文件里。打开你项目的 &lt;code&gt;src/main/resources&lt;/code&gt; 目录，找这几个文件：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;logback-spring.xml&lt;/code&gt;（最常见）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;logback.xml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;log4j2.xml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;打开之后搜 &lt;code&gt;file&lt;/code&gt; 或 &lt;code&gt;path&lt;/code&gt; 关键字，一般能找到类似这样的配置：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;LOG_PATH&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;/var/log/order-service&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;code&gt;nohup java -jar xxx.jar&lt;/code&gt; 启动的，那 nohup 会把控制台输出重定向到一个文件。看一下启动脚本（通常是 &lt;code&gt;start.sh&lt;/code&gt; 或部署平台的命令），找类似这样的写法：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;nohup&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;java&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-jar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order-service.jar&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;/span&gt;&lt;span&gt;/var/log/order-service/startup.log&lt;/span&gt;&lt;span&gt; 2&amp;gt;&amp;amp;1 &amp;amp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&lt;/code&gt; 后面跟的就是启动日志的路径。这个日志里会有应用启动时的输出，包括 Spring 的启动信息和一些早期报错。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方法三：问 AI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果项目能访问外网，可以用 Claude Code、CodeX 这类 AI 工具直接读你的项目代码，它会帮你找到日志配置文件并告诉你路径在哪。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方法四：看文档或问同事&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有些团队会有部署文档或运维文档，里面会写各个服务的日志路径，入职的时候留意一下有没有这种文档。有文档就先看文档，没有再问同事。&lt;/p&gt;&lt;p&gt;直接问同事：“咱们这个服务的日志在服务器哪个目录下？“。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、找到了一堆文件，看哪个&lt;a href=&quot;#二找到了一堆文件看哪个&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;假设你已经知道日志在 &lt;code&gt;/var/log/order-service/&lt;/code&gt; 目录下，SSH 上去 &lt;code&gt;ls&lt;/code&gt; 一看，可能长这样：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;zcloud-learning.log&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;zcloud-learning.log.2026-07-03&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;zcloud-learning.log.2026-07-02&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;zcloud-learning-error.log&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;zcloud-learning.log.2026-07-03&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;startup.log&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;/th&gt;&lt;th&gt;看哪个文件&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;刚刚调接口报错了&lt;/td&gt;&lt;td&gt;zcloud-learning.log（当天的主日志）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;想只看报错信息&lt;/td&gt;&lt;td&gt;order-service-error.log（错误专用日志）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;服务启动失败&lt;/td&gt;&lt;td&gt;startup.log 或主日志的最开头部分&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;昨天的问题，今天的日志已经滚动了&lt;/td&gt;&lt;td&gt;zcloud-learning.log.2026-07-02（按日期命名的历史日志）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;大部分时候你需要看的是&lt;strong&gt;当天的主日志文件&lt;/strong&gt;，文件名没有日期后缀的那个（比如 &lt;code&gt;zcloud-learning.log&lt;/code&gt;）。如果配置了 error 日志单独输出，排查报错的时候先看 error 日志会更快，因为它只记录错误，不用在一堆 info 日志里翻。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;找历史日志的要点&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有一种场景更常见：测试同学反馈”昨天下午某个功能报错了”，你去复现发现是好的。这种问题没法重现，只能去翻对应那天的历史日志。操作步骤：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;先确认问题发生的时间点。越精确越好，“昨天下午”和”昨天下午3点到4点之间”差别很大。&lt;/li&gt;
&lt;li&gt;根据时间找到对应的日志文件。如果日志按天分割，直接看文件名日期就行，比如 &lt;code&gt;zcloud-learning.log.2026-07-02&lt;/code&gt;。有些项目配置了按小时分割，文件名会带小时后缀，比如 &lt;code&gt;zcloud-learning.log.2026-07-02-15&lt;/code&gt; 表示 14 号下午 3 点到 4 点的日志。&lt;/li&gt;
&lt;li&gt;打开文件后，用时间关键字缩小范围，再用错误关键字定位。&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 在历史日志里搜某个时间段的报错&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;2026-07-02 15:&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zcloud-learning.log.2026-07-02&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;ERROR&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;还有一个坑要注意：&lt;strong&gt;日志不会永远保留&lt;/strong&gt;。服务器磁盘空间有限，运维一般会配置日志保留策略，比如只保留 7 天或 15 天。如果问题发生在一个月前，对应的日志文件大概率已经被清理了。所以遇到需要翻历史日志的问题，尽快去看，拖久了日志可能就没了。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、找到日志了，怎么看&lt;a href=&quot;#三找到日志了怎么看&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;情况一：问题可以复现，想实时看&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;用 &lt;code&gt;tail -f&lt;/code&gt;，它会持续输出文件末尾新增的内容。先打开 tail -f，然后去调接口，日志会实时滚出来，按 &lt;code&gt;Ctrl+C&lt;/code&gt; 停止。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zcloud-learning.log&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;如果日志刷得很快（比如有定时任务在跑），你触发的日志一下子就被刷过去了，这时候加过滤：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;问题是报错 → 过滤 ERROR：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zcloud-learning.log&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;ERROR&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;问题是业务逻辑异常 → 过滤业务关键词，比如订单号：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zcloud-learning.log&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;10086&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;想看匹配行的上下文（比如报错那行的前后 5 行），加 &lt;code&gt;-C&lt;/code&gt; 参数：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zcloud-learning.log&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-C&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;ERROR&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;情况二：问题已经发生过了，事后搜索&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这种场景用 &lt;code&gt;grep&lt;/code&gt; 直接在日志文件里搜。搜什么取决于你知道什么：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;知道报错类型 → 搜异常名：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;NullPointerException&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zcloud-learning.log&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;知道业务参数 → 搜订单号、用户ID等：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;10086&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zcloud-learning.log&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;知道大致时间段 → 用两个 grep 组合，先缩小范围再定位：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;2026-07-03 14:&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zcloud-learning.log&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;ERROR&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果你的项目日志格式规范，每条日志都带订单号或 requestId，用业务关键词能把同一个请求的所有日志串起来。&lt;strong&gt;前提是日志里确实打了这个字段&lt;/strong&gt;——这也是为什么写代码时要在关键节点打印业务标识。&lt;/p&gt;&lt;p&gt;除了 grep，事后搜索还有两种方式：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;文件太大，想边翻边看上下文&lt;/strong&gt; → 用 &lt;code&gt;less&lt;/code&gt;：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;less&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;zcloud-learning.log&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;less&lt;/code&gt; 会分页打开文件，用方向键翻页，按 &lt;code&gt;/&lt;/code&gt; 输入关键字搜索，按 &lt;code&gt;n&lt;/code&gt; 跳到下一个匹配项，按 &lt;code&gt;q&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;p&gt;用 VS Code 或 Notepad++ 打开，支持高亮、正则、多文件搜索，适合需要反复翻阅的场景。前提是公司允许把日志下载到本地——有些安全要求高的团队会限制这个操作，不确定的话先问一下。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;</content:encoded></item><item><title>如何快速熟悉项目</title><link>https://study-docs-158.pages.dev/posts/%E5%A6%82%E4%BD%95%E5%BF%AB%E9%80%9F%E7%86%9F%E6%82%89%E9%A1%B9%E7%9B%AE/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%A6%82%E4%BD%95%E5%BF%AB%E9%80%9F%E7%86%9F%E6%82%89%E9%A1%B9%E7%9B%AE/</guid><description>如何快速熟悉项目</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h3&gt;一、为什么要学会快速熟悉项目？&lt;a href=&quot;#一为什么要学会快速熟悉项目&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、什么叫熟悉项目？&lt;a href=&quot;#1什么叫熟悉项目&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;很多人理解的“熟悉项目”，就是把项目代码从头到尾看一遍。 但实际上，&lt;strong&gt;熟悉项目并不是把所有代码都看完，而是先建立对项目的整体认知。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;简单来说，熟悉项目，就是让你尽快搞清楚下面这些问题：&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;li&gt;这个项目怎么启动、怎么运行&lt;/li&gt;
&lt;li&gt;这个项目有哪些核心模块&lt;/li&gt;
&lt;li&gt;核心业务流程是什么&lt;/li&gt;
&lt;li&gt;关键数据存在哪些表里&lt;/li&gt;
&lt;li&gt;功能是通过哪些接口完成的&lt;/li&gt;
&lt;li&gt;一条业务链路大概是怎么走的&lt;/li&gt;
&lt;li&gt;出问题的时候，应该先去哪里找&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;也就是说，&lt;strong&gt;熟悉项目的本质，是先在脑子里建立一张“项目地图”&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;这张“项目地图”里，不只是代码，还包括：&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;li&gt;接口地图&lt;/li&gt;
&lt;li&gt;技术栈地图&lt;/li&gt;
&lt;li&gt;技术架构地图&lt;/li&gt;
&lt;li&gt;启动与运行地图&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、为什么要熟悉项目？&lt;a href=&quot;#2为什么要熟悉项目&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;因为你入职之后，不可能一直停留在“把项目跑起来”这个阶段。 你很快就会碰到这些事情：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;改需求&lt;/li&gt;
&lt;li&gt;修 bug&lt;/li&gt;
&lt;li&gt;联调接口&lt;/li&gt;
&lt;li&gt;排查问题&lt;/li&gt;
&lt;li&gt;写新接口&lt;/li&gt;
&lt;li&gt;改老接口&lt;/li&gt;
&lt;li&gt;查日志&lt;/li&gt;
&lt;li&gt;跟前端、测试、产品沟通&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果你对项目没有整体认知，就很容易出现这些情况：&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;li&gt;不知道问题到底出在代码、配置、表、接口，还是中间件&lt;/li&gt;
&lt;li&gt;不知道这个公司平时是怎么写接口、怎么组织代码的&lt;/li&gt;
&lt;li&gt;看见 Redis、MQ、ES、注册中心、网关就发虚&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以，&lt;strong&gt;熟悉项目，不是为了学习而学习，而是为了后续真正开始干活。熟悉项目，最好有个文档输出，方便后续查询&lt;/strong&gt;&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;二、熟悉项目的正确思路是什么？&lt;a href=&quot;#二熟悉项目的正确思路是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;很多新人一开始最容易犯的错，就是：&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;li&gt;最后什么都没记住&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;更推荐的思路应该是：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;先了解业务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;再了解技术栈&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;再看整体技术架构&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;再看项目启动和运行方式&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;再看模块划分&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;再看核心表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;再看核心接口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;再顺着接口去看代码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;最后通过日志、调试、真实需求和 bug 来验证理解&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;为什么推荐这个顺序？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）先业务，再代码&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为代码是为业务服务的。 如果你连这个系统是干什么的都没搞清楚，直接看代码，很容易迷路。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）先技术栈和架构，再看实现细节&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为你后面看代码时，一定会不断碰到 Redis、MQ、ES、注册中心、网关、定时任务这些东西。 如果你连这些技术是干什么的、项目里怎么用的都不知道，读代码会很慌。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）先整体，再细节&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;先知道项目有哪些模块、哪些是核心模块，再决定先看哪里，不然很容易在边缘代码里浪费时间。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4）先看“做什么”，再看“怎么做”&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;接口、数据表、页面流程，往往比代码更容易帮助你理解业务。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5）先抓主线，再补细节&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;一开始不需要把所有地方都看懂，先抓住一两条核心链路，把主线搞明白，比零零散散看很多代码更有效。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、快速熟悉项目，应该先看什么？&lt;a href=&quot;#三快速熟悉项目应该先看什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;很多新人熟悉项目时，容易只盯着业务和代码。 但实际上，想要真正快速上手一个项目，至少要从下面几个方面一起看：&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;li&gt;项目怎么启动、怎么运行&lt;/li&gt;
&lt;li&gt;项目有哪些模块&lt;/li&gt;
&lt;li&gt;核心表和核心接口有哪些&lt;/li&gt;
&lt;li&gt;核心业务链路是怎么走的&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;也就是说，&lt;strong&gt;熟悉项目，不只是熟悉业务和代码，还要熟悉这个项目的技术实现方式。&lt;/strong&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;1、先看项目是做什么的&lt;a href=&quot;#1先看项目是做什么的&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;先回答下面几个问题：&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;li&gt;这个系统和其他系统是什么关系？&lt;/li&gt;
&lt;li&gt;这个系统在整个业务链路里扮演什么角色？&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;常见了解方式&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;看 README&lt;/li&gt;
&lt;li&gt;看 PRD / 需求文档&lt;/li&gt;
&lt;li&gt;看原型图&lt;/li&gt;
&lt;li&gt;让同事或导师先简单讲一遍业务流程&lt;/li&gt;
&lt;/ul&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;/section&gt;&lt;section&gt;&lt;h4&gt;2、再看项目用了哪些技术栈&lt;a href=&quot;#2再看项目用了哪些技术栈&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;这一点非常重要，但很多新人容易忽略。&lt;/p&gt;&lt;p&gt;因为你后面能不能快速上手，很大程度上取决于你知不知道：&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;li&gt;这些技术在项目里分别是怎么用的&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;你要重点关注什么？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;例如，一个项目里常见的技术栈可能有：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Spring Boot&lt;/li&gt;
&lt;li&gt;Spring Cloud / Dubbo&lt;/li&gt;
&lt;li&gt;MyBatis / JPA&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;Kafka / RabbitMQ / RocketMQ&lt;/li&gt;
&lt;li&gt;Elasticsearch&lt;/li&gt;
&lt;li&gt;Nacos / Apollo&lt;/li&gt;
&lt;li&gt;XXL-Job / Quartz&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Nginx&lt;/li&gt;
&lt;li&gt;工作流引擎&lt;/li&gt;
&lt;li&gt;对象存储&lt;/li&gt;
&lt;li&gt;第三方支付 / 短信 / 邮件服务&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;你要先搞清楚：&lt;/strong&gt;&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;p&gt;&lt;strong&gt;如果有不熟悉的技术栈怎么办？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;不用一开始就把所有技术都学得很深，但至少要做到下面三点：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第一：知道它是干什么的&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Redis 是缓存&lt;/li&gt;
&lt;li&gt;MQ 是异步解耦&lt;/li&gt;
&lt;li&gt;ES 是搜索&lt;/li&gt;
&lt;li&gt;Nacos 是注册中心/配置中心&lt;/li&gt;
&lt;li&gt;XXL-Job 是定时任务调度&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;第二：知道项目里是怎么用它的&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;例如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Redis 缓存了什么数据&lt;/li&gt;
&lt;li&gt;MQ 在什么业务场景下发消息&lt;/li&gt;
&lt;li&gt;ES 搜索的是哪些内容&lt;/li&gt;
&lt;li&gt;配置中心管理了哪些配置&lt;/li&gt;
&lt;li&gt;定时任务在什么时候跑&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;第三：先参考现有代码，不要自己硬猜&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果你不熟某个技术栈，最实用的方法通常不是先啃一堆理论，而是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;先看项目里别人是怎么使用这个技术栈的。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这样你后面真正需要改或者写的时候，就不会太心虚。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;你要建立一个意识&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;熟悉项目里的技术栈，不是为了炫技，而是为了后续需要改到这些地方时，能快速看懂、快速参考、快速上手。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、再看项目的整体技术架构&lt;a href=&quot;#3再看项目的整体技术架构&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;除了知道用了哪些技术栈，还要知道这些技术栈是怎么组合起来的。&lt;/p&gt;&lt;p&gt;也就是要搞清楚：&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;li&gt;数据库、缓存、MQ、搜索、中间件分别放在什么位置&lt;/li&gt;
&lt;li&gt;网关、注册中心、配置中心有没有用&lt;/li&gt;
&lt;li&gt;系统的主要链路是什么&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;你可以从这些角度去看&lt;/strong&gt;&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;li&gt;部署文档&lt;/li&gt;
&lt;li&gt;Nacos / 注册中心里的服务列表&lt;/li&gt;
&lt;li&gt;网关配置&lt;/li&gt;
&lt;li&gt;README / Wiki 里的架构说明&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;你至少要搞清楚这些问题&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;用户请求先到哪里？&lt;/li&gt;
&lt;li&gt;是直接进应用，还是先过网关 / Nginx？&lt;/li&gt;
&lt;li&gt;服务之间是 HTTP 调用还是 RPC 调用？&lt;/li&gt;
&lt;li&gt;数据是落 MySQL、Redis 还是 ES？&lt;/li&gt;
&lt;li&gt;异步流程是不是通过 MQ 处理？&lt;/li&gt;
&lt;li&gt;定时任务有没有参与业务流程？&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;为什么这一步重要？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为很多时候你不是不会写代码，而是你根本不知道：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;这个功能在系统整体链路里是怎么流转的。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;技术架构一旦看不清，你后面就很容易出现：&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;/section&gt;&lt;section&gt;&lt;h4&gt;4、再看项目怎么启动、怎么运行&lt;a href=&quot;#4再看项目怎么启动怎么运行&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;这一点也非常关键。 因为“项目怎么启动”，其实直接决定了你能不能开始真正熟悉项目。&lt;/p&gt;&lt;p&gt;你至少要搞清楚这些：&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;li&gt;依赖哪些中间件（MySQL、Redis、MQ、ES、Nacos 等）&lt;/li&gt;
&lt;li&gt;配置文件在哪&lt;/li&gt;
&lt;li&gt;不同环境配置怎么区分&lt;/li&gt;
&lt;li&gt;启动失败时日志在哪看&lt;/li&gt;
&lt;li&gt;启动之后怎么验证服务是正常的&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;你要重点看什么？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）启动方式&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;直接运行 Spring Boot 启动类&lt;/li&gt;
&lt;li&gt;先启动注册中心/配置中心，再启动服务&lt;/li&gt;
&lt;li&gt;需要先启动数据库、Redis、MQ&lt;/li&gt;
&lt;li&gt;需要 Docker / docker-compose 辅助启动部分依赖&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;2）运行依赖&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;比如项目启动前，是否依赖：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;Nacos&lt;/li&gt;
&lt;li&gt;Kafka / RabbitMQ&lt;/li&gt;
&lt;li&gt;Elasticsearch&lt;/li&gt;
&lt;li&gt;第三方接口配置&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;3）环境配置&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;application.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;application-dev.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bootstrap.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Nacos / Apollo 配置&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;你要知道：&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;p&gt;&lt;strong&gt;为什么这一步重要？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为很多新人虽然能“勉强把项目跑起来”，但其实并不知道：&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;li&gt;为什么本地跑得起来，测试环境不一定跑得起来&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以，&lt;strong&gt;熟悉启动方式，本质上也是在熟悉项目的运行机制。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5、再看项目有哪些模块&lt;a href=&quot;#5再看项目有哪些模块&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;你要先搞清楚这个项目是怎么拆分的。&lt;/p&gt;&lt;p&gt;比如一个项目里可能有：&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;li&gt;支付模块&lt;/li&gt;
&lt;li&gt;权限模块&lt;/li&gt;
&lt;li&gt;公共模块&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;你至少要先知道：&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;li&gt;哪些是边缘模块&lt;/li&gt;
&lt;li&gt;模块之间大概怎么调用&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;常见查看方式&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;看项目目录结构&lt;/li&gt;
&lt;li&gt;看 Maven / Gradle 多模块配置&lt;/li&gt;
&lt;li&gt;看服务注册中心（如果是微服务）&lt;/li&gt;
&lt;li&gt;问同事“平时最常改的是哪些模块”&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;建议&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;一开始先重点熟悉 &lt;strong&gt;最核心的 1~2 个模块&lt;/strong&gt;，不要想着一下把所有模块都吃透。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6、再看核心表&lt;a href=&quot;#6再看核心表&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;对于后端来说，数据表是非常重要的切入口。 因为：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;数据是业务在系统中的投影。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;有时候你先看表，比先看代码更容易理解业务。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;看表时重点看什么？&lt;/strong&gt;&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;li&gt;状态字段&lt;/li&gt;
&lt;li&gt;关联字段&lt;/li&gt;
&lt;li&gt;时间字段&lt;/li&gt;
&lt;li&gt;索引字段&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;推荐做法&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;先找 3~5 张核心表&lt;/li&gt;
&lt;li&gt;理清这些表之间的关系&lt;/li&gt;
&lt;li&gt;查几条真实数据看看&lt;/li&gt;
&lt;li&gt;再去对照代码中的 Entity、Mapper、Service&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;举例&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;假设你在看订单系统：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;user&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;order&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;order_item&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;product&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;payment_record&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;你只要把这几张表的大概关系看明白，对业务整体就会有一个比较直观的理解。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;7、再看核心接口&lt;a href=&quot;#7再看核心接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;很多新人熟悉项目的时候，会忽略接口这一层，直接看代码。 其实，&lt;strong&gt;接口是后端开发最重要的业务入口之一。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为大多数业务流程，本质上都是：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;前端/其他系统发请求&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;接口接收参数&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;后端处理业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;查询/修改数据库&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;返回结果&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;所以，熟悉接口有两个目的：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第一个目的：了解系统有哪些功能入口&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;通过接口，你可以更快看懂：&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;p&gt;&lt;strong&gt;第二个目的：了解这个项目平时怎么写接口&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这个非常重要。 因为你后面自己写接口时，不是随便按自己习惯写，而是要按照项目现有规范来写。&lt;/p&gt;&lt;p&gt;你要通过熟悉接口，总结出这个项目的接口风格，比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;URL 怎么命名&lt;/li&gt;
&lt;li&gt;GET / POST / PUT / DELETE 怎么用&lt;/li&gt;
&lt;li&gt;请求参数怎么封装&lt;/li&gt;
&lt;li&gt;返回结构怎么统一&lt;/li&gt;
&lt;li&gt;错误码怎么定义&lt;/li&gt;
&lt;li&gt;分页怎么写&lt;/li&gt;
&lt;li&gt;模糊查询怎么做&lt;/li&gt;
&lt;li&gt;参数校验怎么做&lt;/li&gt;
&lt;li&gt;鉴权怎么做&lt;/li&gt;
&lt;li&gt;接口文档/注释怎么写&lt;/li&gt;
&lt;li&gt;异常处理怎么做&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;也就是说：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;熟悉接口，不只是为了知道系统有哪些功能，更是为了总结这个项目写接口的规范和风格，方便后续自己按照统一方式开发接口。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;看接口时重点看什么？&lt;/strong&gt;&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;li&gt;响应结构&lt;/li&gt;
&lt;li&gt;错误码&lt;/li&gt;
&lt;li&gt;分页参数&lt;/li&gt;
&lt;li&gt;是否需要登录态/鉴权&lt;/li&gt;
&lt;li&gt;这个接口会影响哪些表&lt;/li&gt;
&lt;li&gt;这个接口最终会走到哪个 Controller / Service&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;建议&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;先看 3~5 个核心接口，例如：&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;li&gt;创建接口&lt;/li&gt;
&lt;li&gt;修改接口&lt;/li&gt;
&lt;li&gt;提交 / 审核 / 支付这类关键动作接口&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;最推荐的方式&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;先看 Swagger / Knife4j / Postman&lt;/li&gt;
&lt;li&gt;再实际调一次接口&lt;/li&gt;
&lt;li&gt;最后顺着接口去看代码&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;四、如何从接口顺着去看代码？&lt;a href=&quot;#四如何从接口顺着去看代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;代码当然要看，但&lt;strong&gt;不要通读，要带着入口去看&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;最推荐的方式是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;从一个真实入口开始追。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这个入口可以是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;一个接口&lt;/li&gt;
&lt;li&gt;一个需求&lt;/li&gt;
&lt;li&gt;一个 bug&lt;/li&gt;
&lt;li&gt;一条日志&lt;/li&gt;
&lt;li&gt;一个表字段&lt;/li&gt;
&lt;/ul&gt;&lt;section&gt;&lt;h4&gt;1、最常见的看法：从接口开始追&lt;a href=&quot;#1最常见的看法从接口开始追&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;以一个创建订单接口为例：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;OrderController.createOrder()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;OrderService.createOrder()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;参数校验 / 业务校验 / 库存校验&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;OrderMapper.insert()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;写订单表、订单明细表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;返回结果&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;你要顺着这条线去看：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Controller 做了什么&lt;/li&gt;
&lt;li&gt;Service 做了什么&lt;/li&gt;
&lt;li&gt;Mapper / DAO 做了什么&lt;/li&gt;
&lt;li&gt;哪些表被查了、被改了&lt;/li&gt;
&lt;li&gt;日志打印在哪&lt;/li&gt;
&lt;li&gt;异常是怎么处理的&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、看代码时先看主干，再看细节&lt;a href=&quot;#2看代码时先看主干再看细节&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;推荐顺序：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;先看 Controller&lt;/li&gt;
&lt;li&gt;再看 Service&lt;/li&gt;
&lt;li&gt;再看 Mapper / DAO&lt;/li&gt;
&lt;li&gt;最后再看工具类、异常处理、事务、边界逻辑&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;一开始不要太纠结这些内容：&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;li&gt;边缘功能代码&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;先把主流程搞懂更重要。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、看代码时重点关注什么？&lt;a href=&quot;#3看代码时重点关注什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;优先看这些：&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;li&gt;状态流转&lt;/li&gt;
&lt;li&gt;异常处理&lt;/li&gt;
&lt;li&gt;日志打印&lt;/li&gt;
&lt;li&gt;事务边界&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、善用 IDE&lt;a href=&quot;#4善用-ide&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;熟悉项目时，IDE 是你的导航工具。&lt;/p&gt;&lt;p&gt;重点会用这些能力：&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;li&gt;全局搜索接口路径、类名、字段名&lt;/li&gt;
&lt;li&gt;打断点调试&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;五、熟悉项目时的常见误区&lt;a href=&quot;#五熟悉项目时的常见误区&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、一上来就通读全部代码&lt;a href=&quot;#1一上来就通读全部代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;这是最容易把自己看崩的方式。 正确做法是：&lt;strong&gt;先抓主线，再按需深入。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、总想一次性全懂&lt;a href=&quot;#2总想一次性全懂&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;这基本是不现实的。 项目的理解一定是循序渐进的，不可能刚接触就把所有内容全部吃透。 实际上，很多在公司待了两三年的同事，也未必对整个项目的每一个模块、每一个细节都完全了解。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、只看代码，不看业务&lt;a href=&quot;#3只看代码不看业务&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;会导致你“看得懂代码，不知道为什么这么写”。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、只看业务，不看技术栈&lt;a href=&quot;#4只看业务不看技术栈&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;这样后面一遇到 Redis、MQ、ES、注册中心、网关，就很容易发虚。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5、只看文档，不动手&lt;a href=&quot;#5只看文档不动手&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;不调接口、不打断点、不看日志，很难真正建立理解。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6、不敢问&lt;a href=&quot;#6不敢问&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;新人最大的问题往往不是不会，而是不好意思问。 实际上，很多项目里的命名、流程、历史包袱，不问根本猜不出来。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>如何写一个接口</title><link>https://study-docs-158.pages.dev/posts/%E5%A6%82%E4%BD%95%E5%86%99%E4%B8%80%E4%B8%AA%E6%8E%A5%E5%8F%A3/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%A6%82%E4%BD%95%E5%86%99%E4%B8%80%E4%B8%AA%E6%8E%A5%E5%8F%A3/</guid><description>如何写一个接口</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、什么是接口？&lt;a href=&quot;#一什么是接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、先理解MVC分层架构&lt;a href=&quot;#1先理解mvc分层架构&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;很多新人刚进公司，听到”写个接口”这个词会一脸懵。别慌，我们先搞清楚项目是怎么分层的。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户（浏览器/APP）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Controller层（接口层）  ← 你写的接口就在这里！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Service层（业务逻辑层）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Mapper/DAO层（数据访问层）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;数据库&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;/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;Controller层&lt;/td&gt;&lt;td&gt;接收请求、返回响应&lt;/td&gt;&lt;td&gt;定义接口地址、接收参数、调用Service、返回结果&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Service层&lt;/td&gt;&lt;td&gt;处理业务逻辑&lt;/td&gt;&lt;td&gt;写业务代码、事务控制&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Mapper/DAO层&lt;/td&gt;&lt;td&gt;操作数据库&lt;/td&gt;&lt;td&gt;写SQL、增删改查&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、“接口”到底是什么？&lt;a href=&quot;#2接口到底是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;此接口非彼接口（Java里的interface）。在工作中，我们说的”接口”通常指的是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Controller层里的一个方法，能够接收前端的请求，处理后将结果返回。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;一个接口就是一个URL地址 + 对应的处理方法。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /api/user/list&lt;/code&gt; - 查询用户列表&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST /api/user/add&lt;/code&gt; - 新增用户&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PUT /api/user/update&lt;/code&gt; - 修改用户&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DELETE /api/user/delete&lt;/code&gt; - 删除用户&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、新人常见的误区&lt;a href=&quot;#3新人常见的误区&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;”接口就是Java的interface”&lt;/td&gt;&lt;td&gt;工作中说的接口通常指Controller里的方法&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;tr&gt;&lt;td&gt;”我要从零开始写”&lt;/td&gt;&lt;td&gt;先看项目里已有的接口，照葫芦画瓢&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、写接口的正确姿势&lt;a href=&quot;#二写接口的正确姿势&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、写接口前先想清楚这几件事&lt;a href=&quot;#1写接口前先想清楚这几件事&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;/td&gt;&lt;td&gt;如 /api/user/list&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;请求方式是什么？&lt;/td&gt;&lt;td&gt;GET查询、POST新增、PUT修改、DELETE删除&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;tr&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;是否需要Token验证&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、写接口的基本步骤&lt;a href=&quot;#2写接口的基本步骤&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;第一步：看项目中已有的接口是怎么写的（最重要！）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;第二步：在Controller里写方法，定义接口地址和参数&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;第三步：在Service里写业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;第四步：在Mapper里写SQL&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;第五步：用Postman测试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人必看：不要一上来就自己写，先找项目中类似的接口，复制粘贴然后改！&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;重要习惯：边写边测试！&lt;/strong&gt; 不要一口气把5个接口全写完再一起测。写完查询接口就测查询，写完新增就测新增。&lt;strong&gt;写一个、测一个、通一个&lt;/strong&gt;，有问题立即发现立即修。不把问题带到后续接口的开发中！&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、常见接口类型示例&lt;a href=&quot;#三常见接口类型示例&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;提醒：下面的示例只是一般写法，不同项目的规范可能不同。实际开发时一定要参考项目中已有接口的写法来写，以项目现有规范为准！&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;1、分页查询接口（最常用）&lt;a href=&quot;#1分页查询接口最常用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Controller层：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RestController&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequestMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/api/user&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserController&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 查询用户列表（分页）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 请求方式：GET&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 接口地址：/api/user/list&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/list&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;userName&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;required&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userName&lt;/span&gt;&lt;span&gt;,  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 用户名（可选）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;phone&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;required&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;phone&lt;/span&gt;&lt;span&gt;,        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 手机号（可选）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;pageNum&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;defaultValue&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pageNum&lt;/span&gt;&lt;span&gt;,  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 页码，默认第1页&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;pageSize&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;defaultValue&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;10&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pageSize&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 每页条数，默认10条&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// Controller只负责接收参数、调用Service、返回结果，不写业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;PageInfo&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;UserVo&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;pageInfo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;(userName, phone, pageNum, pageSize);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(pageInfo);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Service层：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserMapper&lt;/span&gt;&lt;span&gt; userMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PageInfo&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;UserVo&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userName&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;phone&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pageNum&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pageSize&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 开启分页&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;PageHelper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;startPage&lt;/span&gt;&lt;span&gt;(pageNum, pageSize);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 查询数据&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;UserVo&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectList&lt;/span&gt;&lt;span&gt;(userName, phone);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 封装分页结果&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PageInfo&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;(list);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper接口：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Mapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserMapper&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 分页查询用户列表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;UserVo&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;selectList&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Param&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;userName&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userName&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Param&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;phone&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;phone&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper XML（SQL）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;UserMapper.xml&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;selectList&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.vo.UserVo&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;id, user_name, phone, email, create_time&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;FROM sys_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE deleted = 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND user_name LIKE CONCAT(&apos;%&apos;, #{userName}, &apos;%&apos;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null and phone != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND phone = #{phone}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ORDER BY create_time DESC&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人注意：&lt;code&gt;&amp;lt;if&amp;gt;&lt;/code&gt; 标签用于动态SQL，参数为空时不会拼接该条件，这样查询就是”查全部”。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&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;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;@RequestParam&lt;/td&gt;&lt;td&gt;接收URL后面的参数，如 /list?userName=张三&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;required = false&lt;/td&gt;&lt;td&gt;表示这个参数可以不传&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;defaultValue = “1”&lt;/td&gt;&lt;td&gt;不传参数时的默认值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;@Param&lt;/td&gt;&lt;td&gt;Mapper接口中用@Param给参数起别名，XML里才能用#{userName}引用&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;resultType&lt;/td&gt;&lt;td&gt;指定返回结果的类型，指向你的Vo类的全限定名&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;参数太多怎么办？用实体类接收：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/list&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserQueryVo&lt;/span&gt;&lt;span&gt; query) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;PageHelper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;startPage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;query&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getPageNum&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;query&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getPageSize&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;UserVo&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; list &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;(query);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;PageInfo&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;UserVo&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; pageInfo &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PageInfo&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span&gt;(list)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(pageInfo);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;接收参数的实体类：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserQueryVo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; userName&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 用户名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; phone&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 手机号&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; pageNum &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 页码，默认1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; pageSize &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 每页条数，默认10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、新增接口&lt;a href=&quot;#2新增接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;2.1 单表新增（简单场景）&lt;a href=&quot;#21-单表新增简单场景&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;Controller层：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 新增用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 请求方式：POST&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 接口地址：/api/user/add&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/add&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDto&lt;/span&gt;&lt;span&gt; userDto) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(userDto);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;新增成功&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Service层：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserMapper&lt;/span&gt;&lt;span&gt; userMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Transactional&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 加事务，保证数据一致性&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;UserDto&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userDto&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 参数校验&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;StringUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;userDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserName&lt;/span&gt;&lt;span&gt;())) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;用户名不能为空&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 检查用户名是否已存在&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;existUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectByUserName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;userDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserName&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (existUser &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;用户名已存在&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 3. 设置创建时间等默认值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;userDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setCreateTime&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;userDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setDeleted&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 4. 保存到数据库&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(userDto);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper接口：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Mapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserMapper&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 根据用户名查询（用于检查用户名是否已存在）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;selectByUserName&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;Param&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;userName&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userName&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 新增用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;UserDto&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userDto&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper XML（SQL）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;selectByUserName&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.entity.User&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT id, user_name, phone, email&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;FROM sys_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE user_name = #{userName}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND deleted = 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;insert&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parameterType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.dto.UserDto&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;useGeneratedKeys&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;true&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;keyProperty&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;INSERT INTO sys_user (user_name, phone, email, create_time, deleted)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;VALUES (#{userName}, #{phone}, #{email}, #{createTime}, #{deleted})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人注意：&lt;code&gt;useGeneratedKeys=&quot;true&quot; keyProperty=&quot;id&quot;&lt;/code&gt; 表示插入后MyBatis会自动把数据库生成的主键id回写到userDto的id属性中，后续可以直接用&lt;code&gt;userDto.getId()&lt;/code&gt;获取。需要注意的是，如果表没有设置主键自增，则需要手动设置主键值，此时不需要配置&lt;code&gt;useGeneratedKeys&lt;/code&gt;。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.2 主子表新增（进阶场景）&lt;a href=&quot;#22-主子表新增进阶场景&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;blockquote&gt;&lt;p&gt;实际项目中经常会遇到&lt;strong&gt;主子表&lt;/strong&gt;的情况，比如：订单（主表）+ 订单明细（子表）。新增时需要先插主表拿到主键id，再把主键id设置到子表的关联字段上，然后插入子表。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;场景：新增订单，同时新增订单下的多个商品明细&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;订单表（主表）order_info          订单明细表（子表）order_item&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;┌────┬──────────┐                ┌────┬──────────┬──────────────┐&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│ id │ order_no │                │ id │ order_id │ product_name │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├────┼──────────┤                ├────┼──────────┼──────────────┤&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│ 1  │ OD001    │  ←────关联────  │ 1  │ 1        │ 手机         │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│    │          │                │ 2  │ 1        │ 耳机         │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;└────┴──────────┘                └────┴──────────┴──────────────┘&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                                    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;order_id关联主表的id&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;接收参数的DTO：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDto&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; orderNo&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;                 &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 订单号&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BigDecimal&lt;/span&gt;&lt;span&gt; totalPrice&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 总金额&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;OrderItemDto&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; itemList&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 订单明细列表（子表数据）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderItemDto&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; productName&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 商品名称&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; quantity&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 数量&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BigDecimal&lt;/span&gt;&lt;span&gt; price&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 单价&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;前端传入的JSON示例：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;orderNo&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;OD001&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;totalPrice&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;5999.00&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;itemList&quot;&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;productName&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;手机&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;quantity&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;4999.00&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;productName&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;耳机&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;quantity&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;500.00&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Service层（核心逻辑）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderMapper&lt;/span&gt;&lt;span&gt; orderMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderItemMapper&lt;/span&gt;&lt;span&gt; orderItemMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Transactional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;OrderDto&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;orderDto&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 参数校验&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;StringUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;orderDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getOrderNo&lt;/span&gt;&lt;span&gt;())) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;订单号不能为空&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;CollectionUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;orderDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getItemList&lt;/span&gt;&lt;span&gt;())) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;订单明细不能为空&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 设置默认值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;orderDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setCreateTime&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 3. 先插入主表（订单）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(orderDto);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 插入后 orderDto.getId() 就有值了（因为配置了 useGeneratedKeys）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 4. 遍历子表数据，设置主表id后插入子表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;OrderItemDto&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;orderDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getItemList&lt;/span&gt;&lt;span&gt;()) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setOrderId&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;orderDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;());  &lt;/span&gt;&lt;span&gt;// 关键：把主表id设到子表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setCreateTime&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;orderItemMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(item);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper接口：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Mapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderMapper&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;OrderDto&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;orderDto&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Mapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderItemMapper&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;OrderItemDto&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;itemDto&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper XML（SQL）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;OrderMapper.xml&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;insert&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parameterType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.dto.OrderDto&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;useGeneratedKeys&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;true&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;keyProperty&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;INSERT INTO order_info (order_no, total_price, create_time)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;VALUES (#{orderNo}, #{totalPrice}, #{createTime})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- OrderItemMapper.xml --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;insert&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parameterType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.dto.OrderItemDto&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;useGeneratedKeys&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;true&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;keyProperty&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;INSERT INTO order_item (order_id, product_name, quantity, price, create_time)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;VALUES (#{orderId}, #{productName}, #{quantity}, #{price}, #{createTime})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人注意：主子表新增的关键点：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;主表的insert必须配置 &lt;code&gt;useGeneratedKeys=&quot;true&quot; keyProperty=&quot;id&quot;&lt;/code&gt;，插入后主键id会自动回写&lt;/li&gt;
&lt;li&gt;循环子表数据时，用 &lt;code&gt;主表对象.getId()&lt;/code&gt; 设置子表的关联字段&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;必须加 &lt;code&gt;@Transactional&lt;/code&gt;&lt;/strong&gt;，主表和子表要么全成功要么全回滚，不然会出现主表有数据但子表没数据的情况&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、修改接口&lt;a href=&quot;#3修改接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Controller层：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 修改用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 请求方式：PUT&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 接口地址：/api/user/update&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PutMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/update&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDto&lt;/span&gt;&lt;span&gt; userDto) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;(userDto);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;修改成功&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Service层：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;UserDto&lt;/span&gt;&lt;span&gt; userDto) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 1. 检查用户是否存在&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; user &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;userDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (user &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;用户不存在&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 2. 更新数据&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userDto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setUpdateTime&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;updateById&lt;/span&gt;&lt;span&gt;(userDto);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper接口：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 在UserMapper中添加&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;selectById&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Param&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt; id)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;updateById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;UserDto&lt;/span&gt;&lt;span&gt;&lt;span&gt; userDto)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper XML（SQL）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;selectById&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.entity.User&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT id, user_name, phone, email&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;FROM sys_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE id = #{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND deleted = 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;updateById&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parameterType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.dto.UserDto&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;UPDATE sys_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;userName != null and userName != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;user_name = #{userName},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;phone != null and phone != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;phone = #{phone},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;email != null and email != &apos;&apos;&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;email = #{email},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;update_time = #{updateTime},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE id = #{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AND deleted = 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人注意：&lt;code&gt;&amp;lt;set&amp;gt;&lt;/code&gt; 标签会自动去掉最后一个多余的逗号，比手动拼SET语句更安全，且只更新非空的字段。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、删除接口&lt;a href=&quot;#4删除接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;单个删除：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 删除用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 请求方式：DELETE&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 接口地址：/api/user/delete/{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DeleteMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/delete/{id}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;PathVariable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; id) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deleteById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;删除成功&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;批量删除（更常用）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 批量删除用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 请求方式：DELETE&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 接口地址：/api/user/delete?ids=1,2,3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DeleteMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/delete&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;ids&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; ids) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// ids = &quot;1,2,3&quot; 需要转成列表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; idList &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Arrays&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stream&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ids&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;split&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(String&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;trim)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(Integer&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;parseInt)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;collect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Collectors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toList&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deleteByIds&lt;/span&gt;&lt;span&gt;(idList);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;删除成功&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Service层（删除相关方法）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deleteById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; id) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 建议用逻辑删除，而不是物理删除&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;logicDeleteById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deleteByIds&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; idList) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;logicDeleteByIds&lt;/span&gt;&lt;span&gt;(idList);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper接口：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 在UserMapper中添加&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;logicDeleteById&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Param&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt; id)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;logicDeleteByIds&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Param&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;idList&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; idList)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper XML（SQL）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;logicDeleteById&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;UPDATE sys_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SET deleted = 1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE id = #{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;logicDeleteByIds&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;UPDATE sys_user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SET deleted = 1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE id IN&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;idList&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;(&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;separator&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;,&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;close&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;)&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;#{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;foreach&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）正式项目中推荐使用&lt;/strong&gt;逻辑删除**（把&lt;code&gt;deleted&lt;/code&gt;字段设为1），而不是&lt;code&gt;DELETE FROM&lt;/code&gt;物理删除。逻辑删除的数据可以恢复，也不会影响关联数据。&lt;code&gt;&amp;lt;foreach&amp;gt;&lt;/code&gt; 标签用于遍历集合，自动拼接&lt;code&gt;IN (1, 2, 3)&lt;/code&gt;。&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;2）&lt;code&gt;DELETE&lt;/code&gt;请求在某些服务器或Nginx配置下可能会被禁用&lt;/strong&gt;（出于安全考虑）。如果遇到DELETE请求返回405或被拦截，可以改成用&lt;code&gt;POST&lt;/code&gt;请求来代替删除操作，具体以项目现有规范为准。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、详情查询接口（一对多关联查询）&lt;a href=&quot;#5详情查询接口一对多关联查询&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;实际项目中，详情查询经常需要关联查询子表数据。比如：查订单详情，需要同时返回订单基本信息和订单下的商品明细列表。下面用MyBatis的&lt;code&gt;&amp;lt;resultMap&amp;gt;&lt;/code&gt; + &lt;code&gt;&amp;lt;collection&amp;gt;&lt;/code&gt;实现一对多映射，&lt;strong&gt;一条SQL&lt;/strong&gt;搞定。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;场景：根据订单id查询订单详情，包含订单基本信息 + 商品明细列表&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;数据库字段（下划线命名）            Java实体类字段（驼峰命名）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;─────────────────────            ─────────────────────&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;order_info表：                    OrderDetailVo：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;order_no        ──映射──→         orderNo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;total_price     ──映射──→         totalPrice&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;create_time     ──映射──→         createTime&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;order_item表：                    OrderItemVo：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;order_id        ──映射──→         orderId&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;product_name    ──映射──→         productName&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;数据库字段用下划线命名（如 &lt;code&gt;order_no&lt;/code&gt;），Java实体类用驼峰命名（如 &lt;code&gt;orderNo&lt;/code&gt;），需要在&lt;code&gt;&amp;lt;resultMap&amp;gt;&lt;/code&gt;中用&lt;code&gt;&amp;lt;result&amp;gt;&lt;/code&gt;标签做映射，或者在&lt;code&gt;application.yml&lt;/code&gt;中配置&lt;code&gt;map-underscore-to-camel-case: true&lt;/code&gt;开启全局自动驼峰转换。下面演示手动映射的方式，让你清楚了解映射关系。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;返回的Vo：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDetailVo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;                      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 订单id&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; orderNo&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;                  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 订单号&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BigDecimal&lt;/span&gt;&lt;span&gt; totalPrice&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 总金额&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt; createTime&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;                 &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 下单时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;OrderItemVo&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; itemList&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 订单明细列表（一对多）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderItemVo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 明细id&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; orderId&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;         &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 关联的订单id&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; productName&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 商品名称&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; quantity&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 数量&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BigDecimal&lt;/span&gt;&lt;span&gt; price&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 单价&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;返回数据示例：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;code&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;200&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;message&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;操作成功&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;data&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;orderNo&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;OD001&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;totalPrice&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;5999.00&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;createTime&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;2026-05-07 10:30:00&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;itemList&quot;&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;orderId&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;productName&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;手机&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;quantity&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;4999.00&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;orderId&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;productName&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;耳机&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;quantity&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;500.00&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Controller层：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 查询订单详情&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 请求方式：GET&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 接口地址：/api/order/detail/{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/detail/{id}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;detail&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;PathVariable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; id) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;OrderDetailVo&lt;/span&gt;&lt;span&gt; order &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getDetailById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Service层：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderMapper&lt;/span&gt;&lt;span&gt; orderMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDetailVo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getDetailById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;OrderDetailVo&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectDetailById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (order &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;订单不存在&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; order;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper接口：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Mapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderMapper&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 一条SQL查询订单详情（主表+子表），MyBatis自动通过resultMap组装&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;OrderDetailVo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;selectDetailById&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;Param&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mapper XML（SQL）—— 重点：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;OrderMapper.xml&lt;/span&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 1. 先定义主表的resultMap --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;resultMap&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;OrderDetailResultMap&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.vo.OrderDetailVo&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&amp;lt;!-- 主表字段映射：column=数据库字段名，property=Vo属性名 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;order_no&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;orderNo&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;total_price&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;totalPrice&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;create_time&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;createTime&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&amp;lt;!-- 一对多映射：用collection标签关联子表数据 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;itemList&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ofType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.vo.OrderItemVo&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&amp;lt;!-- 子表字段映射 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;item_id&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;order_id&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;orderId&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;product_name&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;productName&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;quantity&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;quantity&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;column&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;price&quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;collection&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;resultMap&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 2. 查询语句：主表LEFT JOIN子表，一条SQL查出所有数据 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;selectDetailById&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultMap&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;OrderDetailResultMap&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SELECT&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;o.id,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;o.order_no,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;o.total_price,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;o.create_time,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;i.id          AS item_id,       -- 子表id取别名，避免和主表id冲突&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;i.order_id,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;i.product_name,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;i.quantity,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;i.price&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;FROM order_info o&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;LEFT JOIN order_item i ON o.id = i.order_id&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WHERE o.id = #{id}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ORDER BY i.id ASC&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;resultMap&amp;gt;&lt;/code&gt; 中的 &lt;code&gt;column&lt;/code&gt; 是数据库字段名（下划线），&lt;code&gt;property&lt;/code&gt; 是Java属性名（驼峰），MyBatis会自动按这个规则映射，不需要你手动转换&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;collection&amp;gt;&lt;/code&gt; 标签用来映射一对多关系，&lt;code&gt;property&lt;/code&gt; 对应Vo中的List字段名，&lt;code&gt;ofType&lt;/code&gt; 指定List中每个元素的类型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主表和子表都有&lt;code&gt;id&lt;/code&gt;字段时，子表的id必须取别名&lt;/strong&gt;（如 &lt;code&gt;AS item_id&lt;/code&gt;），否则&lt;code&gt;&amp;lt;resultMap&amp;gt;&lt;/code&gt;会分不清哪个是主表的、哪个是子表的，导致数据错乱&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;LEFT JOIN&lt;/code&gt; 而不是 &lt;code&gt;INNER JOIN&lt;/code&gt;，这样即使订单没有明细也能返回订单基本信息&lt;/li&gt;
&lt;li&gt;如果项目配置了 &lt;code&gt;map-underscore-to-camel-case: true&lt;/code&gt;，可以不用写&lt;code&gt;&amp;lt;result&amp;gt;&lt;/code&gt;标签，但&lt;strong&gt;主子表id冲突的问题仍然需要取别名处理&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、Mapper层核心知识&lt;a href=&quot;#四mapper层核心知识&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、Mapper接口和XML的关系&lt;a href=&quot;#1mapper接口和xml的关系&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Mapper接口（Java）          Mapper XML（SQL）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;┌──────────────────┐      ┌──────────────────────┐&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│ selectById(id)   │ ──→  │ &amp;lt;select id=&quot;selectById&quot;&amp;gt; │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│ insert(user)     │ ──→  │ &amp;lt;insert id=&quot;insert&quot;&amp;gt;     │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│ updateById(user) │ ──→  │ &amp;lt;update id=&quot;updateById&quot;&amp;gt;  │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│ deleteById(id)   │ ──→  │ &amp;lt;delete id=&quot;deleteById&quot;&amp;gt;  │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;└──────────────────┘      └──────────────────────┘&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;核心规则：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Mapper接口的&lt;strong&gt;方法名&lt;/strong&gt;必须和XML中的&lt;strong&gt;id&lt;/strong&gt;一致&lt;/li&gt;
&lt;li&gt;XML文件放在 &lt;code&gt;resources/mapper/&lt;/code&gt; 目录下&lt;/li&gt;
&lt;li&gt;XML的 &lt;code&gt;namespace&lt;/code&gt; 必须指向Mapper接口的全限定名&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- UserMapper.xml 头部 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;?&lt;/span&gt;&lt;span&gt;xml&lt;/span&gt;&lt;span&gt; version&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span&gt; encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!&lt;/span&gt;&lt;span&gt;DOCTYPE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mapper&lt;/span&gt;&lt;span&gt; PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;mapper&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;com.example.mapper.UserMapper&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&amp;lt;!-- 你的SQL写在这里 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;mapper&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、常用MyBatis动态SQL标签&lt;a href=&quot;#2常用mybatis动态sql标签&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;示例场景&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;条件判断，满足才拼接&lt;/td&gt;&lt;td&gt;参数不为空时加WHERE条件&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;自动处理WHERE和AND&lt;/td&gt;&lt;td&gt;动态拼接查询条件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;遍历集合，拼IN语句&lt;/td&gt;&lt;td&gt;批量删除 IN (1,2,3)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;多条件分支（类似if-else）&lt;/td&gt;&lt;td&gt;多种排序方式&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、&lt;code&gt;#{}&lt;/code&gt; 和 &lt;code&gt;${}&lt;/code&gt; 的区别（面试常考）&lt;a href=&quot;#3-和--的区别面试常考&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- #{} 推荐！预编译处理，防SQL注入 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;WHERE user_name = #{userName}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 实际执行：WHERE user_name = ?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- ${} 字符串拼接，有SQL注入风险，尽量少用 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;WHERE user_name = &apos;${userName}&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 实际执行：WHERE user_name = &apos;张三&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- ${} 的使用场景：动态表名、动态列名（不能用#{}的情况） --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ORDER BY ${orderColumn} ${orderDir}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;新人记住：99%的情况用 &lt;code&gt;#{}&lt;/code&gt; 就对了，只有动态表名/列名才用 &lt;code&gt;${}&lt;/code&gt;。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、参数接收方式详解&lt;a href=&quot;#五参数接收方式详解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、@RequestParam - 接收URL参数&lt;a href=&quot;#1requestparam---接收url参数&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 请求：GET /api/user/list?name=张三&amp;amp;pageNum=1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/list&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; name&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;pageNum&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;defaultValue&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; pageNum&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、@PathVariable - 接收路径参数&lt;a href=&quot;#2pathvariable---接收路径参数&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 请求：GET /api/user/detail/123&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/detail/{id}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;detail&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;PathVariable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; id) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// id = 123&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、@RequestBody - 接收JSON格式参数&lt;a href=&quot;#3requestbody---接收json格式参数&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 请求：POST /api/user/add&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// Body: {&quot;userName&quot;:&quot;张三&quot;,&quot;phone&quot;:&quot;13800138000&quot;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/add&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDto&lt;/span&gt;&lt;span&gt; userDto) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// userDto.getUserName() = &quot;张三&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、返回结果封装&lt;a href=&quot;#六返回结果封装&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、统一的返回格式&lt;a href=&quot;#1统一的返回格式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; code&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 状态码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 提示信息&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt; data&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 返回数据&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 成功&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;200&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setMessage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;操作成功&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setData&lt;/span&gt;&lt;span&gt;(data);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; result;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 失败&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setCode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;500&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setMessage&lt;/span&gt;&lt;span&gt;(message);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; result;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、返回示例&lt;a href=&quot;#2返回示例&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;成功：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;code&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;200&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;message&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;操作成功&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;data&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;userId&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;userName&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;张三&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;失败：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;code&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;500&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;message&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;用户名已存在&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;data&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、新人避坑指南&lt;a href=&quot;#七新人避坑指南&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、常见错误&lt;a href=&quot;#1常见错误&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;/td&gt;&lt;td&gt;按项目规范来，参考已有接口&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;请求方式用错&lt;/td&gt;&lt;td&gt;查询用GET、新增用POST、修改用PUT、删除用DELETE&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;参数接收不到&lt;/td&gt;&lt;td&gt;检查注解是否正确：@RequestParam、@RequestBody、@PathVariable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;没加事务&lt;/td&gt;&lt;td&gt;多表操作一定要加 @Transactional&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;/section&gt;&lt;section&gt;&lt;h3&gt;2、Integer类型判空的坑&lt;a href=&quot;#2integer类型判空的坑&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 错误：Integer类型不能用 != &quot;&quot; 判断&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (userId &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; userId &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt;) {  &lt;/span&gt;&lt;span&gt;// 编译报错！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 正确：Integer只判断是否为null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (userId &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 字符串才需要判断空&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;StringUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isNotEmpty&lt;/span&gt;&lt;span&gt;&lt;span&gt;(userName)&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、批量插入性能问题&lt;a href=&quot;#3批量插入性能问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 错误：循环调用单条插入，效率很低&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; user &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; userList) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(user);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 正确：使用批量插入&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insertBatch&lt;/span&gt;&lt;span&gt;(userList);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;八、终极大法&lt;a href=&quot;#八终极大法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;不会写？看项目里已有的接口是怎么写的，Ctrl+C、Ctrl+V，然后改一改！&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h3&gt;步骤：&lt;a href=&quot;#步骤&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;找一个类似的接口（比如要写用户查询，就找其他查询接口）&lt;/li&gt;
&lt;li&gt;复制Controller、Service、Mapper的代码&lt;/li&gt;
&lt;li&gt;改接口地址、改参数、改业务逻辑&lt;/li&gt;
&lt;li&gt;用Postman测试&lt;/li&gt;
&lt;li&gt;没问题就提交&lt;/li&gt;
&lt;/ol&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;记住：工作中的代码，大部分是”改”出来的，不是”写”出来的。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;九、写完接口后要做什么？&lt;a href=&quot;#九写完接口后要做什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;自己先测试&lt;/strong&gt;：用Postman或Apifox测试接口是否正常&lt;/li&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;li&gt;&lt;strong&gt;看日志&lt;/strong&gt;：检查是否有异常日志&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更新接口文档&lt;/strong&gt;：如果有要求，更新Swagger或接口文档&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;十、注意事项&lt;a href=&quot;#十注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;参考项目中已有的接口写法&lt;/strong&gt;，不要自己创造新风格&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多表操作要加事务&lt;/strong&gt; &lt;code&gt;@Transactional&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;批量插入不要超过5000条&lt;/strong&gt;，太多要分批处理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integer类型判空不要加非空字符串判断&lt;/strong&gt;&lt;/li&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;/ol&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;十一、常见报错及解决方法&lt;a href=&quot;#十一常见报错及解决方法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;写接口时报错了别慌，大部分都是常见问题，对照下面的表排查就行，也可以直接百度或者交给ai分析。&lt;/p&gt;&lt;/blockquote&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;Required request body is missing&lt;/td&gt;&lt;td&gt;Controller方法的参数没加@RequestBody&lt;/td&gt;&lt;td&gt;POST/PUT请求用JSON传参时，参数前必须加@RequestBody&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Parameter ‘id’ not found&lt;/td&gt;&lt;td&gt;@PathVariable的名字和路径里的占位符不一致&lt;/td&gt;&lt;td&gt;路径是{id}，注解就写@PathVariable(“id”)，两边名字要一样&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Invalid bound statement (not found)&lt;/td&gt;&lt;td&gt;Mapper XML没被扫描到&lt;/td&gt;&lt;td&gt;1. 检查XML的namespace是否和Mapper接口全限定名一致 2. 检查XML的id是否和接口方法名一致 3. 检查XML文件是否放在正确的目录下（如resources/mapper/） 4. 检查application.yml中mybatis.mapper-locations配置路径是否正确&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Unknown column ‘xxx’&lt;/td&gt;&lt;td&gt;SQL里写的字段名在数据库表中不存在&lt;/td&gt;&lt;td&gt;检查数据库表结构，确认字段名是否正确，注意下划线命名和驼峰命名的对应&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Bad SQL Grammar&lt;/td&gt;&lt;td&gt;SQL语法写错了&lt;/td&gt;&lt;td&gt;打开控制台看完整的SQL语句，复制到Navicat里执行排查&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;No serializer found for class&lt;/td&gt;&lt;td&gt;返回的对象没有getter方法&lt;/td&gt;&lt;td&gt;实体类加上@Data注解（Lombok）或者手动写getter/setter&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Request method ‘POST’ not supported&lt;/td&gt;&lt;td&gt;请求方式和Controller定义的不匹配&lt;/td&gt;&lt;td&gt;Controller用的是@GetMapping，前端却用了POST请求，改成一致的就行&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Ambiguous mapping&lt;/td&gt;&lt;td&gt;接口地址重复了&lt;/td&gt;&lt;td&gt;两个方法用了相同的URL和请求方式，改掉其中一个的地址&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;NullPointerException&lt;/td&gt;&lt;td&gt;空指针，某个对象是null却调用了它的方法&lt;/td&gt;&lt;td&gt;重点检查：①Service有没有加@Service ②@Autowired有没有加 ③Mapper查询结果是否为null但没有判空&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HttpMessageNotReadableException&lt;/td&gt;&lt;td&gt;前端传的JSON格式不对&lt;/td&gt;&lt;td&gt;检查JSON的字段名是否和DTO的属性名一致，JSON格式是否合法（多余逗号、缺少引号等）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;</content:encoded></item><item><title>入职后初次写代码该注意什么</title><link>https://study-docs-158.pages.dev/posts/%E5%85%A5%E8%81%8C%E5%90%8E%E5%88%9D%E6%AC%A1%E5%86%99%E4%BB%A3%E7%A0%81%E8%AF%A5%E6%B3%A8%E6%84%8F%E4%BB%80%E4%B9%88/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%85%A5%E8%81%8C%E5%90%8E%E5%88%9D%E6%AC%A1%E5%86%99%E4%BB%A3%E7%A0%81%E8%AF%A5%E6%B3%A8%E6%84%8F%E4%BB%80%E4%B9%88/</guid><description>入职后初次写代码该注意什么</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、务必在正确的 Git 分支上开发&lt;a href=&quot;#一务必在正确的-git-分支上开发&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;开始编码前，第一件事是确认你所在的分支。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;切勿直接在默认主分支（如 main/master）上修改代码。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;要问清楚：该在什么分支开发、是否需要新建分支、如果需要新建分支基于哪个分支新建。 如果不确认就写代码，后面可能要返工甚至造成代码冲突。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、务必确保需求已经理解清楚&lt;a href=&quot;#二务必确保需求已经理解清楚&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;在动手写任何代码之前，确保你对需求的理解与产品、测试、导师的理解完全一致。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;具体做法：&lt;/strong&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;blockquote&gt;&lt;p&gt;不要没搞清楚需求就开始写代码，这样很容易返工。&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、边写边测，不要一次性写完再去测试&lt;a href=&quot;#三边写边测不要一次性写完再去测试&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;如果一项功能需要开发 10 个接口，切忌全部写完再统一测试。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;每完成一个接口，就立即进行自测&lt;/strong&gt;（使用 Postman、Swagger 或单元测试）。这样可以把问题提前暴露出来，避免把问题带到后面的接口开发中。&lt;/p&gt;&lt;p&gt;一次性写完再测，如果出了问题，排查起来会非常痛苦。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、推荐采用”自上而下”的编写顺序&lt;a href=&quot;#四推荐采用自上而下的编写顺序&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;建议从**接口层（Controller）&lt;strong&gt;开始写，明确接口的入参、出参。再到&lt;/strong&gt;业务层（Service）&lt;strong&gt;编写逻辑，此时仅定义你真正需要的实体类和 DAO 方法。最后才到&lt;/strong&gt;数据层（Mapper/DAO）**实现具体数据库操作。&lt;/p&gt;&lt;p&gt;这种方式能有效避免提前过度设计，确保每一行代码都服务于明确的业务需求。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;如果从 DAO 层开始写，可能会定义很多没有用的方法和实体类，浪费过多的时间。&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、合理使用 AI，让它成为你的”副驾驶”而非”代驾”&lt;a href=&quot;#五合理使用-ai让它成为你的副驾驶而非代驾&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;对于刚入行的同学，在使用 AI 辅助编程时，需注意方法，避免过度依赖。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;不要将完整的需求描述直接丢给 AI 并期望它生成最终代码&lt;/strong&gt;，这容易导致生成的代码结构混乱、不符合业务上下文，且后期调试和修改会异常困难。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;建议采用”分段提问，主动把控”的策略：&lt;/strong&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;：对 AI 给出的代码，务必逐行理解其逻辑和意图，确保你知其所以然。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手动验证与调试&lt;/strong&gt;：AI 生成的代码可能存在边界错误或性能隐患，关键部分一定要亲自测试、调试，并将其融入你整体的代码框架中。&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;**AI 是强大的辅助工具，而非替代你思考的”代驾”。**合理使用能提升效率，过度依赖则会阻碍你真正理解业务、积累解决问题的能力。保持主动思考，让 AI 为你的思路服务，而不是被它的输出牵着走。&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、编码常犯问题&lt;a href=&quot;#六编码常犯问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;以下列出入职新人最常犯的几个编码问题，一定要注意避免。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、for 循环里面不要有数据库操作&lt;a href=&quot;#1for-循环里面不要有数据库操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;for 循环里面进行数据库操作，循环次数越多，性能下降越严重，最终可能导致接口超时或拖垮数据库。&lt;/p&gt;&lt;p&gt;一般都是用空间换时间：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;对于查询操作，提前把需要的数据查询出来&lt;/li&gt;
&lt;li&gt;对于修改操作，可以批量进行修改&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、不要使用 System.out.println 打印日志&lt;a href=&quot;#2不要使用-systemoutprintln-打印日志&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;这种打印日志只适合本地调试的时候使用。&lt;/p&gt;&lt;p&gt;真正上线或者提交代码到远程仓库的时候，一定要把这种打印日志注释掉。因为它是同步输出到控制台，会阻塞主线程，并且无法按级别过滤、归档或收集到日志中心。&lt;/p&gt;&lt;p&gt;正式项目中应该使用日志框架（如 &lt;code&gt;@Slf4j&lt;/code&gt;）来打印日志。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、不要使用魔法数字/字符串&lt;a href=&quot;#3不要使用魔法数字字符串&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;直接在代码中写数字或字符串，可读性会很差，修改的时候还需要全局搜索，很容易出错。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;错误的写法：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 7 和 &quot;SUCCESS&quot; 是什么，可读性和可维护性都比较差&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getStatus&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;SUCCESS&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;正确的写法：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 定义枚举&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;enum&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderStatus&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;COMPLETED&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;已完成&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getStatus&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;OrderStatus&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;COMPLETED&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getCode&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ResultEnum&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SUCCESS&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getMessage&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、使用事务注解的方法里用 try-catch 把数据库操作包住了&lt;a href=&quot;#4使用事务注解的方法里用-try-catch-把数据库操作包住了&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Spring 事务注解的回滚是通过捕捉异常来回滚的，如果你使用了 try-catch 把异常捕捉掉了，就无法回滚了。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Transactional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;updateOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; order) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 数据库操作1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;accountService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deductBalance&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getAmount&lt;/span&gt;&lt;span&gt;&lt;span&gt;());&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 数据库操作2，可能抛异常&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;更新失败&quot;&lt;/span&gt;&lt;span&gt;, e);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 异常被捕获，事务标记为成功，即使扣款失败，订单状态也已被更新！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、忽视空指针异常&lt;a href=&quot;#5忽视空指针异常&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;对任何可能为 &lt;code&gt;null&lt;/code&gt; 的对象（特别是方法参数、查询返回值）进行判空处理，否则很容易出现空指针异常。&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getOrderDetail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;orderId&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 直接调用，查询结果可能为 null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderRepository&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;findById&lt;/span&gt;&lt;span&gt;(orderId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 直接转换，可能 NPE&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;convertToDTO&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; dto; &lt;/span&gt;&lt;span&gt;// 如果 order 为 null，convertToDTO 内部可能 NPE&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;convertToDTO&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setOrderId&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;()); &lt;/span&gt;&lt;span&gt;// 如果 order 为 null，这里 NPE&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setAmount&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getTotalAmount&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setItems&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getItems&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;stream&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;// 如果 getItems() 返回 null，这里 NPE&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;convertItem)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;collect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Collectors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toList&lt;/span&gt;&lt;span&gt;()));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; dto;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6、集合遍历删除元素方式不对，导致 ConcurrentModificationException&lt;a href=&quot;#6集合遍历删除元素方式不对导致-concurrentmodificationexception&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在对集合进行迭代时，如果直接修改集合（添加或删除元素），会抛出 &lt;code&gt;ConcurrentModificationException&lt;/code&gt;。这在单线程环境下也可能发生。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;错误的写法：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 遍历时删除元素会抛出异常&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; list &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ArrayList&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Arrays&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;asList&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;A&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;B&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;C&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; item &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; list) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;&quot;B&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;&lt;span&gt;(item)&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;remove&lt;/span&gt;&lt;span&gt;&lt;span&gt;(item);&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 抛出 ConcurrentModificationException!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;正确的写法：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Iterator&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; iterator &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;iterator&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;iterator&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;hasNext&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; item &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;iterator&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;next&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;&quot;B&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;&lt;span&gt;(item)&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;iterator&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;remove&lt;/span&gt;&lt;span&gt;&lt;span&gt;();&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 安全删除&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>入职前需要纠正的认知误区</title><link>https://study-docs-158.pages.dev/posts/%E5%85%A5%E8%81%8C%E5%89%8D%E9%9C%80%E8%A6%81%E7%BA%A0%E6%AD%A3%E7%9A%84%E8%AE%A4%E7%9F%A5%E8%AF%AF%E5%8C%BA/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%85%A5%E8%81%8C%E5%89%8D%E9%9C%80%E8%A6%81%E7%BA%A0%E6%AD%A3%E7%9A%84%E8%AE%A4%E7%9F%A5%E8%AF%AF%E5%8C%BA/</guid><description>入职前需要纠正的认知误区</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h3&gt;一、为什么需要转变认知？&lt;a href=&quot;#一为什么需要转变认知&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;很多新人在入职前，技术不一定是最大的问题。 真正容易拖垮一个人的，往往是&lt;strong&gt;错误的认知和心态&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;因为一旦认知没有转过来，入职之后你很容易出现下面这些状态：&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;li&gt;别人说什么就信什么，缺乏基本的判断和验证意识&lt;/li&gt;
&lt;li&gt;明明可以通过查资料、看日志、读代码解决的问题，却总觉得这样做“显得自己很弱”&lt;/li&gt;
&lt;li&gt;不敢主动推进工作，习惯等别人告诉你下一步该做什么&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这些问题表面上看是情绪问题， 但本质上，它们会直接影响你的工作表现。&lt;/p&gt;&lt;p&gt;轻一点，你会进入一种持续慌乱、低效、容易否定自己的状态； 重一点，你会在试用期里长期没有存在感、没有产出、没有成长，最后很难顺利通过考核。&lt;/p&gt;&lt;p&gt;所以，&lt;strong&gt;入职前最先要调整的，不只是技术，而是认知&lt;/strong&gt;&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;二、关于”程序员能力”的认知&lt;a href=&quot;#二关于程序员能力的认知&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、不要把所有程序员都想得很厉害&lt;a href=&quot;#1不要把所有程序员都想得很厉害&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见认知：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;只要是在公司里上班的程序员，肯定都特别厉害。&lt;/p&gt;&lt;/blockquote&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;/th&gt;&lt;th&gt;真实情况&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/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;p&gt;&lt;strong&gt;更合理的认知：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;行业里有很厉害的人，也有能力一般的人，大家的水平差异其实很大。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这样你既不会过度自卑，也不会对别人产生不切实际的幻想。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、不要认为厉害的程序员什么都不用查&lt;a href=&quot;#2不要认为厉害的程序员什么都不用查&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见认知：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;厉害的程序员是不是一遇到问题，什么都不用查，什么技术都张口就来？&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;实际情况：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;哪怕是经验丰富的程序员，也离不开：&lt;/p&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;/td&gt;&lt;td&gt;快速找到类似问题的解决方案&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;官方文档&lt;/td&gt;&lt;td&gt;确认API的正确用法&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;AI 工具&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;tr&gt;&lt;td&gt;社区经验&lt;/td&gt;&lt;td&gt;CSDN、掘金等&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;真正有经验的程序员，不是”什么都不用查”，而是：&lt;/strong&gt;&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;li&gt;知道怎么结合项目现有代码落地&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：厉害的程序员，不是不用查资料，而是更会查资料。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、不要认为别人写代码很快是因为技术特别强&lt;a href=&quot;#3不要认为别人写代码很快是因为技术特别强&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见认知：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;看到同事写代码很快，就觉得对方技术特别强，自己差太远。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;实际情况：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;很多时候写代码快，是因为：&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;li&gt;对方不需要重新理解业务&lt;/li&gt;
&lt;/ul&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;/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;tr&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;&lt;strong&gt;核心原则：很多时候写代码快，是因为熟悉，而不是因为天赋。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;对新人来说，前期最大的差距往往不是能力，而是对业务、项目、代码结构的熟悉程度。这些都是可以通过时间慢慢补上的。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、关于”学习与成长”的认知&lt;a href=&quot;#三关于学习与成长的认知&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、要有主动使用搜索引擎和 AI 的意识&lt;a href=&quot;#1要有主动使用搜索引擎和-ai-的意识&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;对于程序员来说，搜索能力和借助工具解决问题的能力，本身就是工作能力的一部分。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;很多时候，一个问题你不会，不代表你真的不会，可能只是：&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;li&gt;你还没有结合项目代码去验证&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：先查、先搜、先问 AI、先看文档，再判断自己到底会不会。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;可以这样理解：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;在合理利用搜索引擎、AI、文档和现有代码之后，仍然解决不了的问题，才是真正需要重点突破的”不会”。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;这并不是说什么都靠搜，而是说：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;要先学会借助工具&lt;/li&gt;
&lt;li&gt;再逐渐把这些能力沉淀成自己的东西&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、不要认为”没有问题”才说明自己厉害&lt;a href=&quot;#2不要认为没有问题才说明自己厉害&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见认知：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;一个厉害的程序员，应该是拿到需求就什么问题都没有，什么都懂，什么都不会卡。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;实际情况：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;真实工作里，越有经验的人，往往越能发现问题：&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;li&gt;哪些改动会影响上下游&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：没有问题，不一定代表你很厉害；很多时候，恰恰说明你还没有真正看出问题。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;反而是那些能及时发现问题、指出风险、提前确认边界的人，通常才更有经验。&lt;/p&gt;&lt;p&gt;工作中最重要的不是”看起来没问题”，而是有问题能够及时发现，并推动解决。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、不要认为看不懂项目代码就是自己太菜&lt;a href=&quot;#3不要认为看不懂项目代码就是自己太菜&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见心理：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;项目代码看不懂，我是不是太菜了？&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;实际情况：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;公司代码经常会存在：&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;li&gt;业务流程绕&lt;/li&gt;
&lt;li&gt;系统之间调用很多&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：看不懂项目代码，不一定是你太菜，而是你还处在熟悉项目的阶段。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;对刚进入公司的人来说，看不懂代码本来就是一个正常阶段。即使是一个具备真实开发经验的人来说，也不是说进入一家新公司就立马把项目都看懂了。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;关键不是一开始能不能全看懂，而是：&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;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;四、关于”信息判断与问题排查”的认知&lt;a href=&quot;#四关于信息判断与问题排查的认知&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、不要对任何信息都毫无保留地直接相信&lt;a href=&quot;#1不要对任何信息都毫无保留地直接相信&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;/th&gt;&lt;th&gt;可能的信息&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/tr&gt;&lt;tr&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;/tr&gt;&lt;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;这些信息都可以参考，但不能完全不加判断地全盘接受。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为很多时候，问题之所以复杂，正是因为：&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;li&gt;别人只是凭经验判断，并没有真正验证&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置文件、服务器信息、数据库信息也有可能是错的或过时的&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：对别人提供的信息，先参考，再验证。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&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;/th&gt;&lt;th&gt;验证方式&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/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;p&gt;这样才能减少因为”别人说是这样”而踩坑。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、不要认为所有问题都是代码问题&lt;a href=&quot;#2不要认为所有问题都是代码问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见反应：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;遇到问题时，第一反应是：是不是代码写错了？&lt;/p&gt;&lt;p&gt;&lt;strong&gt;实际情况：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;真实工作里，很多问题并不一定出在代码本身：&lt;/p&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;/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;tr&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;/tr&gt;&lt;tr&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;/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;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：问题不一定是代码问题，要从多个角度去分析。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;如果一遇到问题就只盯着代码，很容易：&lt;/strong&gt;&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;p&gt;&lt;strong&gt;更好的方式是先判断：&lt;/strong&gt;&lt;/p&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;需求 vs 代码&lt;/td&gt;&lt;td&gt;是需求理解问题还是代码实现问题&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;配置 vs 代码&lt;/td&gt;&lt;td&gt;是配置问题还是代码问题&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;数据 vs 代码&lt;/td&gt;&lt;td&gt;是数据问题还是代码问题&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;本地 vs 远程&lt;/td&gt;&lt;td&gt;是自己这边的问题还是上下游联动的问题&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;五、关于”工作方式与态度”的认知&lt;a href=&quot;#五关于工作方式与态度的认知&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、不要还有被动接收的意识，要具备主观能动性&lt;a href=&quot;#1不要还有被动接收的意识要具备主观能动性&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见状态：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;总觉得别人会主动告诉你该做什么，主动把资料给你，主动把环境和权限准备好。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;真实工作里：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;不会有人一直这样照顾你。很多事情，如果你自己不开口、不主动推进，就会一直卡着。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：缺什么，就主动去补什么；少什么，就主动去要什么。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&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;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/tr&gt;&lt;tr&gt;&lt;td&gt;权限&lt;/td&gt;&lt;td&gt;Git权限、服务器权限&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;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;不要因为不好意思、怕打扰别人，就一直被动等着。很多时候，事情推进不下去，不是因为真的做不了，而是因为你一直在等。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、不要认为工作就是一直写代码&lt;a href=&quot;#2不要认为工作就是一直写代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见认知：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;程序员的工作就是每天写代码。&lt;/p&gt;&lt;/blockquote&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;/th&gt;&lt;th&gt;占比说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/tr&gt;&lt;tr&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;/tr&gt;&lt;tr&gt;&lt;td&gt;联调&lt;/td&gt;&lt;td&gt;与前后端、第三方对接&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;改 bug&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;tr&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;&lt;strong&gt;核心原则：程序员的工作，本质上是解决问题，而不是单纯写代码。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;如果你只把自己理解成”写代码的人”，后面就很容易在需求理解、业务沟通、问题排查、联调推进这些事情上吃亏。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、不要急着证明自己很厉害&lt;a href=&quot;#3不要急着证明自己很厉害&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见心态：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;刚进公司时会特别急：&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;li&gt;想尽快接复杂需求&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;实际情况：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;刚入职更重要的不是”证明自己”，而是：&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;li&gt;先建立”靠谱”的印象&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：刚入职阶段，先建立”靠谱”，比急着证明自己更重要。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&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;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/tr&gt;&lt;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;六、关于”人际沟通”的认知&lt;a href=&quot;#六关于人际沟通的认知&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、不要认为别人不帮你就是针对你&lt;a href=&quot;#1不要认为别人不帮你就是针对你&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见心理：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;问同事问题时，对方可能回答很简单、回答比较慢、让你自己先看看，看起来不是特别热情。&lt;/p&gt;&lt;p&gt;于是开始多想：&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;p&gt;&lt;strong&gt;实际情况：&lt;/strong&gt;&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;li&gt;对方只是表达方式比较直接&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：不要过度解读别人的反应。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;更合理的做法是：&lt;/strong&gt;&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;p&gt;这样别人通常也更愿意帮你。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、提问前要先自己尝试&lt;a href=&quot;#2提问前要先自己尝试&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见做法：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;遇到问题立刻就去问别人，完全没有自己先思考或尝试。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;更合理的方式是：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在提问之前，先做到以下几点：&lt;/p&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;/td&gt;&lt;td&gt;搜索引擎、AI、文档&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;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：提问之前先自己尝试，带着问题去问，而不是带着懒惰去问。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这样别人会觉得你是经过思考才来问的，而不是一遇到问题就依赖别人。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;七、关于”面对不确定性”的认知&lt;a href=&quot;#七关于面对不确定性的认知&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、学会接受不确定性，不要总想一开始就拿到标准答案&lt;a href=&quot;#1学会接受不确定性不要总想一开始就拿到标准答案&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见期待：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;最好有人把需求讲得很清楚，文档写得很完整，逻辑很统一，流程很明确，我只要照着做就行。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;实际情况：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;真实工作里，很多事情并不会一开始就那么清晰。你会经常遇到：&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;li&gt;老逻辑没人讲得明白&lt;/li&gt;
&lt;li&gt;不同的人说法不一致&lt;/li&gt;
&lt;li&gt;代码实现和文档描述对不上&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：工作中很多事情，不是”先完全看清，再开始做”，而是”先往前做一点，再慢慢看清”。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;新人最容易陷入的痛苦：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;我想先把一切都看明白，再开始做。 可问题是，我现在又看不明白。 所以我就一直卡着，不敢动。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;但你要明白：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;很多问题的答案，不是在你原地想的时候出现的，而是在你开始查、开始问、开始试、开始推进的过程中，慢慢浮现出来的。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;不要试图一开始就拿到全局地图，先走通眼前能走的路。很多时候，是做着做着才看清了，而不是看清了再做。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&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;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/tr&gt;&lt;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;遇到”还没有完全搞明白”的情况，先问自己三个问题：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;现在已经明确的是什么？&lt;/li&gt;
&lt;li&gt;我眼下能推进的第一步是什么？&lt;/li&gt;
&lt;li&gt;我还缺哪些信息，可以通过什么方式补齐？&lt;/li&gt;
&lt;/ol&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;记住：很多事情，不是因为你看清了才敢做，而是因为你开始做了，才慢慢看清。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、接受”在模糊中前进”是工作的常态&lt;a href=&quot;#2接受在模糊中前进是工作的常态&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;新人常见心理：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;觉得信息不完整就不能开始工作，一定要等所有信息都确认清楚。&lt;/p&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;/th&gt;&lt;th&gt;信息完整度&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/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;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心原则：接受”在模糊中前进”，在工作中逐步明确，而不是等到完全明确才开始。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这种能力需要在实践中培养：&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;li&gt;不要追求一次性完美&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>入职之后需要注意哪些问题</title><link>https://study-docs-158.pages.dev/posts/%E5%85%A5%E8%81%8C%E4%B9%8B%E5%90%8E%E9%9C%80%E8%A6%81%E6%B3%A8%E6%84%8F%E5%93%AA%E4%BA%9B%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%85%A5%E8%81%8C%E4%B9%8B%E5%90%8E%E9%9C%80%E8%A6%81%E6%B3%A8%E6%84%8F%E5%93%AA%E4%BA%9B%E9%97%AE%E9%A2%98/</guid><description>入职之后需要注意哪些问题</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、建立良好的人际关系&lt;a href=&quot;#一建立良好的人际关系&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;和同事处好关系，融入团队，是很多人会忽视的。认为程序猿只要搞好技术就行了，其实是大错特错。 你要清楚，你是一个新人，刚进入这个行业，你必然会遇到一堆连不上环境、摸不清流程的坑。这时候，团队里如果能有一个愿意随口提点你两句的‘自己人’，能帮你省掉几个小时甚至一天的瞎折腾。因此，人际关系的基础一定要提前打好，切忌在遇到麻烦时才临时抱佛脚，那种带有强目的性的求助往往效果很差，也容易引起别人反感。 社会很现实：如果大家关系好，你的技术失误那叫‘新人正常踩坑’，大家笑笑就帮你解了；如果大家看你不顺眼，你写错一个标点符号那都叫‘能力不行’。更别忘了，‘团队融入度’本身就是领导决定你试用期去留的隐形考核指标。&lt;/p&gt;&lt;p&gt;当然，这里说的“建立关系”，不是让你去刻意讨好谁， 而是让你在进入新环境后，不要把自己完全封闭起来。&lt;/p&gt;&lt;p&gt;那应该怎么做？&lt;/p&gt;&lt;p&gt;其实不需要太刻意，也不需要一上来就搞复杂的人情往来。 更重要的是做到以下几点：&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;li&gt;在工作配合上积极一点，让别人感受到你是愿意沟通、愿意配合的人&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;有时候一些小的善意动作，比如一起买水、顺手帮忙、请大家喝个饮料， 当然也可以起到拉近关系的作用。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、尽快熟悉开发流程&lt;a href=&quot;#二尽快熟悉开发流程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;入职后，要尽快搞清楚公司的开发流程和规范。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、了解公司的开发环境&lt;a href=&quot;#1了解公司的开发环境&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;需要了解的内容：&lt;/strong&gt;&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;/section&gt;&lt;section&gt;&lt;h3&gt;2、明确 Git 协作流程&lt;a href=&quot;#2明确-git-协作流程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;需要搞清楚的问题：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;公司使用什么 Git 协调开发的工作流程是什么&lt;/li&gt;
&lt;li&gt;分支命名规范是什么&lt;/li&gt;
&lt;li&gt;提交代码的流程是怎样的&lt;/li&gt;
&lt;li&gt;Code Review 的标准是什么&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;记住：这些问题要大胆地问，尽早搞清楚。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;不懂就问，总比因为不懂而犯错要好得多。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、开发任务前的准备&lt;a href=&quot;#三开发任务前的准备&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;在给你开发任务的时候，有几个关键点一定要注意。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、需求必须搞清楚&lt;a href=&quot;#1需求必须搞清楚&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;开发前要确认：&lt;/strong&gt;&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;li&gt;有哪些异常场景需要考虑&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;不要没搞清楚需求就开始写代码，这样很容易返工。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、确定开发分支&lt;a href=&quot;#2确定开发分支&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;开发前要确认：&lt;/strong&gt;&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;p&gt;&lt;strong&gt;一定要搞清楚在哪个分支开发之后，再写代码。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;避免写完代码才发现分支搞错了，需要重新来过。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、工作态度和表现&lt;a href=&quot;#四工作态度和表现&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;刚入职的前几个月，你的工作态度和表现非常重要。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、态度要端正&lt;a href=&quot;#1态度要端正&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;第一印象很重要：&lt;/strong&gt;&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;p&gt;&lt;strong&gt;第一印象一旦形成，后面就很难改变了。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、不要心虚，放平心态&lt;a href=&quot;#2不要心虚放平心态&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;正确的心理状态：&lt;/strong&gt;&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;p&gt;&lt;strong&gt;既不要妄自菲薄，也不要盲目自大。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、少说话，多做事（技术层面）&lt;a href=&quot;#3少说话多做事技术层面&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;技术上的”少说话”是指：&lt;/strong&gt;&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;p&gt;&lt;strong&gt;为什么不说更好？&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;你不说，别人可能会认为你对待技术很严谨&lt;/li&gt;
&lt;li&gt;说了一些比较低级的问题，别人很容易看出你的水平&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;多做事是指：&lt;/strong&gt;&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;/section&gt;&lt;section&gt;&lt;h3&gt;4、多说话，多沟通（非技术层面）&lt;a href=&quot;#4多说话多沟通非技术层面&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;非技术上的”多说话”是指：&lt;/strong&gt;&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;p&gt;&lt;strong&gt;总结：技术严谨少说话，融入团队多沟通。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、提前做好准备&lt;a href=&quot;#五提前做好准备&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;如果时间比较充裕，可以做一些提前准备。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、提前写测试接口&lt;a href=&quot;#1提前写测试接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;为什么要提前写？&lt;/strong&gt;&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;p&gt;&lt;strong&gt;怎么做？&lt;/strong&gt;&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;li&gt;熟悉常见的工具类和组件&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、Git 操作注意事项&lt;a href=&quot;#六git-操作注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Git 操作一定要谨慎，一个小错误可能导致严重后果。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、不明确的操作先备份&lt;a href=&quot;#1不明确的操作先备份&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;操作前要做的事：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;不确定的操作，先备份当前代码&lt;/li&gt;
&lt;li&gt;确保出问题时可以快速恢复&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、Pull 前先 Commit&lt;a href=&quot;#2pull-前先-commit&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;为什么要这样做？&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;方便回滚&lt;/li&gt;
&lt;li&gt;避免代码冲突时丢失自己的修改&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;操作流程：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;1. 先 commit 自己的修改&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;2. 再 pull 远程代码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;3. 如果有冲突，解决冲突&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;4. 最后再提交&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、切换分支前先 Commit&lt;a href=&quot;#3切换分支前先-commit&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;为什么要这样做？&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;避免切换分支时把未提交的修改带到其他分支&lt;/li&gt;
&lt;li&gt;保持代码的清晰和可追溯&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;记住：本地有修改时，一定要先 commit 再切换分支。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、风险报备意识&lt;a href=&quot;#七风险报备意识&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;当任务可能无法按时完成时，一定要提前报备。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、为什么要提前报备？&lt;a href=&quot;#1为什么要提前报备&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;提前报备的好处：&lt;/strong&gt;&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;/section&gt;&lt;section&gt;&lt;h3&gt;2、什么时候报备？&lt;a href=&quot;#2什么时候报备&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;报备的时机：&lt;/strong&gt;&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;li&gt;意识到时间可能不够&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;在规定时间内搞不出的需求，一定要提前找 leader 把风险报备上去。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;不是等到最后一刻才说，而是发现问题就要及时沟通。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;八、保持正确的学习节奏&lt;a href=&quot;#八保持正确的学习节奏&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;刚入职时，很容易受到老员工的影响，要注意保持自己的节奏。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、不要好高骛远&lt;a href=&quot;#1不要好高骛远&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;要认清的现实：&lt;/strong&gt;&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;/section&gt;&lt;section&gt;&lt;h3&gt;2、围绕公司项目去学习&lt;a href=&quot;#2围绕公司项目去学习&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;正确的学习方式：&lt;/strong&gt;&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;/section&gt;&lt;section&gt;&lt;h3&gt;3、不要受老员工影响&lt;a href=&quot;#3不要受老员工影响&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;老员工的吐槽不代表你的感受：&lt;/strong&gt;&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;p&gt;&lt;strong&gt;记住：这是你的第一份工作，围绕公司项目去学习，保持自己的节奏。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;九、关于包装经验的注意事项&lt;a href=&quot;#九关于包装经验的注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;这是一个比较敏感但非常重要的问题。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、不要跟任何同事说&lt;a href=&quot;#1不要跟任何同事说&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;无论关系多好：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;不要跟任何同事说你的经验是包装的&lt;/li&gt;
&lt;li&gt;即使别人怀疑你，也不要承认&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、可以承认自己菜&lt;a href=&quot;#2可以承认自己菜&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;正确的应对方式：&lt;/strong&gt;&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;/section&gt;&lt;section&gt;&lt;h3&gt;3、菜很正常，包装不正常&lt;a href=&quot;#3菜很正常包装不正常&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;为什么可以承认菜？&lt;/strong&gt;&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;p&gt;&lt;strong&gt;为什么不能承认包装？&lt;/strong&gt;&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;p&gt;&lt;strong&gt;总结：可以承认自己菜，但不要承认自己包装经验。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>微服务系统中如何开发</title><link>https://study-docs-158.pages.dev/posts/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E7%B3%BB%E7%BB%9F%E4%B8%AD%E5%A6%82%E4%BD%95%E5%BC%80%E5%8F%91/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E7%B3%BB%E7%BB%9F%E4%B8%AD%E5%A6%82%E4%BD%95%E5%BC%80%E5%8F%91/</guid><description>微服务系统中如何开发</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;​&lt;br /&gt;
从开发角度来说，微服务项目和单体项目的日常开发区别并没有想象中那么大。因为说到底，微服务架构下的每一个服务，本质上也都是一个独立的 Spring Boot 项目，我们平时写 Controller、Service、Mapper、SQL、接口开发等工作，和在单体项目中并没有太大区别。&lt;/p&gt;
&lt;p&gt;真正的区别在于：原本在一个项目内部完成的事情，被拆分到了多个服务之间协同完成。因此在开发过程中，会额外涉及一些单体项目中不太会遇到的问题，例如&lt;strong&gt;服务的注册与发现、远程配置管理、服务间远程调用、API 网关、分布式锁、分布式事务&lt;/strong&gt;等。&lt;/p&gt;
&lt;p&gt;所以，对于刚接触微服务的新人来说，不必把它想得过于高深。先把每个服务当成一个普通的 Spring Boot 项目去理解，再逐步掌握服务之间的协作方式，会更容易上手。&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/f9245c82-5a6a-4693-919d-83b98eccf67a.png&quot; alt=&quot;微服务架构&quot; /&gt;&lt;figcaption&gt;微服务架构&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;一、远程配置与注册中心&lt;a href=&quot;#一远程配置与注册中心&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;在微服务架构下，有两个基础组件几乎是必须的：&lt;strong&gt;配置中心&lt;/strong&gt;和&lt;strong&gt;注册中心&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;配置中心解决的是”配置怎么统一管理”的问题，注册中心解决的是”服务之间怎么找到对方”的问题。&lt;/p&gt;&lt;p&gt;这两个东西看起来是独立的功能，但在实际项目中，它们经常由同一个中间件来承担，比如 Nacos 就同时支持配置中心和注册中心。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、远程配置&lt;a href=&quot;#1远程配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1.1 为什么需要远程配置？&lt;a href=&quot;#11-为什么需要远程配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在单体项目里，配置文件一般就直接放在项目里，比如 &lt;code&gt;application.yml&lt;/code&gt;，改了配置就重启服务就行。&lt;/p&gt;&lt;p&gt;但在微服务架构下，通常有这些问题：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;公共配置分散，改一处要动 N 个项目&lt;/strong&gt;：微服务下有十几个甚至几十个服务，很多配置是多个服务共用的（比如 Redis 地址、数据库连接、第三方接口密钥）。虽然 Spring Boot 自带的 Profile 机制（&lt;code&gt;application-dev.yml&lt;/code&gt;、&lt;code&gt;application-prod.yml&lt;/code&gt;）也能做多环境切换，但当服务数量多了之后，每个服务都维护自己的一套配置文件，公共配置一旦变更就要逐个修改 N 个项目，很容易漏改或改错。配置中心可以把公共配置集中管理，改一次所有服务都生效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;敏感配置不适合放在代码仓库中&lt;/strong&gt;：数据库密码、第三方接口密钥等敏感信息，如果直接写在项目的配置文件里，会被提交到 Git 仓库，存在泄露风险。配置中心可以集中管理这些敏感配置，代码仓库里只保留非敏感的基本配置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置修改需要重启才能生效&lt;/strong&gt;：有些配置改了之后，服务必须重启才能生效，这在生产环境是很不方便的&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以，微服务架构下，通常会引入&lt;strong&gt;配置中心&lt;/strong&gt;来统一管理配置。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单理解&lt;/strong&gt;：配置中心就是把你之前放在 &lt;code&gt;application.yml&lt;/code&gt; 里的配置，搬到远程服务器上统一管理。你可以随时改，改完之后服务可以做到动态生效，不需要重启。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.2 常见的配置中心&lt;a href=&quot;#12-常见的配置中心&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;Nacos&lt;/td&gt;&lt;td&gt;阿里开源，国内使用最广泛，同时支持注册中心和配置中心&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Apollo&lt;/td&gt;&lt;td&gt;携程开源，功能丰富，配置管理能力很强&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Spring Cloud Config&lt;/td&gt;&lt;td&gt;Spring Cloud 官方提供，需要依赖 Git 等存储&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;其中，&lt;strong&gt;Nacos 是国内企业用得最多的&lt;/strong&gt;，很多公司的微服务架构都是基于 Spring Cloud Alibaba + Nacos 搭建的。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.3 远程配置一般怎么用？&lt;a href=&quot;#13-远程配置一般怎么用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;以 Nacos 为例，一般的用法是这样的：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/a2a3b0e9-8a97-48ef-911a-22043800149b.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）在 Nacos 控制台上创建配置&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;你登录 Nacos 控制台，在里面创建一个配置，比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Data ID：&lt;code&gt;order-service-dev.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Group：&lt;code&gt;DEFAULT_GROUP&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;配置内容：就是你的 yml 配置，比如数据库连接、Redis 地址等&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/abc44b42-c976-4648-8778-ec1682d2bc2a.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）在项目的 bootstrap.yml 中配置 Nacos 地址&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;order-service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;cloud&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;nacos&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;server-addr&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;127.0.0.1:8848&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;file-extension&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;yml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;DEFAULT_GROUP&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;#分组不设置，默认就是DEFAULT_GROUP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;7c5c0c0d-c0c5-4c0c-b0c5-0c5c0c5c0c5c&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;#命名空间不设置，默认是public&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;username&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;nacos&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;nacos&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;shared-configs&lt;/span&gt;&lt;span&gt;:           &lt;/span&gt;&lt;span&gt;# 引入公共配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;data-id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;application-dev.yml&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;# 公共配置的 Data ID&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;refresh&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;         &lt;/span&gt;&lt;span&gt;# 是否支持动态刷新&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;注意：Nacos 配置相关的内容一般放在 &lt;code&gt;bootstrap.yml&lt;/code&gt;（或 &lt;code&gt;bootstrap.properties&lt;/code&gt;）里，而不是 &lt;code&gt;application.yml&lt;/code&gt;。因为 &lt;code&gt;bootstrap.yml&lt;/code&gt; 的加载优先级比 &lt;code&gt;application.yml&lt;/code&gt; 更高，这样可以保证在应用启动时先连上 Nacos 拉取配置，再进行后续初始化。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;除了在 &lt;code&gt;bootstrap.yml&lt;/code&gt; 里写死 Nacos 地址，也可以在 IDEA 的启动配置里通过 JVM 参数指定，本地开发时用这种方式更灵活，不用改代码：&lt;/p&gt;&lt;p&gt;在 IDEA 的 Run Configuration 里，找到 &lt;strong&gt;VM options&lt;/strong&gt;，添加：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.cloud.nacos.config.server-addr=http://127.0.0.1:8848&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.cloud.nacos.config.file-extension=yml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.cloud.nacos.config.namespace=0662a2cc-f7fd-42e0-b33b-aa07603950bd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.cloud.nacos.config.shared-configs[0].data-id=application-dev.yml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.cloud.nacos.config.shared-configs.refresh=true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.profiles.active=dev&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.cloud.nacos.config.group=DEFAULT_GROUP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.cloud.nacos.discovery.server-addr=http://127.0.0.1:8848&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.cloud.nacos.discovery.group=zy&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-Dspring.cloud.nacos.discovery.namespace=0662a2cc-f7fd-42e0-b33b-aa07603950bd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这样本地开发连自己电脑的 Nacos，测试环境连测试环境的 Nacos，只需要改 VM 参数就行，不用动配置文件。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/ff845013-206b-4211-b7e5-6401231bb11f.png&quot; alt=&quot;7&quot; /&gt;&lt;figcaption&gt;7&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）启动服务时自动拉取远程配置&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;服务启动后，会自动去 Nacos 拉取对应的配置，和本地配置合并后生效。&lt;/p&gt;&lt;p&gt;启动过程中，各个配置被读入的先后顺序是这样的：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;1、bootstrap.yml（本地）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;2、拉取公共配置（shared-configs）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;3、拉取当前服务自己的配置（Data ID = 服务名.yml）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;4、application.yml（本地）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;最终合并生效&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;特别注意：这里讲的”加载顺序”和下面讲的”优先级”不是一回事，别搞混了。&lt;/strong&gt; 上面说的是各个配置在启动过程中”什么时候被读到”，而真正决定同名属性最终用哪个值的，是优先级。Nacos 拉取到的远程配置会被插入到比本地配置更高的优先级位置上，所以它虽然比 &lt;code&gt;application.yml&lt;/code&gt; 先被加载，最终却能覆盖 &lt;code&gt;application.yml&lt;/code&gt;。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;如果同一个属性在多处都配了，最终生效遵循以下优先级（&lt;strong&gt;高优先级覆盖低优先级&lt;/strong&gt;）：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Nacos 服务专属配置（Data ID = 服务名.yml）    ← 最高&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 覆盖&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Nacos 公共配置（shared-configs）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 覆盖&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;application.yml（本地）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 覆盖&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;bootstrap.yml（本地）                          ← 最低&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;简单记三条就够：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;远程 &amp;gt; 本地&lt;/strong&gt;：Nacos 上的配置会覆盖本地配置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;专属 &amp;gt; 共享&lt;/strong&gt;：服务自己的配置会覆盖公共配置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;application &amp;gt; bootstrap&lt;/strong&gt;：本地文件中，&lt;code&gt;application.yml&lt;/code&gt; 覆盖 &lt;code&gt;bootstrap.yml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;优先级能改吗？&lt;/strong&gt; 能，但一般不需要。Spring Cloud Nacos 提供了一些配置项（如 &lt;code&gt;spring.cloud.config.override-none=true&lt;/code&gt; 可以让远程配置不覆盖本地），但实际项目中几乎不会去改默认优先级，了解有这么回事就行。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这也是为什么很多项目本地只保留最基本的配置（服务名、Nacos 地址、端口号等），其他配置全部放到 Nacos 上管理——避免本地和远程配置打架。&lt;/p&gt;&lt;p&gt;当然，如果某个属性只在某一处配了，其他地方没配，那自然就是那一处的值生效。&lt;/p&gt;&lt;p&gt;其中，&lt;strong&gt;公共配置&lt;/strong&gt;是多个服务共用的配置，比如数据库连接、Redis 地址、通用日志配置等。这些配置不需要每个服务都重复配一遍，只需要在 Nacos 上创建一份公共配置文件（如 &lt;code&gt;common.yml&lt;/code&gt;），然后在每个服务的 &lt;code&gt;bootstrap.yml&lt;/code&gt; 中引入即可。修改公共配置时，所有引用它的服务都会生效，不用一个一个改。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.4 哪些配置适合放远程，哪些不适合？&lt;a href=&quot;#14-哪些配置适合放远程哪些不适合&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;/td&gt;&lt;td&gt;服务端口号&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Redis 地址&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;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;原则&lt;/strong&gt;：&lt;strong&gt;多环境有差异的、需要经常修改的、敏感信息类的配置，优先放配置中心。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.5 配置修改后，服务怎么感知？&lt;a href=&quot;#15-配置修改后服务怎么感知&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;有两种常见方式：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方式一：自动刷新&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;通过 &lt;code&gt;@RefreshScope&lt;/code&gt; 注解，配合 Nacos 的配置监听机制，配置修改后，对应的 Bean 会自动重新创建，不需要重启服务。&lt;/p&gt;&lt;p&gt;实际开发中，最常见的场景是&lt;strong&gt;业务开关&lt;/strong&gt;——比如某个功能上线后发现问题，需要紧急关闭，如果配置写在代码里就只能重新发版；但放在 Nacos 上，改个配置就能即时生效，不用重启服务。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）在 Nacos 上添加开关配置&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 比如配置在 order-service-dev.yml 中&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;flash-sale-enabled&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# 秒杀功能开关，false 表示关闭&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;max-order-count&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;span&gt;# 单用户最大下单数&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2）在代码中通过 &lt;code&gt;@Value&lt;/code&gt; 读取，配合 &lt;code&gt;@RefreshScope&lt;/code&gt; 实现动态刷新&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RestController&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RefreshScope&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderController&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;${order.flash-sale-enabled:false}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt; flashSaleEnabled&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;${order.max-order-count:10}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; maxOrderCount&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/flashSale&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flashSale&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;flashSaleEnabled) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;秒杀活动暂未开放&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;秒杀活动进行中，每人限购&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; maxOrderCount &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;件&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;启动服务后，浏览器访问 &lt;code&gt;/flashSale&lt;/code&gt; 会返回”秒杀活动暂未开放”。然后在 Nacos 上把 &lt;code&gt;order.flash-sale-enabled&lt;/code&gt; 改成 &lt;code&gt;true&lt;/code&gt;，&lt;strong&gt;不用重启服务&lt;/strong&gt;，再刷新页面就能看到返回”秒杀活动进行中，每人限购5件”。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方式二：手动重启&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有些配置改了之后，确实需要重启服务才能生效（比如数据库连接池的配置）。这种情况就直接改配置、重启服务。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.6 远程配置相关的常见问题&lt;a href=&quot;#16-远程配置相关的常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;问题一：本地配置不生效&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这是新人特别容易遇到的问题。排查思路：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;检查 &lt;code&gt;bootstrap.yml&lt;/code&gt; 或 Idea 启动脚本里配置的 Nacos 地址是否正确&lt;/li&gt;
&lt;li&gt;检查 Data ID、Group 是否和 Nacos 上的一致&lt;/li&gt;
&lt;li&gt;检查环境（dev / test / prod）是否正确&lt;/li&gt;
&lt;li&gt;检查远程配置是否覆盖了本地配置（优先级问题）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;问题二：配置改了但没生效&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;确认你改的是不是正确的环境配置（可能改的是测试环境的，但本地连的是开发环境）&lt;/li&gt;
&lt;li&gt;确认是否需要 &lt;code&gt;@RefreshScope&lt;/code&gt; 才能动态刷新&lt;/li&gt;
&lt;li&gt;确认修改后是否需要重启服务&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;问题三：远程配置里数据库、Redis 这些中间件的 IP，应该写哪个？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;很多新人会困惑：Nacos 是配置中心，那配置里的数据库 IP，到底是要写 &lt;strong&gt;Nacos 能访问的&lt;/strong&gt;，还是&lt;strong&gt;服务自己能访问的&lt;/strong&gt;？&lt;/p&gt;&lt;p&gt;答案：&lt;strong&gt;写”服务自己能访问的”IP。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;原因很简单：Nacos 只是配置的”仓库”，它负责存储和分发配置，本身根本不去连接数据库、Redis 这些中间件。真正拿着这些连接信息去建立连接、发 SQL 的，是消费配置的业务服务（order-service、user-service 等）。所以 IP 必须是业务服务所在的网络环境里能访问到的地址。&lt;/p&gt;&lt;p&gt;举个例子：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Nacos、MySQL、Redis 都部署在 &lt;strong&gt;A 服务器&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;你的业务服务部署在 &lt;strong&gt;B 服务器&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;那么远程配置里数据库、Redis 的 IP &lt;strong&gt;不能写 &lt;code&gt;127.0.0.1&lt;/code&gt; 或 &lt;code&gt;localhost&lt;/code&gt;&lt;/strong&gt;，因为 &lt;code&gt;127.0.0.1&lt;/code&gt; 在 B 服务器的视角下指的是 B 自己，B 上根本没有装 MySQL/Redis，肯定连不上。应该写 &lt;strong&gt;A 服务器对外的 IP&lt;/strong&gt;（也就是从 B 服务器上能 ping 通的那个 IP）。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、注册中心（服务的注册与发现）&lt;a href=&quot;#2注册中心服务的注册与发现&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;2.1 为什么需要注册中心？&lt;a href=&quot;#21-为什么需要注册中心&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在单体项目里，所有代码都在一起，调用另一个模块的方法直接调就行了，不需要关心对方在哪台机器上。&lt;/p&gt;&lt;p&gt;但在微服务架构下，每个服务都是独立部署的，可能分布在不同机器上，而且服务的实例数量还可能随时变化（比如某个服务扩容了，从 2 个实例变成 5 个；某个实例挂了，只剩 4 个了）。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;订单服务想调用用户服务，问题是：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 用户服务部署在哪台机器上？&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- IP 地址是多少？端口是多少？&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 用户服务有几个实例？调哪个？&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 如果某个实例挂了怎么办？&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;如果这些信息全靠人工维护，比如在配置文件里写死每个服务的 IP 和端口，那根本管不过来：&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;p&gt;&lt;strong&gt;注册中心就是用来自动解决这些问题的。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.2 注册中心是做什么的？&lt;a href=&quot;#22-注册中心是做什么的&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;用一句话概括：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注册中心就是一个”服务通讯录”，每个服务启动时把自己的地址登记上去，需要调用别人时从通讯录里查。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.3 注册中心的工作流程&lt;a href=&quot;#23-注册中心的工作流程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/3db7d7ab-5764-451d-9c4a-d35cdbeb4f32.png&quot; alt=&quot;3&quot; /&gt;&lt;figcaption&gt;3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.4 常见的注册中心&lt;a href=&quot;#24-常见的注册中心&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;Nacos&lt;/td&gt;&lt;td&gt;阿里开源，国内使用最广泛，同时支持注册中心和配置中心&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Eureka&lt;/td&gt;&lt;td&gt;Netflix 开源，Spring Cloud 早期默认组件，目前已停止维护&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ZooKeeper&lt;/td&gt;&lt;td&gt;Apache 基金会项目，Dubbo 早期默认使用的注册中心&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Consul&lt;/td&gt;&lt;td&gt;HashiCorp 开源，功能丰富，支持多数据中心&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;其中，&lt;strong&gt;Nacos 是目前国内企业使用最多的注册中心&lt;/strong&gt;，特别是基于 Spring Cloud Alibaba 的微服务项目，基本上都是用 Nacos。前面说过，Nacos 同时支持配置中心和注册中心，所以很多公司只需要部署一个 Nacos 就够了。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.5 服务注册与发现在代码中是怎么体现的？&lt;a href=&quot;#25-服务注册与发现在代码中是怎么体现的&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;很多新人会觉得：“注册中心这么重要，我是不是要写很多注册相关的代码？”&lt;/p&gt;&lt;p&gt;实际上，&lt;strong&gt;注册中心的使用基本上是自动的，你不需要手动写注册和发现的代码。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;以 Spring Cloud Alibaba + Nacos 为例，我们的项目只需要：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）添加依赖&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;com.alibaba.cloud&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;spring-cloud-starter-alibaba-nacos-discovery&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2）在配置文件中指定 Nacos 地址&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;order-service&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# 服务名，注册到 Nacos 上的名称&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;cloud&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;nacos&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;discovery&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;server-addr&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;127.0.0.1:8848&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;# Nacos 地址&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;DEFAULT_GROUP&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;#分组不设置，默认就是DEFAULT_GROUP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;7c5c0c0d-c0c5-4c0c-b0c5-0c5c0c5c0c5c&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;#命名空间不设置，默认是public&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;username&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;nacos&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;nacos&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;也是可以在IDEA 的启动配置里通过 JVM 参数指定。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）启动服务&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;服务启动后，Spring Cloud 会自动帮你完成以下操作：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;把当前服务（&lt;code&gt;order-service&lt;/code&gt;）注册到 Nacos&lt;/li&gt;
&lt;li&gt;定时向 Nacos 发送心跳，告诉它”我还活着”&lt;/li&gt;
&lt;li&gt;当你用 Feign 或 Dubbo 调用其他服务时，自动从 Nacos 查询目标服务的地址&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;你在 Nacos 控制台的”服务列表”页面，就能看到所有已注册的服务及其实例信息。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/3e800095-cf41-460d-a513-39fcc8e86e07.png&quot; alt=&quot;4&quot; /&gt;&lt;figcaption&gt;4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.6 关于服务注册与发现的几个关键概念&lt;a href=&quot;#26-关于服务注册与发现的几个关键概念&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;1）服务注册&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;服务启动时，将自己的信息（服务名、IP、端口等）注册到注册中心。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）服务发现&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;服务消费方从注册中心获取目标服务的实例列表，选择其中一个进行调用。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）心跳检测&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;注册中心会定时检查每个服务是否还活着。如果某个服务长时间没有发送心跳，注册中心会认为它已经挂了，把它从服务列表中剔除。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4）负载均衡&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;当一个服务有多个实例时，调用方需要决定请求哪个实例。常见的负载均衡策略有：&lt;/p&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;/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;tr&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;在 Spring Cloud 中，负载均衡默认使用的是 &lt;strong&gt;Spring Cloud LoadBalancer&lt;/strong&gt;（早期版本用的是 Ribbon，从 Spring Cloud 2020.0 开始 Ribbon 已被移除，统一换成 LoadBalancer）。一般不需要你手动配置。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.7 注册中心相关的常见问题&lt;a href=&quot;#27-注册中心相关的常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;问题一：服务启动了，但注册中心上看不到&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;排查思路：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;检查 Nacos 地址是否配置正确&lt;/li&gt;
&lt;li&gt;检查服务名是否正确&lt;/li&gt;
&lt;li&gt;检查网络是否能连上 Nacos（telnet 一下 Nacos 的端口）&lt;/li&gt;
&lt;li&gt;检查依赖是否引入了 &lt;code&gt;spring-cloud-starter-alibaba-nacos-discovery&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;看启动日志里有没有注册失败的报错&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;问题二：远程调用报错”找不到服务”&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这种情况通常是调用方在注册中心上找不到目标服务。排查思路：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;确认目标服务是否已启动并注册成功&lt;/li&gt;
&lt;li&gt;确认调用方配置的目标服务名和注册中心上的服务名是否一致（大小写、横杠、下划线等）&lt;/li&gt;
&lt;li&gt;确认调用方和目标服务连的是同一个 Nacos、同一个命名空间（namespace）、同一个分组&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、一些注意事项&lt;a href=&quot;#3一些注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1）先搞清楚你们公司用的是哪个注册中心和配置中心&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果有使用注册中心：确认注册中心和配置中心用的是 Nacos、Apollo + Eureka 还是别的？管理后台地址是什么？可以直接问AI或者看pom文件引入的依赖是什么。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）配置改完，记得确认是否生效&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;不要改完 Nacos 上的配置就觉得万事大吉了。有时候你可能改的是测试环境的配置，但本地连的是开发环境；或者配置改了但没刷新成功。改完之后，最好实际验证一下。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）不要随便改生产环境的配置&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;生产环境的配置修改一般有流程和审批机制，不要直接上去改。如果确实需要改，先和同事确认。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4）服务启动后，先去注册中心确认注册成功&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;不要启动完就不管了。登录 Nacos 控制台，看服务列表里有没有你的服务，实例信息（IP、端口）是否正确。如果注册都没成功，后续的远程调用肯定会出问题。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5）本地开发时，注意环境隔离&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;本地调试代码时，经常会遇到一种情况：你明明改了代码，但调用时发现改的没生效。这时候很可能是请求没有走到你本地启动的服务实例，而是走到了线上或测试环境的服务实例上。&lt;/p&gt;&lt;p&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;code&gt;dev-local&lt;/code&gt;），这样本地实例和线上实例互不干扰&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dubbo 可以改版本号&lt;/strong&gt;：本地服务配置一个不同的版本号（比如 &lt;code&gt;version = &quot;1.0.0-local&quot;&lt;/code&gt;），调用方指定这个版本号，就能确保请求只走你本地的实例&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、远程调用&lt;a href=&quot;#二远程调用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、为什么需要远程调用？&lt;a href=&quot;#1为什么需要远程调用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在单体项目里，所有代码都在一个项目里，模块之间直接调用方法就行了：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 单体项目：直接调用&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;orderService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createOrder&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;但在微服务架构下，系统被拆成了多个独立的服务，比如：&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;li&gt;支付服务&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;订单服务要查用户信息，不可能直接调用用户服务的方法，因为它们是两个独立的 Java 进程，跑在不同的机器上。&lt;/p&gt;&lt;p&gt;这时候就需要通过&lt;strong&gt;远程调用&lt;/strong&gt;来让服务之间互相通信。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;订单服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ （远程调用）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单理解&lt;/strong&gt;：远程调用，就是服务 A 通过网络请求去调用服务 B 的接口，看起来像调用本地方法一样，但底层实际上是通过 HTTP 或 RPC 发了一次网络请求。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、常见的远程调用方式&lt;a href=&quot;#2常见的远程调用方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;典型框架&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;HTTP 调用&lt;/td&gt;&lt;td&gt;通过 HTTP 协议调用其他服务的接口&lt;/td&gt;&lt;td&gt;RestTemplate、OpenFeign&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RPC 调用&lt;/td&gt;&lt;td&gt;通过自定义协议直接调用，性能更好&lt;/td&gt;&lt;td&gt;Dubbo&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;目前企业里用得比较多的是 &lt;strong&gt;OpenFeign&lt;/strong&gt;（HTTP 方式）和 &lt;strong&gt;Dubbo&lt;/strong&gt;（RPC 方式）。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、OpenFeign 的基本用法&lt;a href=&quot;#3openfeign-的基本用法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;OpenFeign 是 Spring Cloud 提供的一个声明式 HTTP 客户端，用起来非常简单。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）添加依赖&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.springframework.cloud&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;spring-cloud-starter-openfeign&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2）在启动类上开启 Feign&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;EnableFeignClients&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;SpringBootApplication&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderApplication&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;[] &lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;SpringApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;OrderApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;, args);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3）定义 Feign 接口&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;FeignClient&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;user-service&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserClient&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user/{id}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;PathVariable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这段代码的意思是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name = &quot;user-service&quot;&lt;/code&gt;：要调用的目标服务名（注册中心上的服务名）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@GetMapping(&quot;/user/{id}&quot;)&lt;/code&gt;：目标服务的接口路径&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UserDTO&lt;/code&gt;：返回值类型&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;重要：Feign 接口的入参必须加注解。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;普通 Controller 里，简单类型的参数不加注解默认当 &lt;code&gt;@RequestParam&lt;/code&gt; 处理，但 Feign 接口不行，不加注解会报错或参数传不过去。必须通过注解明确告诉 Feign 参数放在哪：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 路径参数 → @PathVariable&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user/{id}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;PathVariable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; id)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 查询参数 → @RequestParam&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user/list&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;listUsers&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; name&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;page&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt;&lt;span&gt; page)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 请求体 → @RequestBody（POST/PUT 传对象）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createUser&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; user)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 请求头 → @RequestHeader&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user/info&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getInfo&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestHeader&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; token)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 文件上传 → @RequestPart&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;/upload&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;consumes&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;MediaType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MULTIPART_FORM_DATA_VALUE&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;upload&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestPart&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;file&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;MultipartFile&lt;/span&gt;&lt;span&gt;&lt;span&gt; file)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// consumes 指定请求格式，文件上传用 multipart/form-data，不加一般也能自动识别&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;4）在业务代码中直接注入使用&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserClient&lt;/span&gt;&lt;span&gt; userClient&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getOrderDetail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;orderId&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectById&lt;/span&gt;&lt;span&gt;(orderId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 远程调用用户服务，查询下单用户信息&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 组装返回&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setOrder&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setUser&lt;/span&gt;&lt;span&gt;(user);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; dto;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;可以看到，使用起来和调用本地方法几乎没有区别，这就是 OpenFeign 的好处。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;3.1 Feign 接口抽取到独立 API 模块（最常见的做法）&lt;a href=&quot;#31-feign-接口抽取到独立-api-模块最常见的做法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;上面演示的是在消费方（order-service）里自己写 Feign 接口。但工作中更常见的做法是：&lt;strong&gt;服务提供方把 Feign 接口和 DTO 放到一个独立的模块里，打成 jar 包，消费方直接引用这个 jar 包就行&lt;/strong&gt;。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;openfeign-test/                       ← 父工程&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── user-api                          ← 独立模块，只放接口和 DTO&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│   └── com.example.user.api&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│       ├── UserClient.java           ← Feign 接口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│       └── UserDTO.java              ← 数据传输对象&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── user-service                      ← 服务提供方（用户服务）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│   └── com.example.user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│       ├── UserServiceApplication.java&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│       └── controller/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│           └── UserController.java   ← Controller 实现 UserClient 接口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;└── order-service                     ← 服务消费方（订单服务）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;└── com.example.order&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;└── OrderServiceApplication.java&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;服务提供方的 Controller &lt;strong&gt;直接实现&lt;/strong&gt;这个 Feign 接口：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// user-api 模块中的 Feign 接口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;FeignClient&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;user-service&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserClient&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user/{id}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;PathVariable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createUser&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// user-service-impl 模块中的 Controller 实现该接口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RestController&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserController&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserClient&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createUser&lt;/span&gt;&lt;span&gt;(user);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;消费方只需要在 pom.xml 里引用 user-api 的依赖，就能直接注入使用：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- order-service 的 pom.xml --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;com.example&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;user-api&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;1.0.0&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// order-service 中直接注入，不用自己写 Feign 接口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserClient&lt;/span&gt;&lt;span&gt; userClient&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这样做的好处：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;消费方不用自己写 Feign 接口&lt;/strong&gt;，直接引用提供方的 jar 包，减少重复代码&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接口和实现天然一致&lt;/strong&gt;，因为 Controller 实现了 Feign 接口，路径、参数、返回值都是一样的，不会出现”调用方写的接口和提供方不一致”的问题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DTO 共享&lt;/strong&gt;，请求和响应的对象也放在 api 模块里，双方用的是同一个类&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单理解&lt;/strong&gt;：就像你调用别人的 SDK，人家把接口定义好打成 jar 包给你用，你不用关心人家怎么实现的，直接调就行。&lt;/p&gt;&lt;p&gt;入职后看到项目结构里有 &lt;code&gt;xxx-api&lt;/code&gt; 模块，多半就是这种模式。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2 &lt;code&gt;contextId&lt;/code&gt; 解决同服务名多个 FeignClient（了解）&lt;a href=&quot;#32-contextid-解决同服务名多个-feignclient了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;有些项目会把一个大服务的接口拆成多个 FeignClient（比如用户查询一组、用户管理一组），这时会出现两个 &lt;code&gt;@FeignClient&lt;/code&gt; 的 &lt;code&gt;name&lt;/code&gt; 相同的情况，启动会报错。加上 &lt;code&gt;contextId&lt;/code&gt; 就能解决：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 两个接口都指向 user-service，用 contextId 区分&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;FeignClient&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;user-service&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;contextId&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;userQueryClient&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserQueryClient&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user/{id}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;PathVariable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;FeignClient&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;user-service&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;contextId&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;userManageClient&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserManageClient&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createUser&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PutMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;updateUser&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单理解&lt;/strong&gt;：Spring 容器里不能有两个同名的 Bean。&lt;code&gt;name&lt;/code&gt; 相同的 FeignClient 会冲突，&lt;code&gt;contextId&lt;/code&gt; 就是给它们起不同的 Bean 名字。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、Dubbo 的基本用法&lt;a href=&quot;#4dubbo-的基本用法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Dubbo 是阿里开源的 RPC 框架，在国内企业中使用也非常广泛。和 OpenFeign 基于 HTTP 不同，Dubbo 使用自定义的二进制协议进行通信，性能更高。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;4.1 Dubbo 和 OpenFeign 的区别&lt;a href=&quot;#41-dubbo-和-openfeign-的区别&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;







































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;对比项&lt;/th&gt;&lt;th&gt;OpenFeign&lt;/th&gt;&lt;th&gt;Dubbo&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;通信协议&lt;/td&gt;&lt;td&gt;HTTP&lt;/td&gt;&lt;td&gt;自定义 RPC 协议（默认 Dubbo 协议）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;性能&lt;/td&gt;&lt;td&gt;一般（HTTP 协议开销较大）&lt;/td&gt;&lt;td&gt;更高（二进制协议，序列化效率更高）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;使用方式&lt;/td&gt;&lt;td&gt;声明式接口 + Spring MVC 注解&lt;/td&gt;&lt;td&gt;声明式接口 + Dubbo 注解&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;服务注册&lt;/td&gt;&lt;td&gt;依赖 Spring Cloud 注册中心&lt;/td&gt;&lt;td&gt;自带注册中心集成（Nacos、ZooKeeper 等）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;生态&lt;/td&gt;&lt;td&gt;Spring Cloud 生态&lt;/td&gt;&lt;td&gt;Dubbo 生态（Spring Boot 也可以集成）&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;&lt;strong&gt;简单理解&lt;/strong&gt;：OpenFeign 就像你用浏览器访问网页，走的是通用的 HTTP 协议；Dubbo 就像两个人打专线电话，用专门的协议直接通话，速度更快但需要两边都用同一套协议。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4.2 Dubbo 的基本用法&lt;a href=&quot;#42-dubbo-的基本用法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Dubbo 的使用方式有两种主流写法：一种是老版本的 XML / 注解方式，另一种是新版本推荐的 Spring Boot 方式。现在新项目基本都用 Spring Boot 方式，这里也以此为例。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）添加依赖&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;服务提供方和服务消费方都需要引入 Dubbo 的 starter：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.apache.dubbo&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;dubbo-spring-boot-starter&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;3.2.0&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 注册中心以 Nacos 为例 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.apache.dubbo&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;dubbo-registry-nacos&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;3.2.0&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2）配置 Dubbo&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;user-service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;address&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;nacos://127.0.0.1:8848?namespace=7c5c0c0d-c0c5-4c0c-b0c5-0c5c0c5c0c5c&amp;amp;group=zy&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;username&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;nacos&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;nacos&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;protocol&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;20880&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3）定义服务接口&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Dubbo 的做法是：把接口定义抽成一个独立的模块（API 模块），服务提供方和消费方都依赖这个模块。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// user-api 模块（公共接口）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;4）服务提供方实现接口&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在用户服务中实现这个接口，并暴露为 Dubbo 服务：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// user-service 模块（服务提供方）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboService&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserMapper&lt;/span&gt;&lt;span&gt; userMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectById&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setId&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getName&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; dto;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;@DubboService&lt;/code&gt; 注解表示：这个类是一个 Dubbo 服务，会自动注册到注册中心，其他服务可以通过远程调用来使用它。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5）服务消费方调用远程服务&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在订单服务中，通过 &lt;code&gt;@DubboReference&lt;/code&gt; 注入远程服务：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// order-service 模块（服务消费方）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getOrderDetail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;orderId&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectById&lt;/span&gt;&lt;span&gt;(orderId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 远程调用用户服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderDTO&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setOrder&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;dto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setUser&lt;/span&gt;&lt;span&gt;(user);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; dto;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;可以看到，使用方式和 OpenFeign 类似，注入后直接调用方法就行，底层 Dubbo 会自动完成远程调用。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;6）启动类上加注解&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;EnableDubbo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;SpringBootApplication&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderApplication&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;[] &lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;SpringApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;OrderApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;, args);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：Dubbo 3.x 配合 &lt;code&gt;dubbo-spring-boot-starter&lt;/code&gt; 时已经支持自动装配，理论上可以不写 &lt;code&gt;@EnableDubbo&lt;/code&gt;。但项目里如果用到了包路径扫描（比如服务接口分散在多个包下），写上 &lt;code&gt;@EnableDubbo&lt;/code&gt; 并配合 &lt;code&gt;@DubboService&lt;/code&gt;/&lt;code&gt;@DubboReference&lt;/code&gt; 会更稳妥，所以很多老项目和教程里都保留了这个注解。新人照着现有代码来就行。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4.3 Dubbo 使用时的注意事项&lt;a href=&quot;#43-dubbo-使用时的注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;1）接口模块要独立&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Dubbo 的服务接口（如 &lt;code&gt;UserService&lt;/code&gt;）通常放在一个独立的 &lt;code&gt;api&lt;/code&gt; 模块中，服务提供方和消费方都依赖这个模块。这样消费方不需要依赖服务提供方的整个项目，只需要知道接口定义就行。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）序列化问题&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Dubbo 远程调用时，传输的对象需要能被序列化。所以 DTO 类一定要实现 &lt;code&gt;Serializable&lt;/code&gt; 接口：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Serializable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt; serialVersionUID &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;1L&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; id&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; name&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3）版本号&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Dubbo 支持给同一个接口配置不同的版本号，在做接口升级时非常有用：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 服务提供方&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboService&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;2.0&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserServiceImplV2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 服务消费方&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;2.0&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;4）超时和重试配置&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Dubbo 的超时和重试配置在后面”远程调用失败怎么办”章节会详细讲，这里先知道有这个概念就行。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5）Dubbo 和 OpenFeign 在 Nacos 服务列表中的区别&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;使用 OpenFeign 的项目，所有服务都会注册到 Nacos 服务列表中，不管是调用方还是被调用方。&lt;/p&gt;&lt;p&gt;但 Dubbo 不一样：&lt;strong&gt;只有服务提供者会注册到 Nacos 服务列表，消费者默认不会注册。&lt;/strong&gt; 消费者只是订阅它需要调用的服务，不会把自己作为”服务”注册上去。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/4ed88e5f-9741-45b0-be2e-f02f4a4077c5.png&quot; alt=&quot;5&quot; /&gt;&lt;figcaption&gt;5&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;所以如果你用的是 Dubbo，在 Nacos 服务列表里只看到提供者、看不到消费者，这是正常的，不是配置问题。想确认消费者是否正常工作，可以在 Nacos 控制台点进某个服务，查看它的”订阅者列表”（注意：Dubbo 3.x 中订阅者的应用名可能显示为 “unknown”，这也是正常现象，不影响实际调用）。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/d702de00-368f-4d0e-954a-0f1da4e31fdc.png&quot; alt=&quot;6&quot; /&gt;&lt;figcaption&gt;6&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4.4 怎么快速判断项目用的是哪种？&lt;a href=&quot;#44-怎么快速判断项目用的是哪种&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;入职后，快速判断项目远程调用方式的方法：&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;特征&lt;/th&gt;&lt;th&gt;OpenFeign&lt;/th&gt;&lt;th&gt;Dubbo&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;看依赖&lt;/td&gt;&lt;td&gt;有 spring-cloud-starter-openfeign&lt;/td&gt;&lt;td&gt;有 dubbo-spring-boot-starter&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;看注解&lt;/td&gt;&lt;td&gt;有 @FeignClient&lt;/td&gt;&lt;td&gt;有 @DubboService、@DubboReference（3.x）或 @Service、@Reference（2.x）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;看配置&lt;/td&gt;&lt;td&gt;有 feign 相关配置&lt;/td&gt;&lt;td&gt;有 dubbo 相关配置&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;看项目结构&lt;/td&gt;&lt;td&gt;不一定有独立 api 模块&lt;/td&gt;&lt;td&gt;通常有独立的 api/接口模块&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：有些项目可能同时用了 OpenFeign 和 Dubbo。比如内部服务间调用用 Dubbo（性能更好），调用外部系统用 OpenFeign（走 HTTP 更通用）。碰到这种情况不要奇怪。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、远程调用失败怎么办？&lt;a href=&quot;#5远程调用失败怎么办&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;5.1 超时配置&lt;a href=&quot;#51-超时配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;不管是 OpenFeign 还是 Dubbo，都需要合理配置超时时间。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OpenFeign 超时配置&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;feign&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;client&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;connectTimeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;5000&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;# 连接超时 5 秒&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;readTimeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;10000&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;# 读取超时 10 秒&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Dubbo 超时配置&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;consumer&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;5000&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# 全局超时 5 秒&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;也可以在注解上针对单个服务设置超时：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;timeout&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;10000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：正常情况下不需要单独设置超时时间，公司一般通过 Nacos 远程配置统一管理，或者直接使用框架默认值。除非你新写的接口调用比较耗时，而且已经优化到极限、业务方也可以接受，这时候再去修改超时配置。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.2 重试&lt;a href=&quot;#52-重试&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;有些临时性的网络抖动，重试一次可能就好了。但重试要谨慎，因为&lt;strong&gt;很多时候，请求超时并不代表业务一定失败&lt;/strong&gt;。比如下游服务可能已经成功执行了，只是响应返回过程中超时了，如果此时直接重试，可能会导致重复下单、重复扣款等问题。&lt;/p&gt;&lt;p&gt;正因为如此，大部分项目不会在远程调用层面对所有接口统一开启自动重试。通常只会对查询类、幂等接口做有限重试，而新增、扣减、支付类接口一般会禁用自动重试。&lt;/p&gt;&lt;p&gt;处理方式有两种思路：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;直接禁用重试&lt;/strong&gt;：简单粗暴，非幂等接口设置 &lt;code&gt;retries = 0&lt;/code&gt;，大部分项目用这种&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;把接口做成幂等&lt;/strong&gt;：比如下单接口用唯一订单号做去重，扣款接口用唯一交易流水号做去重，同样的请求只处理一次。这样即使重试也不会重复操作，但需要额外开发去重逻辑&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：OpenFeign 默认不重试，调用失败直接抛异常，所以一般不需要额外配置。Dubbo 默认会重试 2 次（总共调用 3 次），非幂等接口一定要手动设置 &lt;code&gt;retries = 0&lt;/code&gt;，否则可能会重复操作。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;如果确实需要 OpenFeign 开启重试（比如查询类接口），配置一个 &lt;code&gt;Retryer&lt;/code&gt; Bean 即可：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FeignConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Bean&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Retryer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;retryer&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 参数：初始间隔(ms)、最大间隔(ms)、最大尝试次数（含首次调用）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; Retryer.&lt;/span&gt;&lt;span&gt;Default&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：这是全局配置，对所有 FeignClient 生效。如果项目中既有查询接口（可重试）又有写入接口（不可重试），就不要全局开启，可以在 &lt;code&gt;@FeignClient&lt;/code&gt; 的 &lt;code&gt;configuration&lt;/code&gt; 属性上针对单个客户端指定配置。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;如果用的是 Dubbo，可以通过配置或注解设置重试次数：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dubbo&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;consumer&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;retries&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;       &lt;/span&gt;&lt;span&gt;# 全局重试 2 次（总共调用 3 次）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;也可以在注解上针对单个服务设置：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;retries&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 不重试（非幂等接口建议关闭）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; orderService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;retries&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 重试 2 次（查询类接口可以开）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.3 降级（Fallback）&lt;a href=&quot;#53-降级fallback&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;降级就是调用失败时，不直接报错，而是返回一个兜底结果：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;FeignClient&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;user-service&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fallback&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;UserClientFallback&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserClient&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/user/{id}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(@&lt;/span&gt;&lt;span&gt;PathVariable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 降级类&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserClientFallback&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserClient&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fallback&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;fallback&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setId&lt;/span&gt;&lt;span&gt;(id);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;fallback&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;未知用户&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; fallback;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;踩坑提醒&lt;/strong&gt;：Spring Cloud 2020+ 移除了 Hystrix，如果项目中没有引入替代的断路器依赖（如 &lt;code&gt;spring-cloud-starter-circuitbreaker-resilience4j&lt;/code&gt;），或者没有在配置文件中开启 &lt;code&gt;spring.cloud.openfeign.circuitbreaker.enabled=true&lt;/code&gt;，&lt;code&gt;fallback&lt;/code&gt; 属性会&lt;strong&gt;静默失效&lt;/strong&gt;，不报错也不降级。另外，降级类一定要加 &lt;code&gt;@Component&lt;/code&gt; 注解，否则 Spring 不认识它，fallback 同样不会生效。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Dubbo 没有像 OpenFeign 那样内置的 &lt;code&gt;fallback&lt;/code&gt; 参数，但可以通过 &lt;code&gt;mock&lt;/code&gt; 属性声明降级逻辑：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DubboReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;return null&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UserService&lt;/span&gt;&lt;span&gt; userService&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;mock&lt;/code&gt; 的几种写法：&lt;/p&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;mock = “return null”&lt;/td&gt;&lt;td&gt;调用失败直接返回 null&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mock = “return 默认值”&lt;/td&gt;&lt;td&gt;比如 return new UserDTO()&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mock = “force: return null”&lt;/td&gt;&lt;td&gt;不管调用是否失败，直接返回 null（用于手动关闭某个调用）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mock = “com.example.MockUserService”&lt;/td&gt;&lt;td&gt;指定一个 Mock 类，实现完整的降级逻辑&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：&lt;code&gt;mock&lt;/code&gt; 方式虽然简单，但大部分项目中用得不多，很多项目直接不配降级，远程调用失败就抛异常，由全局异常处理器统一处理。入职后先看项目里有没有现成的写法，照着来就行。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;不过，降级不是所有项目都会用。有些公司要求每个远程调用都配置降级；也有很多项目不配降级，远程调用失败就直接抛异常，由全局异常处理器统一处理。两种方式都可以，取决于公司的技术规范。入职后先看项目里有没有降级相关的代码，照着现有写法来就行。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：配置了 fallback 的话，降级类里返回的值要合理。比如查询用户信息失败，返回”未知用户”是合理的；但如果下单接口失败返回”下单成功”，那就会出大问题。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.4 熔断(了解)&lt;a href=&quot;#54-熔断了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;熔断和降级通常会配合使用。当某个服务调用失败率过高、响应时间过长，或者异常次数达到阈值后，熔断器会暂时阻止继续调用下游服务，避免故障扩散。此时系统通常会进入降级逻辑，返回默认值、缓存数据或友好提示。就像家里的保险丝，电流过大时自动断开，保护整个电路不烧毁。&lt;/p&gt;&lt;p&gt;常见的熔断框架有 &lt;strong&gt;Sentinel&lt;/strong&gt; 和 &lt;strong&gt;Resilience4j&lt;/strong&gt;，国内企业用 Sentinel 比较多。早期的 Hystrix 目前已经停止维护，新项目基本不再使用。&lt;/p&gt;&lt;p&gt;如果项目用了 Sentinel，通常会通过 &lt;code&gt;@SentinelResource&lt;/code&gt; 注解标记需要保护的远程调用方法，然后在 Sentinel 控制台上配置熔断规则。&lt;/p&gt;&lt;p&gt;不过，&lt;strong&gt;熔断在很多公司的项目中并没有使用&lt;/strong&gt;。因为熔断、限流等治理功能会增加系统复杂度，需要额外维护规则、监控和告警。对于访问量不大、服务链路不复杂的项目，很多公司不会专门引入完整的熔断体系，只用 Nacos + OpenFeign/Dubbo + Gateway 就够了。所以入职后发现项目里没有熔断相关的代码，不要觉得奇怪。先了解公司有没有用，如果有就学一下 Sentinel 的用法，如果没有就不用管。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6、远程调用时需要注意的问题&lt;a href=&quot;#6远程调用时需要注意的问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1）不要循环调用远程接口&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 错误示范：循环调用远程接口，性能极差&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; order &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; orders) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt; user &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setUserName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getName&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;如果列表有 100 条数据，就要发 100 次远程调用，性能会非常差。&lt;/p&gt;&lt;p&gt;正确做法是&lt;strong&gt;提供一个批量查询接口&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 正确做法：批量查询&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; userIds &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orders&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stream&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;(Order&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;getUserId).&lt;/span&gt;&lt;span&gt;collect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Collectors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toList&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;UserDTO&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; users &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;listUsersByIds&lt;/span&gt;&lt;span&gt;(userIds);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2）远程调用报”找不到服务”或”No provider available”&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这是远程调用最常见的报错之一，但问题根源通常不在调用代码本身，而是注册中心层面的问题（服务没注册上、命名空间/分组不一致等）。排查思路见前面「注册中心」章节的常见问题。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）本地调试时注意环境隔离，避免请求打到远程实例&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;本地开发时，你的服务和线上/测试环境的服务都注册在同一个 Nacos 上。这时候远程调用可能会被负载均衡到别人的实例上，而不是你本地启动的实例。表现就是：你明明改了代码，但调用时发现没生效，断点也进不去。&lt;/p&gt;&lt;p&gt;解决方法在前面「注册中心」章节的注意事项里有详细说明（独立命名空间、Dubbo 改版本号等），这里不再重复。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、API 网关&lt;a href=&quot;#三api-网关&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、为什么需要 API 网关？&lt;a href=&quot;#1为什么需要-api-网关&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在微服务架构下，系统被拆分成了多个独立服务，每个服务都有自己的地址。如果让前端直接调各个服务，会有一堆问题：前端要维护多个服务地址、每个服务各自做鉴权逻辑重复、跨域问题无法统一处理、没有统一入口做限流。&lt;/p&gt;&lt;p&gt;所以，微服务架构下通常会引入 &lt;strong&gt;API 网关&lt;/strong&gt;，作为整个系统的&lt;strong&gt;统一入口&lt;/strong&gt;。网关的核心功能：&lt;/p&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;/td&gt;&lt;td&gt;根据请求路径，把请求转发到对应的微服务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;统一鉴权&lt;/td&gt;&lt;td&gt;在网关层统一校验 Token 和权限，不需要每个服务各自处理&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;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单理解&lt;/strong&gt;：网关就像一栋大楼的前台。你要找不同部门的人，不需要自己记住每个人在哪个房间，只需要到前台，前台帮你转接到对应的房间。同时，前台还会检查你的身份（鉴权）、控制来访人数（限流）。&lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;前端 / 客户端&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;API 网关（统一入口）—— 鉴权、限流、日志、路由转发&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;┌────┴────┬────────┐&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓         ↓         ↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户服务   订单服务   商品服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;常见的网关有 &lt;strong&gt;Spring Cloud Gateway&lt;/strong&gt;（Spring 官方，目前国内使用最广泛）、&lt;strong&gt;Zuul&lt;/strong&gt;（Netflix 开源，已停止维护）、&lt;strong&gt;Kong&lt;/strong&gt;（基于 Nginx + Lua）。目前新项目基本都用 Spring Cloud Gateway。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、Spring Cloud Gateway 快速上手&lt;a href=&quot;#2spring-cloud-gateway-快速上手&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1）添加依赖&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.springframework.cloud&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;spring-cloud-starter-gateway&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：Gateway 基于 Netty + WebFlux，因此网关模块中一般不要再引入 &lt;code&gt;spring-boot-starter-web&lt;/code&gt;（Spring MVC），否则容易出现 Web 容器冲突导致启动失败。只是网关模块不能用 Spring MVC，其他业务服务正常使用 Spring MVC 没有问题。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;2）配置路由规则&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;以若依微服务版的网关配置为例（国内使用非常广泛的开源框架）：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;spring&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;cloud&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;gateway&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;routes&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# 认证中心&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ruoyi-auth&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;lb://ruoyi-auth&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;predicates&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;Path=/auth/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;filters&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;CacheRequestFilter&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# 自定义过滤器：缓存请求体&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;ValidateCodeFilter&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# 自定义过滤器：校验验证码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;StripPrefix=1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# 系统模块&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ruoyi-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;lb://ruoyi-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;predicates&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;Path=/system/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;filters&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;StripPrefix=1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# 代码生成&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ruoyi-gen&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;lb://ruoyi-gen&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;predicates&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;Path=/code/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;filters&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;StripPrefix=1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# 定时任务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ruoyi-job&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;lb://ruoyi-job&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;predicates&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;Path=/schedule/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;filters&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;StripPrefix=1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# 文件服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ruoyi-file&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;lb://ruoyi-file&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;predicates&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;Path=/file/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;filters&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;StripPrefix=1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;每条路由的核心就三个配置：&lt;/p&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;uri: lb://服务名&lt;/td&gt;&lt;td&gt;转发到哪个服务。lb:// 表示从注册中心获取地址并负载均衡&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;predicates: Path=/**&lt;/td&gt;&lt;td&gt;什么样的请求路径匹配这条路由&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;filters: StripPrefix=1&lt;/td&gt;&lt;td&gt;转发前去掉第一段路径&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;StripPrefix 为什么要去掉？&lt;/strong&gt; 因为前端请求的路径带前缀（如 &lt;code&gt;/auth/login&lt;/code&gt;），但服务端 Controller 的路径不带（如 &lt;code&gt;@PostMapping(&quot;/login&quot;)&lt;/code&gt;）。&lt;code&gt;/auth&lt;/code&gt; 只是网关用来区分”转发给哪个服务”的标识，转发前必须去掉，否则服务匹配不到路径会返回 404。StripPrefix 配几段取决于 Controller 的实际路径，入职后看项目里怎么配的就行。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;另外注意 &lt;code&gt;ruoyi-auth&lt;/code&gt; 路由多配了两个东西：&lt;code&gt;CacheRequestFilter&lt;/code&gt; 和 &lt;code&gt;ValidateCodeFilter&lt;/code&gt;。这两个就是&lt;strong&gt;过滤器（Filter）&lt;/strong&gt;——请求在转发到服务之前，先经过过滤器处理。比如 &lt;code&gt;ValidateCodeFilter&lt;/code&gt; 会在登录请求到达认证服务之前，先校验验证码是否正确，不对的话直接拦截，不用等到服务层才报错。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）启动类&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;SpringBootApplication&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;GatewayApplication&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;[] &lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;SpringApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;GatewayApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;, args);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;只要配置了 Nacos 地址，Gateway 会自动从注册中心发现服务，不需要额外写代码。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、常见问题&lt;a href=&quot;#3常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;3.1 放开接口时，网关层和服务层都要放&lt;a href=&quot;#31-放开接口时网关层和服务层都要放&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;这是一个新人特别容易踩的坑。&lt;/p&gt;&lt;p&gt;很多项目中，网关层会做统一鉴权（Token 校验、权限检查等），不在白名单里的请求会被网关直接拦截，根本到不了后端服务。所以当你需要放开某个接口（比如登录、注册、公共查询等无需登录就能访问的接口）时，&lt;strong&gt;不能只在服务层放开，网关层也要同步放开&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;举个例子：你写了一个 &lt;code&gt;/system/register&lt;/code&gt; 注册接口，不需要登录就能访问。你在系统服务里把 Security 配置放开了，但前端调用时还是返回 401。原因是：请求先到了网关，网关的鉴权过滤器发现没有 Token，直接返回 401 了，请求根本没到你的系统服务。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;前端请求 /system/register（没带 Token）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;网关鉴权过滤器 → 没有 Token → 直接返回 401 ❌&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ （请求根本没到系统服务）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;系统服务（你配的放开规则没机会生效）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;正确做法：在网关的鉴权过滤器白名单中，也把这个接口加上。&lt;/strong&gt; 比如前面示例中的 &lt;code&gt;AuthGlobalFilter&lt;/code&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 白名单路径（不需要鉴权的接口）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;startsWith&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/auth/login&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;startsWith&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/system/register&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// ← 加上需要放开的接口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;startsWith&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/file/public&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;chain&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;filter&lt;/span&gt;&lt;span&gt;(exchange);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单记&lt;/strong&gt;：微服务架构下，一个请求要经过网关 → 服务两道关。放开接口时两道关都要放，少放一个就会被拦住。排查 401、403 问题时，先确认是网关拦的还是服务拦的，不要只盯着服务层看。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2 通过接口路径定位到哪个服务处理的&lt;a href=&quot;#32-通过接口路径定位到哪个服务处理的&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;入职后经常会遇到这种情况：前端跟你说某个接口报错了，你拿到接口路径（比如 &lt;code&gt;/system/user/list&lt;/code&gt;），但不知道这个请求最终是由哪个后端服务处理的。这时候就可以通过网关的路由规则来定位。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;定位步骤：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）找到网关的路由配置&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;路由配置一般在网关模块的 &lt;code&gt;application.yml&lt;/code&gt;（或 &lt;code&gt;bootstrap.yml&lt;/code&gt;）里，也可能在 Nacos 的网关配置中。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）用请求路径匹配路由规则&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;比如接口路径是 &lt;code&gt;/system/user/list&lt;/code&gt;，对照路由规则：匹配 &lt;code&gt;Path=/system/**&lt;/code&gt;，对应的 &lt;code&gt;uri&lt;/code&gt; 是 &lt;code&gt;lb://ruoyi-system&lt;/code&gt;，所以这个接口是 &lt;strong&gt;ruoyi-system&lt;/strong&gt; 处理的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）确认转发后的实际路径&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;由于配了 &lt;code&gt;StripPrefix=1&lt;/code&gt;，转发前会去掉第一段 &lt;code&gt;/system&lt;/code&gt;，所以 ruoyi-system 收到的请求路径是 &lt;code&gt;/user/list&lt;/code&gt;，对应 Controller 里的 &lt;code&gt;@GetMapping(&quot;/user/list&quot;)&lt;/code&gt;。&lt;/p&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;/th&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;/auth/login&lt;/td&gt;&lt;td&gt;Path=/auth/**&lt;/td&gt;&lt;td&gt;ruoyi-auth&lt;/td&gt;&lt;td&gt;/login&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/system/user/list&lt;/td&gt;&lt;td&gt;Path=/system/**&lt;/td&gt;&lt;td&gt;ruoyi-system&lt;/td&gt;&lt;td&gt;/user/list&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/code/gen/tables&lt;/td&gt;&lt;td&gt;Path=/code/**&lt;/td&gt;&lt;td&gt;ruoyi-gen&lt;/td&gt;&lt;td&gt;/gen/tables&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/file/upload&lt;/td&gt;&lt;td&gt;Path=/file/**&lt;/td&gt;&lt;td&gt;ruoyi-file&lt;/td&gt;&lt;td&gt;/upload&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：如果请求路径没有匹配到任何路由规则，网关会直接返回 404。如果匹配到了但目标服务不可用，网关会返回 502。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;常见问题排查&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;接口返回 404&lt;/strong&gt;：先确认路由规则是否匹配你的接口路径，再确认 &lt;code&gt;StripPrefix&lt;/code&gt; 配置是否正确（比如接口实际路径是 &lt;code&gt;/user/list&lt;/code&gt;，但 &lt;code&gt;StripPrefix&lt;/code&gt; 多去了一段，转发后变成 &lt;code&gt;/list&lt;/code&gt;，服务里根本匹配不到）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接口返回 502&lt;/strong&gt;：通常表示网关调用下游服务失败，不一定是服务宕机，也可能是服务未注册、连接超时、网络异常等原因。先确认服务是否注册成功，再确认服务本身是否正常（直接调服务 IP 看看能不能通）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本地调试时可以先绕过网关&lt;/strong&gt;：如果网关出了问题不好排查，先直接请求你自己服务的本地端口，确认接口本身没问题。服务没问题之后，再去看网关层面的问题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在浏览器控制台（F12 → Network）看到接口请求&lt;/strong&gt;，对照路由规则就能快速定位到对应的服务&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.3 跨域处理（了解）&lt;a href=&quot;#33-跨域处理了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;前端页面直接请求多个不同地址的服务会碰到跨域问题。在微服务架构下，跨域&lt;strong&gt;最理想的做法是在网关层统一处理&lt;/strong&gt;，比如在网关模块里写一个跨域过滤器（实现 &lt;code&gt;WebFilter&lt;/code&gt;），统一设置跨域响应头，这样所有经过网关的请求都不用再单独处理。&lt;/p&gt;&lt;p&gt;但真实项目中，不一定都在网关层做。也有可能通过以下方式处理：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;在业务服务的公共模块里统一配置&lt;/strong&gt;：所有服务都依赖一个公共模块（如 framework、common），在公共模块里通过 &lt;code&gt;CorsFilter&lt;/code&gt; 统一处理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在 Nginx 层处理&lt;/strong&gt;：有些项目在 Nginx 反向代理时直接加跨域头，请求还没到网关就解决了&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;按需单独处理&lt;/strong&gt;：只在需要的接口上单独配，比如通过 &lt;code&gt;WebMvcConfigurer.addCorsMappings()&lt;/code&gt; 或在 Controller 上加 &lt;code&gt;@CrossOrigin&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以入职后，遇到跨域问题先看项目里是怎么处理的，不要自己加配置，可能和已有的配置冲突。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、锁与并发问题&lt;a href=&quot;#四锁与并发问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、为什么微服务下并发问题更复杂？&lt;a href=&quot;#1为什么微服务下并发问题更复杂&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在单体项目里，如果多个线程同时操作同一份数据，可以用 Java 自带的锁（如 &lt;code&gt;synchronized&lt;/code&gt;、&lt;code&gt;ReentrantLock&lt;/code&gt;）来解决：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 单体项目：用 synchronized 就行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;synchronized&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; stock &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;getStock&lt;/span&gt;&lt;span&gt;&lt;span&gt;(productId)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (stock &lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;deductStock&lt;/span&gt;&lt;span&gt;&lt;span&gt;(productId)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;但在微服务架构下，同一个服务可能会部署多个实例（多台机器），每个实例都是独立的 JVM。这时候，Java 自带的锁就只能锁住自己这台机器上的线程，&lt;strong&gt;其他机器上的线程完全不受影响&lt;/strong&gt;。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;实例 A（JVM 1）: synchronized → 只能锁住实例 A 内部的线程&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;实例 B（JVM 2）: synchronized → 只能锁住实例 B 内部的线程&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;实例 C（JVM 3）: synchronized → 只能锁住实例 C 内部的线程&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;也就是说，Java 自带的锁在多实例部署的情况下，&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;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/810d9b1a-e630-4f3d-aefa-2ea4cfd6795b.png&quot; alt=&quot;8&quot; /&gt;&lt;figcaption&gt;8&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、什么是分布式锁？&lt;a href=&quot;#2什么是分布式锁&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;分布式锁，就是&lt;strong&gt;让多个服务实例在操作同一份数据时，也能做到互斥&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;不管是哪台机器上的线程，谁先抢到锁，谁就能执行；其他线程必须等锁释放后才能继续。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;实例 A → 抢锁 → 成功 → 执行业务 → 释放锁&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;实例 B → 抢锁 → 失败，等待&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;实例 C → 抢锁 → 失败，等待&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、常见的分布式锁实现方式&lt;a href=&quot;#3常见的分布式锁实现方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;Redis 分布式锁&lt;/td&gt;&lt;td&gt;最常用，基于 Redis 的 SETNX 命令实现&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Redisson&lt;/td&gt;&lt;td&gt;基于 Redis 的分布式锁框架，封装得更完善&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ZooKeeper 分布式锁&lt;/td&gt;&lt;td&gt;基于 ZooKeeper 的临时顺序节点实现&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;p&gt;其中，&lt;strong&gt;Redis + Redisson 是企业里用得最多的方案&lt;/strong&gt;。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、Redis 分布式锁的基本原理&lt;a href=&quot;#4redis-分布式锁的基本原理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;最简单的实现方式是借助 Redis 的 &lt;code&gt;SETNX&lt;/code&gt; 命令，核心思路就三步：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;抢锁&lt;/strong&gt;：往 Redis 写一个 key，谁先写成功谁就拿到锁（&lt;code&gt;SETNX&lt;/code&gt; = set if not exists，key 不存在才写入成功）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;设过期时间&lt;/strong&gt;：防止拿到锁的服务突然宕机，导致锁永远不释放&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;释放锁&lt;/strong&gt;：业务执行完，把这个 key 删掉&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;下面是一个最简实现（基于 &lt;code&gt;StringRedisTemplate&lt;/code&gt;），只有两个方法：&lt;code&gt;tryLock&lt;/code&gt; 抢锁、&lt;code&gt;unlock&lt;/code&gt; 释放锁：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SimpleRedisLock&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StringRedisTemplate&lt;/span&gt;&lt;span&gt; redisTemplate&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 尝试获取锁（不阻塞，拿不到立即返回 false）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* &lt;/span&gt;&lt;span&gt;@param&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;     锁的 key，例如 &quot;lock:job:order_report_daily&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* &lt;/span&gt;&lt;span&gt;@param&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;expire&lt;/span&gt;&lt;span&gt;  锁的过期时间（防止宕机后锁不释放）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* &lt;/span&gt;&lt;span&gt;@param&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;unit&lt;/span&gt;&lt;span&gt;    时间单位&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tryLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;expire&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;unit&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// setIfAbsent 就是 SETNX：key 不存在才写入&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 这里用 4 参数版本，把&quot;设值 + 设过期时间&quot;合成一步，保证原子性&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TRUE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForValue&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;setIfAbsent&lt;/span&gt;&lt;span&gt;(key, &lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;, expire, unit)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/** 释放锁：把 key 删掉 */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;unlock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(key);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;小贴士&lt;/strong&gt;：早期写法是先 &lt;code&gt;SETNX&lt;/code&gt; 设值、再单独 &lt;code&gt;expire&lt;/code&gt; 设过期时间，两步之间如果服务宕机，锁就永远不释放了。现在推荐用上面这种「设值 + 过期时间一条命令完成」的 4 参数版本，从根上避免这个坑。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;工作中的一个使用场景是&lt;strong&gt;定时任务防重复执行&lt;/strong&gt;（多台机器都部署了同一个定时任务，但只希望其中一台真正执行）：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SimpleRedisLock&lt;/span&gt;&lt;span&gt; redisLock&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cron&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;30 30 0 * * ?&quot;&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 每天 00:30:30 执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;generateDailyReport&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 1. 抢锁，过期时间设 6 小时（只要够任务跑完就行）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; locked &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisLock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;lock:job:order_report_daily&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;HOURS&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 2. 没抢到锁，说明其他机器正在执行，本次直接跳过&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;locked) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;其他实例正在执行，本次跳过&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 3. 抢到了，执行业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;reportService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;generateDailyReport&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;finally&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 4. 跑完后释放锁（放 finally 里，即使抛异常也能释放）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;redisLock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unlock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;lock:job:order_report_daily&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：这种基于 &lt;code&gt;SETNX&lt;/code&gt; 的实现比较简单，适合定时任务这种”获取失败就跳过”的场景。但对于库存扣减、订单处理这种需要等待锁释放的业务场景，一般用 Redisson。真实项目里通常不会让你从零写这套工具类，公司大概率已经有现成的封装（比如下面 Redisson 那节会提到的自定义注解）。先看项目里已有的，有的话直接用。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、Redisson 分布式锁的基本用法&lt;a href=&quot;#5redisson-分布式锁的基本用法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;第 4 节那套 SETNX 锁要自己处理过期时间、释放时机等一堆边界问题。而 Redisson 作为成熟的分布式锁框架，已经把这些都封装好了（比如锁续期、可重入、公平锁等），实际项目里基本都用它。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;Redisson 加锁 API 速览&lt;a href=&quot;#redisson-加锁-api-速览&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Redisson 加锁常用的方法就下面几个，先有个整体印象，看后面的代码才不懵：&lt;/p&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;lock.lock()&lt;/td&gt;&lt;td&gt;阻塞等待，一直等到拿到锁为止&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;lock.lock(10, TimeUnit.SECONDS)&lt;/td&gt;&lt;td&gt;阻塞等待，但显式指定过期时间（这里是 10 秒），到点强制释放&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;lock.tryLock(5, 30, TimeUnit.SECONDS)&lt;/td&gt;&lt;td&gt;带超时返回：最多等 5 秒，拿不到就返回 false；拿到后锁 30 秒强制释放&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;lock.unlock()&lt;/td&gt;&lt;td&gt;释放锁&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;简单记：&lt;strong&gt;&lt;code&gt;lock&lt;/code&gt; 是”抢不到就一直等”，&lt;code&gt;tryLock&lt;/code&gt; 是”等一会儿就算了”&lt;/strong&gt;。至于”不写过期时间会不会出问题”，下面会专门讲。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.1 Redisson 原生写法&lt;a href=&quot;#51-redisson-原生写法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;下面是一个电商项目中&lt;strong&gt;库存锁定&lt;/strong&gt;的真实代码，使用 Redisson 的 &lt;code&gt;lock()&lt;/code&gt; 方法：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedissonClient&lt;/span&gt;&lt;span&gt; redissonClient&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Transactional&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rollbackFor&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lockStock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;StockLockParam&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; stockLockParams) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;RLock&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; locks &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ArrayList&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;StockLockParam&lt;/span&gt;&lt;span&gt; param &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; stockLockParams) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 1. 按商品 SKU ID 获取锁（每个商品一把锁，粒度细）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;RLock&lt;/span&gt;&lt;span&gt; lock &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redissonClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;lock:stock:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;param&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getSkuId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 2. 加锁（阻塞等待，直到获取成功）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;locks&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(lock);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 3. 执行业务逻辑：校验库存 → 扣减库存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; stock &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;stockService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getStock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;param&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getSkuId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (stock &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;param&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getCount&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;库存不足&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;stockService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deductStock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;param&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getSkuId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;param&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getCount&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 4. 保存库存锁定记录&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;stockLockMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;saveBatch&lt;/span&gt;&lt;span&gt;(stockLockParams);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 5. 发送延时消息，1小时后自动解锁库存（订单超时未支付场景）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;mqTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;syncSend&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;stock-unlock-topic&quot;&lt;/span&gt;&lt;span&gt;, orderIds);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;finally&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 6. 释放所有锁（只释放当前线程持有的，避免释放别人的锁）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;RLock&lt;/span&gt;&lt;span&gt; lock &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; locks) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isHeldByCurrentThread&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unlock&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：这里用 &lt;code&gt;lock.lock()&lt;/code&gt; 阻塞等待，保证一定拿到锁才继续执行。获取锁后，通过 &lt;code&gt;isHeldByCurrentThread()&lt;/code&gt; 判断再释放，防止释放别人的锁。锁的粒度是 &lt;strong&gt;SKU 级别&lt;/strong&gt;（&lt;code&gt;lock:stock:{skuId}&lt;/code&gt;），不是整个订单，并发性能更好。&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;疑问：上面 &lt;code&gt;lock.lock()&lt;/code&gt; 没有写过期时间，会不会出问题？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;不会。这正是 Redisson 和手写 SETNX 锁（第 4 节那种）最大的区别——&lt;strong&gt;无参的 &lt;code&gt;lock.lock()&lt;/code&gt; 会自动带过期时间，并启动”看门狗”机制自动续期&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;拿到锁时，Redisson 在底层设了一个默认过期时间（默认 30 秒）&lt;/li&gt;
&lt;li&gt;同时启动一个后台线程（看门狗），每隔 10 秒检查一次：“这个锁还被当前线程持有吗？是的话，把过期时间重新刷回 30 秒”&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这样就化解了一个矛盾：业务没跑完时一直续期，不会出现”锁提前过期、别人插队”的超卖问题；而服务一旦宕机，看门狗也跟着死了，锁最多 30 秒后自动释放，不会永远卡死。&lt;/p&gt;&lt;p&gt;⚠️ &lt;strong&gt;反直觉的坑&lt;/strong&gt;：一旦你&lt;strong&gt;显式指定过期时间&lt;/strong&gt;（比如 &lt;code&gt;lock.lock(10, SECONDS)&lt;/code&gt; 或 &lt;code&gt;tryLock(5, 30, SECONDS)&lt;/code&gt;），&lt;strong&gt;看门狗就不会启动了&lt;/strong&gt;，锁到点强制释放，哪怕业务还没跑完。所以要么用无参 &lt;code&gt;lock.lock()&lt;/code&gt;（靠看门狗），要么自己估算一个足够长的过期时间，别设太短。&lt;/p&gt;&lt;p&gt;下面是一个 &lt;code&gt;tryLock&lt;/code&gt; 的例子，抢锁失败时还能给用户一个友好提示：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;RLock&lt;/span&gt;&lt;span&gt; lock &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redissonClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;lock:product:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; productId);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;30&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SECONDS&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;) {   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 最多等 5 秒；拿到后锁 30 秒强制释放&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;doDeductStock&lt;/span&gt;&lt;span&gt;&lt;span&gt;(productId)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;finally&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unlock&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;系统繁忙，请稍后重试&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 抢锁失败，给用户友好提示&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;InterruptedException&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Thread&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;currentThread&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;interrupt&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.2 实际项目中的封装方式&lt;a href=&quot;#52-实际项目中的封装方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在实际开发中，&lt;strong&gt;公司一般会把 Redisson 封装成自定义注解&lt;/strong&gt;，你不会直接写上面的代码。最常见的封装方式是「自定义注解 + AOP」：通过注解声明锁，AOP 切面自动处理加锁和解锁，业务代码完全不感知锁的存在。以下是某项目的真实封装：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 注解定义&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Target&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;span&gt;ElementType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;METHOD&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Retention&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;RetentionPolicy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;RUNTIME&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedissonLock&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;/** 锁的 key，支持 SpEL 表达式，例如：keys = {&quot;#orderId&quot;} */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;[] &lt;/span&gt;&lt;span&gt;keys&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;/** key 前缀，默认用「类名:方法名」 */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;prefix&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;/** 锁超时时间（毫秒），默认 30000ms */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lockTimeout&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;/** 等待加锁超时时间（毫秒），0 表示不等待 */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;waitTimeout&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// AOP 切面实现（核心逻辑）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Aspect&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedissonLockAspect&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RedissonClient&lt;/span&gt;&lt;span&gt; redissonClient&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Around&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;@annotation(RedissonLock)&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;around&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ProceedingJoinPoint&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;joinPoint&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Method&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;targetMethod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ((MethodSignature) &lt;/span&gt;&lt;/span&gt;&lt;span&gt;joinPoint&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getSignature&lt;/span&gt;&lt;span&gt;()).&lt;/span&gt;&lt;span&gt;getMethod&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;RedissonLock&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;annotation&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;targetMethod&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getAnnotation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;RedissonLock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 通过 SpEL 解析锁的 key（例如从参数中取 orderId）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lockKey&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;getLockKey&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;annotation&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;keys&lt;/span&gt;&lt;span&gt;(), targetMethod, &lt;/span&gt;&lt;span&gt;joinPoint&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getArgs&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;keyPrefix&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;targetMethod&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getDeclaringClass&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;getName&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                         &lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;targetMethod&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getName&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 获取锁&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;RLock&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redissonClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;lock:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; keyPrefix &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; lockKey);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lockFlag&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;proceed&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 3. 尝试加锁（带超时）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lockFlag &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;tryLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;annotation&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;waitTimeout&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                                    &lt;/span&gt;&lt;span&gt;annotation&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;lockTimeout&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MILLISECONDS&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (lockFlag) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;// 4. 获取成功，执行业务方法&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;proceed &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;joinPoint&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;proceed&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;finally&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (lockFlag &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isHeldByCurrentThread&lt;/span&gt;&lt;span&gt;()) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;lock&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unlock&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 5. 获取失败，抛异常（防重复提交）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (proceed &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;操作过于频繁，请稍后重试&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; proceed;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;使用时只需加一个注解：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RedissonLock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;keys&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;#orderId&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;waitTimeout&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;5000&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lockTimeout&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;30000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;processOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; orderId) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 业务逻辑，自动被分布式锁保护&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6、分布式锁使用时的注意事项&lt;a href=&quot;#6分布式锁使用时的注意事项&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1）锁的粒度要合理&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;锁的范围要尽量小，只锁住真正需要互斥的操作。比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;不要锁整个方法，只锁住操作共享资源的代码块&lt;/li&gt;
&lt;li&gt;锁的 key 要精确到具体的业务对象，比如 &lt;code&gt;lock:order:123&lt;/code&gt; 而不是 &lt;code&gt;lock:order&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;2）一定要设置过期时间&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;防止服务宕机后锁一直不释放，导致其他服务永远获取不到锁。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）释放锁一定要放在 finally 里&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;保证即使业务代码抛异常，锁也能正常释放。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4）获取锁失败时要处理&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;获取锁失败，说明有其他线程在操作，不能直接忽略。要么返回提示信息让用户重试，要么走其他逻辑。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、事务如何解决&lt;a href=&quot;#五事务如何解决&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、微服务下的事务问题&lt;a href=&quot;#1微服务下的事务问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在单体项目里，事务很好处理，一个 &lt;code&gt;@Transactional&lt;/code&gt; 注解就能搞定：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 单体项目：一个事务搞定&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Transactional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; order) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 写订单表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;orderItemMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;batchInsert&lt;/span&gt;&lt;span&gt;&lt;span&gt;(items);&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 写订单明细表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;productMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deductStock&lt;/span&gt;&lt;span&gt;&lt;span&gt;(productId);&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 扣库存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;但在微服务架构下，这些操作可能分布在不同服务中：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;创建订单 → 订单服务（写订单表、订单明细表）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;扣库存   → 商品服务（扣商品库存）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这时候，&lt;code&gt;@Transactional&lt;/code&gt; 只能保证订单服务自己数据库的事务，商品服务那边出了问题，订单服务是管不了的：&lt;/p&gt;&lt;p&gt;这就是&lt;strong&gt;分布式事务&lt;/strong&gt;问题。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/c260770b-037a-4f06-8f96-33659faed1f2.png&quot; alt=&quot;9&quot; /&gt;&lt;figcaption&gt;9&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、解决分布式事务的常见思路&lt;a href=&quot;#2解决分布式事务的常见思路&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;分布式事务没有完美解决方案，只有&lt;strong&gt;在一致性和性能之间做取舍&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;常见的思路有：&lt;/p&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;2PC（两阶段提交）&lt;/td&gt;&lt;td&gt;准备阶段 + 提交阶段，所有参与者都成功才提交&lt;/td&gt;&lt;td&gt;强一致&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TCC&lt;/td&gt;&lt;td&gt;Try-Confirm-Cancel，手动编写三个阶段的逻辑（Seata 支持此模式，详见 4.5）&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;tr&gt;&lt;td&gt;Seata&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;/section&gt;&lt;section&gt;&lt;h3&gt;3、先搞清楚：大多数业务不需要强一致性&lt;a href=&quot;#3先搞清楚大多数业务不需要强一致性&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;这是新人特别容易纠结的一个点。&lt;/p&gt;&lt;p&gt;很多新人一听到”分布式事务”，就觉得必须保证所有服务的数据实时一致。但实际上，&lt;strong&gt;大部分业务场景只需要最终一致性就够了&lt;/strong&gt;。而且&lt;strong&gt;很多互联网业务项目并不会引入 Seata，而是采用本地事务 + MQ + 补偿机制实现最终一致性；只有一致性要求较高或业务复杂的场景，才可能采用 Seata、TCC 等方案&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;什么叫最终一致性？&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;不要求所有服务的数据在同一时刻完全一致，但经过一段时间后，数据最终会变成一致的。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;比如下单场景：&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;p&gt;用户看到的可能有一小段时间的”不一致”，但最终数据是对的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;哪些场景需要强一致性？&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;转账、支付等金融场景（钱必须实时一致，不能有中间态）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;哪些场景只需要最终一致性？&lt;/strong&gt;&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;p&gt;&lt;strong&gt;关于库存的一个常见疑问&lt;/strong&gt;：库存不是怕超卖吗，为什么也算最终一致性？因为&lt;strong&gt;防止超卖靠的是「分布式锁 + 原子扣减」&lt;/strong&gt;（上一章讲过的 &lt;code&gt;lock:stock:{skuId}&lt;/code&gt;），而不是靠分布式事务——锁保证同一时刻只有一个请求在扣库存，扣减成功后通过 MQ 通知其他服务即可。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;这两个概念新人特别容易混，一定要分清&lt;/strong&gt;：&lt;strong&gt;分布式事务&lt;/strong&gt;解决的是「跨服务数据一致性」问题（A 服务成功了，B 服务也要成功）；&lt;strong&gt;分布式锁&lt;/strong&gt;解决的是「并发竞争」问题（同一时刻只有一个线程能操作）。两者关注点不同，不要混为一谈。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、实际开发中最常见的处理方式&lt;a href=&quot;#4实际开发中最常见的处理方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;说实话，很多中小型公司的微服务项目，并不一定会引入完整的分布式事务框架，甚至有些公司压根不会对分布式事务做系统性处理——出了数据不一致就人工修。原因很简单：&lt;strong&gt;发生事务不一致的概率本身就很低&lt;/strong&gt;（网络正常、服务不宕机的绝大部分时间里，数据都是一致的），如果业务本身能容忍这个极低概率的不一致，那加一堆补偿逻辑、消息表、分布式事务框架反而增加了系统复杂度，得不偿失。&lt;strong&gt;能简单解决的问题就不要用复杂方案，这是 KISS 原则&lt;/strong&gt;。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;4.1 本地事务 + 普通消息（最常用，但有隐患）&lt;a href=&quot;#41-本地事务--普通消息最常用但有隐患&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;这是企业里用得最多的一种方式。&lt;strong&gt;注意这里用的是 MQ 的「普通消息」，不是「事务消息」&lt;/strong&gt;，所以会有一个先天的隐患，下面会专门讲。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;实现思路&lt;/strong&gt;：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/b2266cd1-e4c3-45cc-8284-32138870b6fc.png&quot; alt=&quot;12&quot; /&gt;&lt;figcaption&gt;12&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;代码示例&lt;/strong&gt;（以 RocketMQ 为例）：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）订单服务（生产者）——创建订单后发送扣库存消息&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderMapper&lt;/span&gt;&lt;span&gt; orderMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQTemplate&lt;/span&gt;&lt;span&gt; rocketMQTemplate&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Transactional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 写订单表（本地事务）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 发送消息到 MQ，通知商品服务扣库存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;StockMessage&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StockMessage&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setOrderId&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;());         &lt;/span&gt;&lt;span&gt;// 带上订单 ID，消费端用于幂等校验和取消订单&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setProductId&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getProductId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setQuantity&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getQuantity&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;rocketMQTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;convertAndSend&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;topic-stock-deduct&quot;&lt;/span&gt;&lt;span&gt;, msg);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;//其他业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2）商品服务（消费者）——收到消息后扣库存&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RocketMQMessageListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;topic&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;topic-stock-deduct&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 监听哪个 topic（和生产者发送时的 topic 一致）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;consumerGroup&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;product-service-group&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;// 消费者组名：同一组内只有一台机器消费这条消息，避免重复消费&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StockConsumer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQListener&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;StockMessage&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ProductMapper&lt;/span&gt;&lt;span&gt; productMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderClient&lt;/span&gt;&lt;span&gt; orderClient&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 回调订单服务，用于取消订单&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StringRedisTemplate&lt;/span&gt;&lt;span&gt; redisTemplate&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;onMessage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;StockMessage&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 【幂等校验】防止 MQ 重复投递导致库存被多扣&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// MQ 保证「至少一次」投递，不保证「恰好一次」，所以消费端必须自己做幂等&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lockKey&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;mq:stock:deducted:&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getOrderId&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;alreadyDeducted&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opsForValue&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;setIfAbsent&lt;/span&gt;&lt;span&gt;(lockKey, &lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;TimeUnit&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;HOURS&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TRUE&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;(alreadyDeducted)) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;订单{}已扣过库存，跳过重复消息&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getOrderId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;  &lt;/span&gt;&lt;span&gt;// 已处理过，直接返回&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 扣库存（SQL 里带 stock &amp;gt; 0 条件，原子操作防超卖）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rows&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;productMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deductStock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getProductId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getQuantity&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (rows &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;// 库存不足是「业务异常」，不能靠 MQ 重试解决（重试再多库存还是不够）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;// 正确做法：走业务补偿 —— 通知订单服务取消这张订单&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(lockKey);  &lt;/span&gt;&lt;span&gt;// 清除标记，允许后续如果用户重新下单时能正常处理&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;orderClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;cancelOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getOrderId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;&quot;库存不足&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;   &lt;/span&gt;&lt;span&gt;// 正常返回，消息消费成功，不再重试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 扣库存过程中发生异常（如数据库超时），清除幂等标记&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// 让 MQ 重试时能重新进入，否则 key 会把重试全部挡住&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;redisTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt;(lockKey);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; e;  &lt;/span&gt;&lt;span&gt;// 抛出异常，触发 MQ 重试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3）消息体定义&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;AllArgsConstructor&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;NoArgsConstructor&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StockMessage&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Serializable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; orderId&lt;/span&gt;&lt;span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 订单 ID（用于幂等校验 + 取消订单）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; productId&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Integer&lt;/span&gt;&lt;span&gt; quantity&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;⚠️ 必须知道的隐患&lt;/strong&gt;：上面这段代码有一个经典坑——&lt;strong&gt;&lt;code&gt;@Transactional&lt;/code&gt; 方法里直接调用 &lt;code&gt;rocketMQTemplate.convertAndSend()&lt;/code&gt; 发消息&lt;/strong&gt;。如果消息发出之后，本地事务因为后续代码抛异常而&lt;strong&gt;回滚&lt;/strong&gt;了，会出现：本地数据没写入，但 MQ 消息已经发出去并被下游消费了，导致数据不一致。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;关于消费端的幂等&lt;/strong&gt;：MQ 默认会重试，所以消费端要做幂等处理（比如通过消息 ID 或业务 ID 去重），防止重复消费导致库存多扣。多次重试仍失败的消息会进入死信队列，需要人工介入。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：实现简单，服务间解耦 &lt;strong&gt;缺点&lt;/strong&gt;：有上述”事务回滚但消息已发”的隐患；属于最终一致性，有少量延迟&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4.2 本地消息表 + MQ（推荐）&lt;a href=&quot;#42-本地消息表--mq推荐&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;上面的方案有一个隐患：本地事务和消息发送不在同一个原子操作中。&lt;strong&gt;本地消息表&lt;/strong&gt;就是用来解决这个问题的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;思路&lt;/strong&gt;：不直接发 MQ 消息，而是先在本地数据库里写一条消息记录，和业务数据在同一个事务中，然后由定时任务扫描并发送。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;流程&lt;/strong&gt;：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/8da60f3a-a1c0-47aa-bec8-96c0ee8a61c5.png&quot; alt=&quot;10&quot; /&gt;&lt;figcaption&gt;10&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）消息表结构（参考）&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;CREATE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TABLE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;local_message&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;id          &lt;/span&gt;&lt;span&gt;BIGINT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PRIMARY KEY&lt;/span&gt;&lt;span&gt; AUTO_INCREMENT,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;topic       &lt;/span&gt;&lt;span&gt;VARCHAR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;)    COMMENT &lt;/span&gt;&lt;span&gt;&apos;MQ topic&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;content     &lt;/span&gt;&lt;span&gt;TEXT&lt;/span&gt;&lt;span&gt;            COMMENT &lt;/span&gt;&lt;span&gt;&apos;消息内容（JSON）&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;TINYINT&lt;/span&gt;&lt;span&gt;         COMMENT &lt;/span&gt;&lt;span&gt;&apos;0-待发送 1-已发送 2-发送失败&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;retry_count &lt;/span&gt;&lt;span&gt;INT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;DEFAULT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;   COMMENT &lt;/span&gt;&lt;span&gt;&apos;重试次数&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;create_time &lt;/span&gt;&lt;span&gt;DATETIME&lt;/span&gt;&lt;span&gt;        COMMENT &lt;/span&gt;&lt;span&gt;&apos;创建时间&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;INDEX&lt;/span&gt;&lt;span&gt; idx_status (&lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2）订单服务——在本地事务中同时写入业务数据和消息记录&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderMapper&lt;/span&gt;&lt;span&gt; orderMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;MessageMapper&lt;/span&gt;&lt;span&gt; messageMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Transactional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 写订单表（本地事务）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 2. 写消息表（和业务数据在同一个事务中，保证原子性）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;LocalMessage&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;LocalMessage&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setTopic&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;topic-stock-deduct&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setContent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toJSONString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StockMessage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getProductId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getQuantity&lt;/span&gt;&lt;span&gt;())));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setStatus&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;);  &lt;/span&gt;&lt;span&gt;// 0-待发送&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;messageMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(message);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3）定时任务——扫描消息表并发送&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;MessageScheduler&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;MessageMapper&lt;/span&gt;&lt;span&gt; messageMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQTemplate&lt;/span&gt;&lt;span&gt; rocketMQTemplate&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Scheduled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fixedRate&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;5000&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 每 5 秒扫描一次&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sendPendingMessages&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 查询条件：status != 1（未成功的）且 retry_count &amp;lt;= 5（没超过重试上限）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 这样 status=0（待发送）和 status=2（之前发送失败）的消息都会被查出来重试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;LocalMessage&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;messages&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;messageMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectPendingAndFailed&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;LocalMessage&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; messages) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;rocketMQTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;convertAndSend&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getTopic&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getContent&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setStatus&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);  &lt;/span&gt;&lt;span&gt;// 1-已发送&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;messageMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;updateById&lt;/span&gt;&lt;span&gt;(msg);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setRetryCount&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getRetryCount&lt;/span&gt;&lt;span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setStatus&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;);  &lt;/span&gt;&lt;span&gt;// 标记为失败&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;// 查询条件是 status != 1 AND retry_count &amp;lt;= 5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;// retryCount &amp;lt;= 5 的消息下次扫描依然会被查出来重试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;// retryCount &amp;gt; 5 的消息不会再被查出，留给人工处理&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;messageMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;updateById&lt;/span&gt;&lt;span&gt;(msg);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;warn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;消息发送失败，id={}，重试次数={}&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getRetryCount&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;一句话总结&lt;/strong&gt;：把”发消息”这个不可靠动作，变成”写本地数据库”这个可靠动作，和业务操作绑在同一个事务里，再由定时任务异步发送、失败重试。这是实际项目中最稳妥的最终一致性方案。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：解决了 4.1 的隐患，本地数据与消息严格原子一致 &lt;strong&gt;缺点&lt;/strong&gt;：要额外建一张消息表、配一个定时任务，有少量延迟&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4.3 RocketMQ 事务消息（推荐）&lt;a href=&quot;#43-rocketmq-事务消息推荐&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;本地消息表虽然可靠，但要额外建表 + 定时任务，有点重。&lt;strong&gt;RocketMQ 本身提供了事务消息机制&lt;/strong&gt;，可以不建表就解决 4.1 的隐患。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;原理&lt;/strong&gt;：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-07-24/32d572c6-7e25-450a-b007-e9b5c33559ec.png&quot; alt=&quot;11&quot; /&gt;&lt;figcaption&gt;11&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;和本地消息表（4.2）的对比&lt;/strong&gt;：&lt;/p&gt;


































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;本地消息表（4.2）&lt;/th&gt;&lt;th&gt;事务消息（4.3）&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&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;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;较低（RocketMQ 原生支持）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;依赖&lt;/td&gt;&lt;td&gt;无特殊依赖&lt;/td&gt;&lt;td&gt;依赖 RocketMQ&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;代码示例&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderServiceImpl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQTemplate&lt;/span&gt;&lt;span&gt; rocketMQTemplate&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 1. 发送半消息（此时消费者还收不到）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;//    发完后 RocketMQ 会自动回调 OrderTransactionListener.executeLocalTransaction()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;//    写订单表的操作在那个回调方法里执行，不在这里&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;rocketMQTemplate&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sendMessageInTransaction&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;tx-order-group&quot;&lt;/span&gt;&lt;span&gt;,           &lt;/span&gt;&lt;span&gt;// 事务消息生产者组&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;&quot;topic-stock-deduct&quot;&lt;/span&gt;&lt;span&gt;,       &lt;/span&gt;&lt;span&gt;// 目标 topic&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;MessageBuilder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;withPayload&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StockMessage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getProductId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getQuantity&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;order                       &lt;/span&gt;&lt;span&gt;// 传递给本地事务的参数&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 2. 事务监听器：执行本地事务 + 处理回查&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RocketMQTransactionListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;txProducerGroup&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;tx-order-group&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderTransactionListener&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQLocalTransactionListener&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderMapper&lt;/span&gt;&lt;span&gt; orderMapper&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQLocalTransactionState&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;executeLocalTransaction&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Message&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;arg&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (Order) arg;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(order);   &lt;/span&gt;&lt;span&gt;// 执行本地事务：写订单表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQLocalTransactionState&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;COMMIT&lt;/span&gt;&lt;span&gt;;    &lt;/span&gt;&lt;span&gt;// 成功 → 通知 Broker 投递消息&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQLocalTransactionState&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ROLLBACK&lt;/span&gt;&lt;span&gt;;  &lt;/span&gt;&lt;span&gt;// 失败 → 通知 Broker 丢弃消息&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQLocalTransactionState&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;checkLocalTransaction&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Message&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 回查逻辑：Broker 主动来问&quot;本地事务到底成功没有&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 从消息体中取出 orderId，查数据库确认订单是否已写入&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;StockMessage&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;stockMsg&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;parseObject&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;byte&lt;/span&gt;&lt;span&gt;[]) &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getPayload&lt;/span&gt;&lt;span&gt;()), &lt;/span&gt;&lt;span&gt;StockMessage&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stockMsg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getOrderId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (order &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQLocalTransactionState&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;COMMIT&lt;/span&gt;&lt;span&gt;;    &lt;/span&gt;&lt;span&gt;// 订单存在 → 提交&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RocketMQLocalTransactionState&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ROLLBACK&lt;/span&gt;&lt;span&gt;;      &lt;/span&gt;&lt;span&gt;// 订单不存在 → 回滚&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;一句话总结&lt;/strong&gt;：先发半消息 → 执行本地事务 → 根据结果 commit/rollback → 万一没响应 Broker 会回查。不需要建消息表和定时任务，是&lt;strong&gt;4.1 隐患的最优解&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：事务消息需要 RocketMQ 4.3+ 版本支持。消费端的幂等处理和 4.1 一样，不能省。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4.4 本地事务 + 补偿机制&lt;a href=&quot;#44-本地事务--补偿机制&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;如果不想用 MQ，也可以在业务代码里手动处理补偿。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;为什么不用 &lt;code&gt;@Transactional&lt;/code&gt; 直接回滚？&lt;/strong&gt; 因为 &lt;code&gt;productClient.deductStock()&lt;/code&gt; 是远程调用，如果放在 &lt;code&gt;@Transactional&lt;/code&gt; 里，数据库连接会在整个远程调用期间被占用（可能 3~5 秒），高并发下连接池会被打爆，整个服务都不可用。所以这里先提交本地事务、释放连接，再调远程服务，失败了手动补偿。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;思路&lt;/strong&gt;：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;先执行主业务逻辑&lt;/li&gt;
&lt;li&gt;再调用其他服务&lt;/li&gt;
&lt;li&gt;如果调用失败，手动回滚主业务的数据&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; order) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 1. 先创建订单（本地事务）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 2. 调用商品服务扣库存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;productClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deductStock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getProductId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getQuantity&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 扣库存失败，回滚本地订单&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deleteById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getId&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;创建订单失败&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;补偿机制的真实难度&lt;/strong&gt;：上面的例子只涉及”调一个服务、回滚一步”，看起来很简单。但实际业务中，一个方法可能调三四个远程服务（扣库存 + 扣积分 + 发优惠券），失败时要逆序补偿每一步，代码很容易写漏。而且&lt;strong&gt;补偿本身也可能失败&lt;/strong&gt;（比如 &lt;code&gt;deleteById&lt;/code&gt; 网络超时），这时候数据照样不一致。所以需要可靠补偿的场景，优先用上面 4.2 的消息表方案，而不是手写补偿逻辑。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4.5 使用 Seata 框架&lt;a href=&quot;#45-使用-seata-框架&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;如果你们公司已经引入了 Seata，那就可以直接用。Seata 支持多种模式：&lt;/p&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;AT 模式&lt;/td&gt;&lt;td&gt;最常用，自动管理全局事务和回滚，对业务代码侵入最小&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TCC 模式&lt;/td&gt;&lt;td&gt;需要手动编写 Try / Confirm / Cancel 三个阶段的逻辑&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Saga 模式&lt;/td&gt;&lt;td&gt;长事务解决方案，通过正向操作和补偿操作来管理事务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;XA 模式&lt;/td&gt;&lt;td&gt;基于数据库 XA 协议的强一致方案，性能较低，适合对一致性要求极高的场景&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;其中，&lt;strong&gt;AT 模式&lt;/strong&gt;用得最多，因为它基本不需要改业务代码，只需要加一个注解：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GlobalTransactional&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createOrder&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; order) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;orderMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;span&gt;                              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 本地事务：写订单表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;productClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deductStock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getProductId&lt;/span&gt;&lt;span&gt;&lt;span&gt;());&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 远程调用 1：扣库存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;pointClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deductPoints&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserId&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;&lt;span&gt;);&lt;/span&gt;&lt;span&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 远程调用 2：扣积分&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 任何一步失败，以上操作全部自动回滚&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;加了 &lt;code&gt;@GlobalTransactional&lt;/code&gt; 注解后，Seata 会自动管理整个分布式事务，任何一步失败都会自动回滚——包括本地事务和所有远程调用。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：Seata 用起来方便，但要额外部署 Server 端、增加运维成本，AT 模式对数据库性能也有一定影响。如前所述，&lt;strong&gt;很多互联网业务项目更倾向用本地事务 + MQ + 补偿的方案来实现最终一致性&lt;/strong&gt;。只有当业务对一致性要求较高、或涉及多步复杂远程调用时，才值得引入 Seata。&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、善用 AI 辅助开发&lt;a href=&quot;#六善用-ai-辅助开发&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;前面五章讲了微服务开发的各个核心知识点——从配置中心、注册中心，到远程调用、网关、分布式锁、分布式事务。内容不少，对于刚接触微服务的新人来说，&lt;strong&gt;不可能一次性全部记住&lt;/strong&gt;，也不需要全部记住。&lt;/p&gt;&lt;p&gt;实际开发中，更高效的方式是：&lt;strong&gt;先把整体概念理清楚，知道每个技术点是干什么的、大概怎么用。具体细节和配置写法，用到的时候再查。&lt;/strong&gt; 遇到不确定的问题，可以直接问 AI。&lt;/p&gt;&lt;p&gt;像 Claude Code 这样的 AI 编程工具，可以直接打开你的项目目录，自动读取所有代码和配置文件，然后用自然语言向它提问。不需要你手动复制粘贴代码，也不需要自己一行一行去翻。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;微服务开发过程中，遇到不确定的问题可以直接问：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;“这个项目的注册中心和配置中心是怎么配的？”&lt;/li&gt;
&lt;li&gt;“这个项目的远程调用方式是什么？OpenFeign 还是 Dubbo？”&lt;/li&gt;
&lt;li&gt;“这个项目的网关路由规则是怎么配的？”&lt;/li&gt;
&lt;li&gt;“我要新增一个远程调用接口，参考哪个现有代码来写？”&lt;/li&gt;
&lt;li&gt;“这个分布式锁的用法对不对？有没有什么边界问题？”&lt;/li&gt;
&lt;li&gt;“服务注册不上 Nacos，可能是什么原因？”&lt;/li&gt;
&lt;li&gt;“远程调用报找不到服务，帮我排查一下”&lt;/li&gt;
&lt;li&gt;“配置改了但没生效，可能是什么原因？”&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;核心思路：遇到不确定的问题，先问 AI。AI 能解决的就不用打扰同事了；AI 解决不了的，你已经对问题有了基本概念，带着这个基础再去问同事，沟通效率会高很多，同事也不需要从零给你解释，同时也会觉得你是有思考过的。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;</content:encoded></item><item><title>项目爆红怎么办</title><link>https://study-docs-158.pages.dev/posts/%E9%A1%B9%E7%9B%AE%E7%88%86%E7%BA%A2%E6%80%8E%E4%B9%88%E5%8A%9E/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E9%A1%B9%E7%9B%AE%E7%88%86%E7%BA%A2%E6%80%8E%E4%B9%88%E5%8A%9E/</guid><description>项目爆红怎么办</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-27/47708f19-a9e5-4955-8d17-23f12be6b8ca.png&quot; alt=&quot;项目爆红问题排查&quot; /&gt;&lt;figcaption&gt;项目爆红问题排查&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;刚拉下公司项目代码，满怀期待地用 IDEA 打开，结果映入眼帘的是漫山遍野的红色报错……先别慌！深呼吸！&lt;/p&gt;
&lt;p&gt;这几乎是每个开发者都会经历的“下马威”。通常情况下，代码本身并没有错，绝大多数的“爆红”都是因为&lt;strong&gt;本地环境配置、构建工具或缓存同步&lt;/strong&gt;出现了偏差。&lt;/p&gt;
&lt;p&gt;按照以下四个维度的排查清单按图索骥，帮你快速将项目“由红转绿”。&lt;/p&gt;
&lt;hr /&gt;
&lt;section&gt;&lt;h2&gt;一、JDK 版本不匹配&lt;a href=&quot;#一jdk-版本不匹配&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;很多时候，项目的地基没打对。如果 IDEA 使用的 JDK 版本和项目实际要求的版本不一致，就会出现大量的基本语法报错。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;排查动作：统一全局 JDK 配置&lt;/strong&gt; 请依次检查以下两个地方，确保版本号（如 JDK 8、JDK 11 等）与项目要求完全一致：
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;项目结构设置：&lt;/strong&gt; 菜单栏 &lt;code&gt;File&lt;/code&gt; -&amp;gt; &lt;code&gt;Project Structure&lt;/code&gt; -&amp;gt; 检查 &lt;code&gt;Project SDK&lt;/code&gt; 和 &lt;code&gt;Modules SDK&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;编译器设置：&lt;/strong&gt; 菜单栏 &lt;code&gt;File&lt;/code&gt; -&amp;gt; &lt;code&gt;Settings&lt;/code&gt; -&amp;gt; &lt;code&gt;Build, Execution, Deployment&lt;/code&gt; -&amp;gt; &lt;code&gt;Compiler&lt;/code&gt; -&amp;gt; &lt;code&gt;Java Compiler&lt;/code&gt; -&amp;gt; 检查 &lt;code&gt;Target bytecode version&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、项目构建异常 (Maven/Gradle)&lt;a href=&quot;#二项目构建异常-mavengradle&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;依赖管理工具（Maven/Gradle）的状态异常，是导致项目爆红的“重灾区”。请按顺序检查：&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1. 构建配置文件未被识别&lt;a href=&quot;#1-构建配置文件未被识别&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;现象：&lt;/strong&gt; &lt;code&gt;pom.xml&lt;/code&gt; 或 &lt;code&gt;build.gradle&lt;/code&gt; 文件图标显示为普通的文本/XML图标，没有对应的官方 Logo。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解决：&lt;/strong&gt; 右键点击该文件，选择 &lt;strong&gt;&lt;code&gt;Add as Maven Project&lt;/code&gt;&lt;/strong&gt;（或 Gradle 对应选项），强制 IDEA 重新解析构建脚本。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2. 目录资源标识丢失&lt;a href=&quot;#2-目录资源标识丢失&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;现象：&lt;/strong&gt; &lt;code&gt;java&lt;/code&gt; 文件夹不是蓝色的，&lt;code&gt;resources&lt;/code&gt; 文件夹没有带有金条图标。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解决：&lt;/strong&gt; 右键对应的目录 -&amp;gt; &lt;code&gt;Mark Directory as&lt;/code&gt; -&amp;gt; 将 java 标记为 &lt;strong&gt;&lt;code&gt;Sources Root&lt;/code&gt;&lt;/strong&gt;，将 resources 标记为 &lt;strong&gt;&lt;code&gt;Resources Root&lt;/code&gt;&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3. 构建存在旧缓存&lt;a href=&quot;#3-构建存在旧缓存&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;code&gt;clean&lt;/code&gt; 命令清除历史，再重新构建（例如在 Maven 面板双击运行 &lt;code&gt;clean&lt;/code&gt;，然后运行 &lt;code&gt;install&lt;/code&gt; 或 &lt;code&gt;compile&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4. 依赖未正确加载（重点！）&lt;a href=&quot;#4-依赖未正确加载重点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;这是最常见的情况，需要分情况讨论：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;情形 A：Jar 包在公司的 Maven 私仓里&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;排查 1：&lt;/strong&gt; 你的 IDEA 是否配置了正确的 &lt;code&gt;settings.xml&lt;/code&gt;？（里面需要包含公司的私服地址和镜像配置）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排查 2：&lt;/strong&gt; 去私仓后台看一眼，包确实存在，但版本号对得上吗？（特别是 &lt;code&gt;SNAPSHOT&lt;/code&gt; 快照版本，可能没有拉取到最新）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;情形 B：Jar 包不在 Maven 私仓里&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;本地依赖：&lt;/strong&gt; 包可能直接扔在项目的 &lt;code&gt;lib&lt;/code&gt; 目录下了，需要手动添加本地依赖（通过 pom 的 &lt;code&gt;scope=system&lt;/code&gt; 引入）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模块依赖：&lt;/strong&gt; 这个 Jar 包其实是公司另一个基础模块的源码。你需要先找到那个模块，在本地跑一遍 &lt;code&gt;mvn clean install&lt;/code&gt;，把它装到你自己的本地仓库里。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5. Lombok 插件“罢工”&lt;a href=&quot;#5-lombok-插件罢工&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;现象：&lt;/strong&gt; 实体类上明明加了 &lt;code&gt;@Data&lt;/code&gt; 等注解，但其他类调用 &lt;code&gt;get/set&lt;/code&gt; 方法时依然报错找不到。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解决：&lt;/strong&gt;
&lt;ol&gt;
&lt;li&gt;检查 IDEA 的 Lombok 插件版本，确保与项目依赖中的 Lombok 版本兼容，必要时更新插件。&lt;/li&gt;
&lt;li&gt;在 IDEA 的 &lt;code&gt;Settings&lt;/code&gt; -&amp;gt; &lt;code&gt;Build, Execution, Deployment&lt;/code&gt; -&amp;gt; &lt;code&gt;Compiler&lt;/code&gt; -&amp;gt; &lt;code&gt;Shared build process VM options&lt;/code&gt; 中添加参数：&lt;code&gt;-Djps.track.ap.dependencies=false&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、IDEA 缓存错乱&lt;a href=&quot;#三idea-缓存错乱&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;IDEA 为了让你搜索和跳转更丝滑，会在后台建立海量索引。一旦这些索引文件损坏，就会出现“薛定谔的报错”（代码没问题，运行也正常，但就是满屏红线）。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;终极杀招：清除 IDEA 缓存&lt;/strong&gt;
&lt;ol&gt;
&lt;li&gt;点击顶部菜单栏 &lt;code&gt;File&lt;/code&gt; -&amp;gt; &lt;strong&gt;&lt;code&gt;Invalidate Caches...&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;在弹出的对话框中，&lt;strong&gt;将前四个选项全部勾选&lt;/strong&gt;（包括 Clear file system cache and Local History 等）。&lt;/li&gt;
&lt;li&gt;点击 &lt;code&gt;Invalidate and Restart&lt;/code&gt;，耐心等待 IDEA 重启并重新建立索引。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、代码真有问题（语法或同步缺失）&lt;a href=&quot;#四代码真有问题语法或同步缺失&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;如果经历了上面三步的洗礼，依然有零星报错，那很可能是代码层面真的少东西了。&lt;/p&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; 提示缺少某个类、或是某个类里缺少刚刚调用的新方法。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解决：&lt;/strong&gt; 看看 Git 提交记录，最近是不是有同事刚推过代码？大概率是这位同事在 Commit 时漏选了某些新增的类文件。这时候不用怀疑自己，大胆去群里艾特对应同事补充提交代码即可。&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;strong&gt;一查 JDK 环境，二看 Maven 依赖，三清 IDEA 缓存，最后核对 Git 同步。&lt;/strong&gt;&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>项目本地启动失败该怎么办</title><link>https://study-docs-158.pages.dev/posts/%E9%A1%B9%E7%9B%AE%E6%9C%AC%E5%9C%B0%E5%90%AF%E5%8A%A8%E5%A4%B1%E8%B4%A5%E8%AF%A5%E6%80%8E%E4%B9%88%E5%8A%9E/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E9%A1%B9%E7%9B%AE%E6%9C%AC%E5%9C%B0%E5%90%AF%E5%8A%A8%E5%A4%B1%E8%B4%A5%E8%AF%A5%E6%80%8E%E4%B9%88%E5%8A%9E/</guid><description>项目本地启动失败该怎么办</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;项目克隆下来之后，下一步就是尝试在本地启动项目。 如果启动失败了，不要慌，大部分启动失败都是有明确原因的，关键是要学会看错误信息。&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;启动前要确认的信息&lt;a href=&quot;#启动前要确认的信息&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;在尝试启动项目之前，先确认以下基础信息是否正确：&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、JDK 版本是否设置正确&lt;a href=&quot;#1jdk-版本是否设置正确&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;检查 IDEA 中 Project SDK 是否与项目要求的 JDK 版本一致。&lt;/p&gt;&lt;p&gt;如果不一致，可以在 File → Project Structure → Project SDK 中修改。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、是否使用正确的方式启动&lt;a href=&quot;#2是否使用正确的方式启动&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;SpringBoot 项目不一定就是直接运行启动类来启动。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;如何判断：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果启动类继承了 &lt;code&gt;SpringBootServletInitializer&lt;/code&gt; 类，说明这个项目采用的是&lt;strong&gt;外置容器&lt;/strong&gt;（如 Tomcat）的部署方式，不是通过内嵌容器直接启动的：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;SpringBootApplication&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;YourApplication&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;extends&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SpringBootServletInitializer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;protected&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SpringApplicationBuilder&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;configure&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;SpringApplicationBuilder&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sources&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;YourApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 可选：保留 main 方法，便于本地用内嵌容器直接运行测试&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt;[] &lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;SpringApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;YourApplication&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;, args);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这种情况，需要先配置外置容器（如配置 Tomcat），然后通过容器来启动项目。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;如果不确定项目应该怎么启动，直接问同事。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、多配置文件，确保使用正确的配置文件启动&lt;a href=&quot;#3多配置文件确保使用正确的配置文件启动&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;很多项目有多个环境配置文件，比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;application-dev.yml&lt;/code&gt;：开发环境&lt;/li&gt;
&lt;li&gt;&lt;code&gt;application-prod.yml&lt;/code&gt;：生产环境&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;确保你激活的是&lt;strong&gt;本地开发环境&lt;/strong&gt;的配置。如果用错了配置文件，可能会连接到错误的数据库或中间件。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、项目启动需要使用的中间件，确保本地网络可以访问&lt;a href=&quot;#4项目启动需要使用的中间件确保本地网络可以访问&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;项目启动可能依赖以下中间件，确保它们已经启动并且网络可达：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;RabbitMQ / Kafka&lt;/li&gt;
&lt;li&gt;Elasticsearch&lt;/li&gt;
&lt;li&gt;Nacos / 注册中心&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;启动失败的关键：看控制台错误信息&lt;a href=&quot;#启动失败的关键看控制台错误信息&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;启动失败，关键就是要看控制台错误信息！&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果看不懂错误信息，可以把错误信息交给 AI 进行分析。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;要多关注报错信息里面的 &lt;code&gt;Caused by&lt;/code&gt; 信息！&lt;/strong&gt; &lt;code&gt;Caused by&lt;/code&gt; 后面的内容，才是导致问题的根本原因。&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;常见启动错误及解决方式&lt;a href=&quot;#常见启动错误及解决方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、拒绝连接&lt;a href=&quot;#1拒绝连接&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Connection refused&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;java.net.ConnectException: Connection refused&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;原因：&lt;/strong&gt; 本地无法连接到目标服务（比如数据库、Redis、中间件等）。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;排查方式：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;使用 &lt;code&gt;telnet&lt;/code&gt; 命令检测具体的 IP 和端口是否通畅：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;telnet &amp;lt;IP&amp;gt; &amp;lt;端口&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;如果 telnet 不通，说明目标服务没有启动，或者网络不通。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、类找不到&lt;a href=&quot;#2类找不到&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ClassNotFoundException&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;NoClassDefFoundError&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;java.lang.NoSuchMethodError&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;原因：&lt;/strong&gt; 明明存在这个类，但运行时却说找不到，基本就是&lt;strong&gt;缓存问题&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;解决方式：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;清除 IDEA 缓存并重启（File → Invalidate Caches → Invalidate and Restart）&lt;/li&gt;
&lt;li&gt;在 Maven 面板中 clean 整个工程&lt;/li&gt;
&lt;li&gt;再 install 整个工程&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、端口被占用&lt;a href=&quot;#3端口被占用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Web server failed to start. Port XXXX was already in use.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;netstat -ano | findstr :8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;找到占用端口的进程 PID 后，可以使用以下命令结束进程：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;taskkill /PID &amp;lt;进程ID&amp;gt; /F&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;或者直接在 IDEA 的启动配置中把端口号改成其他未被占用的端口。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、配置属性错误&lt;a href=&quot;#4配置属性错误&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ConfigurationPropertiesBindException&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;IllegalArgumentException: Could not resolve placeholder &apos;xxx&apos; in value &quot;${xxx}&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;code&gt;application.yml&lt;/code&gt; 或 &lt;code&gt;application.properties&lt;/code&gt; 中对应的配置项，确认属性名是否正确、值是否符合要求。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>写不出代码怎么办</title><link>https://study-docs-158.pages.dev/posts/%E5%86%99%E4%B8%8D%E5%87%BA%E4%BB%A3%E7%A0%81%E6%80%8E%E4%B9%88%E5%8A%9E/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E5%86%99%E4%B8%8D%E5%87%BA%E4%BB%A3%E7%A0%81%E6%80%8E%E4%B9%88%E5%8A%9E/</guid><description>写不出代码怎么办</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、为什么写不出代码？&lt;a href=&quot;#一为什么写不出代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;/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;p&gt;记住：问需求不丢人，&lt;strong&gt;做出来的东西完全跑偏才丢人&lt;/strong&gt;。导师宁愿你花十分钟问清楚，也不想看你憋两天交一坨错的东西。&lt;/p&gt;&lt;p&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;li&gt;&lt;strong&gt;输入是什么？&lt;/strong&gt; 前端传什么参数？&lt;/li&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;li&gt;&lt;strong&gt;异常情况怎么处理？&lt;/strong&gt; 参数为空、查不到数据、用户被禁用……&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;举个具体的例子，比如需求是根据用户 ID 查询订单列表，你得能答出：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;干什么：传一个用户 ID，查出这个用户的所有订单&lt;/li&gt;
&lt;li&gt;谁在用：后台运营人员，在管理页面查某个客户的订单&lt;/li&gt;
&lt;li&gt;输入：userId、pageNum、pageSize（要分页）&lt;/li&gt;
&lt;li&gt;输出：订单编号、金额、下单时间、订单状态&lt;/li&gt;
&lt;li&gt;正常流程：校验参数 → 查库 → 返回分页列表&lt;/li&gt;
&lt;li&gt;异常情况：userId 为空、查不到订单、用户被禁用&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;能这样答出来，才算真正理解了需求。只要有一个答不上来，那就不是”不会写代码”，而是&lt;strong&gt;根本不知道要写什么代码&lt;/strong&gt;。这时候硬写没意义，正确做法是：&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;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、需求理解了，为什么还是写不出？&lt;a href=&quot;#二需求理解了为什么还是写不出&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;因为你&lt;strong&gt;不会拆分问题&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;新人最容易犯的错，就是脑子里装着一整个功能（比如”做一个订单查询接口”），然后开始发呆——因为这问题太大，大到不知道从哪下手。&lt;/p&gt;&lt;p&gt;这时候要做的不是继续想，而是&lt;strong&gt;拆，拆到自己会为止&lt;/strong&gt;。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、不会写，就继续拆&lt;a href=&quot;#三不会写就继续拆&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;假设需求是”根据用户 ID 查询订单列表”，怎么拆？要分两种情况：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;情况一：项目里有高度相似的功能（最常见）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;大部分需求，项目里都有”长得像”的现成功能。这时别自己设计，直接找最像的那个，照它的结构拆：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;它有 Controller，你就建一个 Controller&lt;/li&gt;
&lt;li&gt;它有 Service，你就建一个 Service&lt;/li&gt;
&lt;li&gt;它的入参叫 &lt;code&gt;XxxQueryReq&lt;/code&gt;，你的就叫 &lt;code&gt;OrderQueryReq&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;它的方法叫 &lt;code&gt;pageList&lt;/code&gt;，你的也叫 &lt;code&gt;pageList&lt;/code&gt;，只改里面的表名和字段&lt;/li&gt;
&lt;/ul&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;——整个项目都在用 Controller→Service→Mapper 这套结构，DTO/VO 也是统一的命名。你就照这个骨架，把功能拆成一个个能动手的动作：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;建接口&lt;/strong&gt;：新建 Controller——会吧？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定入参&lt;/strong&gt;：定义 Query 对象，放 &lt;code&gt;userId&lt;/code&gt;、&lt;code&gt;pageNum&lt;/code&gt;、&lt;code&gt;pageSize&lt;/code&gt;——会吧？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定返回&lt;/strong&gt;：定义 OrderVO——会吧？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写 Service&lt;/strong&gt;：定义查询方法——会吧？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写 Mapper&lt;/strong&gt;：写数据库查询——会吧？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;返回结果&lt;/strong&gt;：DO 转 VO——&lt;strong&gt;每一步，都是你已经会的。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;无论哪种情况，结论都一样：原来不会的是”做订单查询接口”这个大问题，拆开以后每一步你都会。所以不是你不会，是&lt;strong&gt;你没拆到足够细&lt;/strong&gt;。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;如果拆出来的小问题你还不会，那就继续拆——一直拆到”新建一个类、写一个方法、定义一个字段”这种粒度，你就一定能动手。&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、真实开发中的万能流程&lt;a href=&quot;#四真实开发中的万能流程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-17/568e946d-8655-4241-a925-e63654e50bb4.jpg&quot; alt=&quot;写不出代码该怎么办&quot; /&gt;&lt;figcaption&gt;写不出代码该怎么办&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&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;p&gt;&lt;strong&gt;第三步：搭空架子&lt;/strong&gt; —— 不管结构是怎么来的，都先把三层空壳搭好、把链路跑通，再往里填逻辑：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// Controller：先把接口和入参出参定下来，方法体先空着&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/pageList&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;OrderVO&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;pageList&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OrderQueryReq&lt;/span&gt;&lt;span&gt; req) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Collections&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;emptyList&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// Service：先写空实现，确认链路通&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;OrderVO&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;pageList&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;OrderQueryReq&lt;/span&gt;&lt;span&gt; req) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Collections&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;emptyList&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;先用 Postman 跑通（请求能进、能返回），再回头填业务逻辑。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第四步：一层层补逻辑&lt;/strong&gt; —— 不要一次写完，每完成一步就测一步：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;第一轮：接口能调通&lt;/li&gt;
&lt;li&gt;第二轮：参数能接到&lt;/li&gt;
&lt;li&gt;第三轮：SQL 能查出数据&lt;/li&gt;
&lt;li&gt;第四轮：自测&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这样出问题时，你只需要检查刚刚改过的那部分代码。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、不会的时候，该问谁？&lt;a href=&quot;#五不会的时候该问谁&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;到底问 AI 还是问同事？判断标准就一句话：&lt;strong&gt;换家公司还存在吗？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;存在 → 问 AI。&lt;/strong&gt; 比如 Stream 怎么转 Map、MyBatis 动态 SQL 加循环条件怎么加、Spring 事务怎么用等。这些是通用知识，问 AI 效率最高——而且最好保证它告诉你的东西，你下次能用上：就算记不住具体怎么写，至少得记住”有这么个东西，下次遇到能想到它”。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;不存在 → 问同事。&lt;/strong&gt; 比如 &lt;code&gt;status=3&lt;/code&gt; 代表什么、为什么必须调用户中心接口、为什么不能直接查库、这表为什么这么设计。这些是项目特有的东西，AI 根本不知道。&lt;/p&gt;&lt;p&gt;但有一点必须强调：&lt;strong&gt;问 AI 是为了学，不是为了代劳。&lt;/strong&gt; 尤其是新人，千万别图省事把整个功能甩给 AI 让它直接生成。问题要自己拆、骨架要自己搭、逻辑要自己写，AI 只在你卡在某个具体小问题上时给个提示。能自己动手的尽量自己动手。等你把基本功练扎实、有了独立写代码的底气之后，再让 AI 来写、你来监工。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、一个重要的认知&lt;a href=&quot;#六一个重要的认知&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;很多新人迟迟不敢动手，不是因为不会，而是&lt;strong&gt;想一步写出完美代码&lt;/strong&gt;——怕命名不规范、怕方法拆得不优雅、怕被导师喷。&lt;/p&gt;&lt;p&gt;但真实开发不是这样。哪怕工作五六年的程序员，拿到需求也是先写出能跑的版本，再优化。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;能跑通的代码，永远比脑子里完美的代码更有价值。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;第一版丑一点没关系。先跑通、先验证、先保证有可交付出去的东西。&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>一般系统的登录鉴权是如何实现的</title><link>https://study-docs-158.pages.dev/posts/%E4%B8%80%E8%88%AC%E7%B3%BB%E7%BB%9F%E7%9A%84%E7%99%BB%E5%BD%95%E9%89%B4%E6%9D%83%E6%98%AF%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%9A%84/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/%E4%B8%80%E8%88%AC%E7%B3%BB%E7%BB%9F%E7%9A%84%E7%99%BB%E5%BD%95%E9%89%B4%E6%9D%83%E6%98%AF%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%9A%84/</guid><description>一般系统的登录鉴权是如何实现的</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、什么是登录鉴权，为什么需要它？&lt;a href=&quot;#一什么是登录鉴权为什么需要它&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、什么是登录鉴权？&lt;a href=&quot;#1什么是登录鉴权&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;简单来说，登录鉴权就是解决一个问题：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;“你是谁？你有没有权限访问这个资源？”&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;在实际系统中，几乎所有的功能都不是”谁都能用”的。比如：&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;p&gt;这就需要系统在用户访问资源时，先验证用户的身份，再判断用户有没有权限做这个操作。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、登录鉴权包含两个核心概念&lt;a href=&quot;#2登录鉴权包含两个核心概念&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;回答的问题&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;认证（Authentication）&lt;/td&gt;&lt;td&gt;验证”你是谁”&lt;/td&gt;&lt;td&gt;你真的是张三吗？&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;授权（Authorization）&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;/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;/section&gt;&lt;section&gt;&lt;h3&gt;3、为什么需要了解登录鉴权？&lt;a href=&quot;#3为什么需要了解登录鉴权&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;虽然基本上不会让你从头实现登录鉴权，但它是几乎所有业务系统都有的功能，作为程序员还是要有一些基本认识。而且，入职后你大概率会碰到以下场景：&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;li&gt;写业务代码时经常需要获取当前登录用户（比如记录”谁创建的&quot;&quot;谁修改的”），要知道怎么从后端拿，而不是让前端传&lt;/li&gt;
&lt;li&gt;和同事沟通登录鉴权相关需求的时候，要具备这方面基本的认知能力&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、登录鉴权的整体流程&lt;a href=&quot;#二登录鉴权的整体流程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;不管系统用的是哪种技术方案，大多数登录鉴权的整体流程都可以概括为下面几个步骤：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-25/903c5292-6417-4de8-a6ca-b13cda1ffc0a.png&quot; alt=&quot;登录鉴权整体流程&quot; /&gt;&lt;figcaption&gt;登录鉴权整体流程&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;用一句话概括：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;登录时验证身份，生成凭证；后续请求携带凭证，后端校验凭证和权限。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、常见的登录认证方式&lt;a href=&quot;#三常见的登录认证方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、前后端不分离项目&lt;a href=&quot;#1前后端不分离项目&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;前后端不分离的老项目的登录认证一般都是使用的 Session + Cookie 的方式。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-25/92526a66-057f-4c5d-ab0f-2971ad3d3b26.png&quot; alt=&quot;Session+Cookie工作流程&quot; /&gt;&lt;figcaption&gt;Session+Cookie工作流程&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;1.1 工作流程&lt;a href=&quot;#11-工作流程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-25/124d4067-9290-4736-94e0-8215636cd2a9.png&quot; alt=&quot;2&quot; /&gt;&lt;figcaption&gt;2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.2 简单理解&lt;a href=&quot;#12-简单理解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;你可以把 Session + Cookie 理解成这样：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;你去银行办业务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;你拿着身份证去柜台验证身份（提交用户名密码）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;验证通过，柜台为你建立一份专属档案，并交给你一张号码牌&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;（登录成功，创建 Session，存入用户信息，通过 Set-Cookie 返回 JSESSIONID）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;你拿着号码牌去办业务（浏览器后续请求自动带上 Cookie）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;柜台看到号码牌，查到你的档案，办理业务（后端根据 Session ID 找到用户信息）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.3 关键点&lt;a href=&quot;#13-关键点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;Session 存在哪&lt;/td&gt;&lt;td&gt;服务端（内存、Redis、数据库等）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Session ID 怎么传给前端&lt;/td&gt;&lt;td&gt;通过 HTTP 响应头 Set-Cookie&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Session 创建时机&lt;/td&gt;&lt;td&gt;理论上首次调用 request.getSession() 就会触发自动创建，但在企业实战中，为了防内存溢出与 Session 固定攻击，拦截器绝不盲目创建，正式 Session 必须在用户登录成功并销毁旧会话后强制重建&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;前端怎么带 Session ID&lt;/td&gt;&lt;td&gt;浏览器每次请求自动携带 Cookie&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Session 过期&lt;/td&gt;&lt;td&gt;服务端设置超时时间，超时后 Session 失效&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;用户退出登录&lt;/td&gt;&lt;td&gt;服务端销毁 Session，前端清除 Cookie&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.4 优点&lt;a href=&quot;#14-优点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;实现简单，浏览器自动管理 Cookie&lt;/li&gt;
&lt;li&gt;服务端可以主动让 Session 失效（用户退出登录、修改密码等场景）&lt;/li&gt;
&lt;li&gt;状态可控，服务端可以随时查看和管理所有在线用户&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.5 缺点&lt;a href=&quot;#15-缺点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;分布式问题&lt;/strong&gt;：Session 默认存在应用服务器内存中，如果是集群部署（多台服务器），用户第一次请求到 A 服务器创建了 Session，第二次请求被分发到 B 服务器，B 服务器没有这个 Session，就会认为用户未登录&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨域问题&lt;/strong&gt;：Cookie 在跨域场景下处理比较麻烦&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;移动端不友好&lt;/strong&gt;：APP、小程序等非浏览器环境，没有自动管理 Cookie 的能力&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.6 分布式 Session 的常见解决方案(了解)&lt;a href=&quot;#16-分布式-session-的常见解决方案了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;Session 共享（Redis）&lt;/td&gt;&lt;td&gt;把 Session 存到 Redis 中，所有服务器都从 Redis 读写 Session&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;IP Hash（Nginx）&lt;/td&gt;&lt;td&gt;同一 IP 的请求始终路由到同一台服务器，但不适合服务器宕机切换的场景&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;粘性 Session&lt;/td&gt;&lt;td&gt;负载均衡器将同一用户的请求始终分配到同一台服务器&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;其中，&lt;strong&gt;把 Session 存到 Redis&lt;/strong&gt; 是企业里最常见的方式。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、前后端分离的项目&lt;a href=&quot;#2前后端分离的项目&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在前后端分离的项目中，我们通常采用 &lt;strong&gt;Token 机制&lt;/strong&gt; 来实现登录认证，而 &lt;strong&gt;JWT&lt;/strong&gt; 则是目前最常用的 Token 格式。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-25/6e5d0c3f-4ea8-49bb-9f4b-ded2c83e8c72.png&quot; alt=&quot;Token自测示例&quot; /&gt;&lt;figcaption&gt;Token自测示例&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;2.1 什么是 Token？&lt;a href=&quot;#21-什么是-token&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Token，翻译过来就是”令牌”。&lt;/p&gt;&lt;p&gt;它就是一个字符串，服务端在用户登录成功后生成，返回给前端，前端后续每次请求都带上这个 Token，服务端通过校验 Token 来判断用户身份。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.2 什么是 JWT？&lt;a href=&quot;#22-什么是-jwt&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;JWT（JSON Web Token）是目前最常用的 Token 格式。&lt;/p&gt;&lt;p&gt;一个 JWT 由三部分组成：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Header（头部）.Payload（载荷）.Signature（签名）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;例如：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiQURNSU4iLCJ1c2VySWQiOjEsInZlcnNpb24iOjAsInVzZXJuYW1lIjoiYWRtaW4iLCJpYXQiOjE3ODA2MjkzNjAsImV4cCI6MTc4MTIzNDE2MH0.YMHDAIskTfOcOl4tjWFUUqwcBsvKA4O_xuD2wijezXQ&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这三部分的作用：&lt;/p&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;Header&lt;/td&gt;&lt;td&gt;描述 Token 类型和签名算法，例如 {“alg”: “HS256”, “typ”: “JWT”}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Payload&lt;/td&gt;&lt;td&gt;存放用户信息和自定义数据，例如用户 ID、用户名、过期时间等&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Signature&lt;/td&gt;&lt;td&gt;对前两部分的签名，用于验证 Token 是否被篡改&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;JWT 的 Payload 部分只是经过 Base64 编码，不是加密。&lt;strong&gt;所以，不要在 JWT 中存放密码、手机号等敏感信息。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.3 工作流程&lt;a href=&quot;#23-工作流程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-25/598a2585-0ccc-471e-bfde-91edf4511c70.png&quot; alt=&quot;5&quot; /&gt;&lt;figcaption&gt;5&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;密钥（Secret Key）的作用说明&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;密钥是 JWT 安全性的核心，它只保存在服务端，不会泄露给前端。它的作用有两个：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;生成 Token 时&lt;/strong&gt;：后端用密钥对 Header 和 Payload 进行签名（计算出一个哈希值），拼接到 JWT 的第三部分（Signature）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;校验 Token 时&lt;/strong&gt;：后端用同一个密钥重新计算签名，如果和 JWT 中携带的签名一致，说明 Token 没有被篡改&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果密钥泄露了，任何人都可以伪造 JWT，所以密钥的安全保管非常重要。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.4 简单理解&lt;a href=&quot;#24-简单理解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;你去景区玩&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;售票处验证你的身份证（验证用户名密码）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;验证通过，给你一张&quot;门票&quot;（生成 JWT）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;门票上写了你的名字、有效期（JWT 的 Payload）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;门票上有景区的防伪印章（JWT 的 Signature）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;你每次进景点，工作人员看门票（后端校验 JWT）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;门票是真的且没过期 → 放行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;门票是假的或已过期 → 拒绝进入&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.5 Token 和 Session 的核心区别(了解)&lt;a href=&quot;#25-token-和-session-的核心区别了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;







































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;对比项&lt;/th&gt;&lt;th&gt;Session + Cookie&lt;/th&gt;&lt;th&gt;Token（JWT）&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;用户信息存储位置&lt;/td&gt;&lt;td&gt;服务端（内存/Redis）&lt;/td&gt;&lt;td&gt;Token 本身（客户端携带）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;服务端是否需要存储会话信息&lt;/td&gt;&lt;td&gt;需要&lt;/td&gt;&lt;td&gt;JWT 本身可以做到无状态，但实际项目中为了实现踢人下线、Token 续期、多端登录控制等能力，经常配合 Redis 使用&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;分布式支持&lt;/td&gt;&lt;td&gt;需要额外做 Session 共享&lt;/td&gt;&lt;td&gt;天然支持，因为 Token 自带用户信息&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;容易（删掉服务端 Session 即可）&lt;/td&gt;&lt;td&gt;较难（JWT 签发后，在过期之前始终有效）&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;/section&gt;&lt;section&gt;&lt;h4&gt;2.6 JWT 的优点（了解）&lt;a href=&quot;#26-jwt-的优点了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;无状态&lt;/strong&gt;：JWT 本身可以做到无状态，服务端不需要存储 Session 信息，天然支持分布式&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨域友好&lt;/strong&gt;：适合前后端分离、多端（Web、APP、小程序）场景&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能好&lt;/strong&gt;：理论上 JWT 中的信息可以直接使用，不必依赖服务端会话存储；但实际项目中通常仍会结合 Redis 缓存用户信息&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.7 JWT 的缺点（了解）&lt;a href=&quot;#27-jwt-的缺点了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;无法主动失效&lt;/strong&gt;：JWT 签发后，在过期之前始终有效。用户修改密码、被踢下线等场景不好处理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payload 不可太大&lt;/strong&gt;：JWT 每次请求都要携带，如果 Payload 里塞太多数据，会增加请求体积&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Token 续期问题&lt;/strong&gt;：Token 过期了怎么处理？是用 Refresh Token 续期，还是让用户重新登录？&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.8 JWT 无法主动失效的常见解决方案&lt;a href=&quot;#28-jwt-无法主动失效的常见解决方案&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;虽然 JWT 本身无法主动失效，但在实际项目中通常有以下几种处理方式：&lt;/p&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;缩短 Token 有效期&lt;/td&gt;&lt;td&gt;把 Token 有效期设短一些（比如 30 分钟），配合 Refresh Token 使用&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;黑名单机制&lt;/td&gt;&lt;td&gt;用户退出登录或修改密码时，把对应 Token 加入黑名单（通常存到 Redis），校验时先查黑名单&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Refresh Token&lt;/td&gt;&lt;td&gt;登录时同时返回一个短期 Token 和一个长期 Refresh Token，Token 过期后用 Refresh Token 换取新的 Token&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、如何获取当前登录用户&lt;a href=&quot;#四如何获取当前登录用户&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;用户登录之后，我在业务代码里怎么知道”当前操作的人是谁”？&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这个问题在实际开发中非常常见。和登录认证一样，获取登录用户信息一般也有现成的代码，不需要从头写。你需要记住两点：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;不要让前端传用户 ID&lt;/strong&gt;（除非你的组长明确告诉你这样做）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;获取登录用户是通过 Session 或 Token 实现的&lt;/strong&gt;，项目中一般已有封装好的工具类，找到直接用就行（最好封装成工具类，后面会频繁用到）。找不到的话，先让 AI 帮你搜，AI 也找不到就问同事：“我们项目里有没有获取当前登录用户的方法？“确认没有再自己写&lt;/li&gt;
&lt;/ol&gt;&lt;section&gt;&lt;h3&gt;1、为什么需要获取当前登录用户？&lt;a href=&quot;#1为什么需要获取当前登录用户&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;举几个你入职后一定会遇到的场景：&lt;/p&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;/td&gt;&lt;td&gt;新增一条记录时，要记录这条数据是谁创建的（create_by 字段）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;数据修改&lt;/td&gt;&lt;td&gt;修改数据时，要记录是谁改的（update_by 字段）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;操作日志&lt;/td&gt;&lt;td&gt;记录”张三在 2024-01-01 删除了某条数据”&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;p&gt;这些场景都有一个共同点：&lt;strong&gt;后端需要知道当前请求是谁发的&lt;/strong&gt;，而不是让前端来告诉后端。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、为什么不能让前端传用户 ID？&lt;a href=&quot;#2为什么不能让前端传用户-id&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;有些新人可能会想：前端直接把用户 ID 传过来不就行了？&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// ❌ 错误做法：让前端传 userId&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/add&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestParam&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt;&lt;span&gt; userId&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; order) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setCreateBy&lt;/span&gt;&lt;span&gt;&lt;span&gt;(userId);&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 前端传过来的 userId&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;orderService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;save&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;这存在严重的安全问题：&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;如果有人用 Postman 之类的工具直接调用接口，把 &lt;code&gt;userId&lt;/code&gt; 改成别人的，就能以别人的身份创建数据。这等于说，谁都能冒充任何人操作。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;所以，&lt;strong&gt;当前用户的身份必须从后端的认证信息中获取，不能依赖前端传递。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;正确的做法是：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// ✅ 正确做法：从后端的认证上下文中获取当前用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PostMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/add&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;RequestBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Order&lt;/span&gt;&lt;span&gt; order) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; userId &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SecurityUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserId&lt;/span&gt;&lt;span&gt;&lt;span&gt;();&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 从后端获取，而非前端传入&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;order&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setCreateBy&lt;/span&gt;&lt;span&gt;(userId);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;orderService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;save&lt;/span&gt;&lt;span&gt;(order);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、真实工作中一般获取登录用户的代码&lt;a href=&quot;#3真实工作中一般获取登录用户的代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;以下均是真实工作中项目代码截图。从这些代码可以看出，这种获取登录用户的逻辑都是封装到工具类里面的。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-25/41bf60a9-15c0-4d15-b016-13d50a93fb05.png&quot; alt=&quot;获取登录用户示例1&quot; /&gt;&lt;figcaption&gt;获取登录用户示例1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-25/f2e2ef81-c80f-4156-8457-43d2035efefe.png&quot; alt=&quot;获取登录用户示例2&quot; /&gt;&lt;figcaption&gt;获取登录用户示例2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-06-25/86fb0363-fc7f-4bec-9bbc-a4516b0531ce.png&quot; alt=&quot;获取登录用户示例3&quot; /&gt;&lt;figcaption&gt;获取登录用户示例3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、一般都是怎么实现的？&lt;a href=&quot;#4一般都是怎么实现的&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;不同登录认证方式，获取用户的实现也有所不同。但一般思路知道即可，真实工作中需要你写的可能性极低，即使让你写，也可以让 AI 直接帮你写。&lt;/p&gt;&lt;p&gt;一般思路如下：&lt;/p&gt;&lt;p&gt;拦截请求 → 解析凭证 → 存储当前用户 → 后续随时获取用户信息&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）、拦截请求&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;请求到达后端后，会先经过全局拦截器（Filter / Interceptor）。它会检查请求中是否携带了 Token、Session ID 等登录凭证。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）、解析用户信息&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;如果是 JWT Token： 后端会解析 Token，拿到 userId 等用户信息，必要时再去 Redis 查询完整用户数据。&lt;/li&gt;
&lt;li&gt;如果是 Session： 后端会根据 Session ID，从 Tomcat 或 Redis 中取出对应的用户对象。&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;3）、存入当前线程（ThreadLocal）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;拿到用户信息后，框架会把当前用户存入 ThreadLocal（例如 Spring Security 的 SecurityContext）。&lt;/p&gt;&lt;p&gt;这样后续业务代码中，就不需要层层传递用户参数了。在 Controller、Service 里直接调用类似：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;SecurityUtils.getUser()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;底层其实就是从 ThreadLocal 中获取当前登录用户。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4）、真实项目中常见的获取用户方式（了解）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;上面讲的是一般思路，下面是真实项目中的统计，帮你了解实际工作中会遇到哪些方式。&lt;/p&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;/th&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;Spring Security Context&lt;/td&gt;&lt;td&gt;最常见&lt;/td&gt;&lt;td&gt;SecurityContextHolder.getContext().getAuthentication()&lt;/td&gt;&lt;td&gt;大部分项目都用这个&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;自定义 ThreadLocal&lt;/td&gt;&lt;td&gt;常见&lt;/td&gt;&lt;td&gt;StaffThreadLocal.getStaff()&lt;/td&gt;&lt;td&gt;自己封装的工具类&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;工具类从 Request 解析&lt;/td&gt;&lt;td&gt;常见&lt;/td&gt;&lt;td&gt;SecurityUserUtil.getCurrentUserId(request)&lt;/td&gt;&lt;td&gt;直接从请求头解析Token&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;框架 API（Sa-Token等）&lt;/td&gt;&lt;td&gt;少见&lt;/td&gt;&lt;td&gt;StpUtil.getLoginIdAsLong()&lt;/td&gt;&lt;td&gt;特定框架提供的API&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HttpSession&lt;/td&gt;&lt;td&gt;老项目&lt;/td&gt;&lt;td&gt;request.getSession().getAttribute(“user”)&lt;/td&gt;&lt;td&gt;传统Session方式&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;实际工作中怎么快速上手？&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;找到项目里获取用户的方式&lt;/strong&gt;：搜索 &lt;code&gt;SecurityUtils&lt;/code&gt;、&lt;code&gt;getLoginUser&lt;/code&gt;、&lt;code&gt;getCurrentUser&lt;/code&gt; 等关键词&lt;/li&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;/ol&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;：入职后不需要从头实现获取用户的逻辑，找到项目里现有的方式直接用就行。如果找不到，先问 AI 帮你搜，搜不到再问同事。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、权限控制（授权）&lt;a href=&quot;#五权限控制授权&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;工作中，我们写的接口一般都需要设置权限，不会让所有用户都能调用。权限控制这块通常不需要你从 0 到 1 去实现，但你需要先了解常见的权限控制逻辑，这样到了公司才能更好地理解你们项目的权限方案。如果公司采用的方式不是通用模式，直接问同事就行（也可以先让 AI 帮你生成一个权限控制设计方案，再跟同事沟通确认）。&lt;strong&gt;如果你连常见的权限控制逻辑都不清楚，可能就很难听懂别人给你讲的东西。&lt;/strong&gt;&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、RBAC 权限模型&lt;a href=&quot;#1rbac-权限模型&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;RBAC（Role-Based Access Control，基于角色的访问控制）是企业中最常见的权限模型。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;核心思路&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户 → 角色 → 权限&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;也就是说：&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;p&gt;&lt;strong&gt;数据库设计通常是这几张表&lt;/strong&gt;&lt;/p&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;user&lt;/td&gt;&lt;td&gt;用户表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;role&lt;/td&gt;&lt;td&gt;角色表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;permission&lt;/td&gt;&lt;td&gt;权限表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;user_role&lt;/td&gt;&lt;td&gt;用户-角色关联表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;role_permission&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;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户：张三&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;角色：普通管理员&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;权限：用户列表查询、用户详情查询、用户编辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;（没有&quot;用户删除&quot;权限）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;张三可以查看和编辑用户，但不能删除用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、权限控制的常见实现方式&lt;a href=&quot;#2权限控制的常见实现方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;示例&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;接口级权限&lt;/td&gt;&lt;td&gt;控制某个接口只有特定角色才能访问&lt;/td&gt;&lt;td&gt;@RequiresRoles(“admin”)&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;p&gt;其中，&lt;strong&gt;接口级权限&lt;/strong&gt; 是后端开发最常接触的。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、为什么要前后端都做权限控制？&lt;a href=&quot;#3为什么要前后端都做权限控制&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;有些同学可能会想：前端已经根据权限隐藏了按钮，后端还需要再校验吗？&lt;/p&gt;&lt;p&gt;答案是：&lt;strong&gt;必须的。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为前端隐藏按钮只是页面展示层面的控制，用户完全可以通过直接调用接口来绕过前端限制。所以：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;前端权限控制是为了用户体验，后端权限控制是为了安全。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;六、实际工作中常见的权限控制方式&lt;a href=&quot;#六实际工作中常见的权限控制方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;下面以国内最常用的后台管理系统脚手架&lt;strong&gt;若依（RuoYi）前后端分离版本&lt;/strong&gt;为例，介绍实际工作中基于 RBAC 模型的权限控制是怎么实现的。很多公司会基于若依进行二次开发，或借鉴其权限方案，入职后你大概率会遇到。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1、权限控制&lt;a href=&quot;#1权限控制&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;若依的权限控制是基于 &lt;strong&gt;RBAC 模型&lt;/strong&gt; 实现的，涉及以下几张核心表：&lt;/p&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;sys_user&lt;/td&gt;&lt;td&gt;用户表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys_role&lt;/td&gt;&lt;td&gt;角色表，其中 data_scope 字段控制数据权限等级&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys_menu&lt;/td&gt;&lt;td&gt;菜单/权限表，每条菜单对应一个权限标识（如 system:user）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys_user_role&lt;/td&gt;&lt;td&gt;用户-角色关联表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys_role_menu&lt;/td&gt;&lt;td&gt;角色-菜单关联表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys_role_dept&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;/p&gt;&lt;p&gt;若依使用 Spring Security 的 &lt;code&gt;@PreAuthorize&lt;/code&gt; 注解来控制接口权限：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;按权限字符控制&lt;/strong&gt;：判断当前用户是否拥有指定权限字符串&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PreAuthorize&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;@ss.hasPermi(&apos;system:user:list&apos;)&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/list&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TableDataInfo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;SysUser&lt;/span&gt;&lt;span&gt; user) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;@ss&lt;/code&gt; 是若依自定义的权限服务 &lt;code&gt;PermissionService&lt;/code&gt;，注册为 Spring Bean，名称为 &lt;code&gt;ss&lt;/code&gt;。&lt;code&gt;hasPermi&lt;/code&gt; 方法会从当前登录用户的权限列表中判断是否包含指定的权限字符串。&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// PermissionService.java — 权限判断的核心逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;ss&quot;&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// 注册为Spring Bean，名称为ss&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PermissionService&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hasPermi&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;permission&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;LoginUser&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;loginUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SecurityUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getLoginUser&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;StringUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isNull&lt;/span&gt;&lt;span&gt;&lt;span&gt;(loginUser) &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;CollectionUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;loginUser&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getPermissions&lt;/span&gt;&lt;span&gt;())) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 判断用户的权限列表中是否包含该权限&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hasPermissions&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;loginUser&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getPermissions&lt;/span&gt;&lt;span&gt;(), permission);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 支持任意一个权限匹配&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hasAnyPermi&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;permissions&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 多个权限用逗号分隔，只要有一个匹配就返回true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 判断是否拥有某个角色&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hasRole&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;role&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 从用户的角色列表中判断&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 支持任意一个角色匹配&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hasAnyRoles&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;roles&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 多个角色用逗号分隔，只要有一个匹配就返回true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;按角色控制&lt;/strong&gt;：判断当前用户是否拥有指定角色&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 判断是否拥有 admin 角色&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PreAuthorize&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;@ss.hasRole(&apos;admin&apos;)&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/list&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TableDataInfo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;SysUser&lt;/span&gt;&lt;span&gt; user) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 判断是否拥有任意一个角色（admin 或 common）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;PreAuthorize&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;@ss.hasAnyRoles(&apos;admin,common&apos;)&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/list&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TableDataInfo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;SysUser&lt;/span&gt;&lt;span&gt; user) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;按钮级权限&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;前端使用自定义指令 &lt;code&gt;v-hasPermi&lt;/code&gt; 来控制按钮是否显示：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 只有拥有 system:user:add 权限的用户才能看到&quot;新增&quot;按钮 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;el-button&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;v-hasPermi&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;[&apos;system:user:add&apos;]&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;新增&amp;lt;/&lt;/span&gt;&lt;span&gt;el-button&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;el-button&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;v-hasPermi&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;[&apos;system:user:edit&apos;]&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;修改&amp;lt;/&lt;/span&gt;&lt;span&gt;el-button&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;el-button&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;v-hasPermi&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;[&apos;system:user:remove&apos;]&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;删除&amp;lt;/&lt;/span&gt;&lt;span&gt;el-button&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- 需要同时拥有多个权限中的任意一个 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;el-dropdown&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;v-hasPermi&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;[&apos;system:user:resetPwd&apos;, &apos;system:user:edit&apos;]&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;el-button&lt;/span&gt;&lt;span&gt;&amp;gt;更多操作&amp;lt;/&lt;/span&gt;&lt;span&gt;el-button&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;el-dropdown&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;v-hasPermi&lt;/code&gt; 指令的判断逻辑：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;hasPermi.js&lt;/span&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;inserted&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;el&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;binding&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;binding&lt;/span&gt;&lt;span&gt;                                    &lt;/span&gt;&lt;span&gt;// 按钮上写的权限标识，如 [&apos;system:user:add&apos;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;permissions&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;store&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;getters&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;permissions&lt;/span&gt;&lt;span&gt;               &lt;/span&gt;&lt;span&gt;// 用户拥有的权限列表（从 /getInfo 接口获取）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hasPermissions&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;permissions&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;some&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;permission&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;*:*:*&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;permission&lt;/span&gt;&lt;span&gt;                              &lt;/span&gt;&lt;span&gt;// 超级管理员有所有权限&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;includes&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;permission&lt;/span&gt;&lt;span&gt;)                            &lt;/span&gt;&lt;span&gt;// 或者用户权限列表中包含这个标识&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;hasPermissions&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;el&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;parentNode&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;el&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;parentNode&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;removeChild&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;el&lt;/span&gt;&lt;span&gt;)            &lt;/span&gt;&lt;span&gt;// 没权限就从页面移除按钮&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&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;blockquote&gt;&lt;p&gt;同样是”用户列表”接口，部门经理能看到本部门所有员工的数据，普通员工只能看到自己的数据。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;若依的数据权限是通过 &lt;strong&gt;AOP + MyBatis 参数注入&lt;/strong&gt; 实现的，核心思路就是在查询 SQL 中动态拼接 WHERE 条件。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）数据权限的五个等级&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;每个角色都有一个 &lt;code&gt;dataScope&lt;/code&gt; 字段，对应 &lt;code&gt;sys_role&lt;/code&gt; 表的 &lt;code&gt;data_scope&lt;/code&gt; 列：&lt;/p&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;生成的 SQL 条件&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;所有数据权限&lt;/td&gt;&lt;td&gt;不加过滤&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;自定义数据权限&lt;/td&gt;&lt;td&gt;dept_id IN (SELECT dept_id FROM sys_role_dept WHERE role_id = ?)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;本部门数据权限&lt;/td&gt;&lt;td&gt;dept_id = 当前用户部门ID&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;本部门及以下数据权限&lt;/td&gt;&lt;td&gt;dept_id IN (…本部门及子部门)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;仅本人数据权限&lt;/td&gt;&lt;td&gt;user_id = 当前用户ID&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;2）怎么使用&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;只需在 Service 方法上加 &lt;code&gt;@DataScope&lt;/code&gt; 注解：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;DataScope&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;deptAlias&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;d&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;userAlias&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;u&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;SysUser&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;selectUserList&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;SysUser&lt;/span&gt;&lt;span&gt; user)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;userMapper&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;selectUserList&lt;/span&gt;&lt;span&gt;(user);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;然后在 MyBatis XML 的查询 SQL 末尾加上 &lt;code&gt;${params.dataScope}&lt;/code&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;selectUserList&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parameterType&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;SysUser&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultMap&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;SysUserResult&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;select u.user_id, u.dept_id, u.user_name, d.dept_name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;from sys_user u&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;left join sys_dept d on u.dept_id = d.dept_id&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;where u.del_flag = &apos;0&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;${params.dataScope}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3）运行原理&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;AOP 切面（&lt;code&gt;DataScopeAspect&lt;/code&gt;）会在方法执行前拦截，获取当前用户的所有角色，根据每个角色的 &lt;code&gt;dataScope&lt;/code&gt; 值生成对应的 SQL 过滤条件，注入到方法参数的 &lt;code&gt;params.dataScope&lt;/code&gt; 中。这样 MyBatis 执行时就会自动拼接上数据权限的过滤条件。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;简单来说&lt;/strong&gt;：加个 &lt;code&gt;@DataScope&lt;/code&gt; 注解 + XML 里写个 &lt;code&gt;${params.dataScope}&lt;/code&gt;，数据权限就生效了。&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：正常业务开发中应谨慎使用 &lt;code&gt;${}&lt;/code&gt;，因为它会直接进行字符串拼接，存在 SQL 注入风险（应优先使用 &lt;code&gt;#{}&lt;/code&gt;）。若依的数据权限实现中，拼接内容由 AOP 切面根据用户角色自动生成，来源可控，因此能够安全使用。不要在其他业务场景中模仿这种写法，除非你能确保拼接内容的安全性。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、其他权限控制方式&lt;a href=&quot;#2其他权限控制方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;上面介绍的若依是典型的 RBAC 权限模型，适合角色多、权限细的场景。但有些项目可能并不需要那么精细的权限控制，只需要区分”管理员”和”普通用户”，这种情况下往往直接在代码里加一层判断就行了。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;2.1 用户表加一个角色字段&lt;a href=&quot;#21-用户表加一个角色字段&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;最简单的做法就是在用户表里加一个字段来标识用户类型：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- user 表中加一个 role 字段&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;CREATE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TABLE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;id &lt;/span&gt;&lt;span&gt;BIGINT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PRIMARY KEY&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;username &lt;/span&gt;&lt;span&gt;VARCHAR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;50&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;VARCHAR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;role&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;VARCHAR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;DEFAULT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;user&apos;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;-- admin 表示管理员，user 表示普通用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;登录后，这个 &lt;code&gt;role&lt;/code&gt; 字段会随着用户信息一起存到 Token 或 Session 中。后续请求时，后端直接判断角色即可。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.2 后端怎么判断权限？&lt;a href=&quot;#22-后端怎么判断权限&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;方式一：在接口里直接判断&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;最直接的方式，就是在需要权限控制的接口里加一个 if 判断：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/admin/users&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserList&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; currentUser &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SecurityUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getCurrentUser&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;admin&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;currentUser&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getRole&lt;/span&gt;&lt;span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;403&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;无权限访问&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 管理员才能执行的逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这种方式简单粗暴，适合接口不多的小项目。但如果需要控制的接口多了，每个接口都写一遍判断就太重复了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方式二：抽一个公共方法&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;稍微好一点的做法，是把判断逻辑抽到一个公共方法里：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/admin/users&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserList&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;checkAdmin&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 公共方法，不是管理员直接抛异常&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;checkAdmin&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt; currentUser &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SecurityUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getCurrentUser&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;admin&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;currentUser&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getRole&lt;/span&gt;&lt;span&gt;&lt;span&gt;())&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;无权限访问&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;方式三：用拦截器统一处理&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;更好的做法是通过拦截器（Filter / Interceptor）统一处理，而不是在每个接口里手动判断：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AdminInterceptor&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HandlerInterceptor&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;preHandle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;HttpServletRequest&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;HttpServletResponse&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;handler&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getRequestURI&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// 只拦截 /admin/** 路径下的接口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;startsWith&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/admin/&quot;&lt;/span&gt;&lt;span&gt;)) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;currentUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SecurityUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getCurrentUser&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;admin&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;currentUser&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getRole&lt;/span&gt;&lt;span&gt;())) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setStatus&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;403&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;然后注册拦截器，把 &lt;code&gt;/admin/**&lt;/code&gt; 路径的请求都交给它处理：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;WebMvcConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;WebMvcConfigurer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AdminInterceptor&lt;/span&gt;&lt;span&gt; adminInterceptor&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;addInterceptors&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;InterceptorRegistry&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addInterceptor&lt;/span&gt;&lt;span&gt;(adminInterceptor)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addPathPatterns&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/admin/**&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这样，所有以 &lt;code&gt;/admin/&lt;/code&gt; 开头的接口，只有管理员才能访问，普通用户会直接被拦截返回 403。不需要在每个接口里写判断，代码更干净。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方式四：用自定义注解&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;和拦截器类似的思路，也可以通过自定义注解来实现：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 定义注解&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Target&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ElementType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;METHOD&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Retention&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;RetentionPolicy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;RUNTIME&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RequireAdmin&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 在需要管理员权限的接口上加注解&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;RequireAdmin&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/users&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getUserList&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;userService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;然后通过 AOP 切面来拦截加了 &lt;code&gt;@RequireAdmin&lt;/code&gt; 注解的方法：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Aspect&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Component&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AdminAspect&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Before&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;@annotation(requireAdmin)&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;checkAdmin&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;RequireAdmin&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;requireAdmin&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;currentUser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SecurityUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getCurrentUser&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;admin&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;equals&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;currentUser&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getRole&lt;/span&gt;&lt;span&gt;())) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;BusinessException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;无权限访问&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这几种方式本质上都是做同一件事：&lt;strong&gt;判断当前用户是不是管理员，不是就拒绝访问&lt;/strong&gt;。区别只是代码组织方式不同。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.3 前端怎么配合？&lt;a href=&quot;#23-前端怎么配合&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;后端控制了接口权限，前端一般也会配合做界面上的控制：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 根据用户角色控制页面元素的显示&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;role&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;admin&apos;&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 显示管理后台入口、用户管理菜单等&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;showAdminMenu&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 隐藏这些元素&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;hideAdminMenu&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;七、登录鉴权常见问题与排查&lt;a href=&quot;#七登录鉴权常见问题与排查&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、什么是跨域？跨域和鉴权有什么关系？&lt;a href=&quot;#1什么是跨域跨域和鉴权有什么关系&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;同源策略&lt;/strong&gt;是浏览器的安全机制：只有当请求的协议、域名、端口三者都相同时，才被认为是”同源”。不满足任一条件就是”跨域”。&lt;/p&gt;&lt;p&gt;例如，前端在 &lt;code&gt;http://localhost:3000&lt;/code&gt;，后端在 &lt;code&gt;http://localhost:8080&lt;/code&gt;，端口不同，就是跨域。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;跨域对鉴权的影响&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cookie 方式&lt;/strong&gt;：默认情况下，跨域请求不会携带 Cookie，需要后端配置 CORS 并设置 &lt;code&gt;Access-Control-Allow-Credentials: true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Token 方式&lt;/strong&gt;：前端手动在请求头中添加 Token，不受 Cookie 限制，但需要后端配置 CORS 允许自定义请求头&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;后端解决跨域的常见方式&lt;/strong&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 方式一：在 Controller 或方法上加注解&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;CrossOrigin&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;origins&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;http://localhost:3000&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 方式二：全局配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;CorsConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;WebMvcConfigurer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;addCorsMappings&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;CorsRegistry&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/**&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;allowedOrigins&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;http://localhost:3000&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;allowedMethods&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;*&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;allowCredentials&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、什么是 OAuth 2.0？它和 JWT 什么区别？&lt;a href=&quot;#2什么是-oauth-20它和-jwt-什么区别&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;OAuth 2.0 是什么？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;OAuth 2.0 是一个&lt;strong&gt;授权框架&lt;/strong&gt;，它解决的核心问题是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;如何让用户在不给第三方应用密码的情况下，授权它访问自己的资源。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;最常见的场景就是”第三方登录”，比如：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;用微信扫码登录某个网站&lt;/li&gt;
&lt;li&gt;用 GitHub 账号登录某个开发工具&lt;/li&gt;
&lt;li&gt;用 Google 账号登录某个 App&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;OAuth 2.0 和 JWT 的区别&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这两个东西经常被混淆，但它们根本不在同一层：&lt;/p&gt;
























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;对比项&lt;/th&gt;&lt;th&gt;OAuth 2.0&lt;/th&gt;&lt;th&gt;JWT&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;本质&lt;/td&gt;&lt;td&gt;授权框架（一套流程规范）&lt;/td&gt;&lt;td&gt;数据格式（一种 Token 规范）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;解决的问题&lt;/td&gt;&lt;td&gt;如何让用户安全地授权第三方访问资源&lt;/td&gt;&lt;td&gt;Token 怎么生成、怎么校验、怎么防篡改&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;典型场景&lt;/td&gt;&lt;td&gt;微信登录、GitHub 登录&lt;/td&gt;&lt;td&gt;前后端分离项目的登录认证&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;简单来说：&lt;strong&gt;OAuth 2.0 定义的是”流程”，JWT 定义的是”格式”。&lt;/strong&gt; OAuth 2.0 流程中产生的 Token 可以用 JWT 格式，也可以不用。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;作为后端开发，你更常接触的是 JWT&lt;/strong&gt;。OAuth 2.0 一般在对接第三方登录时才会用到，而且通常已经有现成的 SDK 或框架集成，不需要你自己从头实现。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、SSO 是什么？&lt;a href=&quot;#3sso-是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;SSO（Single Sign-On，单点登录）解决的问题是：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;用户在多个系统中只需要登录一次，就能访问所有互相信任的系统，不需要重复登录。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;举个例子：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;你们公司有以下系统：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- OA 系统（oa.company.com）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- HR 系统（hr.company.com）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 邮件系统（mail.company.com）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;没有 SSO 的情况：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 你要先登录 OA → 输入一次账号密码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 再登录 HR → 再输入一次账号密码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 再登录邮件 → 又输入一次账号密码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;有了 SSO：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 你只要登录一次（比如先登录 OA）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 然后访问 HR、邮件系统，都自动识别你已登录，不需要再输入密码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;SSO 的核心思路&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户访问系统 A&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;系统 A 发现用户没登录，跳转到 SSO 认证中心&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户在认证中心输入账号密码，登录成功&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;认证中心给用户发一个全局凭证（Ticket / Token），同时记录&quot;这个用户已经登录了&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户带着凭证回到系统 A，系统 A 拿凭证去认证中心验证，验证通过，登录成功&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户再访问系统 B&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;系统 B 发现用户没登录，跳转到认证中心&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;认证中心发现这个用户已经登录过了（不需要再输密码），直接给用户发凭证&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;用户带着凭证回到系统 B，登录成功&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&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;/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;CAS&lt;/td&gt;&lt;td&gt;企业内网最常用的 SSO 方案，基于 Cookie + Ticket&lt;/td&gt;&lt;td&gt;公司内部多个系统统一登录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;OAuth 2.0&lt;/td&gt;&lt;td&gt;适用于第三方应用授权登录&lt;/td&gt;&lt;td&gt;微信登录、Google 登录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;同域 SSO&lt;/td&gt;&lt;td&gt;多个系统在同一个顶级域名下，共享 Cookie&lt;/td&gt;&lt;td&gt;a.company.com 和 b.company.com 共享登录状态&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;入职后你大概率会遇到 SSO&lt;/strong&gt;，因为只要公司有多个内部系统，基本都会做单点登录。不过 SSO 的实现一般也是现成的，你不需要从零写，了解即可。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、如何放行某个接口，不需要登录即可访问？&lt;a href=&quot;#4如何放行某个接口不需要登录即可访问&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;系统里不是所有接口都需要登录才能访问。有些接口天然就不需要鉴权，如果不放行，功能就会出问题。常见的放行场景如下：&lt;/p&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;/td&gt;&lt;td&gt;/login、/register、/captcha&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;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;/actuator/health、Spring Boot 健康检查端点&lt;/td&gt;&lt;td&gt;运维或监控系统需要定期探测服务是否存活&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;静态资源&lt;/td&gt;&lt;td&gt;图片、CSS、JS 文件&lt;/td&gt;&lt;td&gt;前端页面依赖这些资源，不能要求它们也带 Token&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;分享链接&lt;/td&gt;&lt;td&gt;带 Token 的临时分享链接&lt;/td&gt;&lt;td&gt;比如”分享给好友查看”，好友没有账号也能访问&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;想要知道你们项目怎么放行接口的，就全局搜索登录接口，去看它怎么放行的，或者也可以让 AI 告诉你。&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;p&gt;这是最直接的方式，在拦截器注册时指定哪些路径不需要拦截：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;WebMvcConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implements&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;WebMvcConfigurer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Autowired&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AuthInterceptor&lt;/span&gt;&lt;span&gt; authInterceptor&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;addInterceptors&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;InterceptorRegistry&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;registry&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addInterceptor&lt;/span&gt;&lt;span&gt;(authInterceptor)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addPathPatterns&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/**&quot;&lt;/span&gt;&lt;span&gt;)                          &lt;/span&gt;&lt;span&gt;// 拦截所有请求&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;excludePathPatterns&lt;/span&gt;&lt;span&gt;(                            &lt;/span&gt;&lt;span&gt;// 排除以下路径，不做鉴权&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                        &lt;/span&gt;&lt;span&gt;&quot;/login&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                        &lt;/span&gt;&lt;span&gt;&quot;/register&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                        &lt;/span&gt;&lt;span&gt;&quot;/captcha&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                        &lt;/span&gt;&lt;span&gt;&quot;/public/**&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;方式二：在 Security 配置中放行&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果项目用的是 Spring Security，可以在安全配置类中放行：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;EnableWebSecurity&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SecurityConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Bean&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SecurityFilterChain&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;filterChain&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;HttpSecurity&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;http&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;throws&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;http&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;authorizeHttpRequests&lt;/span&gt;&lt;span&gt;(auth &lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; auth&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;requestMatchers&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/login&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;/register&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;/captcha&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;/public/**&quot;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;permitAll&lt;/span&gt;&lt;span&gt;()  &lt;/span&gt;&lt;span&gt;// 放行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;anyRequest&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;authenticated&lt;/span&gt;&lt;span&gt;()  &lt;/span&gt;&lt;span&gt;// 其他请求需要认证&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;http&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;方式三：用自定义注解标记放行接口&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有些项目会定义一个 &lt;code&gt;@Anonymous&lt;/code&gt; 注解，加在接口上就表示不需要登录：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 定义注解&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Target&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;span&gt;ElementType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;METHOD&lt;/span&gt;&lt;span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ElementType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TYPE&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Retention&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;RetentionPolicy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;RUNTIME&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Anonymous&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 在不需要登录的接口上加注解&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Anonymous&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;GetMapping&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/public/article/{id}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getArticle&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span&gt;PathVariable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; id) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;success&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;articleService&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getById&lt;/span&gt;&lt;span&gt;(id));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;然后在拦截器中判断：如果接口方法上有 &lt;code&gt;@Anonymous&lt;/code&gt; 注解，就直接放行：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;preHandle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;HttpServletRequest&lt;/span&gt;&lt;span&gt;&lt;span&gt; request&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;HttpServletResponse&lt;/span&gt;&lt;span&gt;&lt;span&gt; response&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt; handler) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 如果是带有 @Anonymous 注解的接口，直接放行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (handler &lt;/span&gt;&lt;span&gt;instanceof&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HandlerMethod&lt;/span&gt;&lt;span&gt; handlerMethod) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Anonymous&lt;/span&gt;&lt;span&gt; anonymous &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;handlerMethod&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getMethodAnnotation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Anonymous&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (anonymous &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 其他接口正常做鉴权校验&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;方式三的好处&lt;/strong&gt;：放行配置直接写在接口上，一目了然，不用跑到配置类里去找。若依框架就是用的这种注解方式（&lt;code&gt;@Anonymous&lt;/code&gt;）来放行接口的。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、常见鉴权问题排查&lt;a href=&quot;#5常见鉴权问题排查&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;实际工作中，以下是最常见的鉴权相关问题及排查思路。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;实用排查技巧：参考平台其他接口的传参方式&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果不确定某个接口的认证参数怎么传，可以先登录你们公司的平台，按 F12 打开浏览器开发者工具，切换到 Network（网络）面板，然后在页面上随便操作一下，观察其他接口是怎么传 Token/Cookie 的——请求头叫什么名字、格式是什么（比如 &lt;code&gt;Bearer xxx&lt;/code&gt; 还是直接传值）。照着别的接口的传参方式来就行，这是最快的方式，比自己猜或者翻代码都快。&lt;/p&gt;&lt;/blockquote&gt;&lt;section&gt;&lt;h4&gt;5.1、接口返回 401（未认证）&lt;a href=&quot;#51接口返回-401未认证&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;说明：请求没有携带有效的登录凭证，或者凭证已失效。&lt;/p&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;/th&gt;&lt;th&gt;检查内容&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Token 有没有传？检查请求头中是否包含 Authorization 或 token 字段&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Token 格式对不对？有的项目要求 Bearer xxx，有的只要 Token 值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Token 是否过期？看看 Token 的过期时间，或者重新登录拿一个新 Token&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;请求头名字对不对？不同项目的请求头名称可能不同（Authorization、token、X-Token 等），看项目配置&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;是不是跨域导致 Cookie 没带上？Session 方案要检查 Cookie 是否被浏览器拦截&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;网关是否丢失了请求头？如果项目用了网关（如 Nginx、Gateway），检查网关是否把认证相关的请求头透传了&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;接口是否被拦截器拦截？检查接口是否在放行列表中，如果不在，确认是否需要放行&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.2、接口返回 403（无权限）&lt;a href=&quot;#52接口返回-403无权限&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;说明：已登录，但当前用户没有权限访问该资源。&lt;/p&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;/th&gt;&lt;th&gt;检查内容&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;当前用户的角色是否正确？检查用户绑定的角色是否符合预期&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;权限字符是否配置？检查接口上的权限注解（如 @RequiresPermissions(“system:user”)），确认权限字符在数据库中是否存在&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;菜单权限是否绑定到角色？确认权限字符对应的菜单已经绑定到当前用户的角色上&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;数据权限是否限制了数据范围？如果开启了数据权限，可能是 SQL 层面的过滤导致查不到数据，而非 403&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;是不是 admin 账号也 403？如果 admin 也 403，说明可能是配置问题；如果只有普通用户 403，大概率是权限没配置到位&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.3、当前用户获取为空&lt;a href=&quot;#53当前用户获取为空&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;代码中调用获取当前用户的方法返回 null，一般就这几个原因：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;先确认是不是真的登录了（接口有没有返回 401，如果是，先解决登录问题）&lt;/li&gt;
&lt;li&gt;如果是在子线程或异步方法（&lt;code&gt;@Async&lt;/code&gt;、线程池）中获取用户，ThreadLocal 的值可能没有传递过去，需要在进入异步之前先把用户信息取出来，作为参数传进去：&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 在主线程中先获取当前用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; userId &lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SecurityUtils&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getUserId&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 把 userId 作为参数传给异步方法，不要在异步方法里面再去调 SecurityUtils.getUserId()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Async&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;doSomething&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Long&lt;/span&gt;&lt;span&gt; userId) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 这里直接用传进来的 userId，不要再去获取当前登录用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;确认你调用的获取当前用户的方法是不是项目封装好的那个，不同项目方法名可能不一样&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;：遇到鉴权问题，先确认”有没有登录”（401），再确认”有没有权限”（403），最后确认”能不能拿到用户信息”（null）。按这个顺序排查，基本能覆盖 90% 的场景。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Claude Code本地安装与配置国产智谱模型</title><link>https://study-docs-158.pages.dev/posts/claudecode%E6%9C%AC%E5%9C%B0%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE%E5%9B%BD%E4%BA%A7%E6%99%BA%E8%B0%B1%E6%A8%A1%E5%9E%8B/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/claudecode%E6%9C%AC%E5%9C%B0%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE%E5%9B%BD%E4%BA%A7%E6%99%BA%E8%B0%B1%E6%A8%A1%E5%9E%8B/</guid><description>Claude Code本地安装与配置国产智谱模型</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;准备工作&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在开始之前，请确保你的电脑上已经安装了 Node.js（建议 18.0 或更高版本）和 Git 。&lt;/p&gt;
&lt;p&gt;确认安装node&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-23/e83edb37-8322-4054-be20-81d7bd03668e.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;确认安装git&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-23/df4ee0c4-6196-4c40-a179-e2ccdd070586.png&quot; alt=&quot;10&quot; /&gt;&lt;figcaption&gt;10&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;section&gt;&lt;h3&gt;一、安装&lt;a href=&quot;#一安装&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;打开你的终端（Terminal）或命令行工具，输入以下命令。我们使用 npm 进行全局安装，这样你就可以在任何目录下呼出 Claude 了。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 全局安装 Claude Code 核心组件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;npm install -g @anthropic-ai/claude-code&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;注意：如果安装速度较慢，可以考虑切换 npm 的国内镜像源（如淘宝镜像）来加速下载。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;二、验证安装完整性&lt;a href=&quot;#二验证安装完整性&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;安装完成后，我们需要确认工具是否已成功装入你的系统。在终端中输入以下指令来查看当前版本：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 查看版本号，验证是否安装成功&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;claude&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--version&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;如果终端成功返回了一串版本号（如下图所示），那么恭喜你，核心组件已经安装就绪！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-23/cddc1194-09b6-41cf-9dc4-6d945d5e0168.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、绕过区域限制协议&lt;a href=&quot;#三绕过区域限制协议&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;由于一些网络或区域的限制，部分小伙伴直接使用时可能会遇到连接超时或报错的问题。这个时候可以通过配置一个专属脚本来启动 Claude Code，完美且优雅地绕过区域限制。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-23/2c700af9-066f-424b-b285-3d0e29db5cae.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;1、创建专属启动脚本&lt;a href=&quot;#1创建专属启动脚本&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在你的电脑里找一个安全的文件夹（比如 C:\scripts），新建一个文本文件，命名为 cld.bat，然后将以下代码复制进去并保存：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@echo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;off&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1.&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;切换控制台编码为&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UTF-8，确保中文显示正常&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;chcp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;65001&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;nul&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2.&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;设置局部环境变量&lt;/span&gt;&lt;span&gt; (仅对当前进程及其子进程有效)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;请确保&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1080&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;与你的&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Shadowrocket&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;本地代理端口一致&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ALL_PROXY=socks5://127.0.0.1:1080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; [Claude &lt;/span&gt;&lt;span&gt;CLI]&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;代理隧道已建立&lt;/span&gt;&lt;span&gt; (Port:1080)...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;3.&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;动态寻找并执行原始的&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;claude&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;程序&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;允许你传递所有参数，如&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/doctor&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;或&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;explain this code&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; /f &lt;/span&gt;&lt;span&gt;&quot;delims=&quot;&lt;/span&gt;&lt;span&gt; %%i in (&lt;/span&gt;&lt;span&gt;&apos;where claude&apos;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;do&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;%%i&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;goto&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:finish&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;:finish&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;脚本结束，变量自动销毁，不影响系统其他程序&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、配置系统环境变量&lt;a href=&quot;#2配置系统环境变量&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;将存放 cld.bat 的文件夹路径（比如 C:\scripts），添加到你的 Windows 系统环境变量 Path 中。 这样做的目的是，让你可以在系统的任意目录下直接执行该脚本。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、通过脚本启动&lt;a href=&quot;#3通过脚本启动&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;以后在任何项目文件夹下打开终端，不要再输入 claude，而是直接输入 cld！ 这样启动的 Claude Code 就自带代理，完美绕过区域限制。&lt;/p&gt;&lt;p&gt;首次启动时，会出现以下几个初始化界面：&lt;/p&gt;&lt;p&gt;主题设置：询问你终端的主题颜色和文本样式，直接按回车选择默认即可。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-23/b8ac20f2-71f5-4b91-abc1-bbbee64e5c73.jpg&quot; alt=&quot;4&quot; /&gt;&lt;figcaption&gt;4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;安全指南：系统安全提示，直接按回车&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-23/d51a07e1-f7fb-4955-8448-cf8267dd5b4c.png&quot; alt=&quot;5&quot; /&gt;&lt;figcaption&gt;5&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;工作区信任确认：询问你是否信任当前代码文件夹，选择第一项 Yes, I trust this folder，回车即可。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-23/e8e9250e-b520-40b4-91cf-c36b8f0aef0f.jpg&quot; alt=&quot;6&quot; /&gt;&lt;figcaption&gt;6&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;四、配置国产智普模型 如果你不想一直挂着代理，或者觉得官方 API 成本太高，我们可以直接修改底层配置，将其无缝切换 为国内的智谱大模型 (GLM)。使用国产模型，也不会出现区域限制问题，也就不需要通过脚本启动来绕过区域限制。&lt;/p&gt;&lt;p&gt;打开以下路径的配置文件（如果没有 settings.json 文件则手动新建一个）：&lt;/p&gt;&lt;p&gt;Windows 路径：C:\Users\你的用户名\.claude\settings.json&lt;/p&gt;&lt;p&gt;用代码编辑器打开它，编写如下参数（请将 your_zhipu_api_key 替换为你自己在智谱开放平台申请的真实 API Key）：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;env&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_BASE_URL&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;https://open.bigmodel.cn/api/anthropic&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_AUTH_TOKEN&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;your_zhipu_api_key&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_DEFAULT_HAIKU_MODEL&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;glm-4.5-air&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_DEFAULT_SONNET_MODEL&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;glm-5-turbo&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_DEFAULT_OPUS_MODEL&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;glm-5.1&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;配置保存后，再次在终端唤醒 Claude Code，就可以使用智谱了！&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;四、卸载&lt;a href=&quot;#四卸载&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 卸载命令，cmd窗口执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uninstall&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-g&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@anthropic-ai/claude-code&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-23/e1ed24fa-578e-4c0b-bdd3-8f3895ebaad4.png&quot; alt=&quot;7&quot; /&gt;&lt;figcaption&gt;7&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;这个卸载完成之后还要 将 Windows 路径：C:\Users\你的用户名\.claude\ 的该目录删除&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>Claude Code集成DeepSeek V4 pro</title><link>https://study-docs-158.pages.dev/posts/claudecode%E9%9B%86%E6%88%90deepseekv4pro/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/claudecode%E9%9B%86%E6%88%90deepseekv4pro/</guid><description>Claude Code集成DeepSeek V4 pro</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;准备工作&lt;a href=&quot;#准备工作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;前往 DeepSeek 官网 &lt;a href=&quot;https://platform.deepseek.com/usage&quot; target=&quot;_blank&quot;&gt;https://platform.deepseek.com/usage&lt;/a&gt; 创建 API Key，并确保账户余额充足。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-24/c7ca71d7-1044-4123-b9e7-b3ace0c7a9fc.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;一、直接修改配置文件&lt;a href=&quot;#一直接修改配置文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Claude Code 的核心配置存储在用户目录下的 &lt;code&gt;settings.json&lt;/code&gt; 中：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;路径&lt;/strong&gt;：&lt;code&gt;C:\Users\你的用户名\.claude\settings.json&lt;/code&gt;&lt;/p&gt;&lt;p&gt;如果文件不存在，请手动创建。用文本编辑器打开该文件，填入以下内容：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;env&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_AUTH_TOKEN&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;your_deepseek_api_key&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_BASE_URL&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;https://api.deepseek.com/anthropic&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_DEFAULT_HAIKU_MODEL&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;deepseek-v4-flash&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_DEFAULT_OPUS_MODEL&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;deepseek-v4-pro[1m]&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_DEFAULT_SONNET_MODEL&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;deepseek-v4-pro[1m]&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_MODEL&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;deepseek-v4-pro[1m]&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;ANTHROPIC_REASONING_MODEL&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;deepseek-v4-pro[1m]&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、使用 cc-switch（多模型切换工具）&lt;a href=&quot;#二使用-cc-switch多模型切换工具&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;如果你需要在 Claude Code 中集成多个模型并频繁切换，每次都手动修改配置文件会非常繁琐。cc-switch 正是为了解决这个问题而生的。当然，如果你只固定使用一个模型，可以跳过这一步。&lt;/p&gt;&lt;section&gt;&lt;h3&gt;1. 安装 cc-switch&lt;a href=&quot;#1-安装-cc-switch&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;前往 &lt;a href=&quot;https://github.com/farion1231/cc-switch/releases&quot; target=&quot;_blank&quot;&gt;https://github.com/farion1231/cc-switch/releases&lt;/a&gt; 下载 Windows 版（.msi 后缀），双击安装即可。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-24/769ffd8c-f8b5-428c-9b3d-2c494e5a3e90.png&quot; alt=&quot;2&quot; /&gt;&lt;figcaption&gt;2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2. 添加 DeepSeek 供应商&lt;a href=&quot;#2-添加-deepseek-供应商&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-24/ee50d3a8-2194-4aad-8fe2-2bb78c0c3968.png&quot; alt=&quot;3&quot; /&gt;&lt;figcaption&gt;3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3. 配置 DeepSeek V4 Pro&lt;a href=&quot;#3-配置-deepseek-v4-pro&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-24/f1b7e062-475e-437f-aad2-226c6a789661.png&quot; alt=&quot;4&quot; /&gt;&lt;figcaption&gt;4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;需要配置的信息如下：&lt;/p&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;/td&gt;&lt;td&gt;DeepSeek V4 Pro(任意起，通过名字知道自己用的哪个模型即可)&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;tr&gt;&lt;td&gt;官网链接&lt;/td&gt;&lt;td&gt;（空）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;API Key&lt;/td&gt;&lt;td&gt;填写你的 API Key&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;请求地址&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://api.deepseek.com/anthropic&quot; target=&quot;_blank&quot;&gt;https://api.deepseek.com/anthropic&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;API 格式&lt;/td&gt;&lt;td&gt;Anthropic Messages (原生)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;认证字段&lt;/td&gt;&lt;td&gt;ANTHROPIC_AUTH_TOKEN（默认）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;主模型&lt;/td&gt;&lt;td&gt;deepseek-v4-pro[1m]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;推理模型 (Thinking)&lt;/td&gt;&lt;td&gt;deepseek-v4-pro[1m]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Haiku 默认模型&lt;/td&gt;&lt;td&gt;deepseek-v4-flash&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sonnet 默认模型&lt;/td&gt;&lt;td&gt;deepseek-v4-pro[1m]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Opus 默认模型&lt;/td&gt;&lt;td&gt;deepseek-v4-pro[1m]&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;tr&gt;&lt;td&gt;高强度思考&lt;/td&gt;&lt;td&gt;✅ 勾选&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4. 验证配置&lt;a href=&quot;#4-验证配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;点击下图模型名称旁边的测试按钮：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-24/4f679b0f-182f-45bc-ba7f-18a62264b028.png&quot; alt=&quot;5&quot; /&gt;&lt;figcaption&gt;5&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出现如下结果即表示配置成功。此时点击供应商右侧的”启用”，即可使用 DeepSeek V4 Pro 模型。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-24/393988f3-87a9-4d01-8cb0-871cd24c69d5.png&quot; alt=&quot;6&quot; /&gt;&lt;figcaption&gt;6&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、启动与使用&lt;a href=&quot;#三启动与使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;配置完成后，在项目目录下执行以下命令启动 Claude Code（底层已自动切换为 DeepSeek）：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;claude&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;section&gt;&lt;h3&gt;常见问题：模型不匹配报错&lt;a href=&quot;#常见问题模型不匹配报错&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;如果你在已打开的 Claude Code 会话中通过 cc-switch 切换了模型，继续使用当前会话可能会报如下错误：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-24/6a188516-dce6-4400-bde2-277b675b5ef7.png&quot; alt=&quot;7&quot; /&gt;&lt;figcaption&gt;7&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;这是因为当前会话仍在使用旧的模型（如图中的 glm-5.1），而新配置的供应商只支持 &lt;code&gt;deepseek-v4-pro&lt;/code&gt; 或 &lt;code&gt;deepseek-v4-flash&lt;/code&gt;。此时使用 &lt;code&gt;/model&lt;/code&gt; 命令重新选择模型即可：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-24/eeaa177b-f163-4f4f-8751-358d7f65cb90.png&quot; alt=&quot;8&quot; /&gt;&lt;figcaption&gt;8&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;选择第二个模型，回车，再次提问”你是？“，即可得到正确响应。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-05-24/6f0d40c1-1e16-47f1-a33f-cb41d8b810f2.png&quot; alt=&quot;9&quot; /&gt;&lt;figcaption&gt;9&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>DBeaver的使用</title><link>https://study-docs-158.pages.dev/posts/dbeaver%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/dbeaver%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>DBeaver的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、DBeaver是什么？&lt;a href=&quot;#一dbeaver是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;DBeaver&lt;/strong&gt; 是一款&lt;strong&gt;免费开源&lt;/strong&gt;的通用数据库管理工具，支持几乎所有主流数据库。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DBeaver&lt;/strong&gt; 就像是 &lt;strong&gt;Navicat&lt;/strong&gt; 的免费替代品。因为&lt;strong&gt;Navicat&lt;/strong&gt; 是收费的，想要免费使用就要破解，而破解就涉及侵权。所以，很多公司为了免费又不侵权，就选择使用&lt;strong&gt;DBeaver&lt;/strong&gt; 来替代 &lt;strong&gt;Navicat&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DBeaver&lt;/strong&gt; 基于 Eclipse 开发，采用 Java 编写&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、DBeaver的使用&lt;a href=&quot;#二dbeaver的使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、连接数据库、创建库&lt;a href=&quot;#1连接数据库创建库&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1.1 连接数据库&lt;a href=&quot;#11-连接数据库&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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; 图标&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择数据库类型（如 &lt;strong&gt;MySQL&lt;/strong&gt;）&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/2bb0d21a-57ef-4375-bcab-63065f01db8a.png&quot; alt=&quot;新建连接-1&quot; /&gt;&lt;figcaption&gt;新建连接-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;填写连接信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;服务器地址&lt;/strong&gt;：数据库服务器地址（&lt;code&gt;localhost&lt;/code&gt; 表示本机）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Port&lt;/strong&gt;：MySQL默认 &lt;code&gt;3306&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Database&lt;/strong&gt;：数据库名（可选，连接后可选择）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用户名&lt;/strong&gt;：数据库用户名（如：&lt;code&gt;root&lt;/code&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;/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;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/afd636d6-0bbd-4af3-9e6c-ab5556963cf4.png&quot; alt=&quot;新建连接-2&quot; /&gt;&lt;figcaption&gt;新建连接-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.2 创建数据库&lt;a href=&quot;#12-创建数据库&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;上 &lt;strong&gt;右键&lt;/strong&gt; → 选择 &lt;strong&gt;「新建数据库」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/16e06821-3ac8-4308-9e55-7f288309729b.png&quot; alt=&quot;新建数据库&quot; /&gt;&lt;figcaption&gt;新建数据库&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&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;code&gt;utf8mb4&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排序规则&lt;/strong&gt;：同字符集，没有可参考的推荐选择 &lt;code&gt;utf8mb4_general_ci&lt;/code&gt; 或 &lt;code&gt;utf8mb4_unicode_ci&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;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/ee41065f-0628-499d-bf5a-b1455c9fda44.png&quot; alt=&quot;新建数据库-2&quot; /&gt;&lt;figcaption&gt;新建数据库-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、导出SQL脚本和执行SQL脚本&lt;a href=&quot;#2导出sql脚本和执行sql脚本&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;2.1 导出SQL脚本（备份）&lt;a href=&quot;#21-导出sql脚本备份&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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; 或 &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; → &lt;strong&gt;「转储数据库」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/729344c5-789a-44c9-9d6d-ff8782908fea.png&quot; alt=&quot;导出sql脚本-1&quot; /&gt;&lt;figcaption&gt;导出sql脚本-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择导出对象：&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/0c1db708-01a5-438b-9730-255f370eec9b.png&quot; alt=&quot;导出sql脚本-2&quot; /&gt;&lt;figcaption&gt;导出sql脚本-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;导出配置&lt;/p&gt;
&lt;p&gt;该界面可以配置导出路径，导出文件名等，设置完之后点击 &lt;strong&gt;开始&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/38068a0b-a776-4053-b793-dcc087b37a76.png&quot; alt=&quot;导出sql脚本-3&quot; /&gt;&lt;figcaption&gt;导出sql脚本-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;blockquote&gt;&lt;p&gt;💡 &lt;strong&gt;使用场景&lt;/strong&gt;：&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;/section&gt;&lt;section&gt;&lt;h4&gt;2.2 执行SQL脚本（导入）&lt;a href=&quot;#22-执行sql脚本导入&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;&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;strong&gt;「恢复数据库」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/e47049d5-f547-495b-9585-7935d03d620e.png&quot; alt=&quot;导入sql脚本-1&quot; /&gt;&lt;figcaption&gt;导入sql脚本-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择要导入的 &lt;code&gt;.sql&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;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/4738fc32-0727-4dea-bbc8-a1884bd18c73.png&quot; alt=&quot;导入sql脚本-2&quot; /&gt;&lt;figcaption&gt;导入sql脚本-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;新人踩坑点&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;大文件导入时内存不足，需要调整JVM参数&lt;/li&gt;
&lt;li&gt;SQL文件编码不对导致中文乱码（确保UTF-8编码）&lt;/li&gt;
&lt;li&gt;导入前确保选中了正确的数据库&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、新建表、修改表&lt;a href=&quot;#3新建表修改表&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;3.1 新建表&lt;a href=&quot;#31-新建表&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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; → 右键 → &lt;strong&gt;「新建表」&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在表设计器中添加字段：&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/cbc8c587-d5e8-4988-8a93-6ba1b09acd14.png&quot; alt=&quot;新建表&quot; /&gt;&lt;figcaption&gt;新建表&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&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;/td&gt;&lt;td&gt;般规范就是使用小写字母+下划线，如 user_name&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;数据类型&lt;/td&gt;&lt;td&gt;VARCHAR、INT、DATETIME 等，字段长度在类型后的括号里面设置，比如VARCHAR(50)&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;tr&gt;&lt;td&gt;自增&lt;/td&gt;&lt;td&gt;一般主键ID勾选&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;默认值&lt;/td&gt;&lt;td&gt;如 CURRENT_TIMESTAMP&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;tr&gt;&lt;td&gt;约束&lt;/td&gt;&lt;td&gt;这里设置主键字段&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;设置索引&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/89b38897-5f43-4700-8961-4b567ef252db.png&quot; alt=&quot;新建索引&quot; /&gt;&lt;figcaption&gt;新建索引&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&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;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;常用数据类型：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 字符串&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;VARCHAR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;255&lt;/span&gt;&lt;span&gt;)      &lt;/span&gt;&lt;span&gt;-- 变长字符串（推荐）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TEXT&lt;/span&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;-- 长文本&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;CHAR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)           &lt;/span&gt;&lt;span&gt;-- 固定长度（如：性别）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 数字&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;INT&lt;/span&gt;&lt;span&gt;               &lt;/span&gt;&lt;span&gt;-- 整数&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;BIGINT&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;-- 长整数（主键ID）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DECIMAL&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)     &lt;/span&gt;&lt;span&gt;-- 金额字段&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TINYINT&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)        &lt;/span&gt;&lt;span&gt;-- 布尔值&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 日期时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DATETIME&lt;/span&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;-- 日期时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TIMESTAMP&lt;/span&gt;&lt;span&gt;         &lt;/span&gt;&lt;span&gt;-- 时间戳（自动更新）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DATE&lt;/span&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;-- 日期&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;💡 &lt;strong&gt;命名规范&lt;/strong&gt;：&lt;/p&gt;&lt;p&gt;如果公司有命名规范就按照公司的命名规范。如果没有的话，就可以遵循如下一般规范即可。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;表名：&lt;code&gt;t_模块名&lt;/code&gt; 或 &lt;code&gt;tb_模块名&lt;/code&gt;，如 &lt;code&gt;t_user&lt;/code&gt;、&lt;code&gt;tb_order&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;字段名：小写字母+下划线，如 &lt;code&gt;user_name&lt;/code&gt;、&lt;code&gt;create_time&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2 修改表结构&lt;a href=&quot;#32-修改表结构&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;修改表字段，如果是开发环境、测试环境一般都可以直接修改。如果是生产环境在修改的时候，一定要确认清楚你们可不可以直接修改。如果不可以的话，确认需要走什么样的流程，然后按照流程去走。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;进入设计视图：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;选中表 → &lt;strong&gt;右键双击&lt;/strong&gt; → 进入和新建表一样的界面，进行对应修改&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/ff212fc2-4690-4b00-bca0-3e3c64a1aa0f.png&quot; alt=&quot;修改表&quot; /&gt;&lt;figcaption&gt;修改表&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&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;/li&gt;
&lt;li&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;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、数据筛选和排序&lt;a href=&quot;#4数据筛选和排序&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/eaa5da3a-bc6a-488c-9d1f-df7e75b3ea85.png&quot; alt=&quot;数据筛选和过滤&quot; /&gt;&lt;figcaption&gt;数据筛选和过滤&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、执行SQL语句&lt;a href=&quot;#5执行sql语句&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;5.1 打开SQL编辑器&lt;a href=&quot;#51-打开sql编辑器&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/5f9a6bab-66d7-43ff-90b1-269c2abb96b4.png&quot; alt=&quot;打开sql编辑器&quot; /&gt;&lt;figcaption&gt;打开sql编辑器&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.2 编写和执行SQL&lt;a href=&quot;#52-编写和执行sql&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/227e3641-e68b-480f-a683-0d913284913c.png&quot; alt=&quot;打开sql编辑器-2&quot; /&gt;&lt;figcaption&gt;打开sql编辑器-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;新人踩坑点&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;忘记加WHERE条件&lt;/strong&gt;，导致全表更新/删除&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选错库执行&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SQL语句末尾没加分号&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多行SQL时光标位置错误&lt;/strong&gt;，执行了不该执行的语句&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;💡 &lt;strong&gt;安全习惯&lt;/strong&gt;：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;先SELECT查询确认&lt;/li&gt;
&lt;li&gt;再UPDATE/DELETE修改&lt;/li&gt;
&lt;li&gt;执行前检查WHERE条件&lt;/li&gt;
&lt;li&gt;重要操作前备份数据&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6、导出Excel、导入Excel&lt;a href=&quot;#6导出excel导入excel&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;DBeaver&lt;/strong&gt; 本身不支持将表数据导出为Excel表格文件。不过可以导出为CSV文件，然后转成Excel文件。导入的文件如果是Excel文件，可以把Excel文件转成CSV文件，再导入。转换方式可以使用这个在线转行网站进行转行&lt;a href=&quot;https://csvtoexcel.net/zh-cn/excel-to-csv&quot; target=&quot;_blank&quot;&gt;https://csvtoexcel.net/zh-cn/excel-to-csv&lt;/a&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;6.1 导出CSV&lt;a href=&quot;#61-导出csv&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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; → 右键 → &lt;strong&gt;导出数据&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/3039a79e-0d12-4a0e-8f3e-d01bf3ccdd1b.png&quot; alt=&quot;导出数据-1&quot; /&gt;&lt;figcaption&gt;导出数据-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择导出格式：&lt;strong&gt;CSV&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/55be2af1-4ce2-42ec-9149-024d9bc34e42.png&quot; alt=&quot;导出数据-3&quot; /&gt;&lt;figcaption&gt;导出数据-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击 **「下一步」**到如下界面 → 设置保存位置、文件名&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/1d6ccda2-cdb0-47a0-8fa9-cac9380cd5e1.png&quot; alt=&quot;导出数据-2&quot; /&gt;&lt;figcaption&gt;导出数据-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&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;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6.2 导入CSV&lt;a href=&quot;#62-导入csv&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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; → 右键 → &lt;strong&gt;「导入数据」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/c804d67a-09f7-416f-87e3-48bc2f466235.png&quot; alt=&quot;导入数据-1&quot; /&gt;&lt;figcaption&gt;导入数据-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择数据来源：&lt;strong&gt;CSV&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/18a07f9a-5523-4fa8-984c-85b505c07e2e.png&quot; alt=&quot;导入数据-2&quot; /&gt;&lt;figcaption&gt;导入数据-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择要导入的CSV文件&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/74468187-e61a-4dd5-9838-b72370a9d2ba.png&quot; alt=&quot;导入数据-3&quot; /&gt;&lt;figcaption&gt;导入数据-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置字段映射：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;确认Excel列与表字段的对应关系&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设置数据类型转换&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/18e0fb47-31b6-4e4b-8400-5fa950999b30.png&quot; alt=&quot;导入数据-4&quot; /&gt;&lt;figcaption&gt;导入数据-4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&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;strong&gt;「继续」&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;新人踩坑点&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Excel列顺序与表字段不匹配&lt;/li&gt;
&lt;li&gt;日期格式转换失败&lt;/li&gt;
&lt;li&gt;Excel中有合并单元格&lt;/li&gt;
&lt;li&gt;数字字段包含非数字字符&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;💡 &lt;strong&gt;导入前检查&lt;/strong&gt;：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;确认列名与字段一致&lt;/li&gt;
&lt;li&gt;检查数据格式（日期、数字）&lt;/li&gt;
&lt;li&gt;删除空行和合并单元格&lt;/li&gt;
&lt;li&gt;备份原数据&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;7、表数据截断和清空&lt;a href=&quot;#7表数据截断和清空&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;7.1 截断（TRUNCATE）&lt;a href=&quot;#71-截断truncate&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;特点：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;重置自增ID&lt;/li&gt;
&lt;li&gt;速度快（DDL操作）&lt;/li&gt;
&lt;li&gt;不可回滚&lt;/li&gt;
&lt;/ul&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; → 右键 →&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;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/23594e76-cafd-4f1a-a440-481ae5fac44c.png&quot; alt=&quot;截断&quot; /&gt;&lt;figcaption&gt;截断&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;SQL语句：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TRUNCATE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TABLE&lt;/span&gt;&lt;span&gt; t_user;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;7.2 删除表数据（DELETE）&lt;a href=&quot;#72-删除表数据delete&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;特点：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;不重置自增ID&lt;/li&gt;
&lt;li&gt;速度较慢（DML操作）&lt;/li&gt;
&lt;li&gt;可回滚&lt;/li&gt;
&lt;li&gt;可加WHERE条件&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;打开表数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;全选数据（Ctrl+A）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;按 &lt;strong&gt;Delete&lt;/strong&gt; 键&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;保存操作&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9bccc280-e25d-42d4-a138-f736cbaa29a5.png&quot; alt=&quot;清空表&quot; /&gt;&lt;figcaption&gt;清空表&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;SQL语句：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 删除所有数据&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DELETE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;span&gt; t_user;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 删除指定条件数据&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DELETE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;span&gt; t_user &lt;/span&gt;&lt;span&gt;WHERE&lt;/span&gt;&lt;span&gt;&lt;span&gt; create_time &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;2024-01-01&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;新人踩坑点&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;混淆清空和删除&lt;/strong&gt;，自增ID行为不同&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;操作前未备份&lt;/strong&gt;，数据无法恢复&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DELETE无WHERE条件&lt;/strong&gt;，清空整表&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;💡 &lt;strong&gt;安全建议&lt;/strong&gt;：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;重要数据先备份（导出SQL或Excel）&lt;/li&gt;
&lt;li&gt;确认使用清空还是删除&lt;/li&gt;
&lt;li&gt;DELETE前务必检查WHERE条件&lt;/li&gt;
&lt;li&gt;生产环境操作要谨慎&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;8、将表里面部分记录复制成sql语句&lt;a href=&quot;#8将表里面部分记录复制成sql语句&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;当你需要把表里新增的记录或者表记录的更改以sql语句导出来的时候。&lt;/p&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;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;根据你的需求选择 &lt;strong&gt;Insert语句&lt;/strong&gt; 或者 &lt;strong&gt;Update语句&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/a93b48d8-0b96-4005-95d6-f4b6715e39be.png&quot; alt=&quot;将表里面部分记录复制成sql语句&quot; /&gt;&lt;figcaption&gt;将表里面部分记录复制成sql语句&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&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;/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;/td&gt;&lt;td&gt;t_模块名&lt;/td&gt;&lt;td&gt;t_user、t_order&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;字段名&lt;/td&gt;&lt;td&gt;小写+下划线&lt;/td&gt;&lt;td&gt;user_name、create_time&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;索引名&lt;/td&gt;&lt;td&gt;idx_字段名&lt;/td&gt;&lt;td&gt;idx_user_name&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;主键&lt;/td&gt;&lt;td&gt;id（自增）&lt;/td&gt;&lt;td&gt;id&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;外键&lt;/td&gt;&lt;td&gt;fk_关联表_字段&lt;/td&gt;&lt;td&gt;fk_order_user_id&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Gradle的基本使用</title><link>https://study-docs-158.pages.dev/posts/gradle%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/gradle%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/</guid><description>Gradle的基本使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h3&gt;一、什么是Gradle&lt;a href=&quot;#一什么是gradle&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Gradle是一个构建工具，用于自动化项目的构建、测试、部署等过程。它使用一种基于Groovy或Kotlin的领域特定语言（DSL）来编写构建脚本，使得构建配置更加灵活和强大。&lt;/p&gt;&lt;p&gt;通俗来说，Gradle就像是一个智能的助手，你告诉它（通过编写构建脚本）你的项目需要如何编译、需要哪些依赖库、如何打包等，它就会按照你的指示自动完成这些任务。同时，它还能高效地处理任务之间的依赖关系，只执行必要的步骤，从而加快构建速度。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;二、为什么有Maven了，还需要Gradle&lt;a href=&quot;#二为什么有maven了还需要gradle&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Maven 和 Gradle 的本质使命是一样的：&lt;strong&gt;帮你“一键”完成代码编译、测试、打包、发布、依赖管理&lt;/strong&gt;。 但 Maven 是 2004 年的“XML 老将”，Gradle 是 2012 年诞生的“DSL 新兵”，两者设计理念差异巨大，导致在&lt;strong&gt;大型、多模块、持续交付&lt;/strong&gt;的场景下，Gradle 往往能&lt;strong&gt;更快、更省、更灵活&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;一句话，Maven 能干的 Gradle 都能干，反之不行；&lt;strong&gt;当项目规模变大、构建速度、灵活性、持续集成成为瓶颈时，Gradle 就是“升级补丁”&lt;/strong&gt;。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、gradle项目的一般目录结构&lt;a href=&quot;#三gradle项目的一般目录结构&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-27/e93f5ee2-c276-4d1d-88d0-fb5116e59a91.png&quot; alt=&quot;gradle目录结构&quot; /&gt;&lt;figcaption&gt;gradle目录结构&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;四、gradle项目常见操作&lt;a href=&quot;#四gradle项目常见操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、打开gradle项目&lt;a href=&quot;#1打开gradle项目&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;1） 打开时选择当前工程下的build.gradle打开即可。打开后可能出现如下idea右侧无gradle工具栏的问题。此时可以按照如下操作&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-27/27a15cb1-607a-4bb0-9945-cd2b532e47ac.png&quot; alt=&quot;添加为gradle项目&quot; /&gt;&lt;figcaption&gt;添加为gradle项目&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2）打开完成后需要在idea的 &lt;strong&gt;Settings -&amp;gt; Building,Execution,Deployment -&amp;gt; Bulids Tools -&amp;gt;Gradle&lt;/strong&gt; 中配置gradle&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-27/54304d61-c76d-4748-80ef-b57ec1dca573.png&quot; alt=&quot;gradle设置本地仓库&quot; /&gt;&lt;figcaption&gt;gradle设置本地仓库&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、引入依赖&lt;a href=&quot;#2引入依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;引入远程仓库依赖，gradle也是 可以使用maven中央仓库的。&lt;/p&gt;&lt;p&gt;中央仓库的地址：&lt;a href=&quot;https://mvnrepository.com/&quot; target=&quot;_blank&quot;&gt;https://mvnrepository.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;1)、远程仓库存在的依赖，直接引入，刷新gradle&lt;/p&gt;&lt;p&gt;gradle的依赖是在build.gradle文件下的&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dependencies {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;implementation &lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&apos;commons-beanutils&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&apos;commons-beanutils&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;commonsbeanutilsVersion&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;这里面的版本是配置在gradle.properties文件里面的，这个文件定义的属性就是全局的！&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;commonsbeanutilsVersion         =1.9.4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;implementation&lt;/code&gt; 是一个&lt;strong&gt;依赖配置（Dependency Configuration）&lt;/strong&gt;，用于声明依赖项，类似于maven在引入依赖的时候scope标签的值。配置项的可选值如下:&lt;/p&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;implementation&lt;/td&gt;&lt;td&gt;编译期和运行时使用，不传递依赖给其他模块。&lt;/td&gt;&lt;td&gt;推荐首选，用于声明绝大多数私有依赖，有助于加快编译和隐藏接口。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;api&lt;/td&gt;&lt;td&gt;编译期和运行时使用，且会传递依赖。在Gradle 3.4+中引入，作用同已废弃的compile。&lt;/td&gt;&lt;td&gt;制作库时，需要向使用者暴露其依赖的第三方库接口。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;compileOnly&lt;/td&gt;&lt;td&gt;仅在编译期需要，不打包到最终产物（如APK/JAR）。&lt;/td&gt;&lt;td&gt;编译时提供支持，但运行时由环境提供（如Servlet API）。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;runtimeOnly&lt;/td&gt;&lt;td&gt;仅在运行时需要，编译期不需要。&lt;/td&gt;&lt;td&gt;数据库驱动等仅在运行时使用的库。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;testImplementation&lt;/td&gt;&lt;td&gt;用于测试代码（src/test）的编译和运行，不参与主代码打包。&lt;/td&gt;&lt;td&gt;JUnit等测试框架。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;debugImplementation&lt;/td&gt;&lt;td&gt;仅在构建 debug 变体时参与编译和打包。&lt;/td&gt;&lt;td&gt;仅需在调试模式下使用的工具（如LeakCanary）。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;releaseImplementation&lt;/td&gt;&lt;td&gt;仅在构建 release 变体时参与编译和打包。&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;2）仓库不存在的依赖引入方式&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dependencies {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 依赖lib目录下的某个jar文件，指定具体的jar文件使用files()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implementation &lt;/span&gt;&lt;span&gt;files&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;lib/xxx.jar&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 依赖lib目录下的所有以.jar结尾的文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;//fileTree() 用于指定一个目录，并通过通配符规则批量匹配文件，适合依赖一个目录下的多个 JAR（无需逐个指定）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implementation &lt;/span&gt;&lt;span&gt;fileTree&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;dir&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&apos;lib&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;includes&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;span&gt;&apos;*.jar&apos;&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// 依赖lib目录下的除了xxx.jar以外的所有以.jar结尾的文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;implementation &lt;/span&gt;&lt;span&gt;fileTree&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;dir&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&apos;lib&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;excludes&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;span&gt;&apos;xxx.jar&apos;&lt;/span&gt;&lt;span&gt;], &lt;/span&gt;&lt;span&gt;includes&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;span&gt;&apos;*.jar&apos;&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、打包&lt;a href=&quot;#3打包&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;​ 在build.gradle中通过如下方式设置打jar包或者war包&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#打war的话，就把java换成war&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;apply &lt;/span&gt;&lt;span&gt;plugin&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&apos;java&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;​ 点击右侧gradle工具栏下的对应模块下build下的build按钮进行打包对应模块。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-27/45d05fc8-d0fc-451b-8c2a-83c7188e2ddc.png&quot; alt=&quot;gradle打包&quot; /&gt;&lt;figcaption&gt;gradle打包&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;打完的包会在对应模块下的bulid目录下的libs目录下，如下图：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-27/1dbaac2a-7ae9-4ecf-88d1-a55c9f6738a2.png&quot; alt=&quot;gradle-打jar包&quot; /&gt;&lt;figcaption&gt;gradle-打jar包&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Idea的基本使用</title><link>https://study-docs-158.pages.dev/posts/idea%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/idea%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/</guid><description>Idea的基本使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h3&gt;一、idea是什么？&lt;a href=&quot;#一idea是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;IDEA”常常特指 &lt;strong&gt;IntelliJ IDEA&lt;/strong&gt;，这是一款功能强大的集成开发环境。它由JetBrains开发，尤其受Java开发者欢迎，以其&lt;strong&gt;智能代码补全、代码分析和重构功能&lt;/strong&gt;而闻名。它也支持Kotlin、Python等多种语言和框架。IDEA正常情况下是需要破解才可以永久使用，按照网上破解教程破解即可！&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;二、idea常见操作&lt;a href=&quot;#二idea常见操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、打开一个工程&lt;a href=&quot;#1打开一个工程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;1.1、按照下图打开一个工程&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/dce3db36-78a6-419a-9a6c-94c92893a7d7.png&quot; alt=&quot;打开项目&quot; /&gt;&lt;figcaption&gt;打开项目&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;1.2、选择要打开的工程，点击 &lt;strong&gt;Select Folder&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/6a2ae958-2be3-4e3c-8cfd-a629167df23d.png&quot; alt=&quot;打开项目2&quot; /&gt;&lt;figcaption&gt;打开项目2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;1.3、根据当前工程类型选择对应的打开方式&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/400c9041-5991-48a9-b395-beae18ae21e5.png&quot; alt=&quot;打开项目3&quot; /&gt;&lt;figcaption&gt;打开项目3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;有 pom.xml → Maven 工程&lt;/li&gt;
&lt;li&gt;有 build.gradle / settings.gradle → Gradle 工程&lt;/li&gt;
&lt;li&gt;有 .project + .classpath → Eclipse 工程&lt;/li&gt;
&lt;li&gt;上面全没有，只有 src 文件夹 → 裸源码（普通 Java 工程）&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、设置当前工程的JDK版本&lt;a href=&quot;#2设置当前工程的jdk版本&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;如果当前工程的JDK版本为1.8，则以下几处地方均需要设置。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;设置Project里面的JDK版本&lt;/p&gt;
&lt;p&gt;Ctrl+Alt+Shift+S打开如下界面，设置工程的JDK版本。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/06797146-0109-4f9c-8ed0-a048106d2ecc.png&quot; alt=&quot;设置JDK版本&quot; /&gt;&lt;figcaption&gt;设置JDK版本&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;设置Modules里面JDK版本&lt;/p&gt;
&lt;p&gt;Ctrl+Alt+Shift+S打开如下界面，可以在下图界面设置工程里面对应模块的JDK版本。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/b6ce59a4-134a-4b24-bc7b-b257e64cf85a.png&quot; alt=&quot;设置JDK版本2&quot; /&gt;&lt;figcaption&gt;设置JDK版本2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;设置编译的JDK版本&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/59572d81-f194-4949-af90-e2de04e5b150.png&quot; alt=&quot;设置JDK版本3&quot; /&gt;&lt;figcaption&gt;设置JDK版本3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、配置启动类&lt;a href=&quot;#3配置启动类&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/0515ff48-767c-49ae-b840-47b29ec59d40.png&quot; alt=&quot;启动类配置&quot; /&gt;&lt;figcaption&gt;启动类配置&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、插件的安装&lt;a href=&quot;#4插件的安装&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/b2d2703a-4056-4d37-b7c9-b2bf82298fe8.png&quot; alt=&quot;安装插件&quot; /&gt;&lt;figcaption&gt;安装插件&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5、添加Service窗口&lt;a href=&quot;#5添加service窗口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在SpringCloud项目中由于微服务模块很多,此时使用IDEA提供的Service界面可以很方便的可以看的当前工程下有哪些可启动模块，以及这些模块的运行状态和端口。还可以右击下面对应模块的启动类，选择 Jump to source 进入该启动类。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/26b0da52-35d5-403e-98ef-c9655a56f45f.png&quot; alt=&quot;添加service窗口&quot; /&gt;&lt;figcaption&gt;添加service窗口&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;首次添加可以使用Alt 8 快捷键，来添加service窗口，添加步骤如下：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/20ef6024-e278-4556-b119-131b37bdcd45.png&quot; alt=&quot;添加service窗口2&quot; /&gt;&lt;figcaption&gt;添加service窗口2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/ed8406a8-1f2c-4fda-9fb6-ba58d0e49eee.png&quot; alt=&quot;添加service窗口3&quot; /&gt;&lt;figcaption&gt;添加service窗口3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6、当前文件里面查找、替换操作&lt;a href=&quot;#6当前文件里面查找替换操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;1）ctrl f 查找&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/af9ea083-a91f-4761-b374-c7531da03ce8.png&quot; alt=&quot;查找当前文件内容&quot; /&gt;&lt;figcaption&gt;查找当前文件内容&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2）ctrl r 替换，也可以使用这个来查找&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/13c21cdf-5e56-494e-afd2-29d1cefb9143.png&quot; alt=&quot;替换当前文件内容&quot; /&gt;&lt;figcaption&gt;替换当前文件内容&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;7、全局查找、替换&lt;a href=&quot;#7全局查找替换&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;1）查找&lt;/p&gt;&lt;p&gt;ctrl shift f 全局文件查找，查找范围：整个项目/指定目录 &lt;strong&gt;全部文件&lt;/strong&gt;（含源码、配置、XML、JS、MD…）&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/2c0ead7b-0289-4e37-9cdc-a0a706eefab9.png&quot; alt=&quot;全局查找&quot; /&gt;&lt;figcaption&gt;全局查找&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;双击 shift 查找文件, 这个搜索功能的范围几乎涵盖了整个 IDE 的内容，包括项目代码、菜单项、工具窗口、设置和更多。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/8df5dbe8-aca0-4975-b525-751a7f89aa38.png&quot; alt=&quot;全局查找2&quot; /&gt;&lt;figcaption&gt;全局查找2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2）ctrl shift r 替换，也可以使用这个来查找&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/f8bab816-512f-4326-96ca-4139409ab742.png&quot; alt=&quot;全局替换&quot; /&gt;&lt;figcaption&gt;全局替换&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;8、查看当前类、方法、变量在哪里使用&lt;a href=&quot;#8查看当前类方法变量在哪里使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;1）查看类、方法使用处&lt;/p&gt;&lt;p&gt;光标放到你要查看的类或者方法上，按住ctrl键，再点击鼠标左击即可查看当前类或者方法在哪些地方使用。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/07419630-c714-4202-b383-18a15957949f.png&quot; alt=&quot;查看类、方法引用&quot; /&gt;&lt;figcaption&gt;查看类、方法引用&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2）查看变量在哪里使用&lt;/p&gt;&lt;p&gt;鼠标左击变量即可，查看，该变量使用处。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/2ac587d8-6db4-4f9c-b474-102b5d3e1b19.png&quot; alt=&quot;查看变量使用处&quot; /&gt;&lt;figcaption&gt;查看变量使用处&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;9、查看当前类、方法、变量定义处&lt;a href=&quot;#9查看当前类方法变量定义处&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;光标放到你要查看的类、方法或者变量上，按住ctrl键，再点击鼠标左击即可调转到对应类、方法、变量定义的地方。如果调用的方法是接口里面的，则会跳转到对应接口里面，此时需要点击接口方法前的向下的箭头进入到对应的实现类里面的方法里面。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/40a0f30f-2b2f-4ca9-8f45-054bfd63769a.png&quot; alt=&quot;进入实现类方法&quot; /&gt;&lt;figcaption&gt;进入实现类方法&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;10、本地历史&lt;a href=&quot;#10本地历史&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;当你本地代码出现丢失的情况，此时通过版本控制工具比如git也无法找到的话。此时，就可以使用idea本地历史记录来查看记录的历史版本。&lt;/p&gt;&lt;p&gt;1）右击你需要查看的文件或者文件夹查看历史版本&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/6b3422ae-3996-4ca1-b81c-45a18e1a7547.png&quot; alt=&quot;本地历史记录&quot; /&gt;&lt;figcaption&gt;本地历史记录&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2）进入如下界面，按照下图指示，根据需要来恢复代码&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/e11277e5-5145-4053-88c6-c196264b78ff.png&quot; alt=&quot;本地历史记录2&quot; /&gt;&lt;figcaption&gt;本地历史记录2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;11、格式化代码&lt;a href=&quot;#11格式化代码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;格式化代码可以使用快捷键 Ctrl Alt L。直接使用 Ctrl Alt L，默认格式化当前文件。如果当前文件不全是你写的，最好选中格式化的范围之后，再使用Ctrl Alt L进行代码格式化。否则，你可能会修改别人的代码，当你推送代码到远程仓库之后，后续你格式化别人的代码都会变成你写的，当这块代码出问题的时候，可能你会背锅！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/32350161-9145-446c-b6fa-b6d7407db501.png&quot; alt=&quot;格式化代码&quot; /&gt;&lt;figcaption&gt;格式化代码&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;12、快速生成for循环&lt;a href=&quot;#12快速生成for循环&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/7eafbdd4-b79b-4058-b4c8-2f3e06faf0bf.png&quot; alt=&quot;快速生成for循环&quot; /&gt;&lt;figcaption&gt;快速生成for循环&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、其他常用快捷键&lt;a href=&quot;#三其他常用快捷键&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;作用一句话&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;最近文件&lt;/td&gt;&lt;td&gt;Ctrl+E&lt;/td&gt;&lt;td&gt;弹刚才打开过的文件列表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;跳回/跳前&lt;/td&gt;&lt;td&gt;Ctrl+Alt+← / →&lt;/td&gt;&lt;td&gt;光标来回穿越文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;重命名&lt;/td&gt;&lt;td&gt;Shift+F6&lt;/td&gt;&lt;td&gt;重命名变量/类/包&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;万能修复&lt;/td&gt;&lt;td&gt;Alt+Enter&lt;/td&gt;&lt;td&gt;导包、类型转换、生成变量、实现类、实现方法等&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;生成代码&lt;/td&gt;&lt;td&gt;Alt+Insert&lt;/td&gt;&lt;td&gt;一键生成构造器、getter/setter、toString 等&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;包围代码&lt;/td&gt;&lt;td&gt;Ctrl+Alt+T&lt;/td&gt;&lt;td&gt;快速加 if/try/while/Runnable…&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;优化 import&lt;/td&gt;&lt;td&gt;Ctrl+Alt+O&lt;/td&gt;&lt;td&gt;删无用包、按规则排序&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;复制&lt;/td&gt;&lt;td&gt;Ctrl+D&lt;/td&gt;&lt;td&gt;不用剪贴板直接复制当前行&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;剪切&lt;/td&gt;&lt;td&gt;Ctrl+X&lt;/td&gt;&lt;td&gt;剪切&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;</content:encoded></item><item><title>idea中如何debug调试代码</title><link>https://study-docs-158.pages.dev/posts/idea%E4%B8%AD%E5%A6%82%E4%BD%95debug%E8%B0%83%E8%AF%95%E4%BB%A3%E7%A0%81/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/idea%E4%B8%AD%E5%A6%82%E4%BD%95debug%E8%B0%83%E8%AF%95%E4%BB%A3%E7%A0%81/</guid><description>idea中如何debug调试代码</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h3&gt;一、打断点的作用&lt;a href=&quot;#一打断点的作用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;调试是程序员的基本功，当你在程序中打上断点之后，程序运行到断点处就会停下来，此时，你就可以通过跟踪代码的执行过程。让你能够更清晰的理解代码的执行逻辑，以及快速定位bug。使用debug调试的时候需要注意如下几点：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;使用debug调试的时候，一定使用debug模式运行项目 ，这样断点才会生效！&lt;/li&gt;
&lt;li&gt;正常情况下，项目在运行过程中新加断点是不需要重启项目即可生效的！&lt;/li&gt;
&lt;li&gt;项目运行之后，如果在断点前新加了代码的话当前断点就会变成灰色，即不可用！此时需要重启项目灰色才会重新变成红色！&lt;/li&gt;
&lt;li&gt;有时候在启动项目的时候，发现项目长时间卡在那里，一直未显示运行成功。此时，可以将所有断点取消调再重新启动！&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;二、调试工具栏常用按钮说明&lt;a href=&quot;#二调试工具栏常用按钮说明&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/d4d23e37-66bc-4442-a2bd-a4de43a5602b.png&quot; alt=&quot;调试工具栏说明&quot; /&gt;&lt;figcaption&gt;调试工具栏说明&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、断点的基本使用&lt;a href=&quot;#三断点的基本使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、行断点&lt;a href=&quot;#1行断点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;行断点是我们经常使用的一种断点，顾名思义就是将断点，打到代码行上。打断点的方式也很简单，直接将光标移动到当前行代码左侧的行号上，单击鼠标左键即可。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/ae51159b-cd54-4119-858c-5ca3428dc2bb.png&quot; alt=&quot;行断点&quot; /&gt;&lt;figcaption&gt;行断点&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、方法断点(了解)&lt;a href=&quot;#2方法断点了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;方法断点顾名思义就是在方法声明行打断点，打断点的方式和行断点一样。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/6399441c-2071-410f-a6f8-7a5ead3fdc16.png&quot; alt=&quot;方法断点&quot; /&gt;&lt;figcaption&gt;方法断点&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、字段断点（了解）&lt;a href=&quot;#3字段断点了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;字段断点，也就是字段声明行设置，用来监控字段访问或者修改的，打断点的方式和行断点一样。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/dec604fa-9523-418b-a7c8-848fa3708c82.png&quot; alt=&quot;字段断点&quot; /&gt;&lt;figcaption&gt;字段断点&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、异常断点（了解）&lt;a href=&quot;#4异常断点了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;当使用异常断点的时候，再程序捕获异常的时候就会暂停。打异常断点的方式如下：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/5b03710b-6aca-4246-9142-c1b613f04064.png&quot; alt=&quot;断点面板&quot; /&gt;&lt;figcaption&gt;断点面板&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;进入断点面板，添加需要监控的异常信息&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/6f51a5ba-d40d-4d5a-9a1c-ae72f8dc05f3.png&quot; alt=&quot;断点面板2&quot; /&gt;&lt;figcaption&gt;断点面板2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5、条件断点&lt;a href=&quot;#5条件断点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;当循环里只停第N次或当变量==某值时，用条件断点就可以避免手点几百次的情况。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/43606980-2a3a-4eb3-8f36-9eb679187ee1.png&quot; alt=&quot;条件断点&quot; /&gt;&lt;figcaption&gt;条件断点&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;6、多线程断点&lt;a href=&quot;#6多线程断点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;当我们在异步执行逻辑之外设置了普通断点后，程序执行到异步执行的方法时，此时只是打普通的断点是进不去异步方法逻辑里的，而是要按照下图打断点才行。&lt;/li&gt;
&lt;li&gt;当涉及到并发执行某块逻辑的时候，由于多个线程同时运行，相互之间的执行顺序和状态变化较为复杂。如果我们想要跟踪每个并发线程的详细执行情况，或者希望精确控制线程的执行过程，也要按照下图打断点才行。&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/afeea5d8-659e-45ae-b75a-d9945e445bfc.png&quot; alt=&quot;多线程断点使用&quot; /&gt;&lt;figcaption&gt;多线程断点使用&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;7、stream流断点（了解）&lt;a href=&quot;#7stream流断点了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在链式调用的 &lt;strong&gt;lambda 体内&lt;/strong&gt;下断点，才能让我们窥见每一次元素流转的中间结果。使用方式其实也很简单，就直接在你需要监控的stream流前打断点即可。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/e8eb0b07-b9a3-40fb-a9a4-eccf6f97a357.png&quot; alt=&quot;stream流断点&quot; /&gt;&lt;figcaption&gt;stream流断点&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;下图即是stream流链面板：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-25/6c695782-3683-4e69-a4f1-608c58538cf4.png&quot; alt=&quot;stream流追踪面板&quot; /&gt;&lt;figcaption&gt;stream流追踪面板&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Linux系统的使用</title><link>https://study-docs-158.pages.dev/posts/linux%E7%B3%BB%E7%BB%9F%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/linux%E7%B3%BB%E7%BB%9F%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>Linux系统的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;为什么需要学习Linux系统的使用？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因为在真实工作中，很多中间件以及我们的应用服务，通常都是部署在 &lt;strong&gt;Linux 服务器&lt;/strong&gt; 上，而不是 Windows 系统。 所以，Linux 的常见操作是开发人员必须掌握的基础能力。&lt;/p&gt;
&lt;p&gt;另外，Linux 的使用方式和 Windows 也不太一样。 Windows 更多是通过图形化界面进行管理， 而 Linux 在实际工作中，更多是通过&lt;strong&gt;命令行&lt;/strong&gt;来完成文件查看、日志排查、服务启动、进程管理等操作。&lt;/p&gt;
&lt;p&gt;因此，想要更好地适应真实开发工作， Linux 的基本使用一定要会。&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;一、XShell 的使用&lt;a href=&quot;#一xshell-的使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1.1 什么是 XShell&lt;a href=&quot;#11-什么是-xshell&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;XShell 是一个强大的安全终端模拟软件，支持SSH1、SSH2、SFTP、TELNET等多种协议，用于远程连接Linux服务器。它是Java开发人员日常工作中不可或缺的工具。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;1.2 安装&lt;a href=&quot;#12-安装&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/f12b5ff7-8fb3-4e42-b34d-c2cbee5df669.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;1.3 连接服务器步骤&lt;a href=&quot;#13-连接服务器步骤&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;第一步：创建新会话&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;打开 XShell，点击「文件」→「新建」&lt;/li&gt;
&lt;li&gt;或直接点击工具栏的「新建」图标&lt;/li&gt;
&lt;/ol&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;/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;/td&gt;&lt;td&gt;会话名称（自定义，便于识别）&lt;/td&gt;&lt;td&gt;正常服务器少的话，直接填写IP即可&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;协议&lt;/td&gt;&lt;td&gt;连接协议&lt;/td&gt;&lt;td&gt;SSH&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;主机&lt;/td&gt;&lt;td&gt;服务器IP地址&lt;/td&gt;&lt;td&gt;192.168.1.100&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;端口&lt;/td&gt;&lt;td&gt;SSH端口&lt;/td&gt;&lt;td&gt;22（默认）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/e31e83c5-9a9b-46d7-a01e-22975791ef20.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第三步：配置用户认证&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;点击左侧「用户身份验证」&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;输入用户名（如：root）&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/7cd79f71-a4a6-4fd0-a634-47baf7ee317c.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;输入密码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击「确定」连接&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/f80fd206-14c3-4fc9-a8d4-1191b03c6309.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;1.4 保存会话技巧&lt;a href=&quot;#14-保存会话技巧&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;建议按环境分类保存会话，方便管理：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;XShell 会话管理&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── 生产环境&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│   ├── 应用服务器1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│   ├── 应用服务器2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│   └── 数据库服务器&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── 测试环境&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│   ├── 应用服务器&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│   └── 数据库服务器&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;└── 开发环境&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;└── 本地虚拟机&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;1.5 常见问题&lt;a href=&quot;#15-常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;问题1：连接被拒绝&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;检查IP地址和端口是否正确&lt;/li&gt;
&lt;li&gt;检查服务器SSH服务是否启动：&lt;code&gt;systemctl status sshd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;检查防火墙是否开放22端口&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;问题2：密码正确但无法登录&lt;/strong&gt;&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;p&gt;&lt;strong&gt;问题3：连接超时&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;检查网络连通性：&lt;code&gt;ping 服务器IP&lt;/code&gt; &lt;code&gt;telnet 服务器IP SSH端口&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;检查防火墙设置&lt;/li&gt;
&lt;li&gt;确认SSH端口是不是默认端口22&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;问题4：中文乱码&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;将编码设置为 UTF-8&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/197ee8cb-d59b-438b-8667-8d8696102450.png&quot; alt=&quot;1&quot; /&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、XFTP 的使用&lt;a href=&quot;#二xftp-的使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;2.1 什么是 XFTP&lt;a href=&quot;#21-什么是-xftp&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;XFTP 是一个文件传输软件，用于在Windows和Linux之间安全地传输文件，支持SFTP、FTP等协议。通常与XShell配合使用。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2.2 安装&lt;a href=&quot;#22-安装&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/c39239e9-37a7-4a1d-80ba-a67b145959a0.png&quot; alt=&quot;6&quot; /&gt;&lt;figcaption&gt;6&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2.3 连接服务器&lt;a href=&quot;#23-连接服务器&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在已连接的XShell会话中，点击工具栏的「XFTP」图标，可以直接打开XFTP并自动连接到当前服务器，无需重复输入密码。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9b33531d-596e-4b77-8625-f1ed09463623.png&quot; alt=&quot;9&quot; /&gt;&lt;figcaption&gt;9&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2.4 界面说明&lt;a href=&quot;#24-界面说明&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/e15f4ba2-ffc6-4b4e-b676-d2284d63a856.png&quot; alt=&quot;9&quot; /&gt;&lt;figcaption&gt;9&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2.5 文件传输操作&lt;a href=&quot;#25-文件传输操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&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;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&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;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;右键 → 删除 / 选中后按Delete键&lt;/td&gt;&lt;td&gt;删除选中的文件或文件夹&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;重命名&lt;/td&gt;&lt;td&gt;右键 → 重命名 / 选中后按F2键&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;tr&gt;&lt;td&gt;修改权限&lt;/td&gt;&lt;td&gt;右键 → 更改权限&lt;/td&gt;&lt;td&gt;修改文件权限（chmod）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2.6 常用场景&lt;a href=&quot;#26-常用场景&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;场景1：上传Java应用包&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;在左侧本地目录找到打包好的 &lt;code&gt;.jar&lt;/code&gt; 文件&lt;/li&gt;
&lt;li&gt;在右侧服务器目录切换到目标部署目录（如 &lt;code&gt;/opt/app&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;拖拽文件到右侧，或选中后点击「上传」按钮&lt;/li&gt;
&lt;li&gt;等待传输完成&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;场景2：下载日志文件&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;在右侧服务器目录找到日志文件（如 &lt;code&gt;/opt/logs/app.log&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;在左侧本地目录选择保存位置&lt;/li&gt;
&lt;li&gt;拖拽文件到左侧，或选中后点击「下载」按钮&lt;/li&gt;
&lt;li&gt;等待传输完成&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;场景3：批量传输&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;选中多个文件（按住Ctrl键多选，或按住Shift键连续选）&lt;/li&gt;
&lt;li&gt;拖拽或使用上传/下载按钮&lt;/li&gt;
&lt;li&gt;可以看到批量传输进度&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2.7 XShell 与 XFTP 配合使用&lt;a href=&quot;#27-xshell-与-xftp-配合使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在实际工作中，XShell和XFTP通常配合使用：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;XShell&lt;/strong&gt; 用于执行命令、查看日志、管理服务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XFTP&lt;/strong&gt; 用于上传部署包、下载日志文件、修改配置文件&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;典型工作流程：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;1. 使用XFTP上传应用包到服务器&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;2. 使用XShell连接服务器，进入部署目录&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;3. 使用XShell停止旧服务、备份旧版本&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;4. 使用XShell启动新服务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;5. 使用XShell查看运行日志（tail -f）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;6. 如需下载日志分析，使用XFTP下载&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、常用命令&lt;a href=&quot;#三常用命令&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;3.1 目录结构&lt;a href=&quot;#31-目录结构&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Linux只有一个根目录 &lt;code&gt;/&lt;/code&gt;，采用层级式的目录结构。&lt;/p&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;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;/bin -&amp;gt; /usr/bin&lt;/td&gt;&lt;td&gt;系统的可执行文件，可以在任何目录下执行&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/usr/local/bin&lt;/td&gt;&lt;td&gt;用户自己的可执行文件，可以在任何目录下执行&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/etc&lt;/td&gt;&lt;td&gt;存放配置文件，配置环境变量(/etc/profile)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/home&lt;/td&gt;&lt;td&gt;每一个用户的根目录，用来保存用户私人的数据，默认目录名和用户名相同&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/opt&lt;/td&gt;&lt;td&gt;存放额外安装的软件，相当于Windows系统的Program Files目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/var&lt;/td&gt;&lt;td&gt;存放经常变化的文件，如日志文件(/var/log)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/tmp&lt;/td&gt;&lt;td&gt;存放临时文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/root&lt;/td&gt;&lt;td&gt;系统管理员（root用户）的根目录&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;目录结构图：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── bin&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── etc&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── home&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│   ├── user1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│   └── user2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── opt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── root&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── tmp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;└── var&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3.2 基本指令&lt;a href=&quot;#32-基本指令&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;3.2.1 Linux服务器信息&lt;a href=&quot;#321-linux服务器信息&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;查看IP地址&lt;/td&gt;&lt;td&gt;ifconfig 或 ip addr&lt;/td&gt;&lt;td&gt;查看服务器IP地址&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;查看系统性能&lt;/td&gt;&lt;td&gt;top&lt;/td&gt;&lt;td&gt;运行的进程和系统性能信息（CPU、内存等）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;查看内存使用&lt;/td&gt;&lt;td&gt;free -h&lt;/td&gt;&lt;td&gt;以人类可读的方式显示内存使用情况&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;查看磁盘使用&lt;/td&gt;&lt;td&gt;df -h&lt;/td&gt;&lt;td&gt;查看各个分区的磁盘使用情况&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;查看系统版本&lt;/td&gt;&lt;td&gt;cat /etc/redhat-release&lt;/td&gt;&lt;td&gt;查看CentOS版本&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;查看内核版本&lt;/td&gt;&lt;td&gt;uname -r&lt;/td&gt;&lt;td&gt;查看Linux内核版本&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;防火墙相关操作：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 查看防火墙状态&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;firewalld&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 启动防火墙&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;start&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;firewalld&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 停止防火墙&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;stop&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;firewalld&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 开机自启动&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;enable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;firewalld&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 禁用开机自启动&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;disable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;firewalld&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：所有的系统服务都可以使用 &lt;code&gt;systemctl&lt;/code&gt; 进行管理，命令格式为：&lt;code&gt;systemctl start|stop|status|restart [服务名]&lt;/code&gt;&lt;/p&gt;&lt;p&gt;有些版本的服务器可能使用 &lt;code&gt;iptables&lt;/code&gt; 而不是 &lt;code&gt;firewalld&lt;/code&gt;，两者都是设置和管理网络防火墙规则的工具。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;开放端口操作（了解）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 开放3306端口（MySQL常用端口）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--permanent&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--zone=public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--add-port=3306/tcp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 重新加载防火墙配置（必须执行，否则规则不生效）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--reload&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 查看已开放的端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--zone=public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--list-ports&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 查看防火墙所有规则&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--zone=public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--list-all&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 移除已开放的端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--permanent&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--zone=public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--remove-port=3306/tcp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--reload&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2.2 文本编辑：vi/vim&lt;a href=&quot;#322-文本编辑vivim&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;vi和vim是Linux中的文本编辑器，用来在Linux中创建、查看或者编辑文本文件，相当于Windows中的记事本。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三种模式：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;一般模式（默认模式）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 按 i 或 a&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;编辑模式&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;↓ 按 Esc&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;命令行模式（按 shift+: 进入）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&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;/td&gt;&lt;td&gt;打开文件的默认模式&lt;/td&gt;&lt;td&gt;gg：跳到文件首行G：跳到文件末行yy：复制当前行p：粘贴dd：删除当前行u：撤销&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;编辑模式&lt;/td&gt;&lt;td&gt;编辑文件内容&lt;/td&gt;&lt;td&gt;按 i 或 a 进入，可编辑文件内容&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;p&gt;&lt;strong&gt;常用命令：&lt;/strong&gt;&lt;/p&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;q&gt;&lt;/q&gt;&lt;/td&gt;&lt;td&gt;退出编辑器（未修改时）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;q&gt;&lt;/q&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;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;保存但不退出&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt; nu&lt;/td&gt;&lt;td&gt;显示行号&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt; nonu&lt;/td&gt;&lt;td&gt;取消行号&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/搜索内容&lt;/td&gt;&lt;td&gt;搜索内容，小写 n 向下查找，大写 N 向上查找&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;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2.3 文件和目录操作&lt;a href=&quot;#323-文件和目录操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;1. 查看和切换目录&lt;/strong&gt;&lt;/p&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;ll 或 ls -l&lt;/td&gt;&lt;td&gt;查看当前目录下所有目录和文件（详细信息）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ls&lt;/td&gt;&lt;td&gt;查看当前目录下所有目录和文件（简单列表）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ls -a&lt;/td&gt;&lt;td&gt;查看所有文件（包括隐藏文件）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;pwd&lt;/td&gt;&lt;td&gt;显示当前所在目录的完整路径&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cd /opt&lt;/td&gt;&lt;td&gt;切换到opt目录下（绝对路径）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cd ..&lt;/td&gt;&lt;td&gt;切换到上级目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cd bin&lt;/td&gt;&lt;td&gt;切换到当前目录的bin目录下（相对路径）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cd ~&lt;/td&gt;&lt;td&gt;切换到当前用户的根目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cd -&lt;/td&gt;&lt;td&gt;切换到上一次所在的目录&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;2. 创建和复制&lt;/strong&gt;&lt;/p&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;mkdir data&lt;/td&gt;&lt;td&gt;在当前目录下创建目录data&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mkdir -p data/mysql&lt;/td&gt;&lt;td&gt;递归创建目录（一次创建多级目录）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mkdir /opt/data&lt;/td&gt;&lt;td&gt;在opt目录下创建目录data&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cp gateway.jar gateway-bak.jar&lt;/td&gt;&lt;td&gt;复制文件并重命名（备份常用）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cp -r dir1 dir2&lt;/td&gt;&lt;td&gt;递归复制目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cp app.jar /opt/&lt;/td&gt;&lt;td&gt;复制文件到指定目录&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;3. 删除操作（⚠️ 谨慎使用）&lt;/strong&gt;&lt;/p&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;rm file.txt&lt;/td&gt;&lt;td&gt;提示后删除文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;rm -f file.txt&lt;/td&gt;&lt;td&gt;强制删除文件（不提示）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;rm -r data&lt;/td&gt;&lt;td&gt;提示后递归删除目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;rm -rf data&lt;/td&gt;&lt;td&gt;强制递归删除目录（不提示）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;危险命令警告&lt;/strong&gt;：&lt;code&gt;rm -rf /&lt;/code&gt; 会删除整个系统的所有文件，&lt;strong&gt;千万不要执行&lt;/strong&gt;！&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;4. 查看文件内容（Java开发常用）&lt;/strong&gt;&lt;/p&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;cat file.txt&lt;/td&gt;&lt;td&gt;查看文件全部内容，一次性显示&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;more file.txt&lt;/td&gt;&lt;td&gt;分页查看文件内容，空格翻页，q退出&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;less file.txt&lt;/td&gt;&lt;td&gt;分页查看文件内容，支持上下翻页，q退出&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;head -n 50 file.log&lt;/td&gt;&lt;td&gt;查看文件前50行&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;tail -n 50 file.log&lt;/td&gt;&lt;td&gt;查看文件后50行&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;tail -f file.log&lt;/td&gt;&lt;td&gt;实时监控文件末尾内容（查看日志常用）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;`tail -f file.log&lt;/td&gt;&lt;td&gt;grep error`&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;grep “mysql” file.log&lt;/td&gt;&lt;td&gt;查看文件中包含”mysql”的内容&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;grep -n “error” file.log&lt;/td&gt;&lt;td&gt;查看文件中包含”error”的内容，并显示行号&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;grep -i “error” file.log&lt;/td&gt;&lt;td&gt;忽略大小写搜索&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;grep -C 5 “error” file.log&lt;/td&gt;&lt;td&gt;显示匹配行及其前后5行&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;5. 查找文件&lt;/strong&gt;&lt;/p&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;find / -name file.txt&lt;/td&gt;&lt;td&gt;从根目录查找名为file.txt的文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;find /opt -name “*.java”&lt;/td&gt;&lt;td&gt;查找opt目录下所有.java文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;find /opt -name “*.java” | grep user&lt;/td&gt;&lt;td&gt;查找opt目录下名称包含user的.java文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;find /opt -type d -name “logs”&lt;/td&gt;&lt;td&gt;查找名为logs的目录&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2.4 用户相关操作&lt;a href=&quot;#324-用户相关操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：在公司中，用户创建一般由运维人员负责，开发人员主要使用 &lt;code&gt;su&lt;/code&gt; 切换用户命令。&lt;/p&gt;&lt;/blockquote&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;useradd zhuoye&lt;/td&gt;&lt;td&gt;添加用户zhuoye（在/home目录下创建用户根目录）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;useradd -d /home/zhuoyun zhuoye&lt;/td&gt;&lt;td&gt;创建用户并指定根目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;passwd zhuoye&lt;/td&gt;&lt;td&gt;给用户zhuoye设置密码&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;userdel zhuoye&lt;/td&gt;&lt;td&gt;删除用户zhuoye&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;id zhuoye&lt;/td&gt;&lt;td&gt;查看用户zhuoye的信息&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;su zhuoye&lt;/td&gt;&lt;td&gt;切换到用户zhuoye&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;su -&lt;/td&gt;&lt;td&gt;切换到root用户&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;用户切换说明：&lt;/strong&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;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2.5 压缩和解压操作&lt;a href=&quot;#325-压缩和解压操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;1. gzip/gunzip（单个文件）&lt;/strong&gt;&lt;/p&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;gzip file.txt&lt;/td&gt;&lt;td&gt;压缩单个文件，生成.gz压缩包，并删除原文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;gunzip file.txt.gz&lt;/td&gt;&lt;td&gt;解压.gz压缩包，并删除原压缩包&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;2. zip/unzip（多个文件和目录）&lt;/strong&gt;&lt;/p&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;zip archive.zip file1.txt file2.txt&lt;/td&gt;&lt;td&gt;把多个文件压缩为zip文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;zip -r archive.zip dir/&lt;/td&gt;&lt;td&gt;递归压缩目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;unzip archive.zip&lt;/td&gt;&lt;td&gt;解压zip文件到当前目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;unzip archive.zip -d /opt/data&lt;/td&gt;&lt;td&gt;解压zip文件到指定目录&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;3. tar（Java开发最常用）&lt;/strong&gt;&lt;/p&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;tar -zcvf archive.tar.gz file1 file2 dir/&lt;/td&gt;&lt;td&gt;打包并压缩&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;tar -zxvf archive.tar.gz&lt;/td&gt;&lt;td&gt;解压到当前目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;tar -zxvf archive.tar.gz -C /opt/data&lt;/td&gt;&lt;td&gt;解压到指定目录&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;参数说明&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-z&lt;/code&gt;：使用gzip压缩/解压&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt;：创建压缩包&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-x&lt;/code&gt;：解压&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt;：显示详细过程&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt;：指定文件名（必须放在最后）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt;：指定解压目录&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2.6 权限相关操作&lt;a href=&quot;#326-权限相关操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;1. 修改文件所有者&lt;/strong&gt;&lt;/p&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;chown zhuoye file.txt&lt;/td&gt;&lt;td&gt;修改文件的所有者为zhuoye用户&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;chown -R zhuoye data/&lt;/td&gt;&lt;td&gt;递归修改目录及其内部文件的所有者&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;chown zhuoye file.txt&lt;/td&gt;&lt;td&gt;同时修改所有者和所属组&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;2. 文件权限控制&lt;/strong&gt;&lt;/p&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;chmod 777 file.txt&lt;/td&gt;&lt;td&gt;将文件权限设置为777（所有用户可读写执行）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;chmod 755 file.txt&lt;/td&gt;&lt;td&gt;所有者可读写执行，其他用户可读执行&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;chmod 644 file.txt&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;/p&gt;&lt;p&gt;Linux中每个文件或目录都有三部分权限：所有者权限、同组用户权限、其他组用户权限。&lt;/p&gt;


















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;权限&lt;/th&gt;&lt;th&gt;r（读）&lt;/th&gt;&lt;th&gt;w（写）&lt;/th&gt;&lt;th&gt;x（执行）&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;/td&gt;&lt;td&gt;可查看内容&lt;/td&gt;&lt;td&gt;可修改内容&lt;/td&gt;&lt;td&gt;可执行/进入目录&lt;/td&gt;&lt;td&gt;4 / 2 / 1&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;rwx&lt;/td&gt;&lt;td&gt;读写执行&lt;/td&gt;&lt;td&gt;7 (4+2+1)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;r-x&lt;/td&gt;&lt;td&gt;读和执行&lt;/td&gt;&lt;td&gt;5 (4+1)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;r—&lt;/td&gt;&lt;td&gt;只读&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;---&lt;/td&gt;&lt;td&gt;无权限&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;权限表示示例：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-rwxr-xr--  file.txt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;││││││││││&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│││││││││└─ 其他用户：只读(4)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│││││││└──── 同组用户：读执行(5)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│││││└─────── 所有者：读写执行(7)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2.7 进程管理（Java开发必备）&lt;a href=&quot;#327-进程管理java开发必备&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;`ps -ef&lt;/td&gt;&lt;td&gt;grep mysql`&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;`ps -ef&lt;/td&gt;&lt;td&gt;grep java`&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;jps&lt;/td&gt;&lt;td&gt;查看当前运行的Java进程（JDK自带，最常用）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;lsof -i &amp;lt;3306&amp;gt;&lt;/td&gt;&lt;td&gt;查看占用3306端口的进程&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;`netstat -tunlp&lt;/td&gt;&lt;td&gt;grep 8080`&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;kill -9 PID&lt;/td&gt;&lt;td&gt;强制关闭指定PID的进程&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;kill -15 PID&lt;/td&gt;&lt;td&gt;正常关闭指定PID的进程&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;Java应用部署常用操作：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 1. 查看Java进程&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;jps&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 或&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ps&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-ef&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;java&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 2. 查看应用占用的端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;lsof&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 3. 停止应用&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;kill&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-15&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;PID&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 4. 后台启动Java应用（常用）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;nohup&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;java&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-jar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.jar&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;/span&gt;&lt;span&gt;app.log&lt;/span&gt;&lt;span&gt; 2&amp;gt;&amp;amp;1 &amp;amp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 5. 查看应用日志&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.log&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2.8 软件包安装&lt;a href=&quot;#328-软件包安装&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;1. RPM包安装&lt;/strong&gt;&lt;/p&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;rpm -ivh package.rpm&lt;/td&gt;&lt;td&gt;安装rpm包（i-安装，v-显示详情，h-进度条）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;rpm -ivh —force package.rpm&lt;/td&gt;&lt;td&gt;强制安装&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;rpm -e package.rpm&lt;/td&gt;&lt;td&gt;卸载rpm软件包&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;rpm -qa | grep java&lt;/td&gt;&lt;td&gt;查看已安装的软件&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;2. YUM安装（推荐）&lt;/strong&gt;&lt;/p&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;yum install firefox&lt;/td&gt;&lt;td&gt;安装软件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;yum list installed | grep firefox&lt;/td&gt;&lt;td&gt;查看已安装的软件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;yum remove firefox.x86_64&lt;/td&gt;&lt;td&gt;卸载软件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;yum update&lt;/td&gt;&lt;td&gt;更新所有软件包&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;yum search keyword&lt;/td&gt;&lt;td&gt;搜索软件包&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3.3 拓展指令&lt;a href=&quot;#33-拓展指令&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;3.3.1 文件上传下载&lt;a href=&quot;#331-文件上传下载&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;rz -y&lt;/td&gt;&lt;td&gt;上传本地文件到Linux服务器（-y表示覆盖同名文件）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sz filename&lt;/td&gt;&lt;td&gt;下载服务器文件到本地电脑&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：如果提示命令不存在，需要先安装：&lt;code&gt;yum install lrzsz&lt;/code&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.3.2 执行可执行文件&lt;a href=&quot;#332-执行可执行文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 方式1：使用相对路径或绝对路径&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;./script.sh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 方式2：使用sh命令&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;sh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;script.sh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 方式3：使用bash命令&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;bash&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;script.sh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.3.3 网络相关（Java开发调试必备）&lt;a href=&quot;#333-网络相关java开发调试必备&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;ping &lt;a href=&quot;http://www.baidu.com&quot; target=&quot;_blank&quot;&gt;www.baidu.com&lt;/a&gt;&lt;/td&gt;&lt;td&gt;测试网络连通性&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;telnet ip port&lt;/td&gt;&lt;td&gt;测试端口是否连通（如：telnet 192.168.1.100 3306）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;curl &lt;a href=&quot;http://api.example.com&quot; target=&quot;_blank&quot;&gt;http://api.example.com&lt;/a&gt;&lt;/td&gt;&lt;td&gt;测试HTTP接口&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;wget &lt;a href=&quot;http://example.com/file.zip&quot; target=&quot;_blank&quot;&gt;http://example.com/file.zip&lt;/a&gt;&lt;/td&gt;&lt;td&gt;下载文件&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.3.4 环境变量&lt;a href=&quot;#334-环境变量&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;echo $JAVA_HOME&lt;/td&gt;&lt;td&gt;查看JAVA_HOME环境变量&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;echo $PATH&lt;/td&gt;&lt;td&gt;查看PATH环境变量&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;export JAVA_HOME=/opt/jdk11&lt;/td&gt;&lt;td&gt;临时设置环境变量&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;source /etc/profile&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;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 1. 编辑配置文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/profile&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 2. 在文件末尾添加&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;JAVA_HOME&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;opt&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;jdk11&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PATH&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$JAVA_HOME&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;bin&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;$PATH&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 3. 使配置生效&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;source&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/profile&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;四、实战练习&lt;a href=&quot;#四实战练习&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;4.1 日常操作流程练习&lt;a href=&quot;#41-日常操作流程练习&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;任务：部署一个Java应用&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 1. 连接服务器（使用XShell）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 2. 进入应用部署目录&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/opt/app&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 3. 查看当前目录内容&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ll&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 4. 查看是否有Java进程在运行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;jps&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 5. 如果有旧进程，先停止（假设PID是12345）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;kill&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-15&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;12345&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 6. 备份旧版本&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;cp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.jar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app-bak-&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;date&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+%Y%m%d&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.jar&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 7. 使用XFTP上传新版本app.jar到当前目录&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 8. 后台启动应用&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;nohup&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;java&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-jar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.jar&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;/span&gt;&lt;span&gt;app.log&lt;/span&gt;&lt;span&gt; 2&amp;gt;&amp;amp;1 &amp;amp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 9. 查看启动日志&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.log&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 10. 确认启动成功后，按Ctrl+C退出日志查看（应用继续运行）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4.2 问题排查练习&lt;a href=&quot;#42-问题排查练习&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;问题1：应用无法启动&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 检查Java环境&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;java&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-version&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 检查端口是否被占用&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;lsof&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 查看错误日志&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-100&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.log&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ERROR&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 检查磁盘空间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;df&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-h&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;问题2：无法访问应用&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 检查应用是否运行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;jps&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 检查端口监听&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;netstat&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-tunlp&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 检查防火墙&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--zone=public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--list-ports&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 如果没有开放端口，添加端口&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--permanent&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--zone=public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--add-port=8080/tcp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;firewall-cmd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--reload&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Maven的基本使用</title><link>https://study-docs-158.pages.dev/posts/maven%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/maven%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/</guid><description>Maven的基本使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、什么是maven&lt;a href=&quot;#一什么是maven&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Maven的主要作用是简化了Java项目的构建过程。它通过一个名为&lt;code&gt;pom.xml&lt;/code&gt;的核心配置文件来管理项目的依赖关系、编译设置、打包和部署等操作。使用Maven，开发者不需要手动下载和管理依赖的jar包，只需在&lt;code&gt;pom.xml&lt;/code&gt;文件中声明所需的依赖项及其版本，Maven会自动从仓库中下载并添加到项目中。&lt;/p&gt;&lt;p&gt;此外，Maven还提供了许多插件，支持项目的开发、测试、打包和部署等一系列活动。这些插件可以扩展Maven的功能，使其能够满足不同项目的需求。&lt;/p&gt;&lt;p&gt;总的来说，Maven是一个强大的自动化构建工具，它通过标准化的项目结构和生命周期管理，提高了开发效率，降低了项目维护的复杂性。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/a837d4b3-d732-4b8e-a1a0-7b602d307e55.png&quot; alt=&quot;Maven&quot; /&gt;&lt;figcaption&gt;Maven&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;中央仓库的地址：&lt;a href=&quot;https://mvnrepository.com/&quot; target=&quot;_blank&quot;&gt;https://mvnrepository.com/&lt;/a&gt;&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、maven的基本操作&lt;a href=&quot;#二maven的基本操作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h4&gt;1、idea配置maven&lt;a href=&quot;#1idea配置maven&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/c267bae0-9527-4636-a421-5583a562538e.png&quot; alt=&quot;设置maven&quot; /&gt;&lt;figcaption&gt;设置maven&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;需要注意的是，如果公司有使用私仓的话，settings.xml配置文件一定要使用包含私仓信息的，可以直接问同事要一份！&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、引入新的依赖&lt;a href=&quot;#2引入新的依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;section&gt;&lt;h5&gt;2.1、依赖在远程仓库中&lt;a href=&quot;#21依赖在远程仓库中&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;maven仓库存在的依赖，直接引入，刷新maven即可&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.springframework&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;spring-webmvc&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;5.1.6.RELEASE&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;groupld：用于定义当前Maven项目所隶属的组织名称，一般按照域名反写规则来确定，比如“com.zcloud”。 artifactld：用来定义当前Maven项目的名称，通常为具体的模块名称，比如“user-service”“admin-service”等。 version：用于设定当前项目的版本号。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;2.2、依赖不在远程仓库中&lt;a href=&quot;#22依赖不在远程仓库中&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用 &lt;code&gt;system&lt;/code&gt; 作用域&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;将需要引入的jar包放到pom文件同级目录lib下，如果没有这个目录可以新建一个目录，然后使用如下方式引入，坐标信息自定义即可，但最后和jar包实际信息保持一致或者能够正确反映该jar包信息！&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;com.alibaba&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;alicrypto-java-aliyun&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;1.0.4&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;scope&lt;/span&gt;&lt;span&gt;&amp;gt;system&amp;lt;/&lt;/span&gt;&lt;span&gt;scope&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;systemPath&lt;/span&gt;&lt;span&gt;&amp;gt;${project.basedir}/lib/alicrypto-java-aliyun-1.0.4.jar&amp;lt;/&lt;/span&gt;&lt;span&gt;systemPath&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;如果想要在打包的时候也要把本地system的jar包打进来的话，就需要在maven插件中配置一个includeSystemScope属性：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;plugin&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.springframework.boot&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;spring-boot-maven-plugin&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;configuration&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;&amp;lt;!--设置为true，打包的时候把本地的system的jar包也打包进来--&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;includeSystemScope&lt;/span&gt;&lt;span&gt;&amp;gt;true&amp;lt;/&lt;/span&gt;&lt;span&gt;includeSystemScope&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;configuration&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;plugin&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;注：project.basedir 就是pom文件所在的目录。&lt;/p&gt;&lt;p&gt;scop标签的的值有下面几个：&lt;/p&gt;
























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;compile&lt;/th&gt;&lt;th&gt;默认值，适用于所有阶段（测试、运行，编译）&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;provided&lt;/td&gt;&lt;td&gt;期望容器或使用者会提供这个依赖。如servlet-api.jar；适用于（测试，编译）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;runtime&lt;/td&gt;&lt;td&gt;只在运行时使用，如 mysql的驱动jar&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;test&lt;/td&gt;&lt;td&gt;只在测试时使用，如 junit.jar&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;system&lt;/td&gt;&lt;td&gt;Maven不会在仓库中查找对应依赖，在本地磁盘目录中查找；适用于（编译，测试，运行）&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;/ul&gt;&lt;p&gt;安装本地仓库直接使用如下命令安装即可！&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;mvn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install:install-file&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-Dfile=alicrypto-java-aliyun-1.0.4.jar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-DgroupId=com.alibaba&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-DartifactId=alicrypto-java-aliyun&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-Dversion=1.0.4&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-Dpackaging=jar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-DlocalRepositoryPath=D:&lt;/span&gt;&lt;span&gt;\L&lt;/span&gt;&lt;span&gt;earning_Document&lt;/span&gt;&lt;span&gt;\M&lt;/span&gt;&lt;span&gt;aven&lt;/span&gt;&lt;span&gt;\r&lt;/span&gt;&lt;span&gt;epository&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;说明，-Dfile就是你需要安装的jar的路径，可以是绝对路径，也可以是当前命令执行目录下的相对路径。-DlocalRepositoryPath就是需要jar包需要安装到的maven本地仓库的路径！&lt;/p&gt;&lt;p&gt;如下图，就是在对应需要安装的jar包目录下打开cmd的执行成功的结果：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/131370c5-a72c-4e37-9e42-f4f4d8701129.png&quot; alt=&quot;命令安装本地jar包&quot; /&gt;&lt;figcaption&gt;命令安装本地jar包&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;如下，在本地仓库对应目录存在我们安装的jar包，即是成功！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/6782ad6b-1399-4f9a-bb18-10769444a43a.png&quot; alt=&quot;命令安装本地jar包-2&quot; /&gt;&lt;figcaption&gt;命令安装本地jar包-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、maven打包等功能说明&lt;a href=&quot;#3maven打包等功能说明&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/7b6b2de0-38e7-42f8-b889-251c02afe4f2.png&quot; alt=&quot;maven工具栏&quot; /&gt;&lt;figcaption&gt;maven工具栏&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、maven的多环境管理&lt;a href=&quot;#4maven的多环境管理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Maven 多环境管理能够实现多环境配置文件之间的灵活切换，以及对配置文件中不同环境变量值的精准替换。在一些公司的实际项目中会运用到这一功能，了解并知晓其存在即可，当所在公司采用这种方式时，能及时想到即可。当使用maven多环境管理功能的时候，在maven工具栏会出现Profiles项，如下图所示：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/28d0c321-cebd-4d97-91e7-8010009c5892.png&quot; alt=&quot;maven多环境管理&quot; /&gt;&lt;figcaption&gt;maven多环境管理&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;pom文件里面会有如下配置：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;project&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;profiles&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;dev&amp;lt;/&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependencies&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.springframework.boot&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;spring-boot-devtools&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependencies&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;#设置该配置为默认生效&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;activation&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;activeByDefault&lt;/span&gt;&lt;span&gt;&amp;gt;true&amp;lt;/&lt;/span&gt;&lt;span&gt;activeByDefault&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;activation&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;properties&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;&amp;gt;dev&amp;lt;/&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;server.port&lt;/span&gt;&lt;span&gt;&amp;gt;8081&amp;lt;/&lt;/span&gt;&lt;span&gt;server.port&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;log.level&lt;/span&gt;&lt;span&gt;&amp;gt;INFO&amp;lt;/&lt;/span&gt;&lt;span&gt;log.level&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;properties&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;prod&amp;lt;/&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;properties&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;&amp;gt;prod&amp;lt;/&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;server.port&lt;/span&gt;&lt;span&gt;&amp;gt;9090&amp;lt;/&lt;/span&gt;&lt;span&gt;server.port&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;log.level&lt;/span&gt;&lt;span&gt;&amp;gt;WARN&amp;lt;/&lt;/span&gt;&lt;span&gt;log.level&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;properties&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;profiles&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;project&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;application.yml配置文件里面会有如下配置：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 开发环境配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 服务器的HTTP端口，默认为8080&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${server.port}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 日志配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;logging&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;level&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;com.ruoyi&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${log.level}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;org.springframework&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${log.level}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5、maven的私服&lt;a href=&quot;#5maven的私服&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;section&gt;&lt;h5&gt;5.1 maven私服的介绍&lt;a href=&quot;#51-maven私服的介绍&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;maven 私有仓库的搭建，通常都是使用 Nexus 这一主流工具。通过使用maven 私仓，我们为您能够构建专属于公司内部使用的依赖仓库。一方面，我们可以在这个私仓中高效管理公司自己开发的各类 Jar 包，实现内部组件的统一存储与版本管控；另一方面，还能将项目所需的中央仓库 Jar 包缓存到私仓中，既可以提升依赖下载的稳定性与速度，也能解决内网开发环境下的项目构建的需求。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/84e12ceb-841b-489e-a56c-784bcb6ebb38.png&quot; alt=&quot;maven私仓&quot; /&gt;&lt;figcaption&gt;maven私仓&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;上面有四个maven仓库类型，含义如下：&lt;/p&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;maven-central (代理仓库)&lt;/td&gt;&lt;td&gt;海外代购仓库&lt;/td&gt;&lt;td&gt;代理Maven中央仓库，首次购买从国外运来，之后存在本地仓库，下次直接拿&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;maven-releases (宿主仓库)&lt;/td&gt;&lt;td&gt;公司正式产品仓库&lt;/td&gt;&lt;td&gt;存放公司正式发布的版本（打包时不带-SNAPSHOT）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;maven-snapshots (宿主仓库)&lt;/td&gt;&lt;td&gt;公司测试产品仓库&lt;/td&gt;&lt;td&gt;存放公司正在开发的版本（打包时带-SNAPSHOT）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;maven-public (组仓库)&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;/section&gt;&lt;section&gt;&lt;h5&gt;5.2 maven私服的使用&lt;a href=&quot;#52-maven私服的使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;maven私服对于我们来说主要就是有以下两个常见的使用&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;发布jar包&lt;/p&gt;
&lt;p&gt;直接点击maven工具栏的deploy发布即可！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;引入jar包&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/68a6a11a-74da-46d3-b23d-77b5e9e5ed3a.png&quot; alt=&quot;maven私仓2&quot; /&gt;&lt;figcaption&gt;maven私仓2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;三、常见问题&lt;a href=&quot;#三常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h4&gt;1、依赖冲突&lt;a href=&quot;#1依赖冲突&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;当两条依赖路径把同一个坐标的 jar 引了进来，但版本不同，JVM 只能选一个，于是“选错”的那个就把代码搞炸，这也就是依赖冲突。&lt;/p&gt;&lt;section&gt;&lt;h5&gt;1.1 如何查看依赖冲突&lt;a href=&quot;#11-如何查看依赖冲突&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;命令的形式&lt;/p&gt;
&lt;p&gt;不建议用，依赖多的时候，不好查找&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;mvn -Dverbose dependency:tree&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用插件 (建议使用该方式)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/cb024f96-8ea7-4227-aaa7-a19bdac97dda.png&quot; alt=&quot;依赖冲突1&quot; /&gt;&lt;figcaption&gt;依赖冲突1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;如果搜索插件的时候，没有任何结果的时候，可进行如下设置后，再进行搜索&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/cc3091ba-ff65-4768-8d43-44e087759a05.jpg&quot; alt=&quot;依赖冲突2&quot; /&gt;&lt;figcaption&gt;依赖冲突2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;安装完成之后，pom文件下方就会出现 &lt;strong&gt;Dependency Analyzer&lt;/strong&gt; ，点击即可对当前pom文件引入的依赖进行分析。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/255feb0b-3fa7-440b-b544-4bed2375d100.png&quot; alt=&quot;maven-helper&quot; /&gt;&lt;figcaption&gt;maven-helper&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h5&gt;1.2 解决依赖冲突&lt;a href=&quot;#12-解决依赖冲突&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;&lt;p&gt;1）使用maven的依赖传递原则来解决&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;路径最短优先原则&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;​ 主要根据依赖的路径长短来决定引入哪个依赖&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;最先声明优先原则&lt;/p&gt;
&lt;p&gt;如果两个依赖的路径一样，声明在前的则优先选择。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;2）手动排除依赖&lt;/p&gt;&lt;p&gt;使用exclusion标签来排除依赖&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;nl.basjes.parse.useragent&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;yauaa&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;exclusions&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;exclusion&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;commons-collections4&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.apache.commons&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;exclusion&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;exclusions&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;可以自己手动在pom文件添加，也可以使用Maven Helper插件来快速排除依赖！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/0e010226-6624-4695-a3a1-fad1f328cc2d.png&quot; alt=&quot;排除依赖&quot; /&gt;&lt;figcaption&gt;排除依赖&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;3）封装成rpc服务（了解）&lt;/p&gt;&lt;p&gt;当同一个Java程序 里必须同时加载两份不兼容的 jar包的时候，这个时候只能把其中一方单独拆成一个RPC服务，主应用通过 Feign/Dubbo/gRPC等进行远程调用！&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、maven的pom文件未被正确识别&lt;a href=&quot;#2maven的pom文件未被正确识别&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;pom文件为蓝色的m标识的时候，为正确识别。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/02775995-bc87-4ed9-9b4b-5717c1152711.png&quot; alt=&quot;pom文件识别&quot; /&gt;&lt;figcaption&gt;pom文件识别&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;未被识别的时候，右击pom文件点击 &lt;strong&gt;Add as Maven Project&lt;/strong&gt; 添加为maven工程：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/3a8a7f70-19c3-4208-8d7a-4537d1c9b169.png&quot; alt=&quot;pom文件识别2&quot; /&gt;&lt;figcaption&gt;pom文件识别2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、maven工具栏消失&lt;a href=&quot;#3maven工具栏消失&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;未启用maven插件&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/f2f3d52c-4a5c-4160-8b0a-337290b5afde.png&quot; alt=&quot;maven工具栏消失&quot; /&gt;&lt;figcaption&gt;maven工具栏消失&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;pom文件未被正确识别&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/69f40d96-498b-47f9-ac2b-8ecea16c205f.png&quot; alt=&quot;maven工具栏消失2&quot; /&gt;&lt;figcaption&gt;maven工具栏消失2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、依赖未正确加载&lt;a href=&quot;#4依赖未正确加载&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/db232f4a-8b07-46b1-8899-fea2fc01a853.png&quot; alt=&quot;依赖未正确加载&quot; /&gt;&lt;figcaption&gt;依赖未正确加载&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Navicat的使用</title><link>https://study-docs-158.pages.dev/posts/navicat%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/navicat%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>Navicat的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、Navicat是什么？&lt;a href=&quot;#一navicat是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Navicat&lt;/strong&gt; 是一款数据库管理可视化工具，&lt;strong&gt;不是数据库本身&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;打个比方：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Navicat&lt;/strong&gt; 就像是 &lt;strong&gt;Xshell&lt;/strong&gt;，是连接数据库的工具&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MySQL&lt;/strong&gt; 就像是 &lt;strong&gt;Linux服务器&lt;/strong&gt;，是真正的数据库服务&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;常见误区&lt;/strong&gt;：很多新人误以为Navicat就是数据库，其实它只是一个管理工具，就像用Xshell连接Linux服务器一样。&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、Navicat的使用&lt;a href=&quot;#二navicat的使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、连接数据库、创建库&lt;a href=&quot;#1连接数据库创建库&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1.1 连接数据库&lt;a href=&quot;#11-连接数据库&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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; 按钮&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择数据库类型（如 &lt;strong&gt;MySQL&lt;/strong&gt;）&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/c010e768-0776-47bf-9d32-aa4f8bb9f052.png&quot; alt=&quot;新建数据库连接-1&quot; /&gt;&lt;figcaption&gt;新建数据库连接-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;填写连接信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;连接名&lt;/strong&gt;：自定义名称，方便识别，最好包含IP信息，方便通过连接名就可以知道对应的服务器的IP是什么（如：本地测试库-127.0.0.1、生产环境库-10.3.8.221）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主机&lt;/strong&gt;：数据库服务器地址（&lt;code&gt;localhost&lt;/code&gt; 或 &lt;code&gt;127.0.0.1&lt;/code&gt; 表示本机，如果不是本机，就填写对应服务器的ip）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;端口&lt;/strong&gt;：MySQL默认 &lt;code&gt;3306&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用户名&lt;/strong&gt;：数据库用户名（如：&lt;code&gt;root&lt;/code&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;/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;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/f1ce02e0-f1d1-43c8-94b3-b33f9ec66739.png&quot; alt=&quot;新建数据库连接&quot; /&gt;&lt;figcaption&gt;新建数据库连接&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;1.2 创建数据库&lt;a href=&quot;#12-创建数据库&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;方法一：右键菜单&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;在连接名上 &lt;strong&gt;右键&lt;/strong&gt; → 选择 &lt;strong&gt;「新建数据库」&lt;/strong&gt;&lt;/li&gt;
&lt;li&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;code&gt;utf8mb4&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排序规则&lt;/strong&gt;：同字符集，没有可参考的推荐选择 &lt;code&gt;utf8mb4_general_ci&lt;/code&gt; 或 &lt;code&gt;utf8mb4_unicode_ci&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;「确定」&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/da5bfd3c-7604-4f53-b286-e6e4cd76d748.png&quot; alt=&quot;新建数据库&quot; /&gt;&lt;figcaption&gt;新建数据库&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、导出SQL脚本和执行SQL脚本&lt;a href=&quot;#2导出sql脚本和执行sql脚本&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;2.1 导出SQL脚本（备份表结构/数据）&lt;a href=&quot;#21-导出sql脚本备份表结构数据&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;选中要导出的 &lt;strong&gt;数据库&lt;/strong&gt; 或 &lt;strong&gt;表&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;右键&lt;/strong&gt; → 选择 &lt;strong&gt;「转储SQL文件」&lt;/strong&gt;&lt;/li&gt;
&lt;li&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;strong&gt;「保存」&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/66312b7e-25e9-4a0c-b7c1-2af8ae3bbb5d.png&quot; alt=&quot;转储sql&quot; /&gt;&lt;figcaption&gt;转储sql&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;💡 &lt;strong&gt;使用场景&lt;/strong&gt;：&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;/section&gt;&lt;section&gt;&lt;h4&gt;2.2 执行SQL脚本（导入）&lt;a href=&quot;#22-执行sql脚本导入&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;「右键」&lt;/strong&gt; → &lt;strong&gt;「运行SQL文件」&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/3f5eeb5f-1ebb-449e-adf4-ea28ec4da82d.png&quot; alt=&quot;执行sql脚本-1&quot; /&gt;&lt;figcaption&gt;执行sql脚本-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;选择本地要执行的 &lt;code&gt;.sql&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;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/d64db02f-b5da-4d06-b24d-269a550c4d95.png&quot; alt=&quot;执行sql脚本-2&quot; /&gt;&lt;figcaption&gt;执行sql脚本-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;注意&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;导入前未选中目标数据库，导致找不到表&lt;/li&gt;
&lt;li&gt;SQL文件编码不对，导致中文乱码&lt;/li&gt;
&lt;li&gt;大文件导入超时，需要调整 &lt;code&gt;max_allowed_packet&lt;/code&gt; 参数&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、新建表、修改表&lt;a href=&quot;#3新建表修改表&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;3.1 新建表&lt;a href=&quot;#31-新建表&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;选中 &lt;strong&gt;数据库&lt;/strong&gt; → &lt;strong&gt;「新建表」&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/0ed4c2c6-8779-4c37-87e4-497b795973f7.png&quot; alt=&quot;新建表&quot; /&gt;&lt;figcaption&gt;新建表&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;在如下界面，设置新建表的字段、索引、注释等。设置字段的时候不要有空格等特殊字符！&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/e1041cfb-4f9b-42ec-a55c-450cc8d1b703.png&quot; alt=&quot;新建表2&quot; /&gt;&lt;figcaption&gt;新建表2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;新建表界面部分内容说明&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;在设计视图中添加字段说明：&lt;/li&gt;
&lt;/ul&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;/td&gt;&lt;td&gt;字段名称&lt;/td&gt;&lt;td&gt;一般规范就是使用小写字母+下划线，如 user_name&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;类型&lt;/td&gt;&lt;td&gt;数据类型&lt;/td&gt;&lt;td&gt;VARCHAR、INT、DATETIME、DECIMAL 等&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;长度&lt;/td&gt;&lt;td&gt;字段长度&lt;/td&gt;&lt;td&gt;VARCHAR常用255、500、1000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;小数点&lt;/td&gt;&lt;td&gt;小数位数&lt;/td&gt;&lt;td&gt;DECIMAL类型使用，如 DECIMAL(10,2)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;不是null&lt;/td&gt;&lt;td&gt;是否允许NULL&lt;/td&gt;&lt;td&gt;主键字段通常不勾选,因为主键字段本身就不会为NULL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;主键&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;/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;/td&gt;&lt;td&gt;默认值&lt;/td&gt;&lt;td&gt;如当前时间、0等&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;设置索引&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/a6a1ffb9-584d-4868-b7fc-95e7349fc4a5.png&quot; alt=&quot;设置索引&quot; /&gt;&lt;figcaption&gt;设置索引&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击 &lt;strong&gt;「保存」&lt;/strong&gt;（或 Ctrl+S），填写表名。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/83414cdf-4491-4fd8-9b69-04501510a570.png&quot; alt=&quot;填写表名&quot; /&gt;&lt;figcaption&gt;填写表名&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;常用字段类型参考：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 字符串&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;VARCHAR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;255&lt;/span&gt;&lt;span&gt;)      &lt;/span&gt;&lt;span&gt;-- 变长字符串&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TEXT&lt;/span&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;-- 长文本&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 数字&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;INT&lt;/span&gt;&lt;span&gt;               &lt;/span&gt;&lt;span&gt;-- 整数&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;BIGINT&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;-- 长整数&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DECIMAL&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)     &lt;/span&gt;&lt;span&gt;-- 金额字段&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 日期时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DATETIME&lt;/span&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;-- 日期时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TIMESTAMP&lt;/span&gt;&lt;span&gt;         &lt;/span&gt;&lt;span&gt;-- 时间戳&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DATE&lt;/span&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;-- 日期&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TIME&lt;/span&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;-- 时间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 其他&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TINYINT&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)        &lt;/span&gt;&lt;span&gt;-- 布尔值（0或1）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;💡 &lt;strong&gt;命名规范&lt;/strong&gt;：&lt;/p&gt;&lt;p&gt;如果公司有命名规范就按照公司的命名规范。如果没有的话，就可以遵循如下一般规范即可。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;表名：&lt;code&gt;t_模块名&lt;/code&gt; 或 &lt;code&gt;tb_模块名&lt;/code&gt;，如 &lt;code&gt;t_user&lt;/code&gt;、&lt;code&gt;tb_order&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;字段名：小写字母+下划线，如 &lt;code&gt;user_name&lt;/code&gt;、&lt;code&gt;create_time&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3.2 修改表结构&lt;a href=&quot;#32-修改表结构&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;修改表字段，如果是开发环境、测试环境一般都可以直接修改。如果是生产环境在修改的时候，一定要确认清楚你们可不可以直接修改。如果不可以的话，确认需要走什么样的流程，然后按照流程去走。&lt;/p&gt;&lt;p&gt;&lt;strong&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;&lt;/li&gt;
&lt;/ul&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;/th&gt;&lt;th&gt;步骤&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&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;/tr&gt;&lt;tr&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;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;注意&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;修改已存在字段的类型可能导致数据丢失&lt;/li&gt;
&lt;li&gt;删除字段前请确认没有代码在使用&lt;/li&gt;
&lt;li&gt;修改表结构最好&lt;strong&gt;先备份&lt;/strong&gt;！&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、数据筛选和排序&lt;a href=&quot;#4数据筛选和排序&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/553ce3d7-5a98-41fa-9ad7-06e933932479.png&quot; alt=&quot;数据筛选和排序&quot; /&gt;&lt;figcaption&gt;数据筛选和排序&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、执行SQL语句&lt;a href=&quot;#5执行sql语句&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;选中数据库 → 点击顶部 &lt;strong&gt;「查询」&lt;/strong&gt; → &lt;strong&gt;「新建查询」&lt;/strong&gt;,然后在如下界面写要执行的sql点击运行即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/356ed9a5-0da5-4561-ae64-a8cd4b28d46b.png&quot; alt=&quot;执行sql语句&quot; /&gt;&lt;figcaption&gt;执行sql语句&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;hr /&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;新人踩坑点&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;忘记加WHERE条件&lt;/strong&gt;，导致更新/删除了全部数据！&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有先SELECT查询&lt;/strong&gt;，直接执行UPDATE/DELETE&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;💡 &lt;strong&gt;安全操作习惯&lt;/strong&gt;：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;先SELECT查询确认数据&lt;/li&gt;
&lt;li&gt;再UPDATE/DELETE修改&lt;/li&gt;
&lt;li&gt;执行前务必检查WHERE条件&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6、导出Excel、导入Excel&lt;a href=&quot;#6导出excel导入excel&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;6.1 导出Excel&lt;a href=&quot;#61-导出excel&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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; → &lt;strong&gt;「导出向导」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9d41c0f5-f4e6-42e5-93d7-a73da4d755dc.png&quot; alt=&quot;导出excel-1&quot; /&gt;&lt;figcaption&gt;导出excel-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择导出格式：&lt;strong&gt;Excel 文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/856a8e66-7c91-47e2-aec2-bf62c0447fe6.png&quot; alt=&quot;导出excel-2&quot; /&gt;&lt;figcaption&gt;导出excel-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择要导出的表以及要导出的目录。默认就是第一步你选中的那个表，不需要重新设置要导出的表或者也不需要添加其他要导出的表，就直接下一步即可。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/0e9787c6-0ec0-4a27-b3c5-4b8f00c7d7f4.png&quot; alt=&quot;导出excel-3&quot; /&gt;&lt;figcaption&gt;导出excel-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择要导出的字段（可全选或部分选择），点击 &lt;strong&gt;「下一步」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/0ce74fad-8e88-40d0-8d9e-bfbda6f7ea5a.png&quot; alt=&quot;导出excel-4&quot; /&gt;&lt;figcaption&gt;导出excel-4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&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;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/92859cd9-4844-4e84-bd41-59b52e91fbc7.png&quot; alt=&quot;导出excel-5&quot; /&gt;&lt;figcaption&gt;导出excel-5&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;其他导出格式：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Excel 文件（*.xlsx）&lt;/li&gt;
&lt;li&gt;CSV 文件&lt;/li&gt;
&lt;li&gt;JSON 文件&lt;/li&gt;
&lt;li&gt;XML 文件&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;💡 &lt;strong&gt;使用场景&lt;/strong&gt;：&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;/section&gt;&lt;section&gt;&lt;h4&gt;6.2 导入Excel&lt;a href=&quot;#62-导入excel&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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; → &lt;strong&gt;右键&lt;/strong&gt; → &lt;strong&gt;「导入向导」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/5493ede7-381c-4d65-8c32-0ec94f946040.png&quot; alt=&quot;导入excel-1&quot; /&gt;&lt;figcaption&gt;导入excel-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择导入格式：&lt;strong&gt;Excel 文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/7ffec7e5-8ee4-462c-bb97-044008d69abc.png&quot; alt=&quot;导入excel-2&quot; /&gt;&lt;figcaption&gt;导入excel-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择要导入的Excel文件&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/91a36154-c044-44cb-9291-b58dde01ffbb.png&quot; alt=&quot;导入excel-3&quot; /&gt;&lt;figcaption&gt;导入excel-3&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设置开始导入行、时间格式等信息&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/bc4c38a8-c7b9-4bcf-9b63-ab3dc9696e7b.png&quot; alt=&quot;导入excel-4&quot; /&gt;&lt;figcaption&gt;导入excel-4&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下一步到如下界面，配置字段映射（Excel列 ↔ 表字段）&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/bf853bd2-96e3-4ce4-b021-c2cfc8dd7602.png&quot; alt=&quot;导入excel-5&quot; /&gt;&lt;figcaption&gt;导入excel-5&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设置导入模式&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/a4b42d27-404c-431b-ae37-ff280d5f98fc.png&quot; alt=&quot;导入excel-6&quot; /&gt;&lt;figcaption&gt;导入excel-6&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&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;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/8cbf6db3-cfb2-4290-9492-c58b943a93ca.png&quot; alt=&quot;导入excel-7&quot; /&gt;&lt;figcaption&gt;导入excel-7&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;新人踩坑点&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Excel列顺序与表字段不匹配，导致数据错乱&lt;/li&gt;
&lt;li&gt;Excel数据类型与字段类型不一致&lt;/li&gt;
&lt;li&gt;Excel中有空行，导入失败&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;💡 &lt;strong&gt;导入前检查&lt;/strong&gt;：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;确认Excel列名与表字段一致&lt;/li&gt;
&lt;li&gt;检查数据格式（日期、数字等）&lt;/li&gt;
&lt;li&gt;删除Excel中的空行&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;7、表数据截断和清空&lt;a href=&quot;#7表数据截断和清空&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9eba601f-e5cc-4ae5-a50c-3141ff059429.png&quot; alt=&quot;清空和截断表&quot; /&gt;&lt;figcaption&gt;清空和截断表&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;这两个操作都会&lt;strong&gt;清空表中所有数据&lt;/strong&gt;，但有以下区别：&lt;/p&gt;&lt;section&gt;&lt;h4&gt;7.1 截断表（TRUNCATE）&lt;a href=&quot;#71-截断表truncate&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;特点：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;重置自增ID&lt;/li&gt;
&lt;li&gt;速度快（不记录日志）&lt;/li&gt;
&lt;li&gt;不可回滚&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;选中 &lt;strong&gt;表&lt;/strong&gt; → &lt;strong&gt;右键&lt;/strong&gt; → &lt;strong&gt;「截断表」&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;确认操作&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;SQL语句：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TRUNCATE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TABLE&lt;/span&gt;&lt;span&gt; t_user;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;7.2 清空表（DELETE）&lt;a href=&quot;#72-清空表delete&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;特点：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;不重置自增ID&lt;/li&gt;
&lt;li&gt;速度较慢（逐行删除，记录日志）&lt;/li&gt;
&lt;li&gt;可回滚&lt;/li&gt;
&lt;li&gt;可加WHERE条件删除部分数据&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;选中 &lt;strong&gt;表&lt;/strong&gt; → &lt;strong&gt;右键&lt;/strong&gt; → &lt;strong&gt;「清空表」&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;确认操作&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;SQL语句：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 删除所有数据&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DELETE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;span&gt; t_user;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;-- 删除指定条件数据&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;DELETE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;span&gt; t_user &lt;/span&gt;&lt;span&gt;WHERE&lt;/span&gt;&lt;span&gt;&lt;span&gt; create_time &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;2024-01-01&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;新人踩坑点&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;混淆清空和删除&lt;/strong&gt;，导致自增ID不符合预期&lt;/li&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;p&gt;💡 &lt;strong&gt;安全建议&lt;/strong&gt;：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;重要数据先备份&lt;/strong&gt;（导出SQL或Excel）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;测试环境先验证&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;确认使用清空还是删除&lt;/li&gt;
&lt;li&gt;清空前先SELECT确认数据量&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;8、将表里面部分记录复制成sql语句&lt;a href=&quot;#8将表里面部分记录复制成sql语句&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;当你需要把表里新增的记录或者表记录的更改以sql语句导出来的时候。&lt;/p&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;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;根据你的需求选择 &lt;strong&gt;Insert语句&lt;/strong&gt; 或者 &lt;strong&gt;Update语句&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/eca2da6e-9cf6-4675-a6bf-dab87993d99c.png&quot; alt=&quot;将表里面部分记录复制成sql语句&quot; /&gt;&lt;figcaption&gt;将表里面部分记录复制成sql语句&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&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;/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;/td&gt;&lt;td&gt;t_模块名&lt;/td&gt;&lt;td&gt;t_user、t_order&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;字段名&lt;/td&gt;&lt;td&gt;小写+下划线&lt;/td&gt;&lt;td&gt;user_name、create_time&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;索引名&lt;/td&gt;&lt;td&gt;idx_字段名&lt;/td&gt;&lt;td&gt;idx_user_name&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;主键&lt;/td&gt;&lt;td&gt;id（自增）&lt;/td&gt;&lt;td&gt;id&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;外键&lt;/td&gt;&lt;td&gt;fk_关联表_字段&lt;/td&gt;&lt;td&gt;fk_order_user_id&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Postman的使用</title><link>https://study-docs-158.pages.dev/posts/postman%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/postman%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>Postman的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;一、Postman是什么？&lt;a href=&quot;#一postman是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Postman是一款强大的&lt;strong&gt;API开发与测试工具&lt;/strong&gt;，在Java后端开发中主要用于模拟HTTP客户端，用来调试和测试你开发的RESTful API或WebService接口。&lt;/p&gt;&lt;p&gt;它的重要性在于：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;独立验证&lt;/strong&gt;：不依赖前端页面，单独测试后端接口的&lt;strong&gt;请求、响应、业务逻辑&lt;/strong&gt;和&lt;strong&gt;异常处理&lt;/strong&gt;是否正确。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;问题排查&lt;/strong&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;p&gt;官网下载地址：&lt;a href=&quot;https://www.postman.com/downloads/&quot; target=&quot;_blank&quot;&gt;https://www.postman.com/downloads/&lt;/a&gt;&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;二、Postman的基本使用&lt;a href=&quot;#二postman的基本使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、登录&lt;a href=&quot;#1登录&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Postman是需要登录的，如果不登录，则无法使用Postman的更多功能。比如，保存请求，创建工作空间等功能都无法使用。登录的时候会跳转默认浏览器。如果跳转的默认浏览器不是谷歌浏览器的话，可以按照下图点击 &lt;strong&gt;copy the URL&lt;/strong&gt; 将登录路径复制到谷歌浏览器登录即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/0a28dec9-7f2a-4301-8a14-925a97e879c5.png&quot; alt=&quot;登录&quot; /&gt;&lt;figcaption&gt;登录&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、界面介绍&lt;a href=&quot;#2界面介绍&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Postman的主界面主要包含以下几个部分：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/1bcd956b-e3a9-47c9-9140-51def5f5b47b.png&quot; alt=&quot;界面介绍&quot; /&gt;&lt;figcaption&gt;界面介绍&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&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;/td&gt;&lt;td&gt;设置请求方法（GET/POST等）、URL、参数、Headers、Body等&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;tr&gt;&lt;td&gt;侧边栏&lt;/td&gt;&lt;td&gt;管理Collections（集合）、Environments(环境变量)、History（历史记录）等&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、新建工作空间&lt;a href=&quot;#3新建工作空间&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;通过新建工作空间，可以对请求接口做分类管理。比如你可以去一家公司就新建一个工作空间。当然，你也可以每一个项目就新建一个工作空间。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/599f71c0-6b6e-46c4-a143-5eb94f0fee59.png&quot; alt=&quot;新建工作空间&quot; /&gt;&lt;figcaption&gt;新建工作空间&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;进入如下界面，填写，工作空间名称、描述、可见性等信息。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/46ab02ae-1024-48e1-b40b-ed95f294da67.png&quot; alt=&quot;新建工作空间2&quot; /&gt;&lt;figcaption&gt;新建工作空间2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、新建集合&lt;a href=&quot;#4新建集合&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;新建集合，也可以简单的理解就是建立目录。跟目录不同的是，集合他可以独立导出、生成文档、Mock 与自动化测试。通过合理的目录结构，可以清晰、有序地对接口请求进行分类管理。 若你的工作空间以公司维度划分，则集合可直接用项目名称命名；其下再按功能模块细分子目录。 若工作空间已按项目维度隔离，则集合无需再出现项目名，直接以功能模块命名即可。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/4f9cb0cb-9e78-474a-a45c-7f0459990955.png&quot; alt=&quot;新建集合&quot; /&gt;&lt;figcaption&gt;新建集合&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5、新建请求&lt;a href=&quot;#5新建请求&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/52e3b9a7-9a38-4eb5-9346-9648f598088f.png&quot; alt=&quot;新建请求&quot; /&gt;&lt;figcaption&gt;新建请求&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;出出现如下界面&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/39179696-f351-4d53-aa8a-49de7399049a.png&quot; alt=&quot;新建请求2&quot; /&gt;&lt;figcaption&gt;新建请求2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;注意：在 Postman 里，只要新建或修改了请求，不保存就等于“本地草稿”。不ctrl s保存，变更不会上传到云端，账号里仍是旧版本；换电脑、重新登录后，看到的只能是上次保存时的状态——新改的内容全没了。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;5.1 GET请求&lt;a href=&quot;#51-get请求&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;GET请求用于从服务器获取数据，参数通常通过URL传递。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/35fd31ea-3101-4cbf-8611-5a46693ea8d1.png&quot; alt=&quot;GET请求&quot; /&gt;&lt;figcaption&gt;GET请求&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;URL参数设置方式：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;方式一：直接在URL中拼接参数&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;http://localhost:81/dev-api/system/user/list?pageNum=1&amp;amp;pageSize=10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;方式二：使用Params面板（推荐）&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;点击 &lt;strong&gt;Params&lt;/strong&gt; 按钮&lt;/li&gt;
&lt;li&gt;在Key-Value表格中输入参数名和值&lt;/li&gt;
&lt;li&gt;Postman会自动拼接到URL中&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.2 POST请求&lt;a href=&quot;#22-post请求&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;POST请求用于向服务器提交数据，数据通常放在请求体（Body）中。&lt;/p&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;form-data&lt;/td&gt;&lt;td&gt;文件上传、表单提交&lt;/td&gt;&lt;td&gt;multipart/form-data&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;x-www-form-urlencoded&lt;/td&gt;&lt;td&gt;普通表单提交&lt;/td&gt;&lt;td&gt;键值对格式&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;raw&lt;/td&gt;&lt;td&gt;JSON/XML等格式数据&lt;/td&gt;&lt;td&gt;application/json&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;binary&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;strong&gt;JSON格式请求(最常用）：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/09e5ac46-9397-44a1-88a8-8de7becdd571.png&quot; alt=&quot;JSON请求体&quot; /&gt;&lt;figcaption&gt;JSON请求体&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;文件上传，一般使用&lt;strong&gt;form-data&lt;/strong&gt;：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/6a44e5da-f48b-4506-b299-7e7eea667408.png&quot; alt=&quot;form-data&quot; /&gt;&lt;figcaption&gt;form-data&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.3 PUT请求&lt;a href=&quot;#23-put请求&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;PUT请求用于更新资源，用法与POST类似，数据也放在Body中。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2.4 DELETE请求&lt;a href=&quot;#24-delete请求&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;DELETE请求用于删除资源，通常参数通过URL传递。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6、请求Headers设置&lt;a href=&quot;#6请求headers设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;有些接口需要特定的请求头，如Content-Type、Authorization等。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;点击 &lt;strong&gt;Headers&lt;/strong&gt; 标签&lt;/li&gt;
&lt;li&gt;添加Key-Value对&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/bfabc145-77c9-448d-8074-a23fdf838017.png&quot; alt=&quot;Headers设置&quot; /&gt;&lt;figcaption&gt;Headers设置&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&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;Header&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;Content-Type&lt;/td&gt;&lt;td&gt;请求内容类型&lt;/td&gt;&lt;td&gt;application/json&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Authorization&lt;/td&gt;&lt;td&gt;认证信息&lt;/td&gt;&lt;td&gt;Bearer xxxxx&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Accept&lt;/td&gt;&lt;td&gt;期望的响应类型&lt;/td&gt;&lt;td&gt;application/json&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Token&lt;/td&gt;&lt;td&gt;自定义令牌&lt;/td&gt;&lt;td&gt;xxxxx&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;7、环境变量管理&lt;a href=&quot;#7环境变量管理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;环境变量可以让同一套请求在不同环境（开发、测试、生产）下快速切换。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;7.1 创建环境&lt;a href=&quot;#71-创建环境&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/5b653c61-bf07-4ec9-a647-cfcae574092b.png&quot; alt=&quot;创建环境&quot; /&gt;&lt;figcaption&gt;创建环境&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;7.2 使用环境变量&lt;a href=&quot;#72-使用环境变量&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在URL、Params、Headers中使用 &lt;code&gt;{{变量名}}&lt;/code&gt; 格式：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;{{baseUrl}}/api/user/list&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/442c1c47-a542-4db8-97da-fa601bb36b99.png&quot; alt=&quot;使用环境变量&quot; /&gt;&lt;figcaption&gt;使用环境变量&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;注意：创建完环境变量之后，一定要ctrl s保存一下。否则，可能在使用该环境变量的时候出现无法使用的情况！&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;8、导出、导入功能&lt;a href=&quot;#8导出导入功能&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;导出、导入功能。可以让你很方便的将别人新建好的接口请求，导入到你自己的postman里面。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;5.1 导出&lt;a href=&quot;#51-导出&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9f53eec8-55c2-4a68-b654-266cbcccb611.png&quot; alt=&quot;导出&quot; /&gt;&lt;figcaption&gt;导出&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;进入如下界面,点击 &lt;strong&gt;Export&lt;/strong&gt;,便可以导出一份json文件。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/78e3d035-02b4-4fdc-a684-9dee5dae4fb8.png&quot; alt=&quot;导出2&quot; /&gt;&lt;figcaption&gt;导出2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5.2 导入&lt;a href=&quot;#52-导入&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;拿到上一步导出的json文件，按照下图在对应工作区间导入即可！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/741f7f7c-1816-41bc-b131-1fe04e30d250.png&quot; alt=&quot;导入&quot; /&gt;&lt;figcaption&gt;导入&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;9、代码生成&lt;a href=&quot;#9代码生成&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Postman可以生成各种语言的调用代码，方便直接复制到项目中。&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;点击请求右侧的 &lt;strong&gt;&amp;lt;/&amp;gt;&lt;/strong&gt; 图标&lt;/li&gt;
&lt;li&gt;选择目标语言（如 Java - OkHttp）&lt;/li&gt;
&lt;li&gt;复制生成的代码&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/7b66457a-b7fb-4808-b104-e2ae9eee24df.png&quot; alt=&quot;代码生成&quot; /&gt;&lt;figcaption&gt;代码生成&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;10、复制key-vlaue参数&lt;a href=&quot;#10复制key-vlaue参数&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9c037a25-9311-4c91-9be6-acf14df94936.png&quot; alt=&quot;复制参数-1&quot; /&gt;&lt;figcaption&gt;复制参数-1&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;进入如下界面复制即可。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/de9e41dd-2daf-4e97-8c11-792b0b065805.png&quot; alt=&quot;复制参数-2&quot; /&gt;&lt;figcaption&gt;复制参数-2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;五、常见问题&lt;a href=&quot;#五常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1、CORS跨域问题&lt;a href=&quot;#1cors跨域问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Postman作为独立工具，&lt;strong&gt;不受浏览器同源策略限制&lt;/strong&gt;，不会出现CORS问题。这是Postman相比浏览器直接请求的优势。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2、SSL证书验证&lt;a href=&quot;#2ssl证书验证&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;如果接口使用自签名证书，可以设置中关闭SSL验证&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/48046a93-8b13-485f-95d5-173ff897ab6a.png&quot; alt=&quot;关闭ssl&quot; /&gt;&lt;figcaption&gt;关闭ssl&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3、请求超时&lt;a href=&quot;#3请求超时&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;默认超时时间为0（无限），可以在设置中修改：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Settings → Request timeout in ms&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4、中文乱码&lt;a href=&quot;#4中文乱码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;响应出现中文乱码时：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;检查响应Headers中的Content-Type&lt;/li&gt;
&lt;li&gt;确保包含 &lt;code&gt;charset=utf-8&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Swagger的使用</title><link>https://study-docs-158.pages.dev/posts/swagger%E7%9A%84%E4%BD%BF%E7%94%A8/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/swagger%E7%9A%84%E4%BD%BF%E7%94%A8/</guid><description>Swagger的使用</description><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h3&gt;一、Swagger是什么？为什么需要Swagger？&lt;a href=&quot;#一swagger是什么为什么需要swagger&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、Swagger是什么&lt;a href=&quot;#1swagger是什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Swagger是一款&lt;strong&gt;RESTful API文档自动生成和测试工具&lt;/strong&gt;，在Java后端开发中主要用于自动生成API接口文档，并提供在线测试接口的功能。&lt;/p&gt;&lt;p&gt;简单的说，Swagger就是&lt;strong&gt;帮你的接口自动生成文档的工具&lt;/strong&gt;。以前写接口需要手动写Word文档或者Excel表格来记录接口地址、参数、返回值等，现在只需要在代码上加几个注解，Swagger就能自动生成漂亮的网页版接口文档。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;官方网站&lt;/strong&gt;：&lt;a href=&quot;https://swagger.io/&quot; target=&quot;_blank&quot;&gt;https://swagger.io/&lt;/a&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、为什么需要Swagger&lt;a href=&quot;#2为什么需要swagger&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&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;：直接在浏览器中测试接口，不需要打开Postman等额外工具&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文档与代码同步&lt;/strong&gt;：代码变了，文档自动更新，不会出现文档过时的问题&lt;/li&gt;
&lt;/ul&gt;&lt;p&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;li&gt;&lt;strong&gt;便于接口交接&lt;/strong&gt;：新入职的同事可以通过Swagger文档快速了解项目接口&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;二、Swagger的基本使用&lt;a href=&quot;#二swagger的基本使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、Swagger版本区分（了解）&lt;a href=&quot;#1swagger版本区分了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;工作中常见的是以下几种情况：&lt;/p&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;版本&lt;/th&gt;&lt;th&gt;Swagger路径&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;Swagger 2&lt;/td&gt;&lt;td&gt;/swagger-ui.html&lt;/td&gt;&lt;td&gt;io.swagger.annotations&lt;/td&gt;&lt;td&gt;老版本&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Swagger 3&lt;/td&gt;&lt;td&gt;/swagger-ui/index.html&lt;/td&gt;&lt;td&gt;io.swagger.v3.oas.annotations&lt;/td&gt;&lt;td&gt;新版本，也叫 OpenAPI 3.0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Swagger 3（兼容模式）&lt;/td&gt;&lt;td&gt;/swagger-ui/index.html&lt;/td&gt;&lt;td&gt;io.swagger.annotations&lt;/td&gt;&lt;td&gt;使用Swagger 2注解，生成Swagger 3文档 ✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Knife4j（Swagger 2增强版）&lt;/td&gt;&lt;td&gt;/doc.html&lt;/td&gt;&lt;td&gt;io.swagger.annotations&lt;/td&gt;&lt;td&gt;中文增强版，界面美观，国内常用&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Knife4j（Swagger 3增强版）&lt;/td&gt;&lt;td&gt;/doc.html&lt;/td&gt;&lt;td&gt;io.swagger.v3.oas.annotations&lt;/td&gt;&lt;td&gt;基于Swagger 3的增强版&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;如何快速判断项目用的是Swagger 2还是Swagger 3？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;看访问地址：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/swagger-ui.html&lt;/code&gt; → &lt;strong&gt;Swagger 2&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/swagger-ui/index.html&lt;/code&gt; → &lt;strong&gt;Swagger 3&lt;/strong&gt; ✅&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/doc.html&lt;/code&gt; → &lt;strong&gt;Knife4j&lt;/strong&gt;（增强版）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;什么是Knife4j？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Knife4j 是 Swagger 的&lt;strong&gt;中文增强版&lt;/strong&gt;，主要特点：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;界面更美观&lt;/strong&gt;：全新的UI设计，比原生Swagger更好看&lt;/li&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;li&gt;&lt;strong&gt;国内流行&lt;/strong&gt;：在国内项目中使用非常广泛&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Knife4j 本质上是 Swagger 的皮肤增强，底层还是 Swagger，只是界面更好看。&lt;/p&gt;&lt;p&gt;本节以**Swagger 3（兼容模式）**为主进行讲解。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;什么是”兼容模式”？&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;使用 &lt;strong&gt;Swagger 2 的注解&lt;/strong&gt;（&lt;code&gt;@Api&lt;/code&gt;, &lt;code&gt;@ApiOperation&lt;/code&gt; 等）&lt;/li&gt;
&lt;li&gt;生成 &lt;strong&gt;Swagger 3 的文档&lt;/strong&gt;（OpenAPI 3.0 规范）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这样写的好处：可以继续用熟悉的 Swagger 2 注解，享受 Swagger 3 的新特性。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、引入Swagger依赖（了解）&lt;a href=&quot;#2引入swagger依赖了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;使用Swagger 3（兼容模式，推荐用于Spring Boot 2.x）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在&lt;code&gt;pom.xml&lt;/code&gt;中添加依赖：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- Springfox Swagger 3.0 --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;io.springfox&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;springfox-boot-starter&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;3.0.0&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;其他版本参考：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Swagger 2（老版本）：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;io.springfox&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;springfox-swagger2&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;2.9.2&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;io.springfox&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;springfox-swagger-ui&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;2.9.2&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Knife4j（Swagger增强版，推荐）：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- Knife4j 3.x（基于Swagger 2，适用于Spring Boot 2.x）--&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;com.github.xiaoymin&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;knife4j-spring-boot-starter&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;3.0.3&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;!-- Knife4j 4.x（基于Swagger 3，适用于Spring Boot 2.x/3.x）--&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;com.github.xiaoymin&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;knife4j-openapi3-jakarta-spring-boot-starter&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;4.1.0&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Springdoc OpenAPI（用于Spring Boot 3.x）：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;org.springdoc&amp;lt;/&lt;/span&gt;&lt;span&gt;groupId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;springdoc-openapi-starter-webmvc-ui&amp;lt;/&lt;/span&gt;&lt;span&gt;artifactId&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;2.8.14&amp;lt;/&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;dependency&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、配置Swagger(了解)&lt;a href=&quot;#3配置swagger了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;创建配置类，配置Swagger的基本信息。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;RuoYi-Vue项目中的SwaggerConfig配置（实际使用）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;package&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;com.zcloud.web.core.config&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;java.util.ArrayList&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;java.util.List&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;org.springframework.beans.factory.annotation.Value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;io.swagger.annotations.ApiOperation&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;io.swagger.models.auth.In&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.builders.ApiInfoBuilder&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.builders.PathSelectors&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.builders.RequestHandlerSelectors&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.service.ApiInfo&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.service.ApiKey&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.service.AuthorizationScope&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.service.Contact&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.service.SecurityReference&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.spi.DocumentationType&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.spi.service.contexts.SecurityContext&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;springfox.documentation.spring.web.plugins.Docket&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* Swagger3的接口配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 虽然使用Swagger 2的注解（@ApiOperation等），但生成的是Swagger 3（OpenAPI 3.0）文档&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SwaggerConfig&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/** 是否开启swagger */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;${swagger.enabled}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;boolean&lt;/span&gt;&lt;span&gt; enabled&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/** 设置请求的统一前缀 */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;${swagger.pathMapping}&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; pathMapping&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 创建API&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;Bean&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Docket&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createRestApi&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Docket&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;DocumentationType&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;OAS_30&lt;/span&gt;&lt;span&gt;)  &lt;/span&gt;&lt;span&gt;// ← OAS_30表示Swagger 3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;enable&lt;/span&gt;&lt;span&gt;(enabled)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;apiInfo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;apiInfo&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;select&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;// 扫描所有有@ApiOperation注解的方法（Swagger 2注解风格）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;apis&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;RequestHandlerSelectors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;withMethodAnnotation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ApiOperation&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;paths&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;PathSelectors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;any&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;49&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;50&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;/* 设置安全模式，支持token认证 */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;51&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;securitySchemes&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;securitySchemes&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;52&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;securityContexts&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;securityContexts&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;53&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;pathMapping&lt;/span&gt;&lt;span&gt;(pathMapping);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;54&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;55&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;56&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;57&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 安全模式，token通过Authorization请求头传递&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;58&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;59&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;SecurityScheme&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;securitySchemes&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;60&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;SecurityScheme&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;apiKeyList&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ArrayList&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;61&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;apiKeyList&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ApiKey&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;In&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;HEADER&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toValue&lt;/span&gt;&lt;span&gt;()));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;62&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; apiKeyList;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;63&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;64&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;65&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;66&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 安全上下文&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;67&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;68&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;SecurityContext&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;securityContexts&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;69&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;SecurityContext&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;securityContexts&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ArrayList&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;70&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;securityContexts&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;71&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;SecurityContext&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;builder&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;72&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;securityReferences&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;defaultAuth&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;73&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;operationSelector&lt;/span&gt;&lt;span&gt;(o &lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;requestMappingPattern&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;matches&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/.*&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;74&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;75&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; securityContexts;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;76&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;77&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;78&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;79&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 默认的安全上引用&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;80&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;81&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;SecurityReference&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;defaultAuth&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;82&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;AuthorizationScope&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;authorizationScope&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AuthorizationScope&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;global&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;accessEverything&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;83&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;AuthorizationScope&lt;/span&gt;&lt;span&gt;&lt;span&gt;[] &lt;/span&gt;&lt;span&gt;authorizationScopes&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AuthorizationScope&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;84&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;authorizationScopes[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; authorizationScope;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;85&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;SecurityReference&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;span&gt;securityReferences&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ArrayList&lt;/span&gt;&lt;span&gt;&amp;lt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;86&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;securityReferences&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SecurityReference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span&gt;, authorizationScopes));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;87&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; securityReferences;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;88&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;89&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;90&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;91&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 添加摘要信息&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;92&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;93&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ApiInfo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apiInfo&lt;/span&gt;&lt;span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;94&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ApiInfoBuilder&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;95&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;若依管理系统_接口文档&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;96&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;用于管理集团旗下公司的人员信息&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;97&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;contact&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Contact&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;若依&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;98&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;版本号:3.9.1&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;99&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;100&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;101&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;配置说明：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;DocumentationType.OAS_30&lt;/code&gt;：&lt;strong&gt;这是Swagger 3&lt;/strong&gt;（OpenAPI 3.0规范）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)&lt;/code&gt;：扫描&lt;code&gt;@ApiOperation&lt;/code&gt;注解（Swagger 2注解风格）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;securitySchemes()&lt;/code&gt;：配置Token认证&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;配置文件（application.yml）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# Swagger配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;swagger&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 是否开启swagger&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;enabled&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 请求前缀&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;pathMapping&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;/dev-api&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;4、访问Swagger UI&lt;a href=&quot;#4访问swagger-ui&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;只需要启动后端项目，无需启动前端项目，就可以在浏览器中访问Swagger UI界面。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/a6e82f0c-d8ea-4742-989d-f9f168ff5c5d.png&quot; alt=&quot;swagger界面&quot; /&gt;&lt;figcaption&gt;swagger界面&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&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;/th&gt;&lt;th&gt;Swagger路径&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;Swagger 2&lt;/td&gt;&lt;td&gt;/swagger-ui.html&lt;/td&gt;&lt;td&gt;地址中没有 index.html&lt;/td&gt;&lt;td&gt;老版本，界面较简陋&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Swagger 3&lt;/td&gt;&lt;td&gt;/swagger-ui/index.html&lt;/td&gt;&lt;td&gt;地址中有 index.html&lt;/td&gt;&lt;td&gt;新版本，功能更强&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Knife4j&lt;/td&gt;&lt;td&gt;/doc.html&lt;/td&gt;&lt;td&gt;地址是 doc.html&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;/p&gt;&lt;ul&gt;
&lt;li&gt;看到 &lt;code&gt;swagger-ui/index.html&lt;/code&gt; → &lt;strong&gt;Swagger 3&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;看到 &lt;code&gt;swagger-ui.html&lt;/code&gt; → &lt;strong&gt;Swagger 2&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;看到 &lt;code&gt;doc.html&lt;/code&gt; → &lt;strong&gt;Knife4j&lt;/strong&gt;（增强版）✅&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;访问地址的构成说明（重点）：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;实际工作中，访问地址需要根据项目配置来拼接：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;http://[域名或IP]:[端口][项目前缀][Swagger路径]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;如何找到正确的访问地址：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;确认项目端口：查看&lt;code&gt;application.yml&lt;/code&gt;中的&lt;code&gt;server.port&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;确认项目前缀：查看&lt;code&gt;application.yml&lt;/code&gt;中的&lt;code&gt;server.servlet.context-path&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在地址后加上 &lt;code&gt;/swagger-ui/index.html&lt;/code&gt;（Swagger 3）&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;当然，有时候，Swagger路径也可以改的！正常情况，如果更改的话就是在项目配置文件里面去配置这个路径！如果默认路径都无法访问的话，就去配置文件里面去看，有没有自定义swagger路径。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;5、常用注解（了解）&lt;a href=&quot;#5常用注解了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Swagger 3（兼容模式）使用 Swagger 2 的注解风格。了解就行，不同版本注解可能有差异，需要使用的时候对应看别人代码用的什么注解就行！&lt;/p&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;/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;@Api&lt;/td&gt;&lt;td&gt;Controller类&lt;/td&gt;&lt;td&gt;标识接口分组，描述模块功能&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;@ApiOperation&lt;/td&gt;&lt;td&gt;方法&lt;/td&gt;&lt;td&gt;描述接口的具体功能&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;@ApiModel&lt;/td&gt;&lt;td&gt;实体类&lt;/td&gt;&lt;td&gt;描述实体类的信息&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;@ApiModelProperty&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;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;三、Swagger的高级配置（了解）&lt;a href=&quot;#三swagger的高级配置了解&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、环境控制&lt;a href=&quot;#1环境控制&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;通常只在开发环境和测试环境启用Swagger，生产环境需要禁用。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;项目中的配置：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;application.yml&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;swagger&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 是否开启swagger&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;enabled&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;通过配置文件控制（推荐）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# application-dev.yml（开发环境）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;swagger&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;enabled&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# application-prod.yml（生产环境）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;swagger&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;enabled&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、Token认证配置&lt;a href=&quot;#2token认证配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;通过Authorization请求头传递token。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;配置方式（已在SwaggerConfig中配置）：&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/**&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;* 安全模式，token通过Authorization头请求头传递&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;private&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;SecurityScheme&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;securitySchemes&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;SecurityScheme&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; apiKeyList &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ArrayList&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;apiKeyList&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ApiKey&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;In&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;HEADER&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toValue&lt;/span&gt;&lt;span&gt;()));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; apiKeyList&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;使用方式：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;登录后获取token&lt;/li&gt;
&lt;li&gt;在Swagger UI界面点击右上角的 &lt;strong&gt;Authorize&lt;/strong&gt; 按钮&lt;/li&gt;
&lt;li&gt;输入：&lt;code&gt;Bearer {token}&lt;/code&gt; 或直接输入 &lt;code&gt;{token}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;之后所有接口请求都会自动带上这个请求头&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h3&gt;四、在Swagger中测试接口&lt;a href=&quot;#四在swagger中测试接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;1、测试GET请求&lt;a href=&quot;#1测试get请求&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;点击接口名称，展开接口详情&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;Try it out&lt;/strong&gt; 按钮&lt;/li&gt;
&lt;li&gt;填写请求参数（如果有）&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;Execute&lt;/strong&gt; 执行请求&lt;/li&gt;
&lt;li&gt;查看响应结果&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/42442029-f034-449a-9001-95203e956a43.png&quot; alt=&quot;get请求&quot; /&gt;&lt;figcaption&gt;get请求&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;2、测试POST请求&lt;a href=&quot;#2测试post请求&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;点击接口名称，展开接口详情&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;Try it out&lt;/strong&gt; 按钮&lt;/li&gt;
&lt;li&gt;在Request body中填写JSON格式的请求数据&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;Execute&lt;/strong&gt; 执行请求&lt;/li&gt;
&lt;li&gt;查看响应结果&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/6c795821-4f0d-4f3e-b601-e50779333c47.png&quot; alt=&quot;post请求&quot; /&gt;&lt;figcaption&gt;post请求&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;3、设置Token认证&lt;a href=&quot;#3设置token认证&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;使用登录接口或者token或者登录对应前端平台F12获取别的接口传的Token&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击页面右上角的 &lt;strong&gt;Authorize&lt;/strong&gt; 按钮&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/4bd8a600-ff20-4605-97cb-46681d436231.png&quot; alt=&quot;获取token&quot; /&gt;&lt;figcaption&gt;获取token&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;输入token，点击 &lt;strong&gt;Authorize&lt;/strong&gt; 确认&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/uploads/images/2026-03-26/9fe3688d-83a9-49cd-ba25-96a87f2752d6.png&quot; alt=&quot;获取token2&quot; /&gt;&lt;figcaption&gt;获取token2&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>MDX 格式文章示例</title><link>https://study-docs-158.pages.dev/posts/mdx-example/</link><guid isPermaLink="true">https://study-docs-158.pages.dev/posts/mdx-example/</guid><description>这是一个 MDX 格式的示例文章，展示了如何在 Markdown 中使用 JSX。</description><pubDate>Fri, 02 Jan 1970 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Tip&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/CuteLeaf/Firefly&quot; target=&quot;_blank&quot;&gt;Firefly&lt;/a&gt; 支持 &lt;code&gt;MDX&lt;/code&gt; 和 &lt;code&gt;Markdown&lt;/code&gt; 两种类型的文章，你可以在文章中混合使用两种格式，如果没有特别复杂内容和需求，推荐使用 Markdown 格式就够了。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;section&gt;&lt;h2&gt;Markdown 和 MDX 的区别&lt;a href=&quot;#markdown-和-mdx-的区别&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Markdown (MD) 是一种轻量级标记语言，允许用户使用纯文本格式编写文档，然后将其转换为格式化的HTML。它因其简洁易用的语法而广受欢迎，特别适合编写文档和博客文章。&lt;/li&gt;
&lt;li&gt;MDX 是一种扩展了 Markdown 语法的格式，允许在 Markdown 文档中无缝地插入 JSX 代码。通过 MDX，用户可以在文档中嵌入 React 组件，从而实现更丰富的交互性和动态性。&lt;/li&gt;
&lt;/ul&gt;


































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;特性&lt;/th&gt;&lt;th&gt;Markdown&lt;/th&gt;&lt;th&gt;MDX&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;基础语法&lt;/td&gt;&lt;td&gt;支持 (CommonMark)&lt;/td&gt;&lt;td&gt;支持 (CommonMark)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HTML 标签&lt;/td&gt;&lt;td&gt;支持&lt;/td&gt;&lt;td&gt;支持 (作为 JSX)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;组件导入&lt;/td&gt;&lt;td&gt;不支持&lt;/td&gt;&lt;td&gt;支持 (import)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;动态数据&lt;/td&gt;&lt;td&gt;不支持&lt;/td&gt;&lt;td&gt;支持 (JS 表达式)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;样式定制&lt;/td&gt;&lt;td&gt;有限 (class/style)&lt;/td&gt;&lt;td&gt;灵活 (className/CSS-in-JS)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;使用组件&lt;a href=&quot;#使用组件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;这是一个图标组件：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import { Icon } from &apos;astro-icon/components&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;div class=&quot;flex items-center gap-2 my-4&quot;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;Icon name=&quot;fa7-solid:rocket&quot; class=&quot;text-4xl text-red-500&quot; /&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;span&amp;gt;火箭发射！&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;火箭发射！&lt;/span&gt;&lt;/div&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;使用 JSX&lt;a href=&quot;#使用-jsx&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;你也可以直接写 HTML/JSX：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;div className=&quot;p-4 bg-blue-100 dark:bg-blue-900 rounded-lg my-4&quot;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;这是一个自定义样式的 div 块，使用了 Tailwind CSS 类。&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;这是一个自定义样式的 div 块，使用了 Tailwind CSS 类。&lt;/p&gt;&lt;/div&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;简单的变量导出&lt;a href=&quot;#简单的变量导出&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;export const year = new Date().getFullYear()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;今年是 {year} 年。&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;今年是 2026 年。&lt;/p&gt;&lt;p&gt;更多信息，请查看 &lt;a href=&quot;https://mdxjs.com/&quot; target=&quot;_blank&quot;&gt;MDX 文档&lt;/a&gt;&lt;/p&gt;&lt;/section&gt;</content:encoded></item></channel></rss>