<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>学习记录每一步</title>
  
  
  <link href="https://www.yxliu.cc/atom.xml" rel="self"/>
  
  <link href="https://www.yxliu.cc/"/>
  <updated>2026-02-04T06:42:44.030Z</updated>
  <id>https://www.yxliu.cc/</id>
  
  <author>
    <name>yxliu</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Windos使用FNM管理器</title>
    <link href="https://www.yxliu.cc/2026/02/04/84ec4f.html"/>
    <id>https://www.yxliu.cc/2026/02/04/84ec4f.html</id>
    <published>2026-02-04T06:42:44.030Z</published>
    <updated>2026-02-04T06:42:44.030Z</updated>
    
    <content type="html"><![CDATA[<h2 id=""><a href="#" class="headerlink" title=""></a></h2><h4 id="Using-Winget-Windows"><a href="#Using-Winget-Windows" class="headerlink" title="Using Winget (Windows)"></a>Using Winget (Windows)</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">winget install Schniz.fnm</span><br></pre></td></tr></table></figure><h4 id="PowerShell"><a href="#PowerShell" class="headerlink" title="PowerShell"></a>PowerShell</h4><p> 将以下命令添加至配置文件末尾。</p><ul><li>For Windows location is either:<ul><li><code>%userprofile%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1</code> Powershell 5</li><li><code>%userprofile%\Documents\PowerShell\Microsoft.PowerShell_profile.ps1</code> Powershell 6+</li></ul></li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fnm <span class="built_in">env</span> --use-on-cd --shell powershell | Out-String | Invoke-Expression</span><br></pre></td></tr></table></figure><blockquote><p>在 Windows 中，也可以运行<code>notepad $profile</code>命令打开 PowerShell 配置文件，如果提示找不到文件路径，就在新建文件夹中添加上述命令，然后保存文件并命名为<code>Microsoft.PowerShell_profile.ps1</code>即可，注意需要保证父级文件夹名称为<code>WindowsPowerShell</code>。</p></blockquote><h4 id="Bash"><a href="#Bash" class="headerlink" title="Bash"></a>Bash</h4><p>Add the following to your <code>.bashrc</code> profile:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">eval &quot;$(fnm env --use-on-cd --shell bash)&quot;</span><br></pre></td></tr></table></figure><hr><p>执行后 重新打开powershell出现 <strong>无法加载文件 C:\Users\amarlyx\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1，因为在此系统上禁止运行脚本</strong>异常时</p><p>Windows PowerShell 的执行策略限制了脚本的运行。您可以通过以下步骤来解决此问题：</p><h3 id="步骤-1-以管理员身份打开-PowerShell"><a href="#步骤-1-以管理员身份打开-PowerShell" class="headerlink" title="步骤 1: 以管理员身份打开 PowerShell"></a>步骤 1: 以管理员身份打开 PowerShell</h3><ol><li>在开始菜单中搜索“PowerShell”。</li><li>右键单击 <strong>Windows PowerShell</strong>，然后选择 <strong>以管理员身份运行</strong>。</li></ol><h3 id="步骤-2-修改执行策略"><a href="#步骤-2-修改执行策略" class="headerlink" title="步骤 2: 修改执行策略"></a>步骤 2: 修改执行策略</h3><ol><li><p>在 PowerShell 中输入以下命令，允许脚本的执行：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Set-ExecutionPolicy RemoteSigned</span><br></pre></td></tr></table></figure><p>这将允许本地脚本执行，但需要远程脚本具有有效的签名。</p></li><li><p>如果您希望允许任何脚本执行（包括没有签名的远程脚本），您可以使用：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Set-ExecutionPolicy Unrestricted</span><br></pre></td></tr></table></figure></li></ol><h3 id="步骤-3-确认执行策略"><a href="#步骤-3-确认执行策略" class="headerlink" title="步骤 3: 确认执行策略"></a>步骤 3: 确认执行策略</h3><p>执行策略修改后，PowerShell 会要求您确认操作。输入 <code>Y</code> 然后按 Enter 键。</p><h3 id="步骤-4-重新启动-PowerShell"><a href="#步骤-4-重新启动-PowerShell" class="headerlink" title="步骤 4: 重新启动 PowerShell"></a>步骤 4: 重新启动 PowerShell</h3><p>修改完成后，关闭 PowerShell 并重新启动它。</p>]]></content>
    
    
    <summary type="html">Windos配置FNM管理器</summary>
    
    
    
    <category term="nodejs" scheme="https://www.yxliu.cc/categories/nodejs/"/>
    
    
    <category term="FNM" scheme="https://www.yxliu.cc/tags/FNM/"/>
    
    <category term="nodejs" scheme="https://www.yxliu.cc/tags/nodejs/"/>
    
  </entry>
  
  <entry>
    <title>Docker给容器添加代理</title>
    <link href="https://www.yxliu.cc/2025/11/05/ed8d5d66.html"/>
    <id>https://www.yxliu.cc/2025/11/05/ed8d5d66.html</id>
    <published>2025-11-05T09:26:47.000Z</published>
    <updated>2026-02-04T06:42:44.027Z</updated>
    
    <content type="html"><![CDATA[<h4 id="通过-docker-config-json-全局配置（推荐）"><a href="#通过-docker-config-json-全局配置（推荐）" class="headerlink" title="通过 ~/.docker/config.json 全局配置（推荐）"></a>通过 <code>~/.docker/config.json</code> 全局配置（推荐）</h4><ol><li><p>编辑用户目录下的 Docker 配置文件：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vi ~/.docker/config.json</span><br></pre></td></tr></table></figure></li><li><p>添加代理配置：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;proxies&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;default&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;httpProxy&quot;</span><span class="punctuation">:</span> <span class="string">&quot;http://代理IP:端口&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;httpsProxy&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://代理IP:端口&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;noProxy&quot;</span><span class="punctuation">:</span> <span class="string">&quot;localhost,127.0.0.1&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>该配置会对所有新启动的容器生效（无需重启 Docker）。</p></li></ol><h3 id="3-为-Docker-Compose-设置代理"><a href="#3-为-Docker-Compose-设置代理" class="headerlink" title="3. 为 Docker Compose 设置代理"></a><strong>3. 为 Docker Compose 设置代理</strong></h3><p>在 <code>docker-compose.yml</code> 中通过 <code>environment</code> 字段指定代理：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">version:</span> <span class="string">&#x27;3&#x27;</span></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">app:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">镜像名</span></span><br><span class="line">    <span class="attr">environment:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">http_proxy=http://代理IP:端口</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">https_proxy=https://代理IP:端口</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">no_proxy=localhost,127.0.0.1</span></span><br></pre></td></tr></table></figure><h3 id="注意事项："><a href="#注意事项：" class="headerlink" title="注意事项："></a>注意事项：</h3><ul><li>代理地址格式：若代理需要认证，格式为 <code>http://用户名:密码@代理IP:端口</code>。</li><li>本地代理：若代理运行在宿主机，Linux 下可用 <code>host.docker.internal</code> 访问宿主机 IP（Docker 18.03+ 支持）。</li><li>验证配置：通过 <code>docker info</code> 查看守护进程代理是否生效，或在容器内执行 <code>echo $http_proxy</code> 检查容器代理。</li></ul>]]></content>
    
    
    <summary type="html">Docker</summary>
    
    
    
    <category term="Docker" scheme="https://www.yxliu.cc/categories/Docker/"/>
    
    
    <category term="Docker" scheme="https://www.yxliu.cc/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>Git 配置多用户克隆项目指南</title>
    <link href="https://www.yxliu.cc/2025/07/15/b2cf95a7.html"/>
    <id>https://www.yxliu.cc/2025/07/15/b2cf95a7.html</id>
    <published>2025-07-15T08:29:59.000Z</published>
    <updated>2026-02-04T06:42:44.027Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Git-配置多用户克隆项目指南"><a href="#Git-配置多用户克隆项目指南" class="headerlink" title="Git 配置多用户克隆项目指南"></a>Git 配置多用户克隆项目指南</h1><p>在 Git 中，可通过多种方式配置不同用户身份来克隆和管理项目，以下是几种常见解决方案：</p><h2 id="方案-1：全局配置与局部配置"><a href="#方案-1：全局配置与局部配置" class="headerlink" title="方案 1：全局配置与局部配置"></a>方案 1：全局配置与局部配置</h2><p>Git 允许同时存在<strong>全局配置</strong>和<strong>仓库级配置</strong>。全局配置适用于所有仓库，而仓库级配置仅针对当前仓库生效。</p><h3 id="1、设置全局用户（可选）："><a href="#1、设置全局用户（可选）：" class="headerlink" title="1、设置全局用户（可选）："></a><strong>1、设置全局用户</strong>（可选）：</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">git config --global user.name <span class="string">&quot;Your Global Name&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">git config --global user.email <span class="string">&quot;your.global.email@example.com&quot;</span></span><br></pre></td></tr></table></figure><h3 id="2、为特定仓库覆盖配置："><a href="#2、为特定仓库覆盖配置：" class="headerlink" title="2、为特定仓库覆盖配置："></a><strong>2、为特定仓库覆盖配置</strong>：</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 进入项目目录</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">cd</span> /path/to/your/project</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置仓库级用户（覆盖全局配置）</span></span><br><span class="line">git config user.name <span class="string">&quot;Your Local Name&quot;</span></span><br><span class="line"></span><br><span class="line">git config user.email <span class="string">&quot;your.local.email@example.com&quot;</span></span><br></pre></td></tr></table></figure><h3 id="3、验证配置："><a href="#3、验证配置：" class="headerlink" title="3、验证配置："></a><strong>3、验证配置</strong>：</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看仓库级配置（仅当前仓库）</span></span><br><span class="line">git config user.name</span><br><span class="line">git config user.email</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看全局配置</span></span><br><span class="line">git config --global user.name</span><br><span class="line">git config --global user.email</span><br></pre></td></tr></table></figure><h2 id="方案-2：通过-URL-别名区分用户"><a href="#方案-2：通过-URL-别名区分用户" class="headerlink" title="方案 2：通过 URL 别名区分用户"></a>方案 2：通过 URL 别名区分用户</h2><p>若需使用不同用户身份访问同一域名下的不同仓库（例如 GitHub），可通过修改 Git URL 的用户名部分实现。</p><h3 id="1、添加-SSH-密钥到不同账号："><a href="#1、添加-SSH-密钥到不同账号：" class="headerlink" title="1、添加 SSH 密钥到不同账号："></a><strong>1、添加 SSH 密钥到不同账号</strong>：</h3><ul><li><p>生成不同的 SSH 密钥（例如 <code>id_rsa_work</code> 和 <code>id_rsa_personal</code>）。</p></li><li><p>将每个密钥添加到对应的 GitHub&#x2F;GitLab 账号。</p></li></ul><h3 id="2、配置-SSH-别名："><a href="#2、配置-SSH-别名：" class="headerlink" title="2、配置 SSH 别名："></a><strong>2、配置 SSH 别名</strong>：</h3><p>编辑 <code>~/.ssh/config</code> 文件，添加以下内容：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 工作账号</span></span><br><span class="line">Host github.com-work</span><br><span class="line"> HostName github.com</span><br><span class="line"> User git</span><br><span class="line"> IdentityFile \~/.ssh/id\_rsa\_work</span><br><span class="line"></span><br><span class="line"><span class="comment"># 个人账号</span></span><br><span class="line">Host github.com-personal</span><br><span class="line"> HostName github.com</span><br><span class="line"> User git</span><br><span class="line"> IdentityFile \~/.ssh/id\_rsa\_personal</span><br></pre></td></tr></table></figure><h3 id="3、使用别名克隆项目："><a href="#3、使用别名克隆项目：" class="headerlink" title="3、使用别名克隆项目："></a><strong>3、使用别名克隆项目</strong>：</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 使用工作账号克隆</span></span><br><span class="line">git <span class="built_in">clone</span> git@github.com-work:your-work-account/repo.git</span><br><span class="line"><span class="comment"># 使用个人账号克隆</span></span><br><span class="line">git <span class="built_in">clone</span> git@github.com-personal:your-personal-account/repo.git</span><br></pre></td></tr></table></figure><h2 id="方案-3：为不同目录设置不同配置"><a href="#方案-3：为不同目录设置不同配置" class="headerlink" title="方案 3：为不同目录设置不同配置"></a>方案 3：为不同目录设置不同配置</h2><p>若希望根据项目路径自动应用不同配置，可使用 Git 的 <code>includeIf</code> 功能。</p><h3 id="1、创建配置文件："><a href="#1、创建配置文件：" class="headerlink" title="1、创建配置文件："></a><strong>1、创建配置文件</strong>：</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 创建工作项目配置</span></span><br><span class="line"><span class="built_in">echo</span> -e <span class="string">&quot;\[user]\n  name = Work User\n  email = work@example.com&quot;</span> &gt; \~/.gitconfig-work</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建个人项目配置</span></span><br><span class="line"><span class="built_in">echo</span> -e <span class="string">&quot;\[user]\n  name = Personal User\n  email = personal@example.com&quot;</span> &gt; \~/.gitconfig-personal</span><br></pre></td></tr></table></figure><h3 id="2、修改全局配置："><a href="#2、修改全局配置：" class="headerlink" title="2、修改全局配置："></a><strong>2、修改全局配置</strong>：</h3><p>在 <code>~/.gitconfig</code> 中添加：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[includeIf <span class="string">&quot;gitdir:\~/work/&quot;</span>]</span><br><span class="line"> path = \~/.gitconfig-work</span><br><span class="line">[includeIf <span class="string">&quot;gitdir:\~/personal/&quot;</span>]</span><br><span class="line"> path = \~/.gitconfig-personal</span><br></pre></td></tr></table></figure><h3 id="3、按目录结构克隆项目："><a href="#3、按目录结构克隆项目：" class="headerlink" title="3、按目录结构克隆项目："></a><strong>3、按目录结构克隆项目</strong>：</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 工作项目</span></span><br><span class="line"><span class="built_in">mkdir</span> -p \~/work/</span><br><span class="line"><span class="built_in">cd</span> \~/work/</span><br><span class="line">git <span class="built_in">clone</span> git@github.com:your-work-account/repo.git</span><br><span class="line"><span class="comment"># 个人项目</span></span><br><span class="line"><span class="built_in">mkdir</span> -p \~/personal/</span><br><span class="line"><span class="built_in">cd</span> \~/personal/</span><br><span class="line">git <span class="built_in">clone</span> git@github.com:your-personal-account/repo.git</span><br></pre></td></tr></table></figure><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><table><thead><tr><th>方案&#xA;</th><th>适用场景&#xA;</th></tr></thead><tbody><tr><td>方案 1&#xA;</td><td>需要在不同仓库手动切换用户&#xA;</td></tr><tr><td>方案 2&#xA;</td><td>使用 SSH 密钥认证，需通过别名区分不同身份&#xA;</td></tr><tr><td>方案 3&#xA;</td><td>根据项目路径自动应用配置&#xA;</td></tr></tbody></table><p>可根据实际需求选择合适的方法。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Git-配置多用户克隆项目指南&quot;&gt;&lt;a href=&quot;#Git-配置多用户克隆项目指南&quot; class=&quot;headerlink&quot; title=&quot;Git 配置多用户克隆项目指南&quot;&gt;&lt;/a&gt;Git 配置多用户克隆项目指南&lt;/h1&gt;&lt;p&gt;在 Git 中，可通过多种方式配置不</summary>
      
    
    
    
    
    <category term="git" scheme="https://www.yxliu.cc/tags/git/"/>
    
  </entry>
  
  <entry>
    <title>论UFI003 WIFI棒子刷Debian的踩坑教程</title>
    <link href="https://www.yxliu.cc/2025/06/11/2d0a07f5.html"/>
    <id>https://www.yxliu.cc/2025/06/11/2d0a07f5.html</id>
    <published>2025-06-11T02:37:21.000Z</published>
    <updated>2026-02-04T06:42:44.031Z</updated>
    
    <content type="html"><![CDATA[<h2 id="1、UFI003-WIFI棒子刷Debian-青龙的踩坑教程"><a href="#1、UFI003-WIFI棒子刷Debian-青龙的踩坑教程" class="headerlink" title="1、UFI003 WIFI棒子刷Debian 青龙的踩坑教程"></a>1、UFI003 WIFI棒子刷Debian 青龙的踩坑教程</h2><h3 id="安装debian之前"><a href="#安装debian之前" class="headerlink" title="安装debian之前"></a>安装debian之前</h3><p>刷机:根据随身wifi型号选择  本人型号为UFI003</p><p>买个最便宜的随身WiFi   闲鱼4g25包邮 估计被跑PCDN的给搞涨价了<br>WiFi网络环境、Windows电脑</p><h4 id="环境准备："><a href="#环境准备：" class="headerlink" title="环境准备："></a>环境准备：</h4><ol><li>环境软件准备</li><li>9008驱动</li><li>Qualcomm+Premium+Tool+V2.4</li><li>MIKO(系统备份还原工具)</li><li>adb</li><li>Debian系统镜像</li></ol><p><strong>[刷机工具包][<a href="https://www.123684.com/s/ot2VVv-XIl3A?%E6%8F%90%E5%8F%96%E7%A0%81:MAbi%5D">https://www.123684.com/s/ot2VVv-XIl3A?提取码:MAbi]</a></strong> </p><p>[刷机镜像][<a href="https://www.123684.com/s/ot2VVv-2Il3A?%E6%8F%90%E5%8F%96%E7%A0%81:3mpH%5D">https://www.123684.com/s/ot2VVv-2Il3A?提取码:3mpH]</a></p><p>文本参考有:</p><p>1  <a href="https://blog.csdn.net/qq_36724501/article/details/127716153">随身WIFI刷真Linux(Debian)系统搭配拓展坞做超低功耗服务器_随身wifi刷debian_一大颗萝卜的博客-CSDN博客<img src="https://i-blog.csdnimg.cn/blog_migrate/cea7f95729ad651ebb3629e5c3c5c7c1.png" alt="img"><a href="https://blog.csdn.net/qq_36724501/article/details/127716153">https://blog.csdn.net/qq_36724501/article/details/127716153</a></a></p><p>2 <a href="https://blog.csdn.net/2301_76795286/article/details/129489528">随身WiFi410的板子刷Debian安装青龙面板+狗东脚本最详细教程_debian面板_你干嘛-哎哟的博客-CSDN博客<img src="https://i-blog.csdnimg.cn/blog_migrate/cea7f95729ad651ebb3629e5c3c5c7c1.png" alt="img"><a href="https://blog.csdn.net/2301_76795286/article/details/129489528">https://blog.csdn.net/2301_76795286/article/details/129489528</a></a></p><p>3 [随身wifi 高通410 4g安装debian 2023.8.10][<a href="https://blog.csdn.net/2301_76795286/article/details/129489528]">https://blog.csdn.net/2301_76795286/article/details/129489528]</a></p><p><strong>具体的刷机流程参考</strong>  <em>[<strong>随身wifi 高通410 4g安装debian 2023.8.10</strong>][<a href="https://blog.csdn.net/2301_76795286/article/details/129489528]">https://blog.csdn.net/2301_76795286/article/details/129489528]</a></em></p><h3 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h3><p>1 刷完docker 后发现 启动青龙报错</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Error response from daemon: failed to set up container networking: failed to create endpoint qinglong on network bridge: Unable to enable DIRECT ACCESS FILTERING - DROP rule:  (iptables failed: iptables --wait -t raw -A PREROUTING -d 172.18.0.2 ! -i docker0 -j DROP: iptables v1.8.7 (legacy): can&#x27;t initialize iptables table `raw&#x27;: Table does not exist (do you need to insmod?)</span><br><span class="line">Perhaps iptables or your kernel needs to be upgraded.</span><br><span class="line"> (exit status 3))</span><br><span class="line">Error: failed to start containers: qinglong</span><br></pre></td></tr></table></figure><p><strong>方案1</strong></p><p>修改  <code>/etc/docker/daemon.json</code> 设置docker 默认网络模式为 bridge 并关闭iptables</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;registry-mirrors&quot;: [&quot;https://docker.1ms.run&quot;],</span><br><span class="line">  &quot;exec-opts&quot;: [&quot;native.cgroupdriver=systemd&quot;],</span><br><span class="line">  &quot;iptables&quot;: false,</span><br><span class="line">  &quot;bridge&quot;: &quot;docker0&quot;,</span><br><span class="line">  &quot;ip-forward&quot;: true,</span><br><span class="line">  &quot;ip-masq&quot;: true</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>2 ：设置完后发现 青龙容器可以启动但是无法联网 </p><p>防火请将 docker0 放行 并保存规则</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">允许 docker0 接口转发流量</span></span><br><span class="line">iptables -A FORWARD -i docker0 -j ACCEPT</span><br><span class="line">iptables -A FORWARD -o docker0 -j ACCEPT</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">启用 IP 伪装（NAT）</span></span><br><span class="line">iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE</span><br><span class="line">netfilter-persistent save</span><br></pre></td></tr></table></figure><p>问题解决</p><p><strong>方案2 ：使用 host 网络模式（绕过 Docker 网桥）</strong></p><p>让容器使用主机网络（牺牲网络隔离性）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">docker run -d \</span><br><span class="line">  --name=qinglong \</span><br><span class="line">  --network=host \  <span class="comment"># 使用主机网络，跳过 Docker 网桥的 RAW 表规则</span></span><br><span class="line">  --restart=always \</span><br><span class="line">  -v /etc/qinglong:/etc/qinglong \</span><br><span class="line">  -v /var/log/qinglong:/var/log/qinglong \</span><br><span class="line">  whyour/qinglong:latest</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;1、UFI003-WIFI棒子刷Debian-青龙的踩坑教程&quot;&gt;&lt;a href=&quot;#1、UFI003-WIFI棒子刷Debian-青龙的踩坑教程&quot; class=&quot;headerlink&quot; title=&quot;1、UFI003 WIFI棒子刷Debian 青龙的踩坑教程&quot;&gt;</summary>
      
    
    
    
    <category term="WIFI" scheme="https://www.yxliu.cc/categories/WIFI/"/>
    
    
    <category term="WIFI棒子" scheme="https://www.yxliu.cc/tags/WIFI%E6%A3%92%E5%AD%90/"/>
    
    <category term="UFI003" scheme="https://www.yxliu.cc/tags/UFI003/"/>
    
  </entry>
  
  <entry>
    <title>Hexo 静态文件部署web nginx配置</title>
    <link href="https://www.yxliu.cc/2024/12/26/72898477.html"/>
    <id>https://www.yxliu.cc/2024/12/26/72898477.html</id>
    <published>2024-12-26T08:12:25.000Z</published>
    <updated>2026-02-04T06:42:44.027Z</updated>
    
    <content type="html"><![CDATA[<p>重定向规则配置  将子域名 全部重定向到<a href="http://www.yxliuchn.uk/">www.yxliuchn.uk</a></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">if</span> (<span class="variable">$host</span> <span class="regexp">~* ^([^.]+)\.yxliuchn\.uk$)</span> &#123;</span><br><span class="line">    <span class="attribute">return</span> <span class="number">301</span> https://www.yxliuchn.uk<span class="variable">$request_uri</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>或者在Nginx配置中加入</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">return</span> <span class="number">301</span> http://www.yxliuchn.uk<span class="variable">$request_uri</span>;</span><br></pre></td></tr></table></figure><p>外挂标签时 伪静态配置</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 处理 /Gallery 路径下的请求 将其下面链接自动带上.html 后缀</span></span><br><span class="line">   <span class="section">location</span> /Gallery/ &#123;</span><br><span class="line">       <span class="attribute">try_files</span> <span class="variable">$uri</span> <span class="variable">$uri</span>.html <span class="variable">$uri</span>/ =<span class="number">404</span>;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;重定向规则配置  将子域名 全部重定向到&lt;a href=&quot;http://www.yxliuchn.uk/&quot;&gt;www.yxliuchn.uk&lt;/a&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight nginx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutte</summary>
      
    
    
    
    <category term="Hexo" scheme="https://www.yxliu.cc/categories/Hexo/"/>
    
    
    <category term="Hexo" scheme="https://www.yxliu.cc/tags/Hexo/"/>
    
    <category term="Nginx" scheme="https://www.yxliu.cc/tags/Nginx/"/>
    
  </entry>
  
  <entry>
    <title>Oracle Cloud 服务器设置</title>
    <link href="https://www.yxliu.cc/2024/07/15/c88f329b.html"/>
    <id>https://www.yxliu.cc/2024/07/15/c88f329b.html</id>
    <published>2024-07-15T02:57:23.000Z</published>
    <updated>2026-02-04T06:42:44.030Z</updated>
    
    <content type="html"><![CDATA[<p>Oracle Cloud实例开通，并在公共子网中添加安全列表，开通的80等端口后，安装Nginx服务器，依然无法访问，因为操作系统ubuntu的防火墙还未设置，默认情况下，同样是只有ssh端口开放的。</p><p>索性直接强制删除，以后直接通过ufw管理：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">apt-get purge netfilter-persistent</span><br><span class="line"><span class="built_in">rm</span> -rf /etc/iptables</span><br><span class="line">reboot</span><br></pre></td></tr></table></figure><p>安装1panel</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh &amp;&amp; <span class="built_in">sudo</span> bash quick_start.sh</span><br></pre></td></tr></table></figure><p>安装xui</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#原版</span></span><br><span class="line">bash &lt;(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh)</span><br><span class="line"></span><br><span class="line"><span class="comment">#魔改版</span></span><br><span class="line">wget -O xui.sh https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh &amp;&amp; bash xui.sh</span><br></pre></td></tr></table></figure><p>安装docker 和更换软件源</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#安装docker</span></span><br><span class="line">bash &lt;(curl -sSL https://linuxmirrors.cn/docker.sh)</span><br><span class="line"><span class="comment">#更换软件源</span></span><br><span class="line">bash &lt;(curl -sSL https://linuxmirrors.cn/main.sh) --abroad</span><br></pre></td></tr></table></figure><p>8合一</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget -P /root -N --no-check-certificate <span class="string">&quot;https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh&quot;</span> &amp;&amp; <span class="built_in">chmod</span> 700 /root/install.sh &amp;&amp; /root/install.sh</span><br></pre></td></tr></table></figure><p>DD系统</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#ubuntu</span></span><br><span class="line">curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O reinstall.sh <span class="variable">$_</span> &amp;&amp; bash reinstall.sh ubuntu 20.04 --minimal</span><br><span class="line"><span class="comment">#debian</span></span><br><span class="line">wget --no-check-certificate -qO InstallNET.sh <span class="string">&#x27;https://raw.githubusercontent.com/leitbogioro/Tools/master/Linux_reinstall/InstallNET.sh&#x27;</span> &amp;&amp; <span class="built_in">chmod</span> a+x InstallNET.sh &amp;&amp; bash InstallNET.sh -debian 12 -<span class="built_in">pwd</span> <span class="string">&#x27;19951102liu&#x27;</span></span><br></pre></td></tr></table></figure><p>SSH关闭密码登录</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bash &lt;(curl -Lso- https://sh.vps.dance/ssh.sh) <span class="built_in">pwd</span></span><br></pre></td></tr></table></figure><p>装fail2ban</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -sSL  https://raw.githubusercontent.com/FunctionClub/Fail2ban/master/fail2ban.sh -o fail2ban.sh  &amp;&amp; <span class="built_in">sudo</span> bash fail2ban.sh</span><br></pre></td></tr></table></figure><p>更新公钥</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">rm</span> -rf  /root/.ssh/authorized_keys</span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCdLKkffqDKCTa8vsYatp2LASbTBSXtpDHuXQaRMHZ65lkH1baPKCeNk0/pYjBRt0xQ95YTA2Zr72N1hhyQji+xZz6waoDsLVB0siVzKh4V94WtTUQmqQti8leewi+xM9GtucaoT/YYjynijfSxEu161RDIF6GClZd5VUWSGx2KXHRS7BCSUYjaskucA7uOWkgi9KZQmCcRnE/9UJPys31VOsmBwbgPuLfifGRGSIfkrlkvnjkvoMzorfd4rAycDh++VqCl3wssDSnOWjg3WghTM8cicfygVA37U1nWOqwnmgND7OVIQHqRC4nxYOyyKwWXEE0cJJ3XweVUR48Jse5aIvF6IW2NZRwsndhHN6qbmw1M3ce4Dj9StiGSRj/qFQHKAWSUuYsytRcmiF+MQe5VsVvqhebi0Iz5No5uvz9wOZ8qVAB9fs/26FzoAcPvMJ4BVDE0ez3uZ0C8t+NYyBQucyEPkquQ7RGAw/ifx6QjKgEHFF9QumZHHJJRX+KOpP8= 851046264@qq.com&quot;</span> &gt;&gt; /root/.ssh/authorized_keys</span><br><span class="line"><span class="built_in">chmod</span> 600 /root/.ssh/authorized_keys</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Oracle Cloud实例开通，并在公共子网中添加安全列表，开通的80等端口后，安装Nginx服务器，依然无法访问，因为操作系统ubuntu的防火墙还未设置，默认情况下，同样是只有ssh端口开放的。&lt;/p&gt;
&lt;p&gt;索性直接强制删除，以后直接通过ufw管理：&lt;/p&gt;
&lt;fi</summary>
      
    
    
    
    <category term="Ubuntu" scheme="https://www.yxliu.cc/categories/Ubuntu/"/>
    
    
    <category term="Ubuntu" scheme="https://www.yxliu.cc/tags/Ubuntu/"/>
    
  </entry>
  
  <entry>
    <title>Linux 用户操作</title>
    <link href="https://www.yxliu.cc/2023/05/25/352f6e27.html"/>
    <id>https://www.yxliu.cc/2023/05/25/352f6e27.html</id>
    <published>2023-05-25T07:26:16.000Z</published>
    <updated>2026-02-04T06:42:44.027Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Linux命令添加，删除，修改，查看用户和用户组"><a href="#Linux命令添加，删除，修改，查看用户和用户组" class="headerlink" title="Linux命令添加，删除，修改，查看用户和用户组"></a>Linux命令添加，删除，修改，查看用户和用户组</h1><h1 id="一，组操作"><a href="#一，组操作" class="headerlink" title="一，组操作"></a>一，组操作</h1><h2 id="1，创建组"><a href="#1，创建组" class="headerlink" title="1，创建组"></a>1，创建组</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">groupadd  test</span><br></pre></td></tr></table></figure><p>增加一个test组</p><h2 id="2，修改组"><a href="#2，修改组" class="headerlink" title="2，修改组"></a>2，修改组</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">groupmod -n test2  test</span><br></pre></td></tr></table></figure><p>将test组的名子改成test2</p><h2 id="3，删除组"><a href="#3，删除组" class="headerlink" title="3，删除组"></a>3，删除组</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">groupdel test2</span><br></pre></td></tr></table></figure><p>删除 组test2</p><h2 id="4，查看组"><a href="#4，查看组" class="headerlink" title="4，查看组"></a>4，查看组</h2><p>a），查看当前登录用户所在的组 groups，查看apacheuser所在组groups apacheuser</p><p>b），查看所有组 cat &#x2F;etc&#x2F;group</p><p>c），有的linux系统没有&#x2F;etc&#x2F;group文件的，这个时候看下面的这个方法</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat /etc/passwd |awk -F [:] ‘&#123;print $4&#125;’ |sort|uniq | getent group |awk -F [:] ‘&#123;print $1&#125;’</span><br></pre></td></tr></table></figure><p>这里用到一个命令是getent,可以通过组ID来查找组信息,如果这个命令没有的话,那就很难查找,系统中所有的组了.</p><h1 id="二，用户操作"><a href="#二，用户操作" class="headerlink" title="二，用户操作"></a>二，用户操作</h1><h2 id="查看命令参数"><a href="#查看命令参数" class="headerlink" title="查看命令参数"></a>查看命令参数</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">useradd --help  </span><br><span class="line">Usage: useradd [options] LOGIN  </span><br><span class="line"></span><br><span class="line">Options:  </span><br><span class="line"> -b, --base-dir BASE_DIR       设置基本路径作为用户的登录目录  </span><br><span class="line"> -c, --comment COMMENT         对用户的注释  </span><br><span class="line"> -d, --home-dir HOME_DIR       设置用户的登录目录  </span><br><span class="line"> -D, --defaults                改变设置  </span><br><span class="line"> -e, --expiredate EXPIRE_DATE  设置用户的有效期  </span><br><span class="line"> -f, --inactive INACTIVE       用户过期后，让密码无效  </span><br><span class="line"> -g, --gid GROUP               使用户只属于某个组  </span><br><span class="line"> -G, --groups GROUPS           使用户加入某个组  </span><br><span class="line"> -h, --help                    帮助  </span><br><span class="line"> -k, --skel SKEL_DIR           指定其他的skel目录  </span><br><span class="line"> -K, --key KEY=VALUE           覆盖 /etc/login.defs 配置文件  </span><br><span class="line"> -m, --create-home             自动创建登录目录  </span><br><span class="line"> -l,                           不把用户加入到lastlog文件中  </span><br><span class="line"> -M,                           不自动创建登录目录  </span><br><span class="line"> -r,                           建立系统账号  </span><br><span class="line"> -o, --non-unique              允许用户拥有相同的UID  </span><br><span class="line"> -p, --password PASSWORD       为新用户使用加密密码  </span><br><span class="line"> -s, --shell SHELL             登录时候的shell  </span><br><span class="line"> -u, --uid UID                 为新用户指定一个UID  </span><br><span class="line"> -Z, --selinux-user SEUSER     use a specific SEUSER for the SELinux user mapping </span><br></pre></td></tr></table></figure><h2 id="1-增加用户"><a href="#1-增加用户" class="headerlink" title="1.增加用户"></a>1.增加用户</h2><p>useradd test</p><p>passwd test</p><p>增加用户test，有一点要注意的，useradd增加一个用户后，不要忘了给他设置密码，不然不能登录的。</p><p>两个用户创建命令之间的区别：<br>adduser： 会自动为创建的用户指定主目录、系统shell版本，会在创建时输入用户密码。</p><p>useradd：需要使用参数选项指定上述基本设置，如果不使用任何参数，则创建的用户无密码、无主目录、没有指定shell版本。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">useradd [选项] 用户名　　　#创建新用户</span><br><span class="line"></span><br><span class="line">sudo useradd -m -g 组名 用户名</span><br><span class="line">-m : 自动建立用户家目录，创建用户时最好加这个 。</span><br><span class="line">-g 组名 : 指定用户所在的组，否则会建立一个与用户同名的组。</span><br></pre></td></tr></table></figure><h2 id="2-修改用户"><a href="#2-修改用户" class="headerlink" title="2.修改用户"></a>2.修改用户</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">usermod -d /home/test -G test2 test</span><br></pre></td></tr></table></figure><p>将test用户的登录目录改成&#x2F;home&#x2F;test，并加入test2组，注意这里是大G。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gpasswd -a test test2 #将用户test加入到test2组</span><br><span class="line">gpasswd -d test test2 #将用户test从test2组中移出</span><br></pre></td></tr></table></figure><h2 id="3-删除用户"><a href="#3-删除用户" class="headerlink" title="3.删除用户"></a>3.删除用户</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"> userdel [选项] 用户名　　　#删除一个用户</span><br><span class="line"></span><br><span class="line">选项：</span><br><span class="line"></span><br><span class="line">-r : 把用户家目录一并删除</span><br></pre></td></tr></table></figure><p>提示： 如果添加用户时，没有加-m创建家目录，最简单的方法是删除该用户，重新创建。</p><p>userdel test</p><p>将test用户删除</p><h2 id="4-查看用户"><a href="#4-查看用户" class="headerlink" title="4.查看用户"></a>4.查看用户</h2><p>添加的组会保存到&#x2F;etc&#x2F;group文件中，可以通过cat -n &#x2F;etc&#x2F;group | grep 组名 单独查看信息。</p><p>创建的用户保存在&#x2F;etc&#x2F;passwd文件中，可以通过cat -n &#x2F;etc&#x2F;passwd | grep 用户名 单独查看信息。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">$ cat -n /etc/group | grep kmust   # 查看kmust组的信息</span><br><span class="line">     69 kmust:x:1001:              # 组id为1001，69为行号</span><br><span class="line"></span><br><span class="line">$ cat -n /etc/passwd | grep zyq  # 查看 zyq 用户的信息</span><br><span class="line">    40  zyq:x:1000:1000:zyq,,,:/home/zyq:/bin/bash </span><br><span class="line"># 40：行号</span><br><span class="line">#zyq：用户名</span><br><span class="line">#x : 密码标志，真正的密码是放在shadow（影子文件）中，并且加密</span><br><span class="line">#1000:1000: 分别是UID和GID。UID（用户ID）: 0（超级用户），1~499(系统用户)，500~65535(普通用户)。 要想修改一个用户为超级用户，只需将UID改为0即可</span><br><span class="line">#zyq,,,  ： 用户的说明信息，当初创建用户时随便写的</span><br><span class="line">#/home/zyq : 家目录 </span><br><span class="line">#/bin/bash : 登录使用的shell(ubuntu是dash软件)</span><br></pre></td></tr></table></figure><p>a）查看当前登录用户</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">#查看目前所有登录的用户和用户IP地址和时间,未登录用户不能显示</span><br><span class="line">who</span><br></pre></td></tr></table></figure><p>b）查看自己的用户名</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"> #查看我是哪个用户</span><br><span class="line">whoami</span><br></pre></td></tr></table></figure><p>c）查看单个用户信息</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">finger apacheuser</span><br><span class="line">#查看用户的UID(用户id) 和 GID(组id) 和附件组等， 用户不写，默认当前用户</span><br><span class="line">id apacheuser</span><br></pre></td></tr></table></figure><p>d）查看用户登录记录</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#查看登录成功的用户记录</span><br><span class="line">last</span><br><span class="line">#查看登录不成功的用户记录</span><br><span class="line">lastb </span><br></pre></td></tr></table></figure><p>e）查看所有用户</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cut -d : -f 1 /etc/passwd</span><br><span class="line">cat /etc/passwd |awk -F \: &#x27;&#123;print $1&#125;&#x27;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">Linux 相关用户操作命令</summary>
    
    
    
    <category term="Linux" scheme="https://www.yxliu.cc/categories/Linux/"/>
    
    
    <category term="Linux" scheme="https://www.yxliu.cc/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>Oracle 零碎</title>
    <link href="https://www.yxliu.cc/2023/04/20/8e8bf56b.html"/>
    <id>https://www.yxliu.cc/2023/04/20/8e8bf56b.html</id>
    <published>2023-04-20T02:37:31.000Z</published>
    <updated>2026-02-04T06:42:44.030Z</updated>
    
    <content type="html"><![CDATA[<p>oracle补零</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">---1.前端补0： </span></span><br><span class="line"></span><br><span class="line"><span class="keyword">select</span> lpad(<span class="string">&#x27;345&#x27;</span>,<span class="number">8</span>,<span class="string">&#x27;0&#x27;</span>) <span class="keyword">from</span> dual; <span class="keyword">select</span> to_char(<span class="string">&#x27;345&#x27;</span>,<span class="string">&#x27;00000000&#x27;</span>) <span class="keyword">from</span> dual; </span><br><span class="line"></span><br><span class="line"><span class="comment">---2.后端补0 </span></span><br><span class="line"><span class="keyword">select</span> rpad(<span class="string">&#x27;345&#x27;</span>,<span class="number">8</span>,<span class="string">&#x27;0&#x27;</span>) <span class="keyword">from</span> dual; </span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;oracle补零&lt;/p&gt;
&lt;figure class=&quot;highlight sql&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;</summary>
      
    
    
    
    <category term="Sql" scheme="https://www.yxliu.cc/categories/Sql/"/>
    
    
    <category term="Oracle" scheme="https://www.yxliu.cc/tags/Oracle/"/>
    
  </entry>
  
  <entry>
    <title>GIT 提交规范</title>
    <link href="https://www.yxliu.cc/2023/03/23/1235b36.html"/>
    <id>https://www.yxliu.cc/2023/03/23/1235b36.html</id>
    <published>2023-03-23T08:29:59.000Z</published>
    <updated>2026-02-04T06:42:44.027Z</updated>
    
    <content type="html"><![CDATA[<p>commit 的类别</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">用于说明 commit 的类别，常见类别如下：</span><br><span class="line"></span><br><span class="line">types: [</span><br><span class="line">    &#123; value: &#x27;feat&#x27;, name: &#x27;feat:新增功能（feature）&#x27; &#125;,</span><br><span class="line">    &#123; value: &#x27;fix&#x27;, name: &#x27;fix:修订文档，如 Readme, Change Log, Contribute 等&#x27; &#125;,</span><br><span class="line">    &#123; value: &#x27;docs&#x27;, name: &#x27;docs:文档变更&#x27; &#125;,</span><br><span class="line">    &#123; value: &#x27;style&#x27;, name: &#x27;style:仅调整空格、格式缩进等（不改变代码逻辑的变动）&#x27; &#125;,</span><br><span class="line">    &#123; value: &#x27;refactor&#x27;, name: &#x27;代码重构，未新增任何功能和修复任何 bug&#x27;&#125;,</span><br><span class="line">    &#123; value: &#x27;perf&#x27;, name: &#x27;perf:优化相关，改善性能和体验的修改&#x27; &#125;,</span><br><span class="line">    &#123; value: &#x27;test&#x27;, name: &#x27;test:测试用例的增加/修改&#x27; &#125;,</span><br><span class="line">    &#123; value: &#x27;chore&#x27;, name: &#x27;chore:构建过程或辅助工具的变动 非 src 和 test 的修改&#x27; &#125;,</span><br><span class="line">    &#123; value: &#x27;revert&#x27;, name: &#x27;revert: 回滚到上一个版本&#x27; &#125;,</span><br><span class="line">    &#123; value: &#x27;build&#x27;, name: &#x27;build:打包 改变构建流程，新增依赖库、工具等（例如 webpack、maven 修改）&#x27; &#125;</span><br><span class="line">  ],</span><br><span class="line">  // 消息步骤</span><br><span class="line">  messages: &#123;</span><br><span class="line">    type: &#x27;请选择提交类型:&#x27;,</span><br><span class="line">    customScope: &#x27;请输入修改范围(可选):&#x27;,</span><br><span class="line">    subject: &#x27;请简要描述提交(必填):&#x27;,</span><br><span class="line">    body: &#x27;请输入详细描述(可选):&#x27;,</span><br><span class="line">    footer: &#x27;请输入要关闭的issue(可选):&#x27;,</span><br><span class="line">    confirmCommit: &#x27;确认使用以上信息提交？(y/n/e/h)&#x27;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;commit 的类别&lt;/p&gt;
&lt;figure class=&quot;highlight shell&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/sp</summary>
      
    
    
    
    
    <category term="git" scheme="https://www.yxliu.cc/tags/git/"/>
    
  </entry>
  
  <entry>
    <title>Docker 简单学习</title>
    <link href="https://www.yxliu.cc/2023/01/10/72970fee.html"/>
    <id>https://www.yxliu.cc/2023/01/10/72970fee.html</id>
    <published>2023-01-10T10:22:57.000Z</published>
    <updated>2026-02-04T06:42:44.027Z</updated>
    
    <content type="html"><![CDATA[<p>Docker: 容器化技术<br>    作用: 可以实现软件环境的快速迁移与恢复<br>docker原理:<br>    先将软件依赖的一切打成镜像<br>    运行镜像成容器,从而恢复软件的正常使用<br>    容器在运行时直接基于宿主机的内核运行<br>docker名词:<br>    镜像: 将软件&#x2F;应用依赖的一切进行打包,打好的包叫做镜像<br>    容器: 镜像运行后生成容器,镜像就是在容器内运行的. 容器与容器之间相互隔离互补干扰,遵循沙箱机制.<br>        外界访问容器的方式:<br>            在运行容器时,给容器绑定宿主机端口<br>        容器跟容器之间相互访问:<br>            在Linux中创建虚拟网络,将容器加入到虚拟网络中,加入的容器就可以根据容器名称相互访问了.<br>    宿主机:<br>        容器运行的载体,容器在哪个Linux上运行,Linux就是容器的宿主机<br>    镜像服务:<br>        Docker官方提供了很多镜像,这些镜像存放在镜像服务中,使用时直接通过docker命令拉取即可.<br>        镜像仓库: 一款软件对应一个镜像仓库<br>            镜像:<br>                软件名称:tag<br>    数据卷:<br>        本质上就是宿主机上的一个文件夹,可以实现数据与容器相分离。</p><hr><p><strong>docker相关命令:</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">镜像命令:</span><br><span class="line">        docker images</span><br><span class="line">        docker pull 镜像名称:tag</span><br><span class="line">        docker push 镜像名称</span><br><span class="line">        docker rmi 镜像名称</span><br><span class="line">        docker save -o 包名.tar 镜像名称</span><br><span class="line">        docker build -t 镜像名称 .</span><br><span class="line">    容器命令:</span><br><span class="line">        docker run \</span><br><span class="line">            --name 容器名称 \</span><br><span class="line">            -d \</span><br><span class="line">            -p 宿主机端口:容器内软件端口 \</span><br><span class="line">            -v 数据卷名称:容器内的文件夹 \</span><br><span class="line">            镜像名称</span><br><span class="line">        docker ps</span><br><span class="line">        docker ps -a</span><br><span class="line">        docker rm 容器名称</span><br><span class="line">        docker rm -f 容器名称</span><br><span class="line">        docker logs 容器名称</span><br><span class="line">        docker stop 容器名称</span><br><span class="line">        docker start 容器名称</span><br><span class="line">        docker restart 容器名称</span><br><span class="line">        docker exec -it 容器名称 bash</span><br><span class="line">    数据卷命令:</span><br><span class="line">        docker volume ls</span><br><span class="line">        docker volume inspect 数据卷名称</span><br><span class="line">        docker volume rm 数据卷名称</span><br><span class="line">        docker volume prune</span><br><span class="line">        docker volume create 数据卷名称</span><br><span class="line">    操作虚拟网络的命令:</span><br><span class="line">        docker network ls</span><br><span class="line">        docker network inspect 数据卷名称</span><br><span class="line">        docker network rm 数据卷名称</span><br><span class="line">        docker network prune</span><br><span class="line">        docker network create 数据卷名称</span><br><span class="line">docker-compose:</span><br><span class="line">    实现容器编排.</span><br></pre></td></tr></table></figure><p>​    </p>]]></content>
    
    
    <summary type="html">Docker命令</summary>
    
    
    
    <category term="Docker" scheme="https://www.yxliu.cc/categories/Docker/"/>
    
    
    <category term="Docker" scheme="https://www.yxliu.cc/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>关于 Docker Gitea 非 rootless 版配置 SSH Fail2ban 指南</title>
    <link href="https://www.yxliu.cc/2023/01/10/72970fee.html"/>
    <id>https://www.yxliu.cc/2023/01/10/72970fee.html</id>
    <published>2023-01-10T10:22:57.000Z</published>
    <updated>2026-02-04T06:42:44.031Z</updated>
    
    <content type="html"><![CDATA[<p>也就是 gitea&#x2F;gitea:latest 一定存在。因为 Gitea 标准版部署在 Docker 下的 SSH 无法获取日志，尝试过构建镜像，补全 rsyslog ，配置 openssh ，总之得到一个结论：无法在其容器中获取到 SSH 相关爆破日志。</p><p>官网的描述很简单的，只需要改下 app.ini 中的 MODE，一改一个不吱声，gitea.log 不会包含 SSH 相关，请放心做无用功。在 app.ini 中，存在一个 ENABLE_SSH_LOG 仅对 Gitea 内建 SSH 有效，抱歉的是，标准版中的 openssh 不可与内建 SSH 调和。</p><p>当配置为 Gitea 自建，也就是 DISABLE_SSH 为 false ，START_SSH_SERVER 为 true 时，SSH 会在 Gitea 后台显示被禁用，同时开启则端口冲突（也许自己做镜像关闭 openssh 或者更换端口后，可以达到内建 ssh 的效果，只是无法简单在 app.ini 中实现），其他情况则直接 502。于是简单说，不支持。</p><p>在其 github 存在一个 issue ，回复是“既然日志不是由 Gitea 内建 SSH 提供，为何要求 ENABLE_SSH_LOG 会将日志写入 gitea.log ”。于是，只能剑走偏锋，在看到 potainer 中容器的 log 时，发现其正好可以查阅爆破日志，这也是一开始尝试自建镜像的原因。</p><p>问过 GPT，最终选择使用 <code>docker logs -f</code>，同时因为这样产生的日志缺少时间戳，而Fail2ban 需要时间戳，只能追加了<code>--timestamps</code> 补全时间戳并格式化，完整代码如下 <code>gitea_log_monitor.sh</code>：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">!/bin/bash</span></span><br><span class="line"></span><br><span class="line">LOG_DIR=&quot;/path/to/save/log&quot;</span><br><span class="line">LOG_FILE=&quot;$LOG_DIR/gitea.log&quot;</span><br><span class="line">CONTAINER_NAME=&quot;gitea&quot;</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">确保日志目录存在</span></span><br><span class="line">mkdir -p &quot;$LOG_DIR&quot;</span><br><span class="line"></span><br><span class="line">while true; do</span><br><span class="line">    # 检查 gitea 容器是否在运行</span><br><span class="line">    if docker ps --format &quot;&#123;&#123;.Names&#125;&#125;&quot; | grep -q &quot;^$CONTAINER_NAME$&quot;; then</span><br><span class="line">        echo &quot;[$(date +&quot;%Y-%m-%d %H:%M:%S&quot;)] 监控 $CONTAINER_NAME 容器日志...&quot;</span><br><span class="line">        # 获取容器日志并格式化时间戳</span><br><span class="line">        docker logs -f --timestamps &quot;$CONTAINER_NAME&quot; | \</span><br><span class="line">            awk &#x27;&#123; cmd=&quot;date -d &quot;$1&quot; +\&quot;%Y-%m-%d %H:%M:%S\&quot;&quot;; cmd | getline ts; close(cmd); print ts, substr($0, index($0,$2)) &#125;&#x27; &gt;&gt; &quot;$LOG_FILE&quot;</span><br><span class="line">    else</span><br><span class="line">        echo &quot;[$(date +&quot;%Y-%m-%d %H:%M:%S&quot;)] $CONTAINER_NAME 容器未运行，等待启动...&quot;</span><br><span class="line">    fi</span><br><span class="line">    </span><br><span class="line">    sleep 5  # 每 5 秒检查一次容器状态</span><br><span class="line">done</span><br></pre></td></tr></table></figure><p>增加一个系统服务：<code>gitea-log-monitor.service</code> ，内容如下：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">[Unit]</span><br><span class="line">Description=Gitea Log Monitor</span><br><span class="line">After=docker.service</span><br><span class="line">Requires=docker.service</span><br><span class="line"></span><br><span class="line">[Service]</span><br><span class="line">ExecStart=/path/to/gitea_log_monitor.sh</span><br><span class="line">Restart=always</span><br><span class="line">User=root</span><br><span class="line"></span><br><span class="line">[Install]</span><br><span class="line">WantedBy=multi-user.target</span><br></pre></td></tr></table></figure><p>写一个执行脚本：install ,内容如下：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">!/bin/bash</span></span><br><span class="line">chmod +x /path/to/gitea_log_monitor.sh</span><br><span class="line">cp /path/to/gitea-log-monitor.service /etc/systemd/system/gitea-log-monitor.service  </span><br><span class="line"></span><br><span class="line">systemctl daemon-reload</span><br><span class="line">systemctl enable gitea-log-monitor</span><br><span class="line">systemctl start gitea-log-monitor</span><br></pre></td></tr></table></figure><p>以上解决方案描述：系统启动时开启一个脚本轮询 gitea 容器日志并输出至文件，包含了容器未运行的容错处理。</p><p>总之，日志文件解决了，Fail2ban 就不是太想赘述了，当然，如果还是使用官网的那些规则，相信一条鱼都抓不到。简单贡献一下匹配规则：<code>gitea.conf</code></p><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">[Definition]</span></span><br><span class="line"><span class="attr">failregex</span> = <span class="string">^.*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from &lt;HOST&gt; .*</span></span><br><span class="line">            <span class="attr">^.*</span> <span class="string">Invalid user .* from &lt;HOST&gt; .*</span></span><br><span class="line">            <span class="attr">^.*</span> <span class="string">&lt;HOST&gt; not allowed because not listed in AllowUsers.*</span></span><br><span class="line">            <span class="attr">^Disconnected</span> <span class="string">from invalid user .* &lt;HOST&gt; port.*</span></span><br><span class="line">            <span class="attr">^Connection</span> <span class="string">closed by invalid user .* &lt;HOST&gt; port.*</span></span><br><span class="line">            <span class="attr">^Timeout</span> <span class="string">before authentication for connection from &lt;HOST&gt; .*</span></span><br><span class="line"><span class="attr">ignoreregex</span> =<span class="string"></span></span><br></pre></td></tr></table></figure><h3 id="2-创建-Jail-配置"><a href="#2-创建-Jail-配置" class="headerlink" title="2. 创建 Jail 配置"></a>2. 创建 Jail 配置</h3><p>创建 Fail2ban Jail 配置，注意对于 Docker 环境中的 SSH，必须使用 <code>FORWARD</code> 链而非 <code>DOCKER-USER</code> 链才能有效工作：</p><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">[gitea]</span></span><br><span class="line"><span class="attr">enabled</span> = <span class="string">true</span></span><br><span class="line"><span class="attr">chain</span> = <span class="string">FORWARD</span></span><br><span class="line"><span class="attr">filter</span> = <span class="string">gitea</span></span><br><span class="line"><span class="attr">logpath</span> = <span class="string">/path/to/gitea.log</span></span><br><span class="line"><span class="attr">banaction</span> = <span class="string">iptables-allports[blocktype=DROP]</span></span><br></pre></td></tr></table></figure><p>结果自然是简单，试错是相当的麻烦。这里肯定不是 gitea 的最优解，却是获取容器日志的通解。以上。</p>]]></content>
    
    
    <summary type="html">Docker命令 Gitea  Fail2ban</summary>
    
    
    
    <category term="Docker" scheme="https://www.yxliu.cc/categories/Docker/"/>
    
    <category term="Gitea" scheme="https://www.yxliu.cc/categories/Docker/Gitea/"/>
    
    
    <category term="Docker" scheme="https://www.yxliu.cc/tags/Docker/"/>
    
    <category term="Gitea" scheme="https://www.yxliu.cc/tags/Gitea/"/>
    
  </entry>
  
  <entry>
    <title>Spring Bean学习</title>
    <link href="https://www.yxliu.cc/2022/12/16/d61ff02.html"/>
    <id>https://www.yxliu.cc/2022/12/16/d61ff02.html</id>
    <published>2022-12-16T12:11:12.000Z</published>
    <updated>2026-02-04T06:42:44.030Z</updated>
    
    <content type="html"><![CDATA[<h3 id="IoC"><a href="#IoC" class="headerlink" title="IoC"></a>IoC</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># IOC概念</span></span><br><span class="line"><span class="bullet">0.</span> IoC 全称为 Inversion of Control，翻译为 “控制反转”。</span><br><span class="line"><span class="bullet">1.</span> 控制什么?</span><br><span class="line"><span class="code">控制对象的创建和销毁</span></span><br><span class="line"><span class="code">2. 反转什么?</span></span><br><span class="line"><span class="code">对象的控制权（创建和销毁）从主动管理转为交给Spring的容器管理</span></span><br><span class="line"><span class="code">3. Spring的容器(IOC Container)</span></span><br><span class="line"><span class="code">Spring控制的资源全部放置在Spring容器中，该容器也称为IoC容器</span></span><br><span class="line"><span class="code">4. IOC的思想</span></span><br><span class="line"><span class="code">1). 面向接口编程 (多态)</span></span><br><span class="line"><span class="code">接口类型 变量 = 接口实现类对象</span></span><br><span class="line"><span class="code">2). 反射 + 配置文件</span></span><br><span class="line"><span class="code"></span></span><br><span class="line"><span class="code">    3). 工厂模式: 内置容器,管理对象的创建和销毁</span></span><br><span class="line"><span class="code">    </span></span><br><span class="line"><span class="code">5. IOC的作用: 解耦    </span></span><br></pre></td></tr></table></figure><h4 id="IoC入门"><a href="#IoC入门" class="headerlink" title="IoC入门"></a>IoC入门</h4><blockquote><p>配置文件</p><p>applicationContext.xml</p></blockquote><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="string"><span class="tag">        https://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!-- 1.创建spring控制的资源</span></span><br><span class="line"><span class="comment">            1). id 是这个bean的标识, 可以自定义,但是最好见名知意</span></span><br><span class="line"><span class="comment">            2). class 指定实现类的全限定名</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.UserServiceImpl&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="IoC配置（XML格式）"><a href="#IoC配置（XML格式）" class="headerlink" title="IoC配置（XML格式）"></a>IoC配置（XML格式）</h2><h3 id="1-bean"><a href="#1-bean" class="headerlink" title="1)bean"></a>1)bean</h3><ul><li><p>名称：bean</p></li><li><p>类型：<strong>标签</strong></p></li><li><p>归属：beans标签</p></li><li><p>作用：定义spring中的资源，受此标签定义的资源将受到spring控制</p></li><li><p>格式：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">beans</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>基本属性：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;beanId&quot;</span> <span class="attr">name</span>=<span class="string">&quot;beanName1,beanName2&quot;</span> <span class="attr">class</span>=<span class="string">&quot;ClassName&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure><p>​    id：bean的名称，通过id值获取bean</p><p>​    class：bean的类型 (全限定名)</p><p>​    name：bean的名称，可以通过name值获取bean，用于多人配合时给bean起别名</p></li><li><p>代码演示</p><ol><li><p>配置文件修改</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">&lt;!-- name和id的作用相似, 我们也可以通过name获取bean --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService&quot;</span> <span class="attr">name</span>=<span class="string">&quot;userService1,userService2&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.UserServiceImpl&quot;</span>/&gt;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure></li><li><p>测试类修改</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserTest</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test01</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="comment">//2.加载配置文件</span></span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="comment">//3.获取资源: 通过id和name都能获取到bean</span></span><br><span class="line">            <span class="comment">// userService,userService1,userService2都可以</span></span><br><span class="line">            <span class="comment">// userService3 因为没有指定,所以会报以下异常: </span></span><br><span class="line">            <span class="comment">// NoSuchBeanDefinitionException: No bean named &#x27;userService3&#x27; available</span></span><br><span class="line">        <span class="type">UserService</span> <span class="variable">userService</span> <span class="operator">=</span> (UserService) ctx.getBean(<span class="string">&quot;userService3&quot;</span>);</span><br><span class="line">        userService.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></li></ol></li></ul><h3 id="2-bean属性scope"><a href="#2-bean属性scope" class="headerlink" title="2)bean属性scope"></a>2)bean属性scope</h3><ul><li><p>名称：scope</p></li><li><p>类型：<strong>属性</strong></p></li><li><p>归属：bean标签</p></li><li><p>作用：定义bean的作用范围</p></li><li><p>格式：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">scope</span>=<span class="string">&quot;singleton&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>取值：</p><ul><li>singleton：设定创建出的对象保存在spring容器中，是一个单例的对象</li><li>prototype：设定创建出的对象保存在spring容器中，是一个非单例的对象</li><li>request、session、application、 websocket ：设定创建出的对象放置在web容器对应的位置 (了解)</li></ul></li><li><p>代码演示</p><ol><li><p>配置文件修改</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">        scope : 作用范围</span></span><br><span class="line"><span class="comment">            1. singleton : 单例 (默认值)</span></span><br><span class="line"><span class="comment">                    1). 这个类在容器只会有一个实例</span></span><br><span class="line"><span class="comment">                    2). 饿汉单例 : 工厂加载配置文件的时候,实例就创建了</span></span><br><span class="line"><span class="comment">                        效率高</span></span><br><span class="line"><span class="comment">            2. prototype : 多例</span></span><br><span class="line"><span class="comment">                    1). 这个类在容器有多个实例</span></span><br><span class="line"><span class="comment">                    2). 懒汉多例 : 工厂加载配置文件的时候,没有实例, 获取的时候才创建</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">            3. 运用:</span></span><br><span class="line"><span class="comment">                1). 单例: 全工程只要一个实例 (连接池,线程池,工厂...)</span></span><br><span class="line"><span class="comment">                2). 多例: 全工程需要多个实例 (连接,线程 ... )</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.UserServiceImpl&quot;</span></span></span><br><span class="line"><span class="tag">          <span class="attr">scope</span>=<span class="string">&quot;prototype&quot;</span></span></span><br><span class="line"><span class="tag">    /&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>测试类修改</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">UserServiceImpl</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;constructor run...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;UserServiceImpl run...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol></li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">  <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test02</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span></span><br><span class="line">                <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="type">UserService</span> <span class="variable">userService1</span> <span class="operator">=</span> (UserService) ctx.getBean(<span class="string">&quot;userService&quot;</span>);</span><br><span class="line">        <span class="type">UserService</span> <span class="variable">userService2</span> <span class="operator">=</span> (UserService) ctx.getBean(<span class="string">&quot;userService&quot;</span>);</span><br><span class="line"><span class="comment">//        System.out.println(userService1);</span></span><br><span class="line"><span class="comment">//        System.out.println(userService2);</span></span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><p>​     </p><h3 id="3-bean生命周期"><a href="#3-bean生命周期" class="headerlink" title="3)bean生命周期"></a>3)bean生命周期</h3><ul><li><p>名称：init-method，destroy-method</p></li><li><p>类型：<strong>属性</strong></p></li><li><p>归属：bean标签</p></li><li><p>作用：定义bean对象在初始化或销毁时完成的工作</p></li><li><p>格式：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">init-method</span>=<span class="string">&quot;init&quot;</span> <span class="attr">destroy-method</span>=<span class="string">&quot;destroy&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>取值：bean对应的类中对应的具体方法名</p></li><li><p>注意事项：</p><ul><li><p>当scope&#x3D;“singleton”时，spring容器中有且仅有一个对象，init方法在创建容器时仅执行一次</p></li><li><p>当scope&#x3D;“prototype”时，spring容器要创建同一类型的多个对象，init方法在每个对象创建时均执行一次</p></li><li><p>当scope&#x3D;“singleton”时，关闭容器会导致bean实例的销毁，调用destroy方法一次</p></li><li><p>当scope&#x3D;“prototype”时，对象的销毁由垃圾回收机制gc()控制，destroy方法将不会被执行</p></li></ul></li><li><p>代码演示</p><ol><li><p>实现类修改</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">UserServiceImpl</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;UserServiceImpl constructor..&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;userService save--&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">a</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;init&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">destroy</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;destroy&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol></li></ul><ol start="2"><li><p>配置文件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">     bean的生命周期方法</span></span><br><span class="line"><span class="comment">     0. 概念</span></span><br><span class="line"><span class="comment">         生命周期: 从创建到销毁的整个过程</span></span><br><span class="line"><span class="comment">         bean的生命周期方法 : 在一个bean从创建到销毁的整个过程中执行的方法</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">     1. init-method : 用来指定bean的init方法(初始化)</span></span><br><span class="line"><span class="comment">         执行时机: 此方法bean创建的时候调用</span></span><br><span class="line"><span class="comment">         适合 : 初始化数据</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">     2. destroy-method : 用来指定bean的destroy方法(销毁)</span></span><br><span class="line"><span class="comment">         此方法bean销毁的时候调用</span></span><br><span class="line"><span class="comment">         适合 : 保存数据,释放资源</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">     底层原理:</span></span><br><span class="line"><span class="comment">         Class clazz = Class.forName(&quot;com.itheima.service.impl.UserServiceImpl&quot;);</span></span><br><span class="line"><span class="comment">         Object obj = clazz.newInstance(); // 通过空参构造创建实例</span></span><br><span class="line"><span class="comment">         //在类中,找到名为a的public空参方法</span></span><br><span class="line"><span class="comment">         Method method = clazz.getMethod(&quot;a&quot;);</span></span><br><span class="line"><span class="comment">         //调用方法</span></span><br><span class="line"><span class="comment">         method.invoke(obj);</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">    饿汉单例:</span></span><br><span class="line"><span class="comment">         1. 初始化: 工厂创建,bean就会被加载, bean的init方法就会执行</span></span><br><span class="line"><span class="comment">         2. 销毁 : 程序终止, 工厂(ioc容器)销毁,bean也会随之销毁,destroy方法就会执行</span></span><br><span class="line"><span class="comment">    懒汉多例 :</span></span><br><span class="line"><span class="comment">         1. 初始化 : 每从ioc容器中获取一个bean,就会创建一个bean,init方法就会被调用一次</span></span><br><span class="line"><span class="comment">         2. 销毁 : bean对象不由ioc容器管理, ioc容器销毁, bean不会随之销毁的,destroy不执行</span></span><br><span class="line"><span class="comment">                  由GC管理(垃圾回收器)</span></span><br><span class="line"><span class="comment"> --&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">scope</span>=<span class="string">&quot;prototype&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.UserServiceImpl&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">init-method</span>=<span class="string">&quot;a&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">destroy-method</span>=<span class="string">&quot;destroy&quot;</span></span></span><br><span class="line"><span class="tag"> /&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>测试类修改</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">method03</span><span class="params">()</span>&#123;</span><br><span class="line">       <span class="comment">//1. 创建工厂对象</span></span><br><span class="line">       <span class="type">ApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">       <span class="comment">//2. 从ioc容器中获取bean</span></span><br><span class="line">       <span class="type">UserService</span> <span class="variable">userService</span> <span class="operator">=</span> (UserService) context.getBean(<span class="string">&quot;userService&quot;</span>);</span><br><span class="line">       <span class="type">UserService</span> <span class="variable">userService2</span> <span class="operator">=</span> (UserService) context.getBean(<span class="string">&quot;userService&quot;</span>);</span><br><span class="line">       <span class="comment">/*</span></span><br><span class="line"><span class="comment">           工厂销毁(当程序运行结束时, 工厂就会销毁)</span></span><br><span class="line"><span class="comment">           1. 如果程序正常运行终止, 工厂是会销毁的,但是因为demo的运行太快, destroy有执行</span></span><br><span class="line"><span class="comment">               但是时间太短, 看不到destroy,所以现在手动调用close方法(这个代码没必要写)</span></span><br><span class="line"><span class="comment">           2. close方法是属于 ClassPathXmlApplicationContext特有的,ApplicationContext没有</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">       <span class="type">ClassPathXmlApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> (ClassPathXmlApplicationContext) context;</span><br><span class="line">       ctx.close();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure></li></ol><h3 id="4-bean对象创建方式"><a href="#4-bean对象创建方式" class="headerlink" title="4)bean对象创建方式"></a>4)bean对象创建方式</h3><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># bean对象的创建方式</span></span><br><span class="line"><span class="bullet">1.</span> 直接配置</span><br><span class="line"><span class="code">&lt;bean id=&quot;userService&quot; class=&quot;com.itheima.service.impl.UserServiceImpl&quot;/&gt;</span></span><br><span class="line"><span class="code">场景: 在配置的时候,知道实现类的全限定名 (一般自己写bean)</span></span><br><span class="line"><span class="code">底层原理: 空参构造</span></span><br><span class="line"><span class="code">缺陷是: 开发者需要知道类名</span></span><br><span class="line"><span class="code">2. 工厂方式</span></span><br><span class="line"><span class="code">1). 静态工厂 : 创建对象的方法是静态</span></span><br><span class="line"><span class="code">2). 实例工厂 : 创建对象的方法是非静态的</span></span><br><span class="line"><span class="code"></span></span><br><span class="line"><span class="code">场景: 开发者不知道类名,但是可以通过代码创建实例</span></span><br><span class="line"><span class="code">I. 匿名内部类</span></span><br><span class="line"><span class="code">II. 动态代理 : 代理类是运行时动态创建的,开发者不知道类名</span></span><br></pre></td></tr></table></figure><p>除了以上所示的通过调用bean的构造方法创建对象之外,spring还提供了两种工厂创建方式</p><blockquote><p>一般用来配置其他框架的bean</p></blockquote><p>(1)静态工厂</p><ul><li><p>名称：factory-bean</p></li><li><p>类型：<strong>属性</strong></p></li><li><p>归属：bean标签</p></li><li><p>作用：定义bean对象创建方式，使用静态工厂的形式创建bean，兼容早期遗留系统的升级工作</p></li><li><p>格式：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;FactoryClassName&quot;</span> <span class="attr">factory-method</span>=<span class="string">&quot;factoryMethodName&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>取值：工厂bean中用于获取对象的静态方法名</p></li><li><p>注意事项：</p><p>​    class属性必须配置成静态工厂的类名</p></li><li><p>测试代码：</p><ol><li><p>新增一个静态工厂类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.service.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.service.UserService;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserServiceImpl2</span> <span class="keyword">implements</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="type">int</span> a;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">UserServiceImpl2</span><span class="params">(<span class="type">int</span> a)</span>&#123;</span><br><span class="line">        <span class="built_in">this</span>.a = a;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;user service2 running...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></li></ol></li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.factory;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.service.UserService;</span><br><span class="line"><span class="keyword">import</span> com.itheima.service.impl.UserServiceImpl2;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">    静态工厂: 方法是静态的</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">StaticFactory</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> UserService <span class="title function_">getBean</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="type">UserServiceImpl2</span> <span class="variable">service</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">UserServiceImpl2</span>(<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">return</span> service;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><ol start="2"><li><p>配置文件修改</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">      如果一个类没有空参构造,就不能用 bean:id,class方法配置</span></span><br><span class="line"><span class="comment">      1. 静态工厂</span></span><br><span class="line"><span class="comment">      2. 实例工厂</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">      # 静态工厂的原理</span></span><br><span class="line"><span class="comment">         clazz =  Class.forName(&quot;com.itheima.factory.StaticFactory&quot;);</span></span><br><span class="line"><span class="comment">         getBean = clazz.getMethod(&quot;getBean&quot;);</span></span><br><span class="line"><span class="comment">         UserService service = getBean.invoke(null);</span></span><br><span class="line"><span class="comment">         map.put(&quot;userService2&quot;,service);</span></span><br><span class="line"><span class="comment">  --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService2&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.factory.StaticFactory&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">factory-method</span>=<span class="string">&quot;getBean&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>测试类修改</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test04</span><span class="params">()</span>&#123;</span><br><span class="line">       <span class="type">ApplicationContext</span> <span class="variable">ctx</span></span><br><span class="line">               <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">     </span><br><span class="line">       <span class="type">UserService</span> <span class="variable">service</span> <span class="operator">=</span> (UserService) ctx.getBean(<span class="string">&quot;userService2&quot;</span>);</span><br><span class="line">     </span><br><span class="line">       service.save();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure><p>打印结果:</p><blockquote><p>user service2 running…</p></blockquote></li></ol><p>(2)实例工厂</p><ul><li><p>名称：factory-bean，factory-method</p></li><li><p>类型：<strong>属性</strong></p></li><li><p>归属：bean标签</p></li><li><p>作用：定义bean对象创建方式，使用实例工厂的形式创建bean，兼容早期遗留系统的升级工作</p></li><li><p>格式：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">factory-bean</span>=<span class="string">&quot;factoryBeanId&quot;</span> <span class="attr">factory-method</span>=<span class="string">&quot;factoryMethodName&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>取值：工厂bean中用于获取对象的实例方法名</p></li><li><p>注意事项：</p><ul><li>使用实例工厂创建bean首先需要将实例工厂配置bean，交由spring进行管理</li><li>factory-bean是实例工厂的beanId</li></ul></li><li><p>测试代码</p><ol><li><p>创建实例工厂</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.factory;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.service.UserService;</span><br><span class="line"><span class="keyword">import</span> com.itheima.service.impl.UserServiceImpl2;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">*   实例工厂: 方法是非静态</span></span><br><span class="line"><span class="comment">* */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">InstanceFactory</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> UserService <span class="title function_">getBean</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="type">UserServiceImpl2</span> <span class="variable">service</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">UserServiceImpl2</span>(<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">return</span> service;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></li><li><p>配置文件修改</p></li></ol></li></ul><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">     # 实例工厂的原理</span></span><br><span class="line"><span class="comment">         clazz =  Class.forName(&quot;com.itheima.factory.InstanceFactory&quot;);</span></span><br><span class="line"><span class="comment">         if = clazz.newInstance();</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">        getBean =  clazz.getMethod(&quot;getBean&quot;)</span></span><br><span class="line"><span class="comment">        UserService service = getBean.invoke(if);</span></span><br><span class="line"><span class="comment">        map.put(&quot;userService3&quot;,service);</span></span><br><span class="line"><span class="comment">     --&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;if&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.factory.InstanceFactory&quot;</span>/&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService3&quot;</span> <span class="attr">factory-bean</span>=<span class="string">&quot;if&quot;</span> <span class="attr">factory-method</span>=<span class="string">&quot;getBean&quot;</span>/&gt;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><ol start="3"><li><p>测试类修改</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test04</span><span class="params">()</span>&#123;</span><br><span class="line">      <span class="type">ApplicationContext</span> <span class="variable">ctx</span></span><br><span class="line">              <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">     </span><br><span class="line">      <span class="type">UserService</span> <span class="variable">service</span> <span class="operator">=</span> (UserService) ctx.getBean(<span class="string">&quot;userService3&quot;</span>);</span><br><span class="line">     </span><br><span class="line">      service.save();</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>运行结果</p><blockquote><p>user service2 running…</p></blockquote></li></ol><h3 id="5-DI-依赖注入"><a href="#5-DI-依赖注入" class="headerlink" title="5)DI 依赖注入"></a>5)DI 依赖注入</h3><blockquote><p>张三(男)和李四(女)结婚</p><ol><li>张三的亲友: 张三娶了李四</li><li>李四的亲友: 李四嫁给了张三</li></ol></blockquote><ul><li><p>IoC（Inversion Of Control）控制翻转，Spring反向控制应用程序所需要使用的外部资源</p></li><li><p>DI（Dependency Injection）依赖注入，应用程序运行依赖的资源由Spring为其提供，资源进入应用程序的方式称为注入</p></li></ul><p><img src="https://js.hnlyx.top/img/1590659778689.png" alt="1590659778689"></p><p>IoC与DI是同一件事站在不同角度看待问题</p><h3 id="4-6-set注入（主流）"><a href="#4-6-set注入（主流）" class="headerlink" title="4.6)set注入（主流）"></a>4.6)set注入（主流）</h3><ul><li><p>名称：property</p></li><li><p>类型：<strong>标签</strong></p></li><li><p>归属：bean标签</p></li><li><p>作用：使用set方法的形式为bean提供资源</p></li><li><p>格式：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;bean&gt;</span><br><span class="line">&lt;property /&gt;</span><br><span class="line">&lt;/bean&gt;</span><br></pre></td></tr></table></figure></li><li><p>基本属性：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;propertyName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;propertyValue&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;beanId&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure></li></ul><p>​name：对应bean中的属性名，要求该属性必须提供可访问的set方法（严格规范为此名称是set方法对应名称）</p><p>​value：设定非引用类型(8大基本类型和String)属性对应的值，不能与ref同时使用</p><p>​ref：设定引用类型属性对应bean的id ，不能与value同时使用</p><ul><li><p>注意：一个bean可以有多个property标签</p></li><li><p>代码演示</p><ol><li><p>添加和修改代码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.service.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.dao.UserDao;</span><br><span class="line"><span class="keyword">import</span> com.itheima.service.UserService;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.Date;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserServiceImpl3</span> <span class="keyword">implements</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> age;</span><br><span class="line">    <span class="keyword">private</span> UserDao dao;</span><br><span class="line">    <span class="keyword">private</span> Date date;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(name + <span class="string">&quot;,&quot;</span> + age + <span class="string">&quot;,&quot;</span> + date);</span><br><span class="line">        dao.add();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Date <span class="title function_">getDate</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> date;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setDate</span><span class="params">(Date date)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.date = date;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getName</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setName</span><span class="params">(String name)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getAge</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setAge</span><span class="params">(<span class="type">int</span> age)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.age = age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> UserDao <span class="title function_">getDao</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> dao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setDao</span><span class="params">(UserDao dao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.dao = dao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.dao.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.dao.UserDao;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;UserDaoImpl add...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></li><li><p>修改配置文件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">       set注入</span></span><br><span class="line"><span class="comment">       1. 原理 : 空参构造 + set方法</span></span><br><span class="line"><span class="comment">          clazz = Class.forName(&quot;com.itheima.service.impl.UserServiceImpl3&quot;);</span></span><br><span class="line"><span class="comment">          service = class.newInstance(); //</span></span><br><span class="line"><span class="comment">          setName = clazz.getMethod(&quot;setName&quot;)</span></span><br><span class="line"><span class="comment">          setName.invoke(service,&quot;zs&quot;);</span></span><br><span class="line"><span class="comment">          // service.setName(&quot;zs&quot;);</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">       2. 配置 : bean标签内子标签property</span></span><br><span class="line"><span class="comment">           1). name : bean中的属性名</span></span><br><span class="line"><span class="comment">           2). 值</span></span><br><span class="line"><span class="comment">                   value : 写基本类型和字符串</span></span><br><span class="line"><span class="comment">                   ref: 引用类型</span></span><br><span class="line"><span class="comment">   --&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.UserDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;myDate&quot;</span> <span class="attr">class</span>=<span class="string">&quot;java.util.Date&quot;</span>/&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService33&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.UserServiceImpl3&quot;</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;name&quot;</span> <span class="attr">value</span>=<span class="string">&quot;zs&quot;</span>/&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;age&quot;</span> <span class="attr">value</span>=<span class="string">&quot;18&quot;</span>/&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;userDao&quot;</span>/&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;date&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;myDate&quot;</span>/&gt;</span></span><br><span class="line">   <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>修改测试类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test05</span><span class="params">()</span>&#123;</span><br><span class="line">       <span class="type">ApplicationContext</span> <span class="variable">ctx</span></span><br><span class="line">               <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">       <span class="type">UserService</span> <span class="variable">service</span> <span class="operator">=</span> (UserService) ctx.getBean(<span class="string">&quot;userService33&quot;</span>);</span><br><span class="line">       <span class="comment">//zs,18,Tue Aug 10 15:32:32 CST 2021</span></span><br><span class="line">       <span class="comment">//UserDaoImpl add...</span></span><br><span class="line">       service.save();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure></li></ol><p>运行结果</p><blockquote><p>zs,18,Tue Aug 10 15:32:32 CST 2021<br>UserDaoImpl add…</p></blockquote></li></ul><h3 id="4-7-构造器注入（了解）"><a href="#4-7-构造器注入（了解）" class="headerlink" title="4.7)构造器注入（了解）"></a>4.7)构造器注入（了解）</h3><ul><li><p>名称：constructor-arg</p></li><li><p>类型：<strong>标签</strong></p></li><li><p>归属：bean标签</p></li><li><p>作用：使用构造方法的形式为bean提供资源，兼容早期遗留系统的升级工作</p></li><li><p>格式：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">constructor-arg</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>基本属性：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;argsName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;argsValue /&gt;</span></span></span><br></pre></td></tr></table></figure></li></ul><p>​name：对应bean中的构造方法所携带的参数名</p><p>​value：设定非引用类型构造方法参数对应的值，不能与ref同时使用</p><p>其他属性：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">index</span>=<span class="string">&quot;arg-index&quot;</span> <span class="attr">type</span>=<span class="string">&quot;arg-type&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;beanId&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure><p>​ref：设定引用类型构造方法参数对应bean的id ，不能与value同时使用</p><p>​type ：设定构造方法参数的类型，用于按类型匹配参数或进行类型校验</p><p>​index ：设定构造方法参数的位置，用于按位置匹配参数，参数index值从0开始计数</p><ul><li><p>注意：一个bean可以有多个constructor-arg标签</p></li><li><p>代码演示</p><ol><li><p>修改代码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.service.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.dao.UserDao;</span><br><span class="line"><span class="keyword">import</span> com.itheima.service.UserService;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.Date;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserServiceImpl4</span> <span class="keyword">implements</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> age;</span><br><span class="line">    <span class="keyword">private</span> UserDao dao;</span><br><span class="line">    <span class="keyword">private</span> Date date;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">UserServiceImpl4</span><span class="params">(String name, <span class="type">int</span> age, UserDao dao, Date date)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.name = name;</span><br><span class="line">        <span class="built_in">this</span>.age = age;</span><br><span class="line">        <span class="built_in">this</span>.dao = dao;</span><br><span class="line">        <span class="built_in">this</span>.date = date;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(name + <span class="string">&quot;,&quot;</span> + age + <span class="string">&quot;,&quot;</span> + date);</span><br><span class="line">        dao.add();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></li><li><p>修改配置文件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">      构造器注入 (了解)</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">      1. 原理</span></span><br><span class="line"><span class="comment">         clazz = Class.forName(&quot;com.itheima.service.impl.UserServiceImpl3&quot;);</span></span><br><span class="line"><span class="comment">         contructor = clazz.getConstructor(String.class,int.class,UserDao.class,Date.class);</span></span><br><span class="line"><span class="comment">         service = contructor.newInstance(&quot;zs&quot;,18,userDao,myDate);</span></span><br><span class="line"><span class="comment">         map.put(&quot;userService44&quot;,service);</span></span><br><span class="line"><span class="comment">      2. 配置</span></span><br><span class="line"><span class="comment">  --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.UserDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;myDate&quot;</span> <span class="attr">class</span>=<span class="string">&quot;java.util.Date&quot;</span>/&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService44&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.UserServiceImpl4&quot;</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;name&quot;</span> <span class="attr">value</span>=<span class="string">&quot;zs&quot;</span>/&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;age&quot;</span> <span class="attr">value</span>=<span class="string">&quot;18&quot;</span>/&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;dao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;userDao&quot;</span>/&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;date&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;myDate&quot;</span>/&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>修改测试类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test05</span><span class="params">()</span>&#123;</span><br><span class="line">       <span class="type">ApplicationContext</span> <span class="variable">ctx</span></span><br><span class="line">               <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">       <span class="type">UserService</span> <span class="variable">service</span> <span class="operator">=</span> (UserService) ctx.getBean(<span class="string">&quot;userService44&quot;</span>);</span><br><span class="line">       <span class="comment">//zs,18,Tue Aug 10 15:32:32 CST 2021</span></span><br><span class="line">       <span class="comment">//UserDaoImpl add...</span></span><br><span class="line">       service.save();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure></li></ol><p>运行结果</p><blockquote><p>zs,18,Tue Aug 10 15:35:31 CST 2021<br>UserDaoImpl add…</p></blockquote></li></ul><h3 id="4-8-集合类型数据注入-了解"><a href="#4-8-集合类型数据注入-了解" class="headerlink" title="4.8)集合类型数据注入(了解)"></a>4.8)集合类型数据注入(了解)</h3><ul><li><p>名称：array，list，set，map，props</p></li><li><p>类型：<strong>标签</strong></p></li><li><p>归属：property标签 或 constructor-arg标签</p></li><li><p>作用：注入集合数据类型属性</p></li><li><p>格式：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">list</span>&gt;</span><span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure></li></ul><p>(1)集合类型数据注入——list(掌握)</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;al&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>itheima<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>66666<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure><p>(2)集合类型数据注入——props(掌握)</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;properties&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">props</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">&quot;name&quot;</span>&gt;</span>itheima666<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">&quot;value&quot;</span>&gt;</span>666666<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">props</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure><p>(3)集合类型数据注入——array （了解）</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;arr&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">array</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>123456<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>66666<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">array</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure><p>(4)集合类型数据注入——set（了解）</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;hs&quot;</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">set</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">value</span>&gt;</span>itheima<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">value</span>&gt;</span>66666<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure><p>(5)集合类型数据注入——map（了解）</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;hm&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">map</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">&quot;name&quot;</span> <span class="attr">value</span>=<span class="string">&quot;itheima66666&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">&quot;value&quot;</span> <span class="attr">value</span>=<span class="string">&quot;6666666666&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">map</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li><p>代码演示</p><ol><li><p>修改代码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.service.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.service.UserService;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserServiceImpl5</span> <span class="keyword">implements</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//前两个是重点</span></span><br><span class="line">    <span class="keyword">private</span> List&lt;String&gt; list;</span><br><span class="line">    <span class="keyword">private</span> Properties p;</span><br><span class="line">    <span class="comment">//了解</span></span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span>[] array;</span><br><span class="line">    <span class="keyword">private</span> Set&lt;String&gt; set;</span><br><span class="line">    <span class="keyword">private</span> Map&lt;String,String&gt; map;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;UserServiceImpl5 save...&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;list-&gt;&quot;</span> + list);</span><br><span class="line">        System.out.println(list <span class="keyword">instanceof</span> ArrayList);<span class="comment">//true</span></span><br><span class="line">        System.out.println(<span class="string">&quot;properties-&gt;&quot;</span> + p);</span><br><span class="line">        System.out.println(<span class="string">&quot;array-&gt;&quot;</span> + Arrays.toString(array));</span><br><span class="line">        System.out.println(<span class="string">&quot;set-&gt;&quot;</span> + set);</span><br><span class="line">        System.out.println(<span class="string">&quot;map-&gt;&quot;</span> + map);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> List&lt;String&gt; <span class="title function_">getList</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setList</span><span class="params">(List&lt;String&gt; list)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.list = list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Properties <span class="title function_">getP</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> p;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setP</span><span class="params">(Properties p)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.p = p;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span>[] getArray() &#123;</span><br><span class="line">        <span class="keyword">return</span> array;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setArray</span><span class="params">(<span class="type">int</span>[] array)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.array = array;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Set&lt;String&gt; <span class="title function_">getSet</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> set;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setSet</span><span class="params">(Set&lt;String&gt; set)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.set = set;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Map&lt;String, String&gt; <span class="title function_">getMap</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> map;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setMap</span><span class="params">(Map&lt;String, String&gt; map)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.map = map;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></li><li><p>修改配置文件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">    # 集合类型数据注入</span></span><br><span class="line"><span class="comment">      1. properties标签的name属性指定的是UserServiceImpl5中对应的属性名</span></span><br><span class="line"><span class="comment">      2. properties的子标签</span></span><br><span class="line"><span class="comment">          1). list : 声明该属性是List类型</span></span><br><span class="line"><span class="comment">          2). props : 声明该属性是Properties类型</span></span><br><span class="line"><span class="comment">          3). array : 声明该属性是数组类型</span></span><br><span class="line"><span class="comment">          4). set : 声明该属性是Set类型</span></span><br><span class="line"><span class="comment">          5). map : 声明该属性是Map类型</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">     原理:</span></span><br><span class="line"><span class="comment">        clazz = Class.forName(&quot;com.itheima.service.impl.UserServiceImpl5&quot;)</span></span><br><span class="line"><span class="comment">        service = clazz.newInstance();</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">        setList = service.getMethod(&quot;setList&quot;,List.class);</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">        List list = new ArrayList();</span></span><br><span class="line"><span class="comment">        list.add(&quot;zs&quot;);</span></span><br><span class="line"><span class="comment">        list.add(&quot;ls&quot;);</span></span><br><span class="line"><span class="comment">        list.add(&quot;ww&quot;);</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">        setList.invoke(service,list);// service.setList(list)</span></span><br><span class="line"><span class="comment">     </span></span><br><span class="line"><span class="comment">  --&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userServiceImpl5&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.UserServiceImpl5&quot;</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;list&quot;</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">value</span>&gt;</span>zs<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">value</span>&gt;</span>ls<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">value</span>&gt;</span>ww<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;p&quot;</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">props</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">&quot;username&quot;</span>&gt;</span>admin<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">&quot;password&quot;</span>&gt;</span>123<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;/<span class="name">props</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;array&quot;</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">array</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">value</span>&gt;</span>100<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">value</span>&gt;</span>200<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;/<span class="name">array</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;set&quot;</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">set</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">value</span>&gt;</span>ml<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">value</span>&gt;</span>qq<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;map&quot;</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">map</span>&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">&quot;name&quot;</span> <span class="attr">value</span>=<span class="string">&quot;zhangsan&quot;</span>/&gt;</span></span><br><span class="line">               <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">&quot;age&quot;</span> <span class="attr">value</span>=<span class="string">&quot;18&quot;</span>/&gt;</span></span><br><span class="line">           <span class="tag">&lt;/<span class="name">map</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>修改测试类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test06</span><span class="params">()</span>&#123;</span><br><span class="line">       <span class="type">ApplicationContext</span> <span class="variable">ctx</span></span><br><span class="line">               <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">       <span class="type">UserService</span> <span class="variable">service</span> <span class="operator">=</span> (UserService) ctx.getBean(<span class="string">&quot;userServiceImpl5&quot;</span>);</span><br><span class="line">       service.save();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure></li></ol><p>运行结果</p><blockquote><p>UserServiceImpl5 save…<br>list-&gt;[zs, ls, ww]<br>true<br>properties-&gt;{password&#x3D;123, username&#x3D;admin}<br>array-&gt;[100, 200]<br>set-&gt;[ml, qq]<br>map-&gt;{name&#x3D;zhangsan, age&#x3D;18}</p></blockquote></li></ul><h3 id="4-9-SpEL"><a href="#4-9-SpEL" class="headerlink" title="4.9)SpEL"></a>4.9)SpEL</h3><blockquote><p>el : expression language 表达式语言</p><p>总体含义: 都是数据引用</p><p>JSP: el表达式 </p><p>mybatis : el表达式 </p><p>​#{} &#x2F; ${}</p><p>spring : el表达式</p><p>​#{} &#x2F; ${}</p><p>js : el表达式</p><p>​ <code>一共${money}元</code></p></blockquote><ul><li><p>Spring提供了对EL表达式的支持，统一属性注入格</p></li><li><p>类型：<strong>属性值</strong></p></li><li><p>归属：value属性值</p></li><li><p>作用：为bean注入属性值</p></li><li><p>格式：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">value</span>=<span class="string">&quot;EL&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># springEL表达式</span></span><br><span class="line"><span class="bullet">1.</span> $&#123;&#125;</span><br><span class="line"><span class="code">$&#123;&#125; 用于加载外部文件指定的Key值 (在下一节课的properties文件中演示)</span></span><br><span class="line"><span class="code">2. #&#123;&#125;</span></span><br><span class="line"><span class="code">#&#123;&#125; 强调的是把内容赋值给属性</span></span><br></pre></td></tr></table></figure></li><li><p>注意：所有属性值不区分是否引用类型，统一使用value赋值</p></li><li><p>所有格式统一使用  value&#x3D;“********”</p><ul><li><p>常量  #{10}  #{3.14}  #{2e5}  #{‘itcast’}</p></li><li><p>引用bean  #{beanId}    </p></li><li><p>引用bean属性  #{beanId.propertyName}</p></li><li><p>引用bean方法  beanId.methodName().method2()</p></li><li><p>引用静态方法  T(java.lang.Math).PI</p></li><li><p>运算符支持  #{3 lt 4 &#x3D;&#x3D; 4 ge 3}</p></li><li><p>正则表达式支持  #{user.name matches‘[a-z]{6,}’}</p></li><li><p>集合支持  #{likes[3]}</p></li></ul></li><li><p>代码演示：</p><p>修改核心配置文件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">       value属性: 指定基本类型数据 (8大基本类型+String)</span></span><br><span class="line"><span class="comment">       ref属性: 指定的引用类型</span></span><br><span class="line"><span class="comment">  </span></span><br><span class="line"><span class="comment">       springEL</span></span><br><span class="line"><span class="comment">       1. $&#123;表达式&#125;</span></span><br><span class="line"><span class="comment">           引入配置文件中的数据</span></span><br><span class="line"><span class="comment">       2. #&#123;表达式&#125;</span></span><br><span class="line"><span class="comment">           强调的是把内容赋值给属性</span></span><br><span class="line"><span class="comment">  </span></span><br><span class="line"><span class="comment">           #&#123;&#x27;字符串&#x27;&#125;</span></span><br><span class="line"><span class="comment">           #&#123;数字,boolean&#125;</span></span><br><span class="line"><span class="comment">           #&#123;变量名&#125;</span></span><br><span class="line"><span class="comment">   --&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;myDate&quot;</span> <span class="attr">class</span>=<span class="string">&quot;java.util.Date&quot;</span>/&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.UserDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.UserServiceImpl2&quot;</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!-- &lt;property name=&quot;name&quot; value=&quot;zs&quot;/&gt;</span></span><br><span class="line"><span class="comment">      &lt;property name=&quot;age&quot; value=&quot;18&quot;/&gt;</span></span><br><span class="line"><span class="comment">      &lt;property name=&quot;date&quot; ref=&quot;myDate&quot;/&gt;</span></span><br><span class="line"><span class="comment">      &lt;property name=&quot;dao&quot; ref=&quot;userDao&quot;/&gt;--&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;name&quot;</span> <span class="attr">value</span>=<span class="string">&quot;#&#123;&#x27;ls&#x27;&#125;&quot;</span>/&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;age&quot;</span> <span class="attr">value</span>=<span class="string">&quot;#&#123;18&#125;&quot;</span>/&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;date&quot;</span> <span class="attr">value</span>=<span class="string">&quot;#&#123;myDate&#125;&quot;</span>/&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dao&quot;</span> <span class="attr">value</span>=<span class="string">&quot;#&#123;userDao&#125;&quot;</span>/&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li></ul><h3 id="4-10-properties文件"><a href="#4-10-properties文件" class="headerlink" title="4.10)properties文件"></a>4.10)properties文件</h3><ul><li><p>Spring提供了读取外部properties文件的机制，使用读取到的数据为bean的属性赋值</p></li><li><p>操作步骤</p><p>1.准备外部properties文件</p><p>2.开启context命名空间支持</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">xmlns:context=&quot;http://www.springframework.org/schema/context&quot;</span><br></pre></td></tr></table></figure></li></ul><p>​3.加载指定的properties文件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">context:property-placeholder</span> <span class="attr">location</span>=<span class="string">&quot;classpath:filename.properties&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure><p>​4.使用加载的数据</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;propertyName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;propertiesName&#125;&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure><ul><li><p>注意：如果需要加载所有的properties文件，可以使用<code>*.properties</code>表示加载所有的properties文件</p></li><li><p>注意：读取数据使用**${propertiesName}<strong>格式进行，其中</strong>propertiesName**指properties文件中的属性名</p></li></ul><p>测试代码：</p><ol><li><p>新增一个配置文件</p><p><img src="https://js.hnlyx.top/img/1609835447865.png" alt="1609835447865"></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//1. 声明需要注入的资源,并声明对应的set方法</span></span><br><span class="line">    String name;</span><br><span class="line">    <span class="type">int</span> age;</span><br><span class="line"></span><br><span class="line">    UserDao userDao;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setName</span><span class="params">(String name)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setAge</span><span class="params">(<span class="type">int</span> age)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.age = age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setUserDao</span><span class="params">(UserDao userDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.userDao = userDao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;UserServiceImpl run:&quot;</span> + name + <span class="string">&quot;,&quot;</span> + age);</span><br><span class="line">        userDao.find();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></li><li><p>配置文件修改</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">    1. schema约束新增: 开启context命名空间支持</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">        xmlns:context=&quot;http://www.springframework.org/schema/context&quot;</span></span><br><span class="line"><span class="comment">        xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans</span></span><br><span class="line"><span class="comment">        https://www.springframework.org/schema/beans/spring-beans.xsd</span></span><br><span class="line"><span class="comment">        http://www.springframework.org/schema/context</span></span><br><span class="line"><span class="comment">        https://www.springframework.org/schema/context/spring-context.xsd&quot;</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:context</span>=<span class="string">&quot;http://www.springframework.org/schema/context&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="string"><span class="tag">        https://www.springframework.org/schema/beans/spring-beans.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">        http://www.springframework.org/schema/context</span></span></span><br><span class="line"><span class="string"><span class="tag">        https://www.springframework.org/schema/context/spring-context.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">        &quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--2. 加载指定的properties文件--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:property-placeholder</span> <span class="attr">location</span>=<span class="string">&quot;classpath:data.properties&quot;</span>/&gt;</span></span><br><span class="line">    </span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.ioc.dao.impl.UserDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">        3. 使用加载的数据</span></span><br><span class="line"><span class="comment">            $&#123;外部文件中的key&#125;</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.ioc.service.impl.UserServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;userDao&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;name&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;name&#125;&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;age&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;age&#125;&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>测试类修改</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserTest</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test01</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="comment">//2.加载配置文件</span></span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="comment">//3.获取资源: 通过配置文件中的id</span></span><br><span class="line">        <span class="type">UserService</span> <span class="variable">userService</span> <span class="operator">=</span> (UserService) ctx.getBean(<span class="string">&quot;userService&quot;</span>);</span><br><span class="line">        userService.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>打印结果:</p><blockquote><p>UserServiceImpl run:zs,20<br>UserDao find…</p></blockquote></li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;h3 id=&quot;IoC&quot;&gt;&lt;a href=&quot;#IoC&quot; class=&quot;headerlink&quot; title=&quot;IoC&quot;&gt;&lt;/a&gt;IoC&lt;/h3&gt;&lt;figure class=&quot;highlight markdown&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre</summary>
      
    
    
    
    
    <category term="Spring" scheme="https://www.yxliu.cc/tags/Spring/"/>
    
  </entry>
  
  <entry>
    <title>Java 反射应用</title>
    <link href="https://www.yxliu.cc/2022/12/14/52dd996.html"/>
    <id>https://www.yxliu.cc/2022/12/14/52dd996.html</id>
    <published>2022-12-14T11:58:12.000Z</published>
    <updated>2026-02-04T06:42:44.027Z</updated>
    
    <content type="html"><![CDATA[<hr><h2 id="反射调用类中的方法"><a href="#反射调用类中的方法" class="headerlink" title="反射调用类中的方法"></a>反射调用类中的方法</h2><h3 id="不使用过多if判断"><a href="#不使用过多if判断" class="headerlink" title="不使用过多if判断"></a>不使用过多if判断</h3><h4 id="【1】分析："><a href="#【1】分析：" class="headerlink" title="【1】分析："></a>【1】分析：</h4><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">我们上述根据url获取方法名，然后根据方法名是否相等进行if条件的判断。</span><br><span class="line">我们这里可以在当前用户模块无论有多少个需求都只需要书写一套模板代码，使用所有的当前用户模块的需求。</span><br><span class="line"></span><br><span class="line">我们可以使用反射思想，根据获取的页面中的方法名来执行具体的方法，不用再判断了。</span><br><span class="line"></span><br></pre></td></tr></table></figure><h4 id="【2】步骤："><a href="#【2】步骤：" class="headerlink" title="【2】步骤："></a>【2】步骤：</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span>获取要执行的方法所属类的Class对象</span><br><span class="line"><span class="number">2.</span>使用Class对象调用Class类中的方法获取要执行的方法：</span><br><span class="line">     Method <span class="title function_">getMethod</span><span class="params">(String name, Class&lt;?&gt;... parameterTypes)</span>  </span><br><span class="line">    参数：</span><br><span class="line">    name：方法名----根据url获取的方法名</span><br><span class="line">    parameterTypes：要执行方法的参数类型 request  response</span><br><span class="line">    </span><br><span class="line"><span class="number">3.</span>使用Method对象调用Method类中的invoke方法：</span><br><span class="line">     Object <span class="title function_">invoke</span><span class="params">(Object obj, Object... args)</span>  对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。</span><br><span class="line">    参数：</span><br><span class="line">    obj:要执行方法的对象，例如find,这里传递find所属类的对象</span><br><span class="line">                    args：要执行方法的实参。request  response</span><br></pre></td></tr></table></figure><h4 id="【3】代码实现"><a href="#【3】代码实现" class="headerlink" title="【3】代码实现"></a>【3】代码实现</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="meta">@WebServlet(&quot;/user/*&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">User2Servlet</span> <span class="keyword">extends</span> <span class="title class_">HttpServlet</span> &#123;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">void</span> <span class="title function_">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException &#123;</span><br><span class="line">        doGet(request, response);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">void</span> <span class="title function_">doGet</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException &#123;</span><br><span class="line">        <span class="comment">//1.获取请求的方法名</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> request.getRequestURI();<span class="comment">//  &quot;/user/find&quot;</span></span><br><span class="line">        <span class="comment">//获取最后一个/出现的索引</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">lastIndex</span> <span class="operator">=</span> url.lastIndexOf(<span class="string">&#x27;/&#x27;</span>);</span><br><span class="line">        <span class="comment">//从指定索引位置截取到末尾</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">methodName</span> <span class="operator">=</span> url.substring(lastIndex + <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//3.判断当前url的路径请求的是哪个方法</span></span><br><span class="line">       <span class="comment">/* if (&quot;find&quot;.equals(methodName)) &#123;</span></span><br><span class="line"><span class="comment">            //执行查询所有用户的方法</span></span><br><span class="line"><span class="comment">            find(request, response);</span></span><br><span class="line"><span class="comment">        &#125; else if (&quot;update&quot;.equals(methodName)) &#123;</span></span><br><span class="line"><span class="comment">            //执行根据id更新用户的方法</span></span><br><span class="line"><span class="comment">            update(request, response);</span></span><br><span class="line"><span class="comment">        &#125; else if (&quot;add&quot;.equals(methodName)) &#123;</span></span><br><span class="line"><span class="comment">            //执行添加用户的方法</span></span><br><span class="line"><span class="comment">            add(request, response);</span></span><br><span class="line"><span class="comment">        &#125; else if (&quot;delete&quot;.equals(methodName)) &#123;</span></span><br><span class="line"><span class="comment">            //执行根据id删除用户的方法</span></span><br><span class="line"><span class="comment">            delete(request, response);</span></span><br><span class="line"><span class="comment">        &#125;*/</span></span><br><span class="line"><span class="comment">////////////////////////////使用反射执行方法，简化if语句////////////////////////////////////////</span></span><br><span class="line">        <span class="comment">//1.获取要执行的方法所属类的Class对象</span></span><br><span class="line">        <span class="comment">//this表示当前类的对象</span></span><br><span class="line">        <span class="type">Class</span> <span class="variable">clazz</span> <span class="operator">=</span> <span class="built_in">this</span>.getClass();</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">            2.使用Class对象调用Class类中的方法获取要执行的方法：</span></span><br><span class="line"><span class="comment">             Method getMethod(String name, Class&lt;?&gt;... parameterTypes)</span></span><br><span class="line"><span class="comment">                参数：</span></span><br><span class="line"><span class="comment">                    name：方法名----根据url的key获取value即方法名</span></span><br><span class="line"><span class="comment">                    parameterTypes：要执行方法的参数类型 request  response</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Method</span> <span class="variable">m</span> <span class="operator">=</span> clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);</span><br><span class="line"></span><br><span class="line">            <span class="comment">/*</span></span><br><span class="line"><span class="comment">                3.使用Method对象调用Method类中的invoke方法：</span></span><br><span class="line"><span class="comment">                 Object invoke(Object obj, Object... args)  对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。</span></span><br><span class="line"><span class="comment">                        参数：</span></span><br><span class="line"><span class="comment">                            obj:要执行方法的对象，例如findAllUsers,这里传递findAllUsers所属类的对象</span></span><br><span class="line"><span class="comment">                            args：要执行方法的实参。request  response</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            m.invoke(<span class="built_in">this</span>,request,response);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//4.在servlet中创建增删改查的四个方法</span></span><br><span class="line">    <span class="comment">//5.在不同的方法体中完成代码</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">delete</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;根据id删除用户&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;添加用户&quot;</span>);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">update</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;根据id更新用户&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">find</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;查询所有用户&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>小结：</p><p>1.我们这里使用反射思想取代了书写过多if的判断语句，简化代码开发</p><p>2.反射执行方法步骤：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span>获取要执行的方法所属类的Class对象</span><br><span class="line"><span class="number">2.</span>使用Class对象调用方法：getMethod(方法名,方法形参类型的Class对象)</span><br><span class="line"><span class="number">3.</span>使用获取Method对象调用Method类中的invoke(执行方法依赖的对象,执行方法的实参)</span><br></pre></td></tr></table></figure><h3 id="减少代码重复性，不仅仅使用在用户模块。所有模块都可以使用"><a href="#减少代码重复性，不仅仅使用在用户模块。所有模块都可以使用" class="headerlink" title="减少代码重复性，不仅仅使用在用户模块。所有模块都可以使用"></a>减少代码重复性，不仅仅使用在用户模块。所有模块都可以使用</h3><p>BaseServlet:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.case2.web;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.servlet.ServletException;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.annotation.WebServlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Method;</span><br><span class="line"></span><br><span class="line"><span class="comment">//@WebServlet(&quot;/BaseServlet&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BaseServlet</span> <span class="keyword">extends</span> <span class="title class_">HttpServlet</span> &#123;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">void</span> <span class="title function_">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException &#123;</span><br><span class="line">        doGet(request, response);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">void</span> <span class="title function_">doGet</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException &#123;</span><br><span class="line">       <span class="comment">//1.获取请求的方法名</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> request.getRequestURI();<span class="comment">//  &quot;/user/find&quot;</span></span><br><span class="line">        <span class="comment">//获取最后一个/出现的索引</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">lastIndex</span> <span class="operator">=</span> url.lastIndexOf(<span class="string">&#x27;/&#x27;</span>);</span><br><span class="line">        <span class="comment">//从指定索引位置截取到末尾</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">methodName</span> <span class="operator">=</span> url.substring(lastIndex + <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">////////////////////////////使用反射执行方法，简化if语句////////////////////////////////////////</span></span><br><span class="line">        <span class="comment">//1.获取要执行的方法所属类的Class对象</span></span><br><span class="line">        <span class="comment">//this表示子类的对象</span></span><br><span class="line">        <span class="type">Class</span> <span class="variable">clazz</span> <span class="operator">=</span> <span class="built_in">this</span>.getClass();</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">            2.使用Class对象调用Class类中的方法获取要执行的方法：</span></span><br><span class="line"><span class="comment">             Method getMethod(String name, Class&lt;?&gt;... parameterTypes)</span></span><br><span class="line"><span class="comment">                参数：</span></span><br><span class="line"><span class="comment">                    name：方法名----根据url的key获取value即方法名</span></span><br><span class="line"><span class="comment">                    parameterTypes：要执行方法的参数类型 request  response</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Method</span> <span class="variable">m</span> <span class="operator">=</span> clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);</span><br><span class="line"></span><br><span class="line">            <span class="comment">/*</span></span><br><span class="line"><span class="comment">                3.使用Method对象调用Method类中的invoke方法：</span></span><br><span class="line"><span class="comment">                 Object invoke(Object obj, Object... args)  对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。</span></span><br><span class="line"><span class="comment">                        参数：</span></span><br><span class="line"><span class="comment">                            obj:要执行方法的对象，例如findAllUsers,这里传递findAllUsers所属类的对象</span></span><br><span class="line"><span class="comment">                            args：要执行方法的实参。request  response</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            m.invoke(<span class="built_in">this</span>,request,response);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>UserServlet:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.case2.web;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.servlet.ServletException;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.annotation.WebServlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Method;</span><br><span class="line"></span><br><span class="line"><span class="comment">//用户模块</span></span><br><span class="line"><span class="meta">@WebServlet(&quot;/user/*&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">User2Servlet</span> <span class="keyword">extends</span> <span class="title class_">BaseServlet</span> &#123;</span><br><span class="line">    <span class="comment">//4.在servlet中创建增删改查的四个方法</span></span><br><span class="line">    <span class="comment">//5.在不同的方法体中完成代码</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">deleteUserById</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;根据id删除用户&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addUser</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;添加用户&quot;</span>);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">updateUserById</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;根据id更新用户&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">findAllUsers</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;查询所有用户&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="小结："><a href="#小结：" class="headerlink" title="小结："></a>小结：</h2><p>1.我们将反射执行的方法代码放到父类BaseServlet中,然后使用其他模块的servlet直接继承BaseServlet即可</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">url访问路径：</span><br><span class="line">    http:<span class="comment">//localhost:8080/user/find</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;hr&gt;
&lt;h2 id=&quot;反射调用类中的方法&quot;&gt;&lt;a href=&quot;#反射调用类中的方法&quot; class=&quot;headerlink&quot; title=&quot;反射调用类中的方法&quot;&gt;&lt;/a&gt;反射调用类中的方法&lt;/h2&gt;&lt;h3 id=&quot;不使用过多if判断&quot;&gt;&lt;a href=&quot;#不使用过多if判断&quot; </summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>Vue 学习</title>
    <link href="https://www.yxliu.cc/2022/12/07/5106d60a.html"/>
    <id>https://www.yxliu.cc/2022/12/07/5106d60a.html</id>
    <published>2022-12-07T11:58:27.000Z</published>
    <updated>2026-02-04T06:42:44.030Z</updated>
    
    <content type="html"><![CDATA[<h1 id="学习目标"><a href="#学习目标" class="headerlink" title="学习目标"></a>学习目标</h1><ul><li>会创建 Vue 实例，知道 Vue 的常见属性</li><li>会使用 Vue 的生命周期的钩子函数</li><li>会使用 vue 常见指令</li><li>会使用 vue 计算属性和 watch 监控</li><li>会编写 Vue 组件</li><li>掌握组件间通信</li><li>了解 vue-router 使用</li><li>了解 webpack 使用</li><li>会使用 vue-cli 搭建项目</li></ul><h1 id="0-前言"><a href="#0-前言" class="headerlink" title="0.前言"></a>0.前言</h1><p>前几天我们已经对后端的技术栈有了初步的了解、并且已经搭建了整个后端微服务的平台。接下来要做的事情就是功能开发了。但是没有前端页面，我们肯定无从下手，因此今天我们就要来了解一下前端的一些技术，完成前端页面搭建。</p><p>先聊一下前端开发模式的发展。</p><blockquote><p>静态页面</p></blockquote><p>最初的网页以 HTML 为主，是纯静态的网页。网页是只读的，信息流只能从服务端到客户端单向流通。<strong>开发人员也只关心页面的样式和内容</strong>即可。</p><blockquote><p>异步刷新，操作 DOM</p></blockquote><p>1995 年，网景工程师 Brendan Eich 花了 10 天时间设计了 JavaScript 语言.</p><p>随着 JavaScript 的诞生，我们可以操作页面的 DOM 元素及样式，页面有了一些动态的效果，但是依然是以静态为主。</p><p>ajax 盛行：</p><ul><li>2005 年开始，ajax 逐渐被前端开发人员所重视，因为不用刷新页面就可以更新页面的数据和渲染效果。</li><li>此时的<strong>开发人员不仅仅要编写 HTML 样式，还要懂 ajax 与后端交互，然后通过 JS 操作 Dom 元素来实现页面动态效果</strong>。比较流行的框架如 Jquery 就是典型代表。</li></ul><blockquote><p>MVVM，关注模型和视图</p></blockquote><p>2008 年，google 的 Chrome 发布，随后就以极快的速度占领市场，超过 IE 成为浏览器市场的主导者。</p><p>2009 年，Ryan Dahl 在谷歌的 Chrome V8 引擎基础上，打造了基于事件循环的异步 IO 框架：Node.js。</p><ul><li>基于事件循环的异步 IO</li><li>单线程运行，避免多线程的变量同步问题</li><li>JS 可以编写后台代码，前后台统一编程语言</li></ul><p>node.js 的伟大之处不在于让 JS 迈向了后端开发，而是构建了一个庞大的生态系统。</p><p>2010 年，NPM 作为 node.js 的包管理系统首次发布，开发人员可以遵循 Common.js 规范来编写 Node.js 模块，然后发布到 NPM 上供其他开发人员使用。目前已经是世界最大的包模块管理系统。</p><p>随后，在 node 的基础上，涌现出了一大批的前端框架：</p><p><img src="https://js.hnlyx.top/img/1525825983230.png" alt="1525825983230"></p><blockquote><p>MVVM 模式</p></blockquote><ul><li>M：即 Model，模型，包括数据和一些基本操作</li><li>V：即 View，视图，页面渲染结果</li><li>VM：即 View-Model，模型与视图间的双向操作（无需开发人员干涉）</li></ul><p>在 MVVM 之前，开发人员从后端获取需要的数据模型，然后要通过 DOM 操作 Model 渲染到 View 中。而后当用户操作视图，我们还需要通过 DOM 获取 View 中的数据，然后同步到 Model 中。</p><p>而 MVVM 中的 VM 要做的事情就是把 DOM 操作完全封装起来，开发人员不用再关心 Model 和 View 之间是如何互相影响的：</p><ul><li>只要我们 Model 发生了改变，View 上自然就会表现出来。</li><li>当用户修改了 View，Model 中的数据也会跟着改变。</li></ul><p>把开发人员从繁琐的 DOM 操作中解放出来，把关注点放在如何操作 Model 上。</p><p><img src="https://js.hnlyx.top/img/1525828854056.png" alt="1525828854056"></p><p>而我们今天要学习的，就是一款 MVVM 模式的框架：Vue</p><h1 id="1-认识-Vue"><a href="#1-认识-Vue" class="headerlink" title="1.认识 Vue"></a>1.认识 Vue</h1><p>Vue (读音 &#x2F;vjuː&#x2F;，类似于 <strong>view</strong>) 是一套用于构建用户界面的<strong>渐进式框架</strong>。与其它大型框架不同的是，Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层，不仅易于上手，还便于与第三方库或既有项目整合。另一方面，当与<a href="https://cn.vuejs.org/v2/guide/single-file-components.html">现代化的工具链</a>以及各种<a href="https://github.com/vuejs/awesome-vue#libraries--plugins">支持类库</a>结合使用时，Vue 也完全能够为复杂的单页应用提供驱动。</p><p> 前端框架三巨头：Vue.js、React.js、AngularJS，vue.js 以其轻量易用著称，vue.js 和 React.js 发展速度最快，AngularJS 还是老大。</p><p>官网：<a href="https://cn.vuejs.org/">https://cn.vuejs.org/</a></p><p>参考：<a href="https://cn.vuejs.org/v2/guide/">https://cn.vuejs.org/v2/guide/</a></p><p><img src="https://js.hnlyx.top/img/1525829249048.png" alt="1525829249048"></p><p>Git 地址：<a href="https://github.com/vuejs">https://github.com/vuejs</a></p><p><img src="https://js.hnlyx.top/img/1525829030730.png" alt="1525829030730"></p><p><strong>尤雨溪</strong>，Vue.js 创作者，Vue Technology 创始人，致力于 Vue 的研究开发。</p><h1 id="2-Node-和-NPM"><a href="#2-Node-和-NPM" class="headerlink" title="2.Node 和 NPM"></a>2.Node 和 NPM</h1><p>前面说过，NPM 是 Node 提供的模块管理工具，可以非常方便的下载安装很多前端框架，包括 Jquery、AngularJS、VueJs 都有。为了后面学习方便，我们先安装 node 及 NPM 工具。</p><h2 id="2-1-下载-Node-js"><a href="#2-1-下载-Node-js" class="headerlink" title="2.1.下载 Node.js"></a>2.1.下载 Node.js</h2><p>下载地址：<a href="https://nodejs.org/en/">https://nodejs.org/en/</a></p><p><img src="https://js.hnlyx.top/img/1529594451775.png" alt="1529594451775"></p><p>推荐下载 LTS 版本。</p><p>课程中采用的是 8.11.3 版本。也是目前最新的。大家自行下载或者使用课前资料中提供的安装包。然后下一步安装即可。</p><p>完成以后，在控制台输入：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node <span class="literal">-v</span></span><br></pre></td></tr></table></figure><p>看到版本信息：</p><p><img src="/assets/1529595770482.png" alt="1529595770482"></p><h2 id="2-2-NPM"><a href="#2-2-NPM" class="headerlink" title="2.2.NPM"></a>2.2.NPM</h2><p>Node 自带了 NPM 了，在控制台输入<code>npm -v</code>查看：</p><p><img src="https://js.hnlyx.top/img/1529595810923.png" alt="1529595810923"></p><p>npm 默认的仓库地址是在国外网站，速度较慢，建议大家设置到淘宝镜像。但是切换镜像是比较麻烦的。推荐一款切换镜像的工具：nrm</p><p>我们首先安装 nrm，这里<code>-g</code>代表全局安装。可能需要一点儿时间</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install nrm -g</span><br></pre></td></tr></table></figure><p><img src="https://js.hnlyx.top/img/1529596099952.png" alt="1529596099952"></p><p>然后通过<code>nrm ls</code>命令查看 npm 的仓库列表,带*的就是当前选中的镜像仓库：</p><p><img src="https://js.hnlyx.top/img/1529596219439.png" alt="1529596219439"></p><p>通过<code>nrm use taobao</code>来指定要使用的镜像源：</p><p><img src="https://js.hnlyx.top/img/1529596312671.png" alt="1529596312671"></p><p>然后通过<code>nrm test npm </code>来测试速度：</p><p><img src="https://js.hnlyx.top/img/1529596566134.png" alt="1529596566134"></p><p>注意：</p><ul><li>有教程推荐大家使用 cnpm 命令，但是使用发现 cnpm 有时会有 bug，不推荐。</li><li>安装完成请一定要重启下电脑！！！</li><li>安装完成请一定要重启下电脑！！！</li><li>安装完成请一定要重启下电脑！！！</li></ul><h1 id="3-快速入门"><a href="#3-快速入门" class="headerlink" title="3.快速入门"></a>3.快速入门</h1><p>接下来，我们快速领略下 vue 的魅力</p><h2 id="3-1-创建工程"><a href="#3-1-创建工程" class="headerlink" title="3.1.创建工程"></a>3.1.创建工程</h2><p>创建一个新的空工程：</p><p><img src="https://js.hnlyx.top/img/1529596874127.png" alt="1529596874127"></p><p><img src="https://js.hnlyx.top/img/1529597228506.png" alt="1529597228506"></p><p>然后新建一个 module：</p><p><img src="https://js.hnlyx.top/img/1529597325121.png" alt="1529597325121"></p><p>选中 static web，静态 web 项目：</p><p><img src="https://js.hnlyx.top/img/1529597573453.png" alt="1529597573453"></p><p>位置信息：</p><p><img src="https://js.hnlyx.top/img/1529597672429.png" alt="1529597672429"></p><h2 id="3-2-安装-vue"><a href="#3-2-安装-vue" class="headerlink" title="3.2.安装 vue"></a>3.2.安装 vue</h2><h3 id="3-2-1-下载安装"><a href="#3-2-1-下载安装" class="headerlink" title="3.2.1.下载安装"></a>3.2.1.下载安装</h3><p>下载地址：<a href="https://github.com/vuejs/vue">https://github.com/vuejs/vue</a></p><p>可以下载 2.5.16 版本<a href="https://github.com/vuejs/vue/archive/v2.5.16.zip">https://github.com/vuejs/vue/archive/v2.5.16.zip</a></p><p>下载解压，得到 vue.js 文件。</p><h3 id="3-2-2-使用-CDN"><a href="#3-2-2-使用-CDN" class="headerlink" title="3.2.2.使用 CDN"></a>3.2.2.使用 CDN</h3><p>或者也可以直接使用公共的 CDN 服务：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 开发环境版本，包含了用帮助的命令行警告 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.jsdelivr.net/npm/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>或者：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 生产环境版本，优化了尺寸和速度 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.jsdelivr.net/npm/vue&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="3-2-3-推荐-npm-安装"><a href="#3-2-3-推荐-npm-安装" class="headerlink" title="3.2.3.推荐 npm 安装"></a>3.2.3.推荐 npm 安装</h3><p>在 idea 的左下角，有个 Terminal 按钮，点击打开控制台：</p><p><img src="https://js.hnlyx.top/img/1529598030268.png" alt="1529598030268"></p><p>进入 hello-vue 目录，先输入：<code>npm init -y</code> 进行初始化</p><p><img src="https://js.hnlyx.top/img/1529598244471.png" alt="1529598244471"></p><p>安装 Vue，输入命令：<code>npm install vue --save</code></p><p><img src="https://js.hnlyx.top/img/1529598444504.png" alt="1529598444504"></p><p>然后就会在 hello-vue 目录发现一个 node_modules 目录，并且在下面有一个 vue 目录。</p><p><img src="https://js.hnlyx.top/img/1529602488684.png" alt="1529602488684"></p><p>node_modules 是通过 npm 安装的所有模块的默认位置。</p><h2 id="3-3-vue-入门案例"><a href="#3-3-vue-入门案例" class="headerlink" title="3.3.vue 入门案例"></a>3.3.vue 入门案例</h2><h3 id="3-3-1-HTML-模板"><a href="#3-3-1-HTML-模板" class="headerlink" title="3.3.1.HTML 模板"></a>3.3.1.HTML 模板</h3><p>在 hello-vue 目录新建一个 HTML</p><p><img src="https://js.hnlyx.top/img/1529719572523.png" alt="1529719572523"></p><p>在 hello.html 中，我们编写一段简单的代码：</p><p><img src="https://js.hnlyx.top/img/1529719673944.png" alt="1529719673944"></p><p>h2 中要输出一句话：xx 非常帅。前面的 xx 是要渲染的数据。</p><h3 id="3-3-2-vue-声明式渲染"><a href="#3-3-2-vue-声明式渲染" class="headerlink" title="3.3.2.vue 声明式渲染"></a>3.3.2.vue 声明式渲染</h3><p>然后我们通过 Vue 进行渲染：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h2</span>&gt;</span>&#123;&#123;name&#125;&#125;，非常帅！！！<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="comment">// 创建vue实例</span></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>, <span class="comment">// el即element，该vue实例要渲染的页面元素</span></span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="comment">// 渲染页面需要的数据</span></span></span><br><span class="line"><span class="language-javascript">      <span class="attr">name</span>: <span class="string">&quot;峰哥&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li>首先通过 new Vue()来创建 Vue 实例</li><li>然后构造函数接收一个对象，对象中有一些属性：<ul><li>el：是 element 的缩写，通过 id 选中要渲染的页面元素，本例中是一个 div</li><li>data：数据，数据是一个对象，里面有很多属性，都可以渲染到视图中<ul><li>name：这里我们指定了一个 name 属性</li></ul></li></ul></li><li>页面中的<code>h2</code>元素中，我们通过的方式，来渲染刚刚定义的 name 属性。</li></ul><p>打开页面查看效果：</p><p><img src="https://js.hnlyx.top/img/1529722898366.png" alt="1529722898366"></p><p>更神奇的在于，当你修改 name 属性时，页面会跟着变化：</p><p><img src="https://js.hnlyx.top/img/1529723206508.png" alt="1529723206508"></p><h3 id="3-3-3-双向绑定"><a href="#3-3-3-双向绑定" class="headerlink" title="3.3.3.双向绑定"></a>3.3.3.双向绑定</h3><p>我们对刚才的案例进行简单修改：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;num&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h2</span>&gt;</span>&#123;&#123;name&#125;&#125;，非常帅！！！有&#123;&#123;num&#125;&#125;位女神为他着迷。<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="comment">// 创建vue实例</span></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>, <span class="comment">// el即element，该vue实例要渲染的页面元素</span></span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="comment">// 渲染页面需要的数据</span></span></span><br><span class="line"><span class="language-javascript">      <span class="attr">name</span>: <span class="string">&quot;峰哥&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">num</span>: <span class="number">5</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li>我们在 data 添加了新的属性：<code>num</code></li><li>在页面中有一个<code>input</code>元素，通过<code>v-model</code>与<code>num</code>进行绑定。</li><li>同时通过<code>&#123;&#123;num&#125;&#125;</code>在页面输出</li></ul><p>效果：</p><p><img src="https://js.hnlyx.top/img/52.gif" alt="1529723206508"></p><p>我们可以观察到，输入框的变化引起了 data 中的 num 的变化，同时页面输出也跟着变化。</p><ul><li>input 与 num 绑定，input 的 value 值变化，影响到了 data 中的 num 值</li><li>页面<code>&#123;&#123;num&#125;&#125;</code>与数据 num 绑定，因此 num 值变化，引起了页面效果变化。</li></ul><p>没有任何 dom 操作，这就是双向绑定的魅力。</p><h3 id="3-3-4-事件处理"><a href="#3-3-4-事件处理" class="headerlink" title="3.3.4.事件处理"></a>3.3.4.事件处理</h3><p>我们在页面添加一个按钮：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">&quot;num++&quot;</span>&gt;</span>点我<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li>这里用<code>v-on</code>指令绑定点击事件，而不是普通的<code>onclick</code>，然后直接操作 num</li><li>普通 click 是无法直接操作 num 的。</li></ul><p>效果：</p><p><img src="https://js.hnlyx.top/img/53.gif"></p><h1 id="4-Vue-实例"><a href="#4-Vue-实例" class="headerlink" title="4.Vue 实例"></a>4.Vue 实例</h1><h2 id="4-1-创建-Vue-实例"><a href="#4-1-创建-Vue-实例" class="headerlink" title="4.1.创建 Vue 实例"></a>4.1.创建 Vue 实例</h2><p>每个 Vue 应用都是通过用 <code>Vue</code> 函数创建一个新的 <strong>Vue 实例</strong>开始的：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="comment">// 选项</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>在构造函数中传入一个对象，并且在对象中声明各种 Vue 需要的数据和方法，包括：</p><ul><li>el</li><li>data</li><li>methods</li></ul><p>等等</p><p>接下来我们一 一介绍。</p><h2 id="4-2-模板或元素"><a href="#4-2-模板或元素" class="headerlink" title="4.2.模板或元素"></a>4.2.模板或元素</h2><p>每个 Vue 实例都需要关联一段 Html 模板，Vue 会基于此模板进行视图渲染。</p><p>我们可以通过 el 属性来指定。</p><p>例如一段 html 模板：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>然后创建 Vue 实例，关联这个 div</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>这样，Vue 就可以基于 id 为<code>app</code>的 div 元素作为模板进行渲染了。在这个 div 范围以外的部分是无法使用 vue 特性的。</p><h2 id="4-3-数据"><a href="#4-3-数据" class="headerlink" title="4.3.数据"></a>4.3.数据</h2><p>当 Vue 实例被创建时，它会尝试获取在 data 中定义的所有属性，用于视图的渲染，并且监视 data 中的属性变化，当 data 发生改变，所有相关的视图都将重新渲染，这就是“响应式“系统。</p><p>html：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;name&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>js:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">data</span>: &#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&quot;刘德华&quot;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><ul><li>name 的变化会影响到<code>input</code>的值</li><li>input 中输入的值，也会导致 vm 中的 name 发生改变</li></ul><h2 id="4-4-方法"><a href="#4-4-方法" class="headerlink" title="4.4.方法"></a>4.4.方法</h2><p>Vue 实例中除了可以定义 data 属性，也可以定义方法，并且在 Vue 实例的作用范围内使用。</p><p>html:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  &#123;&#123;num&#125;&#125;</span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">&quot;add&quot;</span>&gt;</span>加<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>js:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">data</span>: &#123;</span><br><span class="line">    <span class="attr">num</span>: <span class="number">0</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">methods</span>: &#123;</span><br><span class="line">    <span class="attr">add</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">      <span class="comment">// this代表的当前vue实例</span></span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">num</span>++;</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h2 id="4-5-生命周期钩子"><a href="#4-5-生命周期钩子" class="headerlink" title="4.5.生命周期钩子"></a>4.5.生命周期钩子</h2><h3 id="4-5-1-生命周期"><a href="#4-5-1-生命周期" class="headerlink" title="4.5.1.生命周期"></a>4.5.1.生命周期</h3><p>每个 Vue 实例在被创建时都要经过一系列的初始化过程 ：创建实例，装载模板，渲染模板等等。Vue 为生命周期中的每个状态都设置了钩子函数（监听函数）。每当 Vue 实例处于不同的生命周期时，对应的函数就会被触发调用。</p><p>生命周期：</p><p><img src="https://js.hnlyx.top/img/lifecycle.png" alt="Vue life cycle"></p><h3 id="4-5-2-钩子函数"><a href="#4-5-2-钩子函数" class="headerlink" title="4.5.2.钩子函数"></a>4.5.2.钩子函数</h3><p>beforeCreated：我们在用 Vue 时都要进行实例化，因此，该函数就是在 Vue 实例化是调用，也可以将他理解为初始化函数比较方便一点，在 Vue1.0 时，这个函数的名字就是 init。</p><p>created：在创建实例之后进行调用。</p><p>beforeMount：页面加载完成，没有渲染。如：此时页面还是</p><p>mounted：我们可以将他理解为原生 js 中的 window.onload&#x3D;function({.,.}),或许大家也在用 jquery，所以也可以理解为 jquery 中的$(document).ready(function(){….})，他的功能就是：在 dom 文档渲染完毕之后将要执行的函数，该函数在 Vue1.0 版本中名字为 compiled。 此时页面中的已被渲染成峰哥</p><p>beforeDestroy：该函数将在销毁实例前进行调用 。</p><p>destroyed：改函数将在销毁实例时进行调用。</p><p>beforeUpdate：组件更新之前。</p><p>updated：组件更新之后。</p><p>例如：created 代表在 vue 实例创建后；</p><p>我们可以在 Vue 中定义一个 created 函数，代表这个时期的钩子函数：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建vue实例</span></span><br><span class="line"><span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>, <span class="comment">// el即element，该vue实例要渲染的页面元素</span></span><br><span class="line">  <span class="attr">data</span>: &#123;</span><br><span class="line">    <span class="comment">// 渲染页面需要的数据</span></span><br><span class="line">    <span class="attr">name</span>: <span class="string">&quot;峰哥&quot;</span>,</span><br><span class="line">    <span class="attr">num</span>: <span class="number">5</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">methods</span>: &#123;</span><br><span class="line">    <span class="attr">add</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">num</span>--;</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">created</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">num</span> = <span class="number">100</span>;</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>结果：</p><p><img src="https://js.hnlyx.top/img/1529835200236.png" alt="1529835200236"></p><h3 id="4-5-3-this"><a href="#4-5-3-this" class="headerlink" title="4.5.3.this"></a>4.5.3.this</h3><p>我们可以看下在 vue 内部的 this 变量是谁，我们在 created 的时候，打印 this</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">methods</span>: &#123;</span><br><span class="line">    <span class="attr">add</span>: <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">num</span>--;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure><p>控制台的输出：</p><p><img src="https://js.hnlyx.top/img/1529835379275.png" alt="1529835379275"></p><h1 id="5-指令"><a href="#5-指令" class="headerlink" title="5.指令"></a>5.指令</h1><p>什么是指令？</p><p>指令 (Directives) 是带有  <code>v-</code>  前缀的特殊特性。指令特性的预期值是：<strong>单个 JavaScript 表达式</strong>。指令的职责是，当表达式的值改变时，将其产生的连带影响，响应式地作用于 DOM。</p><p>例如我们在入门案例中的 v-on，代表绑定事件。</p><h2 id="5-1-插值表达式"><a href="#5-1-插值表达式" class="headerlink" title="5.1.插值表达式"></a>5.1.插值表达式</h2><h3 id="5-1-1-花括号"><a href="#5-1-1-花括号" class="headerlink" title="5.1.1.花括号"></a>5.1.1.花括号</h3><p>格式：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;&#123;表达式&#125;&#125;</span><br></pre></td></tr></table></figure><p>说明：</p><ul><li>该表达式支持 JS 语法，可以调用 js 内置函数（必须有返回值）</li><li>表达式必须有返回结果。例如 1 + 1，没有结果的表达式不允许使用，如：var a &#x3D; 1 + 1;</li><li>可以直接获取 Vue 实例中定义的数据或函数</li></ul><p>示例：</p><p>HTML：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span>&#123;&#123;name&#125;&#125;<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>JS:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">data</span>: &#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&quot;Jack&quot;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="5-1-2-插值闪烁"><a href="#5-1-2-插值闪烁" class="headerlink" title="5.1.2.插值闪烁"></a>5.1.2.插值闪烁</h3><p>使用<code>&#123;&#123;&#125;&#125;</code>方式在网速较慢时会出现问题。在数据未加载完成时，页面会显示出原始的<code>&#123;&#123;&#125;&#125;</code>，加载完毕后才显示正确数据，我们称为插值闪烁。</p><p>我们将网速调慢一些，然后试试看刚才的案例：</p><p><img src="https://js.hnlyx.top/img/1529836021593.png" alt="1529836021593"></p><p>刷新页面：</p><p><img src="https://js.hnlyx.top/img/54.gif"></p><h3 id="5-1-3-v-text-和-v-html"><a href="#5-1-3-v-text-和-v-html" class="headerlink" title="5.1.3.v-text 和 v-html"></a>5.1.3.v-text 和 v-html</h3><p>使用 v-text 和 v-html 指令来替代<code>&#123;&#123;&#125;&#125;</code></p><p>说明：</p><ul><li>v-text：将数据输出到元素内部，如果输出的数据有 HTML 代码，会作为普通文本输出</li><li>v-html：将数据输出到元素内部，如果输出的数据有 HTML 代码，会被渲染</li></ul><p>示例：</p><p>HTML:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  v-text:<span class="tag">&lt;<span class="name">span</span> <span class="attr">v-text</span>=<span class="string">&quot;hello&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span> <span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  v-html:<span class="tag">&lt;<span class="name">span</span> <span class="attr">v-html</span>=<span class="string">&quot;hello&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>JS:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">data</span>: &#123;</span><br><span class="line">    <span class="attr">hello</span>: <span class="string">&quot;&lt;h1&gt;大家好，我是峰哥&lt;/h1&gt;&quot;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1529836688083.png" alt="1529836688083"></p><p>并且不会出现插值闪烁，当没有数据时，会显示空白。</p><h2 id="5-2-v-model"><a href="#5-2-v-model" class="headerlink" title="5.2.v-model"></a>5.2.v-model</h2><p>刚才的 v-text 和 v-html 可以看做是单向绑定，数据影响了视图渲染，但是反过来就不行。接下来学习的 v-model 是双向绑定，视图（View）和模型（Model）之间会互相影响。</p><p>既然是双向绑定，一定是在视图中可以修改数据，这样就限定了视图的元素类型。目前 v-model 的可使用元素有：</p><ul><li>input</li><li>select</li><li>textarea</li><li>checkbox</li><li>radio</li><li>components（Vue 中的自定义组件）</li></ul><p>基本上除了最后一项，其它都是表单的输入项。</p><p>举例：</p><p>html：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;language&quot;</span> <span class="attr">value</span>=<span class="string">&quot;Java&quot;</span> /&gt;</span>Java<span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;language&quot;</span> <span class="attr">value</span>=<span class="string">&quot;PHP&quot;</span> /&gt;</span>PHP<span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;language&quot;</span> <span class="attr">value</span>=<span class="string">&quot;Swift&quot;</span> /&gt;</span>Swift<span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span>&gt;</span>你选择了：&#123;&#123;language.join(&#x27;,&#x27;)&#125;&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">language</span>: [],</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li>多个<code>CheckBox</code>对应一个 model 时，model 的类型是一个数组，单个 checkbox 值默认是 boolean 类型</li><li>radio 对应的值是 input 的 value 值</li><li><code>input</code> 和<code>textarea</code> 默认对应的 model 是字符串</li><li><code>select</code>单选对应字符串，多选对应也是数组</li></ul><p>效果：</p><p><img src="https://js.hnlyx.top/img/1529837541201.png" alt="1529837541201"></p><h2 id="5-3-v-on"><a href="#5-3-v-on" class="headerlink" title="5.3.v-on"></a>5.3.v-on</h2><h3 id="5-3-1-基本用法"><a href="#5-3-1-基本用法" class="headerlink" title="5.3.1.基本用法"></a>5.3.1.基本用法</h3><p>v-on 指令用于给页面元素绑定事件。</p><p>语法：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">v-on:事件名=&quot;js片段或函数名&quot;</span><br></pre></td></tr></table></figure><p>示例：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--事件中直接写js片段--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">&quot;num++&quot;</span>&gt;</span>增加一个<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--事件指定一个回调函数，必须是Vue实例中定义的函数--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">&quot;decrement&quot;</span>&gt;</span>减少一个<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span>&gt;</span>有&#123;&#123;num&#125;&#125;个女神迷恋峰哥<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">num</span>: <span class="number">100</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">methods</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="title function_">decrement</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="variable language_">this</span>.<span class="property">num</span>--;</span></span><br><span class="line"><span class="language-javascript">      &#125;,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/55.gif"></p><p>另外，事件绑定可以简写，例如<code>v-on:click=&#39;add&#39;</code>可以简写为<code>@click=&#39;add&#39;</code></p><h3 id="5-3-2-事件修饰符"><a href="#5-3-2-事件修饰符" class="headerlink" title="5.3.2.事件修饰符"></a>5.3.2.事件修饰符</h3><p>在事件处理程序中调用 <code>event.preventDefault()</code> 或 <code>event.stopPropagation()</code> 是非常常见的需求。尽管我们可以在方法中轻松实现这点，但更好的方式是：方法只有纯粹的数据逻辑，而不是去处理 DOM 事件细节。</p><p>为了解决这个问题，Vue.js 为 <code>v-on</code> 提供了<strong>事件修饰符</strong>。修饰符是由点开头的指令后缀来表示的。</p><ul><li><code>.stop</code> ：阻止事件冒泡到父元素</li><li><code>.prevent</code>：阻止默认事件发生</li><li><code>.capture</code>：使用事件捕获模式</li><li><code>.self</code>：只有元素自身触发事件才执行。（冒泡或捕获的都不执行）</li><li><code>.once</code>：只执行一次</li></ul><p>阻止默认事件</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--右击事件，并阻止默认事件发生--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:contextmenu.prevent</span>=<span class="string">&quot;num++&quot;</span>&gt;</span>增加一个<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--右击事件，不阻止默认事件发生--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:contextmenu</span>=<span class="string">&quot;decrement($event)&quot;</span>&gt;</span>减少一个<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span>&gt;</span>有&#123;&#123;num&#125;&#125;个女神迷恋峰哥<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">num</span>: <span class="number">100</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">methods</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="title function_">decrement</span>(<span class="params">ev</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// ev.preventDefault();</span></span></span><br><span class="line"><span class="language-javascript">        <span class="variable language_">this</span>.<span class="property">num</span>--;</span></span><br><span class="line"><span class="language-javascript">      &#125;,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：（右键“增加一个”，不会触发默认的浏览器右击事件；右键“减少一个”，会触发默认的浏览器右击事件）</p><p><img src="https://js.hnlyx.top/img/56.gif"></p><h3 id="5-3-3-按键修饰符"><a href="#5-3-3-按键修饰符" class="headerlink" title="5.3.3.按键修饰符"></a>5.3.3.按键修饰符</h3><p>在监听键盘事件时，我们经常需要检查常见的键值。Vue 允许为  <code>v-on</code>  在监听键盘事件时添加按键修饰符：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">v-on:keyup.13</span>=<span class="string">&quot;submit&quot;</span> /&gt;</span></span><br></pre></td></tr></table></figure><p>记住所有的 <code>keyCode</code> 比较困难，所以 Vue 为最常用的按键提供了别名：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 同上 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">v-on:keyup.enter</span>=<span class="string">&quot;submit&quot;</span> /&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 缩写语法 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">input</span> @<span class="attr">keyup.enter</span>=<span class="string">&quot;submit&quot;</span> /&gt;</span></span><br></pre></td></tr></table></figure><p>全部的按键别名：</p><ul><li><code>.enter</code></li><li><code>.tab</code></li><li><code>.delete</code> (捕获“删除”和“退格”键)</li><li><code>.esc</code></li><li><code>.space</code></li><li><code>.up</code></li><li><code>.down</code></li><li><code>.left</code></li><li><code>.right</code></li></ul><h3 id="5-3-4-组合按钮"><a href="#5-3-4-组合按钮" class="headerlink" title="5.3.4.组合按钮"></a>5.3.4.组合按钮</h3><p>可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。</p><ul><li><code>.ctrl</code></li><li><code>.alt</code></li><li><code>.shift</code></li></ul><p>例如：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- Alt + C --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">input</span> @<span class="attr">keyup.alt.67</span>=<span class="string">&quot;clear&quot;</span> /&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- Ctrl + Click --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> @<span class="attr">click.ctrl</span>=<span class="string">&quot;doSomething&quot;</span>&gt;</span>Do something<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="5-4-v-for"><a href="#5-4-v-for" class="headerlink" title="5.4.v-for"></a>5.4.v-for</h2><p>遍历数据渲染页面是非常常用的需求，Vue 中通过 v-for 指令来实现。</p><h3 id="5-4-1-遍历数组"><a href="#5-4-1-遍历数组" class="headerlink" title="5.4.1.遍历数组"></a>5.4.1.遍历数组</h3><blockquote><p>语法：</p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">v-for=&quot;item in items&quot;</span><br></pre></td></tr></table></figure><ul><li>items：要遍历的数组，需要在 vue 的 data 中定义好。</li><li>item：迭代得到的数组元素的别名</li></ul><blockquote><p>示例</p></blockquote><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;user in users&quot;</span>&gt;</span></span><br><span class="line">      &#123;&#123;user.name&#125;&#125; - &#123;&#123;user.gender&#125;&#125; - &#123;&#123;user.age&#125;&#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">users</span>: [</span></span><br><span class="line"><span class="language-javascript">        &#123; <span class="attr">name</span>: <span class="string">&quot;柳岩&quot;</span>, <span class="attr">gender</span>: <span class="string">&quot;女&quot;</span>, <span class="attr">age</span>: <span class="number">21</span> &#125;,</span></span><br><span class="line"><span class="language-javascript">        &#123; <span class="attr">name</span>: <span class="string">&quot;峰哥&quot;</span>, <span class="attr">gender</span>: <span class="string">&quot;男&quot;</span>, <span class="attr">age</span>: <span class="number">18</span> &#125;,</span></span><br><span class="line"><span class="language-javascript">        &#123; <span class="attr">name</span>: <span class="string">&quot;范冰冰&quot;</span>, <span class="attr">gender</span>: <span class="string">&quot;女&quot;</span>, <span class="attr">age</span>: <span class="number">24</span> &#125;,</span></span><br><span class="line"><span class="language-javascript">        &#123; <span class="attr">name</span>: <span class="string">&quot;刘亦菲&quot;</span>, <span class="attr">gender</span>: <span class="string">&quot;女&quot;</span>, <span class="attr">age</span>: <span class="number">18</span> &#125;,</span></span><br><span class="line"><span class="language-javascript">        &#123; <span class="attr">name</span>: <span class="string">&quot;古力娜扎&quot;</span>, <span class="attr">gender</span>: <span class="string">&quot;女&quot;</span>, <span class="attr">age</span>: <span class="number">25</span> &#125;,</span></span><br><span class="line"><span class="language-javascript">      ],</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530006198953.png" alt="1530006198953"></p><h3 id="5-4-2-数组角标"><a href="#5-4-2-数组角标" class="headerlink" title="5.4.2.数组角标"></a>5.4.2.数组角标</h3><p>在遍历的过程中，如果我们需要知道数组角标，可以指定第二个参数：</p><blockquote><p>语法</p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">v-for=&quot;(item,index) in items&quot;</span><br></pre></td></tr></table></figure><ul><li>items：要迭代的数组</li><li>item：迭代得到的数组元素别名</li><li>index：迭代到的当前元素索引，从 0 开始。</li></ul><blockquote><p>示例</p></blockquote><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;(user, index) in users&quot;</span>&gt;</span></span><br><span class="line">    &#123;&#123;index + 1&#125;&#125;. &#123;&#123;user.name&#125;&#125; - &#123;&#123;user.gender&#125;&#125; - &#123;&#123;user.age&#125;&#125;</span><br><span class="line">  <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br></pre></td></tr></table></figure><blockquote><p>效果：</p></blockquote><p><img src="https://js.hnlyx.top/img/1530006094601.png" alt="1530006094601"></p><h3 id="5-4-3-遍历对象"><a href="#5-4-3-遍历对象" class="headerlink" title="5.4.3.遍历对象"></a>5.4.3.遍历对象</h3><p>v-for 除了可以迭代数组，也可以迭代对象。语法基本类似</p><blockquote><p>语法：</p></blockquote><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">v-<span class="keyword">for</span>=<span class="string">&quot;value in object&quot;</span></span><br><span class="line">v-<span class="keyword">for</span>=<span class="string">&quot;(value,key) in object&quot;</span></span><br><span class="line">v-<span class="keyword">for</span>=<span class="string">&quot;(value,key,index) in object&quot;</span></span><br></pre></td></tr></table></figure><ul><li>1 个参数时，得到的是对象的属性</li><li>2 个参数时，第一个是属性，第二个是键</li><li>3 个参数时，第三个是索引，从 0 开始</li></ul><blockquote><p>示例：</p></blockquote><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;(value, key, index) in user&quot;</span>&gt;</span></span><br><span class="line">      &#123;&#123;index + 1&#125;&#125;. &#123;&#123;key&#125;&#125; - &#123;&#123;value&#125;&#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">user</span>: &#123; <span class="attr">name</span>: <span class="string">&quot;峰哥&quot;</span>, <span class="attr">gender</span>: <span class="string">&quot;男&quot;</span>, <span class="attr">age</span>: <span class="number">18</span> &#125;,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><blockquote><p>效果：</p></blockquote><p><img src="https://js.hnlyx.top/img/1530006251975.png" alt="1530006251975"></p><h3 id="5-4-4-key"><a href="#5-4-4-key" class="headerlink" title="5.4.4.key"></a>5.4.4.key</h3><p>当 Vue.js 用  <code>v-for</code>  正在更新已渲染过的元素列表时，它默认用“就地复用”策略。如果数据项的顺序被改变，Vue 将不会移动 DOM 元素来匹配数据项的顺序， 而是简单复用此处每个元素，并且确保它在特定索引下显示已被渲染过的每个元素。</p><p>这个功能可以有效的提高渲染的效率。</p><p>但是要实现这个功能，你需要给 Vue 一些提示，以便它能跟踪每个节点的身份，从而重用和重新排序现有元素，你需要为每项提供一个唯一  <code>key</code>  属性。理想的  <code>key</code>  值是每项都有的且唯一的 id。</p><p>示例：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;(item,index) in items&quot;</span> <span class="attr">:key</span>=<span class="string">&quot;index&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li>这里使用了一个特殊语法：<code>:key=&quot;&quot;</code> 我们后面会讲到，它可以让你读取 vue 中的属性，并赋值给 key 属性</li><li>这里我们绑定的 key 是数组的索引，应该是唯一的</li></ul><h2 id="5-5-v-if-和-v-show"><a href="#5-5-v-if-和-v-show" class="headerlink" title="5.5.v-if 和 v-show"></a>5.5.v-if 和 v-show</h2><h3 id="5-5-1-基本使用"><a href="#5-5-1-基本使用" class="headerlink" title="5.5.1.基本使用"></a>5.5.1.基本使用</h3><p>v-if，顾名思义，条件判断。当得到结果为 true 时，所在的元素才会被渲染。</p><blockquote><p>语法：</p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">v-if=&quot;布尔表达式&quot;</span><br></pre></td></tr></table></figure><blockquote><p>示例：</p></blockquote><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">&quot;show = !show&quot;</span>&gt;</span>点我呀<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span> <span class="attr">v-if</span>=<span class="string">&quot;show&quot;</span>&gt;</span>看到我啦？！<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span> <span class="attr">v-show</span>=<span class="string">&quot;show&quot;</span>&gt;</span>看到我啦？！show<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">show</span>: <span class="literal">true</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><blockquote><p>效果：</p></blockquote><p><img src="https://js.hnlyx.top/img/57.gif"></p><h3 id="5-5-2-与-v-for-结合"><a href="#5-5-2-与-v-for-结合" class="headerlink" title="5.5.2.与 v-for 结合"></a>5.5.2.与 v-for 结合</h3><p>当 v-if 和 v-for 出现在一起时，v-for 优先级更高。也就是说，会先遍历，再判断条件。</p><p>修改 v-for 中的案例，添加 v-if：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;(user, index) in users&quot;</span> <span class="attr">v-if</span>=<span class="string">&quot;user.gender == &#x27;女&#x27;&quot;</span>&gt;</span></span><br><span class="line">    &#123;&#123;index + 1&#125;&#125;. &#123;&#123;user.name&#125;&#125; - &#123;&#123;user.gender&#125;&#125; - &#123;&#123;user.age&#125;&#125;</span><br><span class="line">  <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530013415911.png" alt="1530013415911"></p><p>只显示女性用户信息</p><h3 id="5-5-3-v-else"><a href="#5-5-3-v-else" class="headerlink" title="5.5.3.v-else"></a>5.5.3.v-else</h3><p>你可以使用 <code>v-else</code> 指令来表示 <code>v-if</code> 的“else 块”：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span> <span class="attr">v-if</span>=<span class="string">&quot;Math.random() &gt; 0.5&quot;</span>&gt;</span>看到我啦？！if<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span> <span class="attr">v-else</span>&gt;</span>看到我啦？！else<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p><code>v-else</code> 元素必须紧跟在带 <code>v-if</code> 或者 <code>v-else-if</code> 的元素的后面，否则它将不会被识别。</p><p><code>v-else-if</code>，顾名思义，充当 <code>v-if</code> 的“else-if 块”，可以连续使用：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">&quot;random=Math.random()&quot;</span>&gt;</span>点我呀&lt;/button</span><br><span class="line">  &gt;<span class="tag">&lt;<span class="name">span</span>&gt;</span>&#123;&#123;random&#125;&#125;<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span> <span class="attr">v-if</span>=<span class="string">&quot;random &gt;= 0.75&quot;</span>&gt;</span>看到我啦？！if<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span> <span class="attr">v-else-if</span>=<span class="string">&quot;random &gt; 0.5&quot;</span>&gt;</span>看到我啦？！if 0.5<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span> <span class="attr">v-else-if</span>=<span class="string">&quot;random &gt; 0.25&quot;</span>&gt;</span>看到我啦？！if 0.25<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span> <span class="attr">v-else</span>&gt;</span>看到我啦？！else<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">random</span>: <span class="number">1</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>类似于 <code>v-else</code>，<code>v-else-if</code> 也必须紧跟在带 <code>v-if</code> 或者 <code>v-else-if</code> 的元素之后。</p><p>演示：</p><p><img src="https://js.hnlyx.top/img/58.gif" alt="1530013415911"></p><h3 id="5-5-4-v-show"><a href="#5-5-4-v-show" class="headerlink" title="5.5.4.v-show"></a>5.5.4.v-show</h3><p>另一个用于根据条件展示元素的选项是 <code>v-show</code> 指令。用法大致一样：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;h1 v-show=&quot;ok&quot;&gt;Hello!&lt;/h1&gt;</span><br></pre></td></tr></table></figure><p>不同的是带有 <code>v-show</code> 的元素始终会被渲染并保留在 DOM 中。<code>v-show</code> 只是简单地切换元素的 CSS 属性 <code>display</code>。</p><p>示例：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--事件中直接写js片段--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">&quot;show = !show&quot;</span>&gt;</span>点击切换<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span> <span class="attr">v-if</span>=<span class="string">&quot;show&quot;</span>&gt;</span>你好<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">show</span>: <span class="literal">true</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>代码：</p><p><img src="https://js.hnlyx.top/img/59.gif"></p><h2 id="5-6-v-bind"><a href="#5-6-v-bind" class="headerlink" title="5.6.v-bind"></a>5.6.v-bind</h2><p>html 属性不能使用双大括号形式绑定，只能使用 v-bind 指令。</p><p>在将  <code>v-bind</code>  用于  <code>class</code>  和  <code>style</code>  时，Vue.js 做了专门的增强。表达式结果的类型除了字符串之外，还可以是对象或数组。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--可以是数据模型，可以是具有返回值的js代码块或者函数--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span></span></span><br><span class="line"><span class="tag">    <span class="attr">v-bind:title</span>=<span class="string">&quot;title&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">style</span>=<span class="string">&quot;border: 1px solid red; width: 50px; height: 50px;&quot;</span></span></span><br><span class="line"><span class="tag">  &gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">title</span>: <span class="string">&quot;title&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530025378843.png" alt="1530025378843"></p><p>在将  <code>v-bind</code>  用于  <code>class</code>  和  <code>style</code>  时，Vue.js 做了专门的增强。表达式结果的类型除了字符串之外，还可以是对象或数组。</p><h3 id="5-6-1-绑定-class-样式"><a href="#5-6-1-绑定-class-样式" class="headerlink" title="5.6.1.绑定 class 样式"></a>5.6.1.绑定 class 样式</h3><blockquote><p>数组语法</p></blockquote><p>我们可以借助于<code>v-bind</code>指令来实现：</p><p>HTML：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-bind:class</span>=<span class="string">&quot;activeClass&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-bind:class</span>=<span class="string">&quot;errorClass&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-bind:class</span>=<span class="string">&quot;[activeClass, errorClass]&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">activeClass</span>: <span class="string">&quot;active&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">errorClass</span>: [<span class="string">&quot;text-danger&quot;</span>, <span class="string">&quot;text-error&quot;</span>],</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>渲染后的效果：（具有 active 和 hasError 的样式）</p><p><img src="https://js.hnlyx.top/img/1530026818515.png" alt="1530026818515"></p><blockquote><p>对象语法</p></blockquote><p>我们可以传给 <code>v-bind:class</code> 一个对象，以动态地切换 class：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">v-bind:class</span>=<span class="string">&quot;&#123; active: isActive &#125;&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>上面的语法表示 <code>active</code> 这个 <strong>class 存在与否将取决于数据属性 <code>isActive</code></strong> 的 <a href="https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy">truthiness</a>（所有的值都是真实的，除了 false,0,“”,null,undefined 和 NaN）。</p><p>你可以在对象中传入更多属性来动态切换多个 class。此外，<code>v-bind:class</code> 指令也可以与普通的 class 属性共存。如下模板:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span></span></span><br><span class="line"><span class="tag">  <span class="attr">class</span>=<span class="string">&quot;static&quot;</span></span></span><br><span class="line"><span class="tag">  <span class="attr">v-bind:class</span>=<span class="string">&quot;&#123; active: isActive, &#x27;text-danger&#x27;: hasError &#125;&quot;</span></span></span><br><span class="line"><span class="tag">&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>和如下 data：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">data</span>: &#123;</span><br><span class="line">  <span class="attr">isActive</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">hasError</span>: <span class="literal">false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>结果渲染为：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;static active&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>active 样式和 text-danger 样式的存在与否，取决于 isActive 和 hasError 的值。本例中 isActive 为 true，hasError 为 false，所以 active 样式存在，text-danger 不存在。</p><p><strong>通常情况下，绑定的数据对象不必内联定义在模板里</strong>：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;static&quot;</span> <span class="attr">v-bind:class</span>=<span class="string">&quot;classObject&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>数据：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">data</span>: &#123;</span><br><span class="line">  <span class="attr">classObject</span>: &#123;</span><br><span class="line">    <span class="attr">active</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="string">&#x27;text-danger&#x27;</span>: <span class="literal">false</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>效果和之前一样：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;static active&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="5-6-2-绑定-style-样式"><a href="#5-6-2-绑定-style-样式" class="headerlink" title="5.6.2.绑定 style 样式"></a>5.6.2.绑定 style 样式</h3><blockquote><p>数组语法</p></blockquote><p>数组语法可以将多个样式对象应用到同一个元素上：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">v-bind:style</span>=<span class="string">&quot;[baseStyles, overridingStyles]&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>数据：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">data</span>: &#123;</span><br><span class="line">    <span class="attr">baseStyles</span>: &#123;<span class="string">&#x27;background-color&#x27;</span>: <span class="string">&#x27;red&#x27;</span>&#125;,</span><br><span class="line">    <span class="attr">overridingStyles</span>: &#123;<span class="attr">border</span>: <span class="string">&#x27;1px solid black&#x27;</span>&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>渲染后的结果：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;background-color: red; border: 1px solid black;&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><blockquote><p>对象语法</p></blockquote><p><code>v-bind:style</code>  的对象语法十分直观——看着非常像 CSS，但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case，记得用单引号括起来) 来命名：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">v-bind:style</span>=<span class="string">&quot;&#123; color: activeColor, fontSize: fontSize + &#x27;px&#x27; &#125;&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>数据：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">data</span>: &#123;</span><br><span class="line">  <span class="attr">activeColor</span>: <span class="string">&#x27;red&#x27;</span>,</span><br><span class="line">  <span class="attr">fontSize</span>: <span class="number">30</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>效果：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;color: red; font-size: 30px;&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>直接绑定到一个样式对象通常更好，这会让模板更清晰</strong>：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">v-bind:style</span>=<span class="string">&quot;styleObject&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">data</span>: &#123;</span><br><span class="line">  <span class="attr">styleObject</span>: &#123;</span><br><span class="line">    <span class="attr">color</span>: <span class="string">&#x27;red&#x27;</span>,</span><br><span class="line">    <span class="attr">fontSize</span>: <span class="string">&#x27;13px&#x27;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>效果同上。</p><h3 id="5-6-3-简写"><a href="#5-6-3-简写" class="headerlink" title="5.6.3.简写"></a>5.6.3.简写</h3><p><code>v-bind:class</code>可以简写为<code>:class</code></p><h2 id="5-7-计算属性"><a href="#5-7-计算属性" class="headerlink" title="5.7.计算属性"></a>5.7.计算属性</h2><p>在插值表达式中使用 js 表达式是非常方便的，而且也经常被用到。</p><p>但是如果表达式的内容很长，就会显得不够优雅，而且后期维护起来也不方便，例如下面的场景，我们有一个日期的数据，但是是毫秒值：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">data</span>: &#123;</span><br><span class="line">  <span class="attr">birthday</span>: <span class="number">1529032123201</span>; <span class="comment">// 毫秒值</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>我们在页面渲染，希望得到 yyyy-MM-dd 的样式：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">h1</span>&gt;</span></span><br><span class="line">  您的生日是：&#123;&#123; new Date(birthday).getFullYear() + &#x27;-&#x27;+ new</span><br><span class="line">  Date(birthday).getMonth()+ &#x27;-&#x27; + new Date(birthday).getDay() &#125;&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br></pre></td></tr></table></figure><p>虽然能得到结果，但是非常麻烦。</p><p>Vue 中提供了计算属性，来替代复杂的表达式：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">data</span>: &#123;</span><br><span class="line">    <span class="attr">birthday</span>: <span class="number">1429032123201</span>, <span class="comment">// 毫秒值</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">computed</span>: &#123;</span><br><span class="line">    <span class="title function_">birth</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="comment">// 计算属性本质是一个方法，但是必须返回结果</span></span><br><span class="line">      <span class="keyword">const</span> d = <span class="keyword">new</span> <span class="title class_">Date</span>(<span class="variable language_">this</span>.<span class="property">birthday</span>);</span><br><span class="line">      <span class="keyword">return</span> d.<span class="title function_">getFullYear</span>() + <span class="string">&quot;-&quot;</span> + d.<span class="title function_">getMonth</span>() + <span class="string">&quot;-&quot;</span> + d.<span class="title function_">getDay</span>();</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><ul><li>计算属性本质就是方法，但是一定要返回数据。然后页面渲染时，可以把这个方法当成一个变量来使用。</li></ul><p>页面使用：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span>&gt;</span>您的生日是：&#123;&#123;birth&#125;&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530029950644.png" alt="1530029950644"></p><p>我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而，不同的是<strong>计算属性是基于它们的依赖进行缓存的</strong>。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要<code>birthday</code>还没有发生改变，多次访问  <code>birthday</code>  计算属性会立即返回之前的计算结果，而不必再次执行函数。</p><h2 id="5-8-watch"><a href="#5-8-watch" class="headerlink" title="5.8.watch"></a>5.8.watch</h2><p>watch 可以让我们监控一个值的变化。从而做出相应的反应。</p><p>示例：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;message&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">message</span>: <span class="string">&quot;&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">watch</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="title function_">message</span>(<span class="params">newVal, oldVal</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="variable language_">console</span>.<span class="title function_">log</span>(newVal, oldVal);</span></span><br><span class="line"><span class="language-javascript">      &#125;,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530030506879.png" alt="1530030506879"></p><h1 id="6-组件化"><a href="#6-组件化" class="headerlink" title="6.组件化"></a>6.组件化</h1><p>在大型应用开发的时候，页面可以划分成很多部分。往往不同的页面，也会有相同的部分。例如可能会有相同的头部导航。</p><p>但是如果每个页面都独自开发，这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件，然后在不同页面就可以共享这些组件，避免重复开发。</p><h2 id="6-1-全局组件"><a href="#6-1-全局组件" class="headerlink" title="6.1.全局组件"></a>6.1.全局组件</h2><p>我们通过 Vue 的 component 方法来定义一个全局组件。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--使用定义好的全局组件--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">counter</span>&gt;</span><span class="tag">&lt;/<span class="name">counter</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="comment">// 定义全局组件，两个参数：1，组件名称。2，组件参数</span></span></span><br><span class="line"><span class="language-javascript">  <span class="title class_">Vue</span>.<span class="title function_">component</span>(<span class="string">&quot;counter&quot;</span>, &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">template</span>:</span></span><br><span class="line"><span class="language-javascript">      <span class="string">&#x27;&lt;button v-on:click=&quot;count++&quot;&gt;你点了我 &#123;&#123; count &#125;&#125; 次，我记住了.&lt;/button&gt;&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="title function_">data</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="keyword">return</span> &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">count</span>: <span class="number">0</span>,</span></span><br><span class="line"><span class="language-javascript">      &#125;;</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li>组件其实也是一个 Vue 实例，因此它在定义时也会接收：data、methods、生命周期函数等</li><li>不同的是组件不会与页面的元素绑定，否则就无法复用了，因此没有 el 属性。</li><li>但是组件渲染需要 html 模板，所以增加了 template 属性，值就是 HTML 模板</li><li>全局组件定义完毕，任何 vue 实例都可以直接在 HTML 中通过组件名称来使用组件了。</li><li>data 必须是一个函数，不再是一个对象。</li></ul><p>效果：</p><p><img src="https://js.hnlyx.top/img/60.gif"></p><h2 id="6-2-组件的复用"><a href="#6-2-组件的复用" class="headerlink" title="6.2.组件的复用"></a>6.2.组件的复用</h2><p>定义好的组件，可以任意复用多次：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--使用定义好的全局组件--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">counter</span>&gt;</span><span class="tag">&lt;/<span class="name">counter</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">counter</span>&gt;</span><span class="tag">&lt;/<span class="name">counter</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">counter</span>&gt;</span><span class="tag">&lt;/<span class="name">counter</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530084943778.png" alt="1530084943778"></p><p>你会发现每个组件互不干扰，都有自己的 count 值。怎么实现的？</p><blockquote><p><strong>组件的 data 属性必须是函数</strong>！</p></blockquote><p>当我们定义这个 <code>&lt;counter&gt;</code> 组件时，它的 data 并不是像这样直接提供一个对象：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">data</span>: &#123;</span><br><span class="line">  <span class="attr">count</span>: <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>取而代之的是，一个组件的 data 选项必须是一个函数，因此每个实例可以维护一份被返回对象的独立的拷贝：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">data</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">count</span>: <span class="number">0</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果 Vue 没有这条规则，点击一个按钮就会影响到其它所有实例！</p><h2 id="6-3-局部注册"><a href="#6-3-局部注册" class="headerlink" title="6.3.局部注册"></a>6.3.局部注册</h2><p>一旦全局注册，就意味着即便以后你不再使用这个组件，它依然会随着 Vue 的加载而加载。</p><p>因此，对于一些并不频繁使用的组件，我们会采用局部注册。</p><p>我们先在外部定义一个对象，结构与创建组件时传递的第二个参数一致：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> counter = &#123;</span><br><span class="line">  <span class="attr">template</span>:</span><br><span class="line">    <span class="string">&#x27;&lt;button v-on:click=&quot;count++&quot;&gt;你点了我 &#123;&#123; count &#125;&#125; 次，我记住了.&lt;/button&gt;&#x27;</span>,</span><br><span class="line">  <span class="title function_">data</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">      <span class="attr">count</span>: <span class="number">0</span>,</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>然后在 Vue 中使用它：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">components</span>: &#123;</span><br><span class="line">    <span class="attr">counter</span>: counter, <span class="comment">// 将定义的对象注册为组件</span></span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><ul><li>components 就是当前 vue 对象子组件集合。<ul><li>其 key 就是子组件名称</li><li>其值就是组件对象的属性</li></ul></li><li>效果与刚才的全局注册是类似的，不同的是，这个 counter 组件只能在当前的 Vue 实例中使用</li></ul><h2 id="6-4-组件通信"><a href="#6-4-组件通信" class="headerlink" title="6.4.组件通信"></a>6.4.组件通信</h2><p>通常一个单页应用会以一棵嵌套的组件树的形式来组织：</p><p><img src="https://js.hnlyx.top/img/1525855149491.png" alt="1525855149491"></p><ul><li>页面首先分成了顶部导航、左侧内容区、右侧边栏三部分</li><li>左侧内容区又分为上下两个组件</li><li>右侧边栏中又包含了 3 个子组件</li></ul><p>各个组件之间以嵌套的关系组合在一起，那么这个时候不可避免的会有组件间通信的需求。</p><h3 id="6-4-1-props（父向子传递）"><a href="#6-4-1-props（父向子传递）" class="headerlink" title="6.4.1.props（父向子传递）"></a>6.4.1.props（父向子传递）</h3><ol><li>父组件使用子组件时，自定义属性（属性名任意，属性值为要传递的数据）</li><li>子组件通过 props 接收父组件属性</li></ol><p>父组件使用子组件，并自定义了 title 属性：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span>&gt;</span>打个招呼：<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--使用子组件，同时传递title属性--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">introduce</span> <span class="attr">title</span>=<span class="string">&quot;大家好，我是锋哥&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="title class_">Vue</span>.<span class="title function_">component</span>(<span class="string">&quot;introduce&quot;</span>, &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="comment">// 直接使用props接收到的属性来渲染页面</span></span></span><br><span class="line"><span class="language-javascript">    <span class="attr">template</span>: <span class="string">&quot;&lt;h1&gt;&#123;&#123;title&#125;&#125;&lt;/h1&gt;&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">props</span>: [<span class="string">&quot;title&quot;</span>], <span class="comment">// 通过props来接收一个父组件传递的属性</span></span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530093525973.png" alt="1530093525973"></p><h3 id="6-4-2-props-验证"><a href="#6-4-2-props-验证" class="headerlink" title="6.4.2.props 验证"></a>6.4.2.props 验证</h3><p>我们定义一个子组件，并接受复杂数据：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> myList = &#123;</span><br><span class="line">  <span class="attr">template</span>:</span><br><span class="line">    <span class="string">&#x27;\</span></span><br><span class="line"><span class="string">        &lt;ul&gt;\</span></span><br><span class="line"><span class="string">            &lt;li v-for=&quot;item in items&quot; :key=&quot;item.id&quot;&gt;&#123;&#123;item.id&#125;&#125; : &#123;&#123;item.name&#125;&#125;&lt;/li&gt;\</span></span><br><span class="line"><span class="string">        &lt;/ul&gt;\</span></span><br><span class="line"><span class="string">        &#x27;</span>,</span><br><span class="line">  <span class="attr">props</span>: &#123;</span><br><span class="line">    <span class="attr">items</span>: &#123;</span><br><span class="line">      <span class="attr">type</span>: <span class="title class_">Array</span>,</span><br><span class="line">      <span class="attr">default</span>: [],</span><br><span class="line">      <span class="attr">required</span>: <span class="literal">true</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><ul><li>这个子组件可以对 items 进行迭代，并输出到页面。</li><li>props：定义需要从父组件中接收的属性<ul><li>items：是要接收的属性名称<ul><li>type：限定父组件传递来的必须是数组</li><li>default：默认值</li><li>required：是否必须</li></ul></li></ul></li></ul><p><strong>当 prop 验证失败的时候，(开发环境构建版本的) Vue 将会产生一个控制台的警告。</strong></p><p>我们在父组件中使用它：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h2</span>&gt;</span>传智播客已开设如下课程：<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!-- 使用子组件的同时，传递属性，这里使用了v-bind，指向了父组件自己的属性lessons --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">my-list</span> <span class="attr">:items</span>=<span class="string">&quot;lessons&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">components</span>: &#123;</span><br><span class="line">    myList, <span class="comment">// 当key和value一样时，可以只写一个</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">data</span>: &#123;</span><br><span class="line">    <span class="attr">lessons</span>: [</span><br><span class="line">      &#123; <span class="attr">id</span>: <span class="number">1</span>, <span class="attr">name</span>: <span class="string">&quot;java&quot;</span> &#125;,</span><br><span class="line">      &#123; <span class="attr">id</span>: <span class="number">2</span>, <span class="attr">name</span>: <span class="string">&quot;php&quot;</span> &#125;,</span><br><span class="line">      &#123; <span class="attr">id</span>: <span class="number">3</span>, <span class="attr">name</span>: <span class="string">&quot;ios&quot;</span> &#125;,</span><br><span class="line">    ],</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530107338625.png" alt="1530107338625"></p><p>type 类型，可以有：</p><p><img src="https://js.hnlyx.top/img/1530108427358.png" alt="1530108427358"></p><h3 id="6-4-3-动态静态传递"><a href="#6-4-3-动态静态传递" class="headerlink" title="6.4.3.动态静态传递"></a>6.4.3.动态静态传递</h3><p>给 prop 传入一个静态的值：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">introduce</span> <span class="attr">title</span>=<span class="string">&quot;大家好，我是锋哥&quot;</span> /&gt;</span></span><br></pre></td></tr></table></figure><p>给 prop 传入一个动态的值： （通过 v-bind 从数据模型中，获取 title 的值）</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">introduce</span> <span class="attr">:title</span>=<span class="string">&quot;title&quot;</span> /&gt;</span></span><br></pre></td></tr></table></figure><p>静态传递时，我们传入的值都是字符串类型的，但实际上<strong>任何类型</strong>的值都可以传给一个 props。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 即便 `42` 是静态的，我们仍然需要 `v-bind` 来告诉 Vue --&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 这是一个JavaScript表达式而不是一个字符串。--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">blog-post</span> <span class="attr">v-bind:likes</span>=<span class="string">&quot;42&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">blog-post</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 用一个变量进行动态赋值。--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">blog-post</span> <span class="attr">v-bind:likes</span>=<span class="string">&quot;post.likes&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">blog-post</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="6-4-4-子向父的通信"><a href="#6-4-4-子向父的通信" class="headerlink" title="6.4.4.子向父的通信"></a>6.4.4.子向父的通信</h3><p>来看这样的一个案例：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h2</span>&gt;</span>num: &#123;&#123;num&#125;&#125;<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--使用子组件的时候，传递num到子组件中--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">counter</span> <span class="attr">:num</span>=<span class="string">&quot;num&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">counter</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;./node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="title class_">Vue</span>.<span class="title function_">component</span>(<span class="string">&quot;counter&quot;</span>, &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="comment">// 子组件，定义了两个按钮，点击数字num会加或减</span></span></span><br><span class="line"><span class="language-javascript">    <span class="attr">template</span>:</span></span><br><span class="line"><span class="language-javascript">      <span class="string">&#x27;\</span></span></span><br><span class="line"><span class="string"><span class="language-javascript">            &lt;div&gt;\</span></span></span><br><span class="line"><span class="string"><span class="language-javascript">                &lt;button @click=&quot;num++&quot;&gt;加&lt;/button&gt;  \</span></span></span><br><span class="line"><span class="string"><span class="language-javascript">                &lt;button @click=&quot;num--&quot;&gt;减&lt;/button&gt;  \</span></span></span><br><span class="line"><span class="string"><span class="language-javascript">            &lt;/div&gt;&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">props</span>: [<span class="string">&quot;num&quot;</span>], <span class="comment">// count是从父组件获取的。</span></span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">num</span>: <span class="number">0</span>,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li>子组件接收父组件的 num 属性</li><li>子组件定义点击按钮，点击后对 num 进行加或减操作</li></ul><p>我们尝试运行，好像没问题，点击按钮试试：</p><p><img src="https://js.hnlyx.top/img/1530115066496.png" alt="1525859093172"></p><p>子组件接收到父组件属性后，默认是不允许修改的。怎么办？</p><p>既然只有父组件能修改，那么加和减的操作一定是放在父组件：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> app = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">data</span>: &#123;</span><br><span class="line">    <span class="attr">num</span>: <span class="number">0</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">methods</span>: &#123;</span><br><span class="line">    <span class="comment">// 父组件中定义操作num的方法</span></span><br><span class="line">    <span class="title function_">increment</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">num</span>++;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="title function_">decrement</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">num</span>--;</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>但是，点击按钮是在子组件中，那就是说需要子组件来调用父组件的函数，怎么做？</p><p>我们可以<strong>通过 v-on 指令将父组件的函数绑定到子组件</strong>上：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h2</span>&gt;</span>num: &#123;&#123;num&#125;&#125;<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">counter</span> <span class="attr">:count</span>=<span class="string">&quot;num&quot;</span> @<span class="attr">inc</span>=<span class="string">&quot;increment&quot;</span> @<span class="attr">dec</span>=<span class="string">&quot;decrement&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">counter</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>在子组件中定义函数，函数的具体实现调用父组件的实现，并在子组件中调用这些函数。当子组件中按钮被点击时，调用绑定的函数：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Vue</span>.<span class="title function_">component</span>(<span class="string">&quot;counter&quot;</span>, &#123;</span><br><span class="line">  <span class="attr">template</span>:</span><br><span class="line">    <span class="string">&#x27;\</span></span><br><span class="line"><span class="string">                &lt;div&gt;\</span></span><br><span class="line"><span class="string">                    &lt;button @click=&quot;plus&quot;&gt;加&lt;/button&gt;  \</span></span><br><span class="line"><span class="string">                    &lt;button @click=&quot;reduce&quot;&gt;减&lt;/button&gt;  \</span></span><br><span class="line"><span class="string">                &lt;/div&gt;&#x27;</span>,</span><br><span class="line">  <span class="attr">props</span>: [<span class="string">&quot;count&quot;</span>],</span><br><span class="line">  <span class="attr">methods</span>: &#123;</span><br><span class="line">    <span class="title function_">plus</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">this</span>.$emit(<span class="string">&quot;inc&quot;</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="title function_">reduce</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">this</span>.$emit(<span class="string">&quot;dec&quot;</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><ul><li>vue 提供了一个内置的 this.$emit()函数，用来调用父组件绑定的函数</li></ul><p>效果：</p><p><img src="https://js.hnlyx.top/img/61.gif"></p><h1 id="7-路由-vue-router"><a href="#7-路由-vue-router" class="headerlink" title="7.路由 vue-router"></a>7.路由 vue-router</h1><h2 id="7-1-场景模拟"><a href="#7-1-场景模拟" class="headerlink" title="7.1.场景模拟"></a>7.1.场景模拟</h2><p>现在我们来实现这样一个功能：</p><p>一个页面，包含登录和注册，点击不同按钮，实现登录和注册页切换：</p><p><img src="H:/%E4%B9%90%E4%BC%98/day05-Vue/assets/8.gif"></p><h3 id="7-1-1-编写父组件"><a href="#7-1-1-编写父组件" class="headerlink" title="7.1.1.编写父组件"></a>7.1.1.编写父组件</h3><p>为了让接下来的功能比较清晰，我们先新建一个文件夹：src</p><p>然后新建一个 HTML 文件，作为入口：index.html</p><p><img src="https://js.hnlyx.top/img/1530148321175.png" alt="1530148321175"></p><p>然后编写页面的基本结构：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">span</span>&gt;</span>登录<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">span</span>&gt;</span>注册<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">hr</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span>&gt;</span>登录页/注册页<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;../node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>样式：</p><p><img src="https://js.hnlyx.top/img/1530149363817.png" alt="1530149363817"></p><h3 id="7-1-2-编写登录及注册组件"><a href="#7-1-2-编写登录及注册组件" class="headerlink" title="7.1.2.编写登录及注册组件"></a>7.1.2.编写登录及注册组件</h3><p>接下来我们来实现登录组件，以前我们都是写在一个文件中，但是为了复用性，开发中都会把组件放入独立的 JS 文件中，我们新建一个 user 目录以及 login.js 及 register.js：</p><p><img src="https://js.hnlyx.top/img/1530156389366.png" alt="1530156389366"></p><p>编写组件，这里我们只写模板，不写功能。</p><p>login.js 内容如下：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> loginForm = &#123;</span><br><span class="line">  <span class="attr">template</span>:</span><br><span class="line">    <span class="string">&#x27;\</span></span><br><span class="line"><span class="string">    &lt;div&gt;\</span></span><br><span class="line"><span class="string">    &lt;h2&gt;登录页&lt;/h2&gt; \</span></span><br><span class="line"><span class="string">    用户名：&lt;input type=&quot;text&quot;&gt;&lt;br/&gt;\</span></span><br><span class="line"><span class="string">    密码：&lt;input type=&quot;password&quot;&gt;&lt;br/&gt;\</span></span><br><span class="line"><span class="string">    &lt;/div&gt;\</span></span><br><span class="line"><span class="string">    &#x27;</span>,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>register.js 内容：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> registerForm = &#123;</span><br><span class="line">  <span class="attr">template</span>:</span><br><span class="line">    <span class="string">&#x27;\</span></span><br><span class="line"><span class="string">    &lt;div&gt;\</span></span><br><span class="line"><span class="string">    &lt;h2&gt;注册页&lt;/h2&gt; \</span></span><br><span class="line"><span class="string">    用 户 名：&lt;input type=&quot;text&quot;&gt;&lt;br/&gt;\</span></span><br><span class="line"><span class="string">    密  码：&lt;input type=&quot;password&quot;&gt;&lt;br/&gt;\</span></span><br><span class="line"><span class="string">    确认密码：&lt;input type=&quot;password&quot;&gt;&lt;br/&gt;\</span></span><br><span class="line"><span class="string">    &lt;/div&gt;\</span></span><br><span class="line"><span class="string">    &#x27;</span>,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3 id="7-1-3-在父组件中引用"><a href="#7-1-3-在父组件中引用" class="headerlink" title="7.1.3.在父组件中引用"></a>7.1.3.在父组件中引用</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">span</span>&gt;</span>登录<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">span</span>&gt;</span>注册<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">hr</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--&lt;loginForm&gt;&lt;/loginForm&gt;--&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            疑问：为什么不采用上面的写法？</span></span><br><span class="line"><span class="comment">            由于html是大小写不敏感的，如果采用上面的写法，则被认为是&lt;loginform&gt;&lt;/loginform&gt;</span></span><br><span class="line"><span class="comment">            所以，如果是驼峰形式的组件，需要把驼峰转化为“-”的形式</span></span><br><span class="line"><span class="comment">         --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">login-form</span>&gt;</span><span class="tag">&lt;/<span class="name">login-form</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">register-form</span>&gt;</span><span class="tag">&lt;/<span class="name">register-form</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;../node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;user/login.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;user/register.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">components</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      loginForm,</span></span><br><span class="line"><span class="language-javascript">      registerForm,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530157389501.png" alt="1530157389501"></p><h3 id="7-1-5-问题"><a href="#7-1-5-问题" class="headerlink" title="7.1.5.问题"></a>7.1.5.问题</h3><p>我们期待的是，当点击登录或注册按钮，分别显示登录页或注册页，而不是一起显示。</p><p>但是，如何才能动态加载组件，实现组件切换呢？</p><p>虽然使用原生的 Html5 和 JS 也能实现，但是官方推荐我们使用 vue-router 模块。</p><h2 id="7-2-vue-router-简介和安装"><a href="#7-2-vue-router-简介和安装" class="headerlink" title="7.2.vue-router 简介和安装"></a>7.2.vue-router 简介和安装</h2><p>使用 vue-router 和 vue 可以非常方便的实现 复杂单页应用的动态路由功能。</p><p>官网：<a href="https://router.vuejs.org/zh-cn/">https://router.vuejs.org/zh-cn/</a></p><p>使用 npm 安装：<code>npm install vue-router --save</code></p><p><img src="https://js.hnlyx.top/img/1530161293338.png" alt="1530161293338"></p><p>在 index.html 中引入依赖：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;../node_modules/vue-router/dist/vue-router.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="7-3-快速入门"><a href="#7-3-快速入门" class="headerlink" title="7.3.快速入门"></a>7.3.快速入门</h2><p>新建 vue-router 对象，并且指定路由规则：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建VueRouter对象</span></span><br><span class="line"><span class="keyword">const</span> router = <span class="keyword">new</span> <span class="title class_">VueRouter</span>(&#123;</span><br><span class="line">  <span class="attr">routes</span>: [</span><br><span class="line">    <span class="comment">// 编写路由规则</span></span><br><span class="line">    &#123;</span><br><span class="line">      <span class="attr">path</span>: <span class="string">&quot;/login&quot;</span>, <span class="comment">// 请求路径</span></span><br><span class="line">      <span class="attr">component</span>: loginForm, <span class="comment">// 组件名称</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">&quot;/register&quot;</span>, <span class="attr">component</span>: registerForm &#125;,</span><br><span class="line">  ],</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><ul><li>创建 VueRouter 对象，并指定路由参数</li><li>routes：路由规则的数组，可以指定多个对象，每个对象是一条路由规则，包含以下属性：<ul><li>path：路由的路径</li><li>component：组件名称</li></ul></li></ul><p>在父组件中引入 router 对象：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">components</span>: &#123;</span><br><span class="line">    <span class="comment">// 引用登录和注册组件</span></span><br><span class="line">    loginForm,</span><br><span class="line">    registerForm,</span><br><span class="line">  &#125;,</span><br><span class="line">  router, <span class="comment">// 引用上面定义的router对象</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>页面跳转控制：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--router-link来指定跳转的路径--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">span</span>&gt;</span><span class="tag">&lt;<span class="name">router-link</span> <span class="attr">to</span>=<span class="string">&quot;/login&quot;</span>&gt;</span>登录<span class="tag">&lt;/<span class="name">router-link</span>&gt;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">span</span>&gt;</span><span class="tag">&lt;<span class="name">router-link</span> <span class="attr">to</span>=<span class="string">&quot;/register&quot;</span>&gt;</span>注册<span class="tag">&lt;/<span class="name">router-link</span>&gt;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">hr</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--vue-router的锚点--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">router-view</span>&gt;</span><span class="tag">&lt;/<span class="name">router-view</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li>通过<code>&lt;router-view&gt;</code>来指定一个锚点，当路由的路径匹配时，vue-router 会自动把对应组件放到锚点位置进行渲染</li><li>通过<code>&lt;router-link&gt;</code>指定一个跳转链接，当点击时，会触发 vue-router 的路由功能，路径中的 hash 值会随之改变</li></ul><p>效果：</p><p><img src="https://js.hnlyx.top/img/62.gif"></p><p><strong>注意</strong>：单页应用中，页面的切换并不是页面的跳转。仅仅是地址最后的 hash 值变化。</p><p>事实上，我们总共就一个 HTML：index.html</p><h1 id="8-webpack"><a href="#8-webpack" class="headerlink" title="8.webpack"></a>8.webpack</h1><p>Webpack 是一个前端资源的打包工具，它可以将 js、image、css 等资源当成一个模块进行打包。</p><p>中文官方网站：<a href="https://www.webpackjs.com/">https://www.webpackjs.com/</a></p><p><img src="https://js.hnlyx.top/img/1530168661348.png" alt="1530168661348"></p><p>官网给出的解释：</p><blockquote><p>本质上，<em>webpack</em>  是一个现代 JavaScript 应用程序的<em>静态模块打包器(module bundler)</em>。当 webpack 处理应用程序时，它会递归地构建一个<em>依赖关系图(dependency graph)</em>，其中包含应用程序需要的每个模块，然后将所有这些模块打包成一个或多个  <em>bundle</em>。</p></blockquote><p>为什么需要打包？</p><ul><li>将许多碎小文件打包成一个整体，减少单页面内的衍生请求次数，提高网站效率。</li><li>将 ES6 的高级语法进行转换编译，以兼容老版本的浏览器。</li><li>将代码打包的同时进行混淆，提高代码的安全性。</li></ul><h2 id="8-1-安装"><a href="#8-1-安装" class="headerlink" title="8.1.安装"></a>8.1.安装</h2><p>webpack 支持全局安装和本地安装，官方推荐是本地安装，我们按照官方的来。</p><p>安装最新版本 webpack，输入命令：<code>npm install --save-dev webpack</code></p><p>webpack 4+ 版本，你还需要安装 CLI ，输入命令：<code>npm install webpack webpack-cli --save-dev</code></p><p><img src="https://js.hnlyx.top/img/1530187524815.png" alt="1530187524815"></p><p>此时，我们注意下项目中文件夹下，会有一个 package.json 文件。（其实早就有了）</p><p><img src="https://js.hnlyx.top/img/1530187744149.png" alt="1530187744149"></p><p>打开文件，可以看到我们之前用 npm 安装过的文件都会出现在这里：</p><p><img src="https://js.hnlyx.top/img/1525873343908.png" alt="1525873343908"></p><h2 id="8-2-核心概念"><a href="#8-2-核心概念" class="headerlink" title="8.2.核心概念"></a>8.2.核心概念</h2><p>学习 Webpack，你需要先理解四个<strong>核心概念</strong>：</p><ul><li><p>入口(entry)</p><p>webpack 打包的起点，可以有一个或多个，一般是 js 文件。webpack 会从启点文件开始，寻找启点直接或间接依赖的其它所有的依赖，包括 JS、CSS、图片资源等，作为将来打包的原始数据</p></li><li><p>输出(output)</p><p>出口一般包含两个属性：path 和 filename。用来告诉 webpack 打包的目标文件夹，以及文件的名称。目的地也可以有多个。</p></li><li><p>加载器（loader）</p><p>webpack 本身只识别 Js 文件，如果要加载非 JS 文件，必须指定一些额外的加载器（loader），例如 css-loader。然后将这些文件转为 webpack 能处理的有效模块，最后利用 webpack 的打包能力去处理。</p></li><li><p>插件(plugins)</p><p>插件可以扩展 webpack 的功能，让 webpack 不仅仅是完成打包，甚至各种更复杂的功能，或者是对打包功能进行优化、压缩，提高效率。</p></li></ul><h2 id="8-3-编写-webpack-配置"><a href="#8-3-编写-webpack-配置" class="headerlink" title="8.3.编写 webpack 配置"></a>8.3.编写 webpack 配置</h2><p>接下来，我们编写一个 webpack 的配置，来指定一些打包的配置项。配置文件的名称，默认就是 webpack.config.js，我们放到 hello-vue 的根目录：</p><p><img src="https://js.hnlyx.top/img/1530199761226.png" alt="1530199761226"></p><p>配置文件中就是要指定上面说的四个核心概念，入口、出口、加载器、插件。</p><p>不过，加载器和插件是可选的。我们先编写入口和出口</p><h3 id="8-3-1-入口-entry"><a href="#8-3-1-入口-entry" class="headerlink" title="8.3.1.入口 entry"></a>8.3.1.入口 entry</h3><p>webpack 打包的启点，可以有一个或多个，一般是 js 文件。现在思考一下我们有没有一个入口？貌似没有，我们所有的东西都集中在 index.html，不是一个 js，那怎么办？</p><p>我们新建一个 js，把 index.html 中的部分内容进行集中，然后在 index.html 中引用这个 js 不就 OK 了！</p><p><img src="https://js.hnlyx.top/img/1530200787599.png" alt="1530200787599"></p><p>然后把原来 index.html 中的 js 代码全部移动到 index.js 中</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用es6的语法导入js模块</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Vue</span> <span class="keyword">from</span> <span class="string">&quot;../node_modules/vue/dist/vue&quot;</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="title class_">VueRouter</span> <span class="keyword">from</span> <span class="string">&quot;../node_modules/vue-router/dist/vue-router&quot;</span>;</span><br><span class="line"><span class="keyword">import</span> loginForm <span class="keyword">from</span> <span class="string">&quot;./user/login&quot;</span>;</span><br><span class="line"><span class="keyword">import</span> registerForm <span class="keyword">from</span> <span class="string">&quot;./user/register&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="title class_">Vue</span>.<span class="title function_">use</span>(<span class="title class_">VueRouter</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建vue对象</span></span><br><span class="line"><span class="keyword">const</span> router = <span class="keyword">new</span> <span class="title class_">VueRouter</span>(&#123;</span><br><span class="line">  <span class="attr">routes</span>: [</span><br><span class="line">    <span class="comment">// 编写路由规则</span></span><br><span class="line">    <span class="comment">// path: 路由请求路径；component：组件名称</span></span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">&quot;/login&quot;</span>, <span class="attr">component</span>: loginForm &#125;,</span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">&quot;/register&quot;</span>, <span class="attr">component</span>: registerForm &#125;,</span><br><span class="line">  ],</span><br><span class="line">&#125;);</span><br><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">  <span class="attr">el</span>: <span class="string">&quot;#app&quot;</span>,</span><br><span class="line">  <span class="attr">components</span>: &#123;</span><br><span class="line">    loginForm,</span><br><span class="line">    registerForm,</span><br><span class="line">  &#125;,</span><br><span class="line">  router,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><ul><li><p>原来的 index.html 中引入了很多其它 js，在这里我们使用 es6 的 import 语法进行导入。</p></li><li><p>注意，要使用 import，就需要在 login.js 和 register.js 中添加 export 导出语句：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> loginForm = &#123;</span><br><span class="line">  <span class="attr">template</span>:</span><br><span class="line">    <span class="string">&#x27;\</span></span><br><span class="line"><span class="string">       &lt;div&gt;\</span></span><br><span class="line"><span class="string">            &lt;h2&gt;登陆页&lt;/h2&gt;\</span></span><br><span class="line"><span class="string">            用户名：&lt;input type=&quot;text&quot;&gt;&lt;br&gt;\</span></span><br><span class="line"><span class="string">            密 码：&lt;input type=&quot;password&quot;&gt;\</span></span><br><span class="line"><span class="string">       &lt;/div&gt;&#x27;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> loginForm;</span><br></pre></td></tr></table></figure><p>register.js:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> registerForm = &#123;</span><br><span class="line">  <span class="attr">template</span>:</span><br><span class="line">    <span class="string">&#x27;\</span></span><br><span class="line"><span class="string">    &lt;div&gt;\</span></span><br><span class="line"><span class="string">    &lt;h2&gt;注册页&lt;/h2&gt; \</span></span><br><span class="line"><span class="string">    用 户 名：&lt;input type=&quot;text&quot;&gt;&lt;br/&gt;\</span></span><br><span class="line"><span class="string">    密  码：&lt;input type=&quot;password&quot;&gt;&lt;br/&gt;\</span></span><br><span class="line"><span class="string">    确认密码：&lt;input type=&quot;password&quot;&gt;&lt;br/&gt;\</span></span><br><span class="line"><span class="string">    &lt;/div&gt;\</span></span><br><span class="line"><span class="string">    &#x27;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> registerForm;</span><br></pre></td></tr></table></figure></li><li><p>vue-router 使用模块化加载后，必须增加一句：Vue.use(VueRouter)</p></li></ul><p>这样，index.js 就成了我们整个配置的入口了。</p><p>我们在 webpack.config.js 中添加以下内容：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="attr">entry</span>: <span class="string">&quot;./src/index.js&quot;</span>, <span class="comment">//指定打包的入口文件</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3 id="8-3-2-出口-output"><a href="#8-3-2-出口-output" class="headerlink" title="8.3.2.出口 output"></a>8.3.2.出口 output</h3><p>出口，就是输出的目的地。一般我们会用一个 dist 目录，作为打包输出的文件夹：</p><p><img src="https://js.hnlyx.top/img/1530201612391.png" alt="1530201612391"></p><p>然后，编写 webpack.config.js，添加出口配置：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="attr">entry</span>: <span class="string">&quot;./src/main.js&quot;</span>, <span class="comment">//指定打包的入口文件</span></span><br><span class="line">  <span class="attr">output</span>: &#123;</span><br><span class="line">    <span class="comment">// path: 输出的目录，__dirname是相对于webpack.config.js配置文件的绝对路径</span></span><br><span class="line">    <span class="attr">path</span>: __dirname + <span class="string">&quot;/dist&quot;</span>,</span><br><span class="line">    <span class="attr">filename</span>: <span class="string">&quot;build.js&quot;</span>, <span class="comment">//输出的js文件名</span></span><br><span class="line">  &#125;,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h2 id="8-4-执行打包"><a href="#8-4-执行打包" class="headerlink" title="8.4.执行打包"></a>8.4.执行打包</h2><p>在控制台输入以下命令：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx webpack --config webpack.config.js</span><br></pre></td></tr></table></figure><p><img src="https://js.hnlyx.top/img/1530203361613.png" alt="1530203361613"></p><p>随后，查看 dist 目录：</p><p><img src="https://js.hnlyx.top/img/1530203406462.png" alt="1530203406462"></p><p>尝试打开 build.js，你根本看不懂：</p><p><img src="https://js.hnlyx.top/img/1530203465737.png" alt="1530203465737"></p><p>所有的 js 合并为 1 个，并且对变量名进行了随机打乱，这样就起到了 压缩、混淆的作用。</p><h2 id="8-5-测试运行"><a href="#8-5-测试运行" class="headerlink" title="8.5.测试运行"></a>8.5.测试运行</h2><p>在 index.html 中引入刚刚生成的 build.js 文件，</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Title<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">      <span class="comment">&lt;!--router-link来指定跳转的路径--&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">span</span>&gt;</span><span class="tag">&lt;<span class="name">router-link</span> <span class="attr">to</span>=<span class="string">&quot;/login&quot;</span>&gt;</span>登录<span class="tag">&lt;/<span class="name">router-link</span>&gt;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">span</span>&gt;</span><span class="tag">&lt;<span class="name">router-link</span> <span class="attr">to</span>=<span class="string">&quot;/register&quot;</span>&gt;</span>注册<span class="tag">&lt;/<span class="name">router-link</span>&gt;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">hr</span> /&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--vue-router的锚点--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">router-view</span>&gt;</span><span class="tag">&lt;/<span class="name">router-view</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;../dist/build.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><p>然后运行：</p><p><img src="https://js.hnlyx.top/img/1530203553915.png" alt="1530203553915"></p><h2 id="8-6-打包-CSS"><a href="#8-6-打包-CSS" class="headerlink" title="8.6.打包 CSS"></a>8.6.打包 CSS</h2><p>我们来编写一段 CSS 代码，对 index 的样式做一些美化：</p><p><img src="https://js.hnlyx.top/img/1530203880056.png" alt="1530203880056"></p><p>内容：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-id">#app</span> <span class="selector-tag">a</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: inline-block;</span><br><span class="line">  <span class="attribute">width</span>: <span class="number">150px</span>;</span><br><span class="line">  <span class="attribute">line-height</span>: <span class="number">30px</span>;</span><br><span class="line">  <span class="attribute">background-color</span>: dodgerblue;</span><br><span class="line">  <span class="attribute">color</span>: white;</span><br><span class="line">  <span class="attribute">font-size</span>: <span class="number">16px</span>;</span><br><span class="line">  <span class="attribute">text-decoration</span>: none;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-id">#app</span> <span class="selector-tag">a</span><span class="selector-pseudo">:hover</span> &#123;</span><br><span class="line">  <span class="attribute">background-color</span>: whitesmoke;</span><br><span class="line">  <span class="attribute">color</span>: dodgerblue;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-id">#app</span> <span class="selector-tag">div</span> &#123;</span><br><span class="line">  <span class="attribute">width</span>: <span class="number">300px</span>;</span><br><span class="line">  <span class="attribute">height</span>: <span class="number">150px</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-id">#app</span> &#123;</span><br><span class="line">  <span class="attribute">width</span>: <span class="number">305px</span>;</span><br><span class="line">  <span class="attribute">border</span>: <span class="number">1px</span> solid dodgerblue;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="8-6-1-安装加载器"><a href="#8-6-1-安装加载器" class="headerlink" title="8.6.1.安装加载器"></a>8.6.1.安装加载器</h3><p>前面说过，webpack 默认只支持 js 加载。要加载 CSS 文件，必须安装加载器：</p><p>命令：<code>npm install style-loader css-loader --save-dev</code></p><p><img src="https://js.hnlyx.top/img/1530204068192.png" alt="1530204068192"></p><p>此时，在 package.json 中能看到新安装的：</p><p><img src="https://js.hnlyx.top/img/1530204160848.png" alt="1530204160848"></p><h3 id="8-6-3-index-js-引入-css-文件"><a href="#8-6-3-index-js-引入-css-文件" class="headerlink" title="8.6.3.index.js 引入 css 文件"></a>8.6.3.index.js 引入 css 文件</h3><p>因为入口在 index.js，因此 css 文件也要在这里引入。依然使用 ES6 的模块语法：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="string">&quot;./css/main.css&quot;</span>;</span><br></pre></td></tr></table></figure><h3 id="8-6-4-配置加载器"><a href="#8-6-4-配置加载器" class="headerlink" title="8.6.4.配置加载器"></a>8.6.4.配置加载器</h3><p>在 webpack.config.js 配置文件中配置 css 的加载器</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="attr">entry</span>: <span class="string">&quot;./src/main.js&quot;</span>, <span class="comment">//指定打包的入口文件</span></span><br><span class="line">  <span class="attr">output</span>: &#123;</span><br><span class="line">    <span class="attr">path</span>: __dirname + <span class="string">&quot;/dist&quot;</span>, <span class="comment">// 注意：__dirname表示webpack.config.js所在目录的绝对路径</span></span><br><span class="line">    <span class="attr">filename</span>: <span class="string">&quot;build.js&quot;</span>, <span class="comment">//输出文件</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">module</span>: &#123;</span><br><span class="line">    <span class="attr">rules</span>: [</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="attr">test</span>: <span class="regexp">/\.css$/</span>, <span class="comment">// 通过正则表达式匹配所有以.css后缀的文件</span></span><br><span class="line">        <span class="attr">use</span>: [</span><br><span class="line">          <span class="comment">// 要使用的加载器，这两个顺序一定不要乱</span></span><br><span class="line">          <span class="string">&quot;style-loader&quot;</span>,</span><br><span class="line">          <span class="string">&quot;css-loader&quot;</span>,</span><br><span class="line">        ],</span><br><span class="line">      &#125;,</span><br><span class="line">    ],</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3 id="8-6-5-重新打包"><a href="#8-6-5-重新打包" class="headerlink" title="8.6.5.重新打包"></a>8.6.5.重新打包</h3><p>再次输入打包指令：<code>npx webpack --config webpack.config.js</code></p><p><img src="https://js.hnlyx.top/img/1530204780240.png" alt="1530204780240"></p><p>效果：</p><p><img src="https://js.hnlyx.top/img/1530204813013.png" alt="1530204813013"></p><h2 id="8-7-script-脚本"><a href="#8-7-script-脚本" class="headerlink" title="8.7.script 脚本"></a>8.7.script 脚本</h2><p>我们每次使用 npm 安装，都会在 package.json 中留下痕迹，事实上，package.json 中不仅可以记录安装的内容，还可编写脚本，让我们运行命令更加快捷。</p><p>我们可以把 webpack 的命令编入其中：</p><p><img src="https://js.hnlyx.top/img/1530205423730.png" alt="1530205423730"></p><p>以后，如果要打包，就可以直接输入：<code>npm run build</code>即可。</p><p><code>npm run</code> ：执行 npm 脚本，后面跟的是配置脚本的名称<code>build</code></p><p><img src="https://js.hnlyx.top/img/1530205504104.png" alt="1530205504104"></p><h2 id="8-8-打包-HTML"><a href="#8-8-打包-HTML" class="headerlink" title="8.8.打包 HTML"></a>8.8.打包 HTML</h2><p>之前的打包过程中，除了 HTML 文件外的其它文件都被打包了，当在线上部署时，我们还得自己复制 HTML 到 dist，然后手动添加生成的 js 到 HTML 中，这非常不友好。</p><p>webpack 中的一个插件：html-webpack-plugin，可以解决这个问题。</p><p>1）安装插件：<code>npm install --save-dev html-webpack-plugin</code></p><p>需要在 webpack.config.js 中添加插件：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title class_">HtmlWebpackPlugin</span> = <span class="built_in">require</span>(<span class="string">&quot;html-webpack-plugin&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="attr">entry</span>: <span class="string">&quot;./src/main.js&quot;</span>, <span class="comment">//指定打包的入口文件</span></span><br><span class="line">  <span class="attr">output</span>: &#123;</span><br><span class="line">    <span class="attr">path</span>: __dirname + <span class="string">&quot;/dist&quot;</span>, <span class="comment">// 注意：__dirname表示webpack.config.js所在目录的绝对路径</span></span><br><span class="line">    <span class="attr">filename</span>: <span class="string">&quot;build.js&quot;</span>, <span class="comment">//输出文件</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">module</span>: &#123;</span><br><span class="line">    <span class="attr">rules</span>: [</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="attr">test</span>: <span class="regexp">/\.css$/</span>, <span class="comment">// 通过正则表达式匹配所有以.css后缀的文件</span></span><br><span class="line">        <span class="attr">use</span>: [</span><br><span class="line">          <span class="comment">// 要使用的加载器，这两个顺序一定不要乱</span></span><br><span class="line">          <span class="string">&quot;style-loader&quot;</span>,</span><br><span class="line">          <span class="string">&quot;css-loader&quot;</span>,</span><br><span class="line">        ],</span><br><span class="line">      &#125;,</span><br><span class="line">    ],</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">plugins</span>: [</span><br><span class="line">    <span class="keyword">new</span> <span class="title class_">HtmlWebpackPlugin</span>(&#123;</span><br><span class="line">      <span class="attr">title</span>: <span class="string">&quot;首页&quot;</span>, <span class="comment">//生成的页面标题&lt;head&gt;&lt;title&gt;首页&lt;/title&gt;&lt;/head&gt;</span></span><br><span class="line">      <span class="attr">filename</span>: <span class="string">&quot;index.html&quot;</span>, <span class="comment">// dist目录下生成的文件名</span></span><br><span class="line">      <span class="attr">template</span>: <span class="string">&quot;./src/index.html&quot;</span>, <span class="comment">// 我们原来的index.html，作为模板</span></span><br><span class="line">    &#125;),</span><br><span class="line">  ],</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>2）将原来 HTML 中的引入 js 代码删除：</p><p><img src="https://js.hnlyx.top/img/1530207035782.png" alt="1530207035782"></p><p>3）再次打包：<code>npm run build</code></p><p><img src="https://js.hnlyx.top/img/1530206990349.png" alt="1530206990349"></p><p>4）查看 dist 目录：</p><p><img src="https://js.hnlyx.top/img/1530207132261.png" alt="1530207132261"></p><p>打开 index.html，发现已经自动添加了当前目录下的 build.js</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Title<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">      <span class="comment">&lt;!--router-link来指定跳转的路径--&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">span</span>&gt;</span><span class="tag">&lt;<span class="name">router-link</span> <span class="attr">to</span>=<span class="string">&quot;/login&quot;</span>&gt;</span>登录<span class="tag">&lt;/<span class="name">router-link</span>&gt;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">span</span>&gt;</span><span class="tag">&lt;<span class="name">router-link</span> <span class="attr">to</span>=<span class="string">&quot;/register&quot;</span>&gt;</span>注册<span class="tag">&lt;/<span class="name">router-link</span>&gt;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--vue-router的锚点--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">router-view</span>&gt;</span><span class="tag">&lt;/<span class="name">router-view</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;build.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="8-9-热更新的-web-服务"><a href="#8-9-热更新的-web-服务" class="headerlink" title="8.9.热更新的 web 服务"></a>8.9.热更新的 web 服务</h2><p>刚才的案例中，每次修改任何 js 或 css 内容，都必须重新打包，非常麻烦。</p><p>webpack 给我们提供了一个插件，可以帮我们运行一个 web 服务，加载页面内容，并且修改 js 后不需要重新加载就能看到最新结果：</p><p>1）安装插件：<code>npm install webpack-dev-server --save-dev</code></p><p>2）添加启动脚本</p><p>在 package.json 中配置 script</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;scripts&quot;</span>: &#123;</span><br><span class="line">  <span class="string">&quot;dev&quot;</span>: <span class="string">&quot;webpack-dev-server --inline --hot --open --port 8080 --host 127.0.0.1&quot;</span></span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure><p>–inline：自动刷新</p><p>–hot：热加载</p><p>–port：指定端口</p><p>–open：自动在默认浏览器打开</p><p>–host：可以指定服务器的 ip，不指定则为 127.0.0.1</p><p>3）运行脚本：<code>npm run dev</code></p><p><img src="https://js.hnlyx.top/img/1530207667660.png" alt="1530207667660"></p><p>4）效果：</p><p><img src="https://js.hnlyx.top/img/1530207505226.png" alt="1530207505226"></p><h1 id="9-vue-cli"><a href="#9-vue-cli" class="headerlink" title="9.vue-cli"></a>9.vue-cli</h1><h2 id="9-1-介绍和安装"><a href="#9-1-介绍和安装" class="headerlink" title="9.1.介绍和安装"></a>9.1.介绍和安装</h2><p>在开发中，需要打包的东西不止是 js、css、html。还有更多的东西要处理，这些插件和加载器如果我们一一去添加就会比较麻烦。</p><p>幸好，vue 官方提供了一个快速搭建 vue 项目的脚手架：vue-cli</p><p>使用它能快速的构建一个 web 工程模板。</p><p>官网：<a href="https://github.com/vuejs/vue-cli">https://github.com/vuejs/vue-cli</a></p><p>安装命令：<code>npm install -g vue-cli</code></p><h2 id="9-2-快速上手"><a href="#9-2-快速上手" class="headerlink" title="9.2.快速上手"></a>9.2.快速上手</h2><p>我们新建一个 module：</p><p><img src="https://js.hnlyx.top/img/1530208068828.png" alt="1530208068828"></p><p>切换到该目录：</p><p><img src="https://js.hnlyx.top/img/1530208139922.png" alt="1530208139922"></p><p>用 vue-cli 命令，快速搭建一个 webpack 的项目：<code>vue init webpack</code></p><p><img src="https://js.hnlyx.top/img/1530208650256.png" alt="1530208556831"></p><p><img src="https://js.hnlyx.top/img/1530208708000.png" alt="1530208708000"></p><p>前面几项都走默认或 yes</p><p>下面这些我们选 no</p><p><img src="/assets/1530208850418.png" alt="1530208850418"></p><p>最后，再选 yes，使用 npm 安装</p><p><img src="https://js.hnlyx.top/img/1530208897063.png" alt="1530208897063"></p><p>开始初始化项目，并安装依赖，可能需要</p><p><img src="https://js.hnlyx.top/img/1530208932814.png" alt="1530208932814"></p><p>安装成功！</p><p><img src="https://js.hnlyx.top/img/1530209062090.png" alt="1530209062090"></p><p>可以使用<code>npm run dev</code>命令启动。</p><h2 id="9-3-项目结构"><a href="#9-3-项目结构" class="headerlink" title="9.3.项目结构"></a>9.3.项目结构</h2><p>安装好的项目结构：</p><p><img src="https://js.hnlyx.top/img/1530209146349.png" alt="1530209146349"></p><p>入口文件：main.js</p><p><img src="https://js.hnlyx.top/img/1530209503007.png" alt="1525913687860"></p><h2 id="9-4-单文件组件"><a href="#9-4-单文件组件" class="headerlink" title="9.4.单文件组件"></a>9.4.单文件组件</h2><p>需要注意的是，我们看到有一类后缀名为.vue 的文件，我们称为单文件组件</p><p><img src="https://js.hnlyx.top/img/1530209769323.png" alt="1530209769323"></p><p>每一个.vue 文件，就是一个独立的 vue 组件。类似于我们刚才写的 login.js 和 register.js</p><p>只不过，我们在 js 中编写 html 模板和样式非常的不友好，而且没有语法提示和高亮。</p><p>而单文件组件中包含三部分内容：</p><ul><li>template：模板，支持 html 语法高亮和提示</li><li>script：js 脚本，这里编写的就是 vue 的组件对象，还可以有 data(){}等</li><li>style：样式，支持 CSS 语法高亮和提示</li></ul><p>每个组件都有自己独立的 html、JS、CSS，互不干扰，真正做到可独立复用。</p><h2 id="9-5-运行"><a href="#9-5-运行" class="headerlink" title="9.5.运行"></a>9.5.运行</h2><p>看看生成的 package.json：</p><p><img src="https://js.hnlyx.top/img/1530210016103.png" alt="1530210016103"></p><ul><li>可以看到这引入了非常多的依赖，绝大多数都是开发期依赖，比如大量的加载器。</li><li>运行时依赖只有 vue 和 vue-router</li><li>脚本有三个：<ul><li>dev：使用了 webpack-dev-server 命令，开发时热部署使用</li><li>start：使用了 npm run dev 命令，与上面的 dev 效果完全一样，当脚本名为“start”时，可以省略“run”。</li><li>build：等同于 webpack 的打包功能，会打包到 dist 目录下。</li></ul></li></ul><p>我们执行<code>npm run dev</code> 或者 <code>npm start</code> 都可以启动项目：</p><p><img src="https://js.hnlyx.top/img/1530210411076.png" alt="1530210411076"></p><p>页面：</p><p><img src="https://js.hnlyx.top/img/1530210349704.png" alt="1530210349704"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;学习目标&quot;&gt;&lt;a href=&quot;#学习目标&quot; class=&quot;headerlink&quot; title=&quot;学习目标&quot;&gt;&lt;/a&gt;学习目标&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;会创建 Vue 实例，知道 Vue 的常见属性&lt;/li&gt;
&lt;li&gt;会使用 Vue 的生命周期的钩子函数&lt;/li&gt;</summary>
      
    
    
    
    
    <category term="Vue" scheme="https://www.yxliu.cc/tags/Vue/"/>
    
  </entry>
  
  <entry>
    <title>Vue简单学习</title>
    <link href="https://www.yxliu.cc/2022/12/07/91c8a1f4.html"/>
    <id>https://www.yxliu.cc/2022/12/07/91c8a1f4.html</id>
    <published>2022-12-07T11:58:27.000Z</published>
    <updated>2026-02-04T06:42:44.030Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Vue-常用指令-掌握"><a href="#Vue-常用指令-掌握" class="headerlink" title="Vue 常用指令(掌握)"></a>Vue 常用指令(掌握)</h1><h2 id="1-Vue-常用指令介绍"><a href="#1-Vue-常用指令介绍" class="headerlink" title="1.Vue 常用指令介绍"></a>1.Vue 常用指令介绍</h2><h3 id="学习目标"><a href="#学习目标" class="headerlink" title="学习目标"></a>学习目标</h3><ul><li>理解什么是Vue 指令</li><li>掌握如何使用Vue指令</li><li>能够说出常见的Vue指令</li></ul><h3 id="内容讲解"><a href="#内容讲解" class="headerlink" title="内容讲解"></a>内容讲解</h3><p>【1】Vue 指令介绍</p><p>在vue中指令是作用在视图中的即html标签，可以在视图中增加一些指令来设置html标签的某些属性和文本。</p><p>指令都是以带有 v- 前缀的特殊属性。</p><p>【2】使用Vue指令</p><p>使用指令时，通常编写在标签的属性上，值可以使用 JS 的表达式。</p><p>【3】常见的Vue指令</p><p><img src="https://js.hnlyx.top/img/image-20210124094135320.png" alt="image-20210124094135320"></p><h3 id="内容小结"><a href="#内容小结" class="headerlink" title="内容小结"></a>内容小结</h3><p>1.使用Vue指令注意事项</p><p>1）就是vue中的常见指令都是必须书写在html标签的属性中，在属性值中书写js代码。</p><p>2）vue中的指令只能使用在视图中，不能使用在脚本。</p><h2 id="2-文本插值v-html"><a href="#2-文本插值v-html" class="headerlink" title="2.文本插值v-html"></a>2.文本插值v-html</h2><h3 id="学习目标-1"><a href="#学习目标-1" class="headerlink" title="学习目标"></a>学习目标</h3><ul><li>能够使用文本插值</li><li>理解文本插值和插值表达式区别</li></ul><h3 id="内容讲解-1"><a href="#内容讲解-1" class="headerlink" title="内容讲解"></a>内容讲解</h3><p>【1】文本插值使用格式</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-html</span>=<span class="string">&quot;vue中data的key&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line">说明：文本插值v-html通过data的key获取value显示标签的文本中</span><br><span class="line">【2】需求：使用文本插值v-html和插值表达式&#123;&#123;&#125;&#125;获取vue中data数据</span><br></pre></td></tr></table></figure><p>【3】步骤：</p><blockquote><p>1.在素材中找到文本插值的代码</p><p>2.使用文本插值获取vue中的数据</p><p>3.打开浏览器查看结果</p></blockquote><p>【4】代码实现:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>文本插值<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--视图--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;div&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span>&gt;</span>&#123;&#123;msg&#125;&#125;<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--使用文本插值指令：v-html--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-html</span>=<span class="string">&quot;msg&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-text</span>=<span class="string">&quot;msg&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;js/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="comment">//脚本</span></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">el</span>:<span class="string">&quot;#div&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">data</span>:&#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">msg</span>:<span class="string">&quot;&lt;h1&gt;Hello Vue&lt;/h1&gt;&quot;</span></span></span><br><span class="line"><span class="language-javascript">        &#125;</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="内容小结-1"><a href="#内容小结-1" class="headerlink" title="内容小结"></a>内容小结</h3><p>1.使用文本插值，v-html 用来获取vue中的数据，将数据放到标签的文本中，并且解析标签。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-html</span>=<span class="string">&quot;data中的key&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br></pre></td></tr></table></figure><p>2.v-html于v-text和插值表达式的区别</p><blockquote><p><strong>1.v-html称为文本插值，属于指令，解析html标签</strong></p><p>2.插值表达式：,不解析html标签</p><p>3.v-text：属于指令，但是不解析html标签 了解</p></blockquote><h2 id="3-绑定属性-v-bind-属性名或者-属性名-重点"><a href="#3-绑定属性-v-bind-属性名或者-属性名-重点" class="headerlink" title="3.绑定属性  v-bind:属性名或者    :属性名  (重点)"></a>3.绑定属性  v-bind:属性名或者    :属性名  (重点)</h2><h3 id="学习目标-2"><a href="#学习目标-2" class="headerlink" title="学习目标"></a>学习目标</h3><ul><li>能够使用绑定属性的完整写法和简写</li></ul><h3 id="内容讲解-2"><a href="#内容讲解-2" class="headerlink" title="内容讲解"></a>内容讲解</h3><p>【1】绑定属性格式</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">完整写法</span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-bind:属性名</span>=<span class="string">&quot;data中key&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line">简写：常用 *****</span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">:属性名</span>=<span class="string">&quot;data中key&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br></pre></td></tr></table></figure><p>【2】需求：给html标签绑定属性</p><p>【3】步骤：</p><blockquote><p>1.在素材中找到绑定属性的代码</p><p>2.给html标签绑定属性，获取vue的data值作为属性值</p><p>3.打开浏览器查看结果</p></blockquote><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line">【4】代码实现:使用文本插值v-html和插值表达式&#123;&#123;&#125;&#125;获取vue中data数据</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span> <span class="attr">xmlns:v-bind</span>=<span class="string">&quot;http://www.w3.org/1999/xhtml&quot;</span> <span class="attr">xmlns:v-on</span>=<span class="string">&quot;http://www.w3.org/1999/xhtml&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>绑定属性<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.my</span>&#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">border</span>: <span class="number">1px</span> solid red;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">    </span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;div&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            插件表达式不能写在属性中</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&quot;&#123;&#123;url&#125;&#125;&quot;</span>&gt;</span>百度一下<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            v-bind：为 HTML 标签绑定属性值</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">a</span> <span class="attr">v-bind:href</span>=<span class="string">&quot;url&quot;</span>&gt;</span>百度一下<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            v-bind 可以省略不写</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">a</span> <span class="attr">:href</span>=<span class="string">&quot;url&quot;</span>&gt;</span>百度一下<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            也可以绑定其他属性</span></span><br><span class="line"><span class="comment">            给当前div标签绑定一个class属性，属性值通过data中的keycls获取到my，</span></span><br><span class="line"><span class="comment">            这里相当于</span></span><br><span class="line"><span class="comment">             &lt;div class=&quot;my&quot;&gt;我是div&lt;/div&gt;</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">:class</span>=<span class="string">&quot;cls&quot;</span>&gt;</span>我是div<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;js/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">el</span>:<span class="string">&quot;#div&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">data</span>:&#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">url</span>:<span class="string">&quot;http://www.baidu.com&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">cls</span>:<span class="string">&quot;my&quot;</span></span></span><br><span class="line"><span class="language-javascript">        &#125;</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="内容小结-2"><a href="#内容小结-2" class="headerlink" title="内容小结"></a>内容小结</h3><p>1.绑定属性格式：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">完整写法：</span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-bind:属性名</span>=<span class="string">&quot;data中的key&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line">简写：重点记忆</span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">:属性名</span>=<span class="string">&quot;data中的key&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="4-条件渲染v-if"><a href="#4-条件渲染v-if" class="headerlink" title="4.条件渲染v-if"></a>4.条件渲染v-if</h2><h3 id="学习目标-3"><a href="#学习目标-3" class="headerlink" title="学习目标"></a>学习目标</h3><ul><li>能够使用条件渲染v-if</li></ul><h3 id="内容讲解-3"><a href="#内容讲解-3" class="headerlink" title="内容讲解"></a>内容讲解</h3><p>【1】条件渲染v-if格式</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-if</span>=<span class="string">&quot;条件表达式&quot;</span>&gt;</span>满足条件显示的内容<span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-else-if</span>=<span class="string">&quot;条件表达式&quot;</span>&gt;</span>满足条件显示的内容<span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-else</span>&gt;</span>上述条件都不满足执行的内容<span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br></pre></td></tr></table></figure><p>【2】需求：判断vue中data的某个变量的值，对3取余，余数为0显示div1，余数为1显示div2，否则显示div3</p><p>【3】步骤</p><blockquote><p>1.在素材中找到条件渲染的代码</p><p>2.在html中获取vue中data的数据并判断，显示结果</p><p>3.打开浏览器查看结果</p></blockquote><p>【4】代码实现</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>条件渲染<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;div&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!-- 判断num的值，对3取余</span></span><br><span class="line"><span class="comment">            余数为0显示div1</span></span><br><span class="line"><span class="comment">            余数为1显示div2</span></span><br><span class="line"><span class="comment">            余数为2显示div3 --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-if</span>=<span class="string">&quot;num % 3 == 0&quot;</span>&gt;</span>div1<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-else-if</span>=<span class="string">&quot;num % 3 == 1&quot;</span>&gt;</span>div2<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--注意：如果不满足上述条件，则执行v-else，这里不用书写判断条件--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-else</span>&gt;</span>div3<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;js/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">el</span>:<span class="string">&quot;#div&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">data</span>:&#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">num</span>:<span class="number">2</span>,</span></span><br><span class="line"><span class="language-javascript">           <span class="attr">flag</span>:<span class="literal">true</span></span></span><br><span class="line"><span class="language-javascript">        &#125;</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="内容小结-3"><a href="#内容小结-3" class="headerlink" title="内容小结"></a>内容小结</h3><p>1.条件渲染：v-if</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-if</span>=<span class="string">&quot;条件表达式&quot;</span>&gt;</span>如果条件表达式为true则执行文本内容，如果为false则向下继续判断<span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-else-if</span>=<span class="string">&quot;条件表达式&quot;</span>&gt;</span>如果条件表达式为true则执行文本内容，如果为false则向下继续判断<span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line">....</span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-else</span>&gt;</span>如果上述条件都为false则执行该文本<span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line">注意：v-else，这里不用书写判断条件</span><br></pre></td></tr></table></figure><h2 id="5-条件渲染v-show"><a href="#5-条件渲染v-show" class="headerlink" title="5.条件渲染v-show"></a>5.条件渲染v-show</h2><h3 id="学习目标-4"><a href="#学习目标-4" class="headerlink" title="学习目标"></a>学习目标</h3><ul><li>能够使用条件渲染v-show</li><li>能够说出v-show和v-if区别</li></ul><h3 id="内容讲解-4"><a href="#内容讲解-4" class="headerlink" title="内容讲解"></a>内容讲解</h3><p>【1】条件渲染v-show格式</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-show</span>=<span class="string">&quot;data中的key&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line">说明：</span><br><span class="line">1.如果data中的key的值是true，则显示标签文本内容，如果是false则不显示标签文本内容</span><br></pre></td></tr></table></figure><p>【2】需求：获取Vue中data的布尔类型数据并显示</p><p>【3】步骤：</p><blockquote><p>1.在素材中找到条件渲染的代码</p><p>2.在html中获取vue中data的数据并判断，显示结果</p><p>3.打开浏览器查看结果</p></blockquote><p>【4】代码实现</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>条件渲染<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;div&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--v-show指令--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-show</span>=<span class="string">&quot;flag&quot;</span>&gt;</span>div4<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">       v-if  v-show 他们俩虽然都是控制元素是否显示，但是底层的原理不一样</span></span><br><span class="line"><span class="comment">           v-if 如果条件为false，页面中根本没有这个元素</span></span><br><span class="line"><span class="comment">           v-show如果条件为false，页面中有这个元素只不过它的display属性值为none</span></span><br><span class="line"><span class="comment">   --&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;js/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">el</span>: <span class="string">&quot;#div&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">data</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">num</span>: <span class="number">2</span>,</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">flag</span>: <span class="literal">false</span></span></span><br><span class="line"><span class="language-javascript">        &#125;</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="内容小结-4"><a href="#内容小结-4" class="headerlink" title="内容小结"></a>内容小结</h3><p>1.条件渲染v-show</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-show</span>=<span class="string">&quot;data中的key&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br></pre></td></tr></table></figure><p>2.v-show和v-if区别</p><blockquote><p>1.v-if：如果条件不满足，那么在页面中没有任何标签内容，直接删除</p><p>2.v-show:如果条件不满足，是通过设置css样式的属性display，设置属性值为none来隐藏标签，标签还在页面中，只是我们看不见</p></blockquote><h2 id="6-列表渲染-v-for"><a href="#6-列表渲染-v-for" class="headerlink" title="6.列表渲染 v-for"></a>6.列表渲染 v-for</h2><h3 id="学习目标-5"><a href="#学习目标-5" class="headerlink" title="学习目标"></a>学习目标</h3><ul><li>掌握如何使用v-for指令</li></ul><h3 id="内容讲解-5"><a href="#内容讲解-5" class="headerlink" title="内容讲解"></a>内容讲解</h3><p>【1】格式</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">增强for循环：掌握</span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-for</span>=<span class="string">&quot;x in 数组或者对象名或者集合名&quot;</span>&gt;</span></span><br><span class="line">     &#123;&#123;x&#125;&#125; 使用插值表达式获取元素</span><br><span class="line"><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line"></span><br><span class="line">普通for循环：了解</span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-for</span>=<span class="string">&quot;(x,index) in 数组或者对象名&quot;</span>&gt;</span></span><br><span class="line">   元素:&#123;&#123;x&#125;&#125;,索引:&#123;&#123;index&#125;&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br></pre></td></tr></table></figure><p>【2】作用：</p><p>遍历数组或者对象</p><p>【3】代码演示</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>列表渲染<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;div&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">               类似于增强for循环</span></span><br><span class="line"><span class="comment">               1. element是遍历得到的每一个元素(变量名可以自定义)</span></span><br><span class="line"><span class="comment">                   有一个作用域,它的作用于在当前的这个循环中</span></span><br><span class="line"><span class="comment">               2. names 是被遍历的数组或对象</span></span><br><span class="line"><span class="comment">               3.我们在标签文本中使用插值表达式根据遍历数组的每个元素的变量element获取对应数据</span></span><br><span class="line"><span class="comment">              --&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--需求：遍历names数组--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;element in names&quot;</span>&gt;</span></span><br><span class="line">                &#123;&#123;element&#125;&#125;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--需求：遍历对象student--&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">                1.stu 表示对象中的每组数据 :张三 23</span></span><br><span class="line"><span class="comment">                2.student表示遍历的对象名</span></span><br><span class="line"><span class="comment">            --&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;stu in student&quot;</span>&gt;</span></span><br><span class="line">                &#123;&#123;stu&#125;&#125;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">                类似于普通for循环(了解)</span></span><br><span class="line"><span class="comment">            --&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--需求：遍历names数组--&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">                1.element表示数组的元素</span></span><br><span class="line"><span class="comment">                2.index表示数组中的索引</span></span><br><span class="line"><span class="comment">            --&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;(element,index) in names&quot;</span>&gt;</span></span><br><span class="line">                元素:&#123;&#123;element&#125;&#125;,索引:&#123;&#123;index&#125;&#125;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--需求：遍历对象student--&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">                结果：</span></span><br><span class="line"><span class="comment">                元素:张三,索引:name</span></span><br><span class="line"><span class="comment">                元素:23,索引:age</span></span><br><span class="line"><span class="comment">                注意：在vue中使用v-for遍历对象时，使用普通for循环遍历，索引是对象中的key或者变量</span></span><br><span class="line"><span class="comment">            --&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;(element,index) in student&quot;</span>&gt;</span></span><br><span class="line">                元素:&#123;&#123;element&#125;&#125;,索引:&#123;&#123;index&#125;&#125;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;js/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">el</span>:<span class="string">&quot;#div&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">data</span>:&#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="comment">//数组</span></span></span><br><span class="line"><span class="language-javascript">            <span class="attr">names</span>:[<span class="string">&quot;张三&quot;</span>,<span class="string">&quot;李四&quot;</span>,<span class="string">&quot;王五&quot;</span>],</span></span><br><span class="line"><span class="language-javascript">            <span class="comment">//对象</span></span></span><br><span class="line"><span class="language-javascript">            <span class="attr">student</span>:&#123;</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">name</span>:<span class="string">&quot;张三&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="attr">age</span>:<span class="number">23</span></span></span><br><span class="line"><span class="language-javascript">            &#125;</span></span><br><span class="line"><span class="language-javascript">        &#125;</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="内容小结-5"><a href="#内容小结-5" class="headerlink" title="内容小结"></a>内容小结</h3><p>1.列表渲染主要用来遍历容器或者对象</p><p><strong>2.使用格式：掌握</strong></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">类似于增强for：</span><br><span class="line"><span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;元素 in 容器名或者对象名&quot;</span>&gt;</span></span><br><span class="line">    &#123;&#123;元素&#125;&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br></pre></td></tr></table></figure><p>说明：取出列表渲染中的元素使用插值表达式。</p><p>3.使用格式：了解</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;(元素,索引) in 容器名或者对象名&quot;</span>&gt;</span></span><br><span class="line">    &#123;&#123;元素&#125;&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br></pre></td></tr></table></figure><p>说明：如果遍历的是对象，那么会将对象中的key作为索引返回。</p><h2 id="7-事件绑定-v-on-事件名或者-事件名-重点"><a href="#7-事件绑定-v-on-事件名或者-事件名-重点" class="headerlink" title="7.事件绑定 v-on:事件名或者@事件名(重点)"></a>7.事件绑定 v-on:事件名或者@事件名(重点)</h2><h3 id="学习目标-6"><a href="#学习目标-6" class="headerlink" title="学习目标"></a>学习目标</h3><ul><li>掌握vue视图的事件绑定</li></ul><h3 id="内容讲解-6"><a href="#内容讲解-6" class="headerlink" title="内容讲解"></a>内容讲解</h3><p>【1】格式</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">标签名</span> <span class="attr">v-on:事件名</span>=<span class="string">&quot;调用的是vue中的js函数&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line">简写：掌握</span><br><span class="line"><span class="tag">&lt;<span class="name">标签名</span> @<span class="attr">事件名</span>=<span class="string">&quot;调用的是vue中的js函数&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">标签名</span>&gt;</span></span><br><span class="line">说明：</span><br><span class="line">1.在vue中绑定的事件名都是将原生js的事件名去掉on:click  blur...</span><br></pre></td></tr></table></figure><p>【2】需求：给视图绑定事件</p><p>【3】代码实现</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span> <span class="attr">xmlns:v-on</span>=<span class="string">&quot;http://www.w3.org/1999/xhtml&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>事件绑定<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;div&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span>&gt;</span>&#123;&#123;name&#125;&#125;<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            v-on：为 HTML 标签绑定事件</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;fn();&quot;</span>&gt;</span>以前方式_单击_改变div的内容<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            1.v-on:click=&quot;change();&quot; 给当前标签即视图绑定一个单击事件，在事件的属性值中直接调用vue中的函数change()</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">&quot;change();&quot;</span>&gt;</span>单击_改变div的内容<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:dblclick</span>=<span class="string">&quot;change();&quot;</span>&gt;</span>双击_改变div的内容<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;change();&quot;</span>&gt;</span>简写_改变div的内容<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;js/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> ve = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">el</span>:<span class="string">&quot;#div&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">data</span>:&#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">name</span>:<span class="string">&quot;黑马程序员&quot;</span></span></span><br><span class="line"><span class="language-javascript">        &#125;,</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">methods</span>:&#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="title function_">change</span>(<span class="params"></span>)&#123;</span></span><br><span class="line"><span class="language-javascript">                <span class="variable language_">this</span>.<span class="property">name</span> = <span class="string">&quot;传智播客&quot;</span>;</span></span><br><span class="line"><span class="language-javascript">            &#125;</span></span><br><span class="line"><span class="language-javascript">        &#125;</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="comment">//定义原生js函数</span></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">function</span> <span class="title function_">fn</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="comment">//调用vue中的函数change</span></span></span><br><span class="line"><span class="language-javascript">        ve.<span class="title function_">change</span>();</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="内容小结-6"><a href="#内容小结-6" class="headerlink" title="内容小结"></a>内容小结</h3><p>1.vue的事件绑定：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"> <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:事件名</span>=<span class="string">&quot;调用vue中的函数&quot;</span>&gt;</span>xxx<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">简写： 经常使用</span><br><span class="line"> <span class="tag">&lt;<span class="name">button</span> @<span class="attr">事件名</span>=<span class="string">&quot;调用vue中的函数&quot;</span>&gt;</span>xxx<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br></pre></td></tr></table></figure><p>2.vue中使用的事件名是将原生js中的事件名中的on给去掉</p><h2 id="8-表单绑定v-model-重点-非常重要"><a href="#8-表单绑定v-model-重点-非常重要" class="headerlink" title="8.表单绑定v-model(重点) 非常重要"></a>8.表单绑定v-model(重点) 非常重要</h2><h3 id="学习目标-7"><a href="#学习目标-7" class="headerlink" title="学习目标"></a>学习目标</h3><ul><li>能够使用v-model表单绑定指令</li><li>能够理解v-model表单绑定指令的作用</li></ul><h3 id="内容讲解-7"><a href="#内容讲解-7" class="headerlink" title="内容讲解"></a>内容讲解</h3><p>【1】v-model表单绑定作用：</p><p>可以实现双向数据绑定：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1）vue中的data数据更改，然后视图中的显示内容也会随着改变</span><br><span class="line">2）视图中的内容改变，vue中的data数据也会随着改变</span><br></pre></td></tr></table></figure><p>单向数据绑定：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vue中的data数据更改，然后视图中的显示内容也会随着改变</span><br></pre></td></tr></table></figure><p>【2】v-model表单绑定实现双向数据绑定的原理：</p><p><strong>MVVM模型(Model,View,ViewModel)：是MVC模式的改进版</strong><br>在前端页面中，JS对象表示Model，页面表示View，两者做到了最大限度的分离。<br>将Model和View关联起来的就是ViewModel，它是桥梁。<br>ViewModel负责把Model的数据同步到View显示出来，还负责把View修改的数据同步回Model。</p><p><img src="https://js.hnlyx.top/img/image-20210124111302902.png" alt="image-20210124111302902"></p><p>【3】</p><p>在vue中实现双向数据绑定使用表单绑定：v-model.</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span> <span class="attr">xmlns:v-bind</span>=<span class="string">&quot;http://www.w3.org/1999/xhtml&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>表单绑定<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;div&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">form</span> <span class="attr">autocomplete</span>=<span class="string">&quot;off&quot;</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">                单向绑定</span></span><br><span class="line"><span class="comment">            --&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">                :value=&quot;username&quot; 表示给当前input标签绑定value属性，username是vue中data的key</span></span><br><span class="line"><span class="comment">            --&gt;</span></span><br><span class="line">            姓名_单向绑定：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span> <span class="attr">:value</span>=<span class="string">&quot;username&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">                双向绑定</span></span><br><span class="line"><span class="comment">                1.v-model=&quot;username&quot;:表示给当前input标签进行双向数据绑定，显示到输入框中，</span></span><br><span class="line"><span class="comment">                直接根据key即username获取value</span></span><br><span class="line"><span class="comment">            --&gt;</span></span><br><span class="line">            姓名_双向绑定：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;username&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line">            年龄：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;number&quot;</span> <span class="attr">name</span>=<span class="string">&quot;age&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;age&quot;</span>&gt;</span></span><br><span class="line">            性别:<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">name</span>=<span class="string">&quot;gender&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;gender&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line">            &#123;&#123;username&#125;&#125;</span><br><span class="line">        <span class="tag">&lt;<span class="name">hr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;js/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">el</span>:<span class="string">&quot;#div&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">        <span class="attr">data</span>:&#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">username</span>:<span class="string">&quot;张三&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">age</span>:<span class="number">23</span>,</span></span><br><span class="line"><span class="language-javascript">            <span class="attr">gender</span>:<span class="string">&quot;男&quot;</span></span></span><br><span class="line"><span class="language-javascript">        &#125;</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="内容小结-7"><a href="#内容小结-7" class="headerlink" title="内容小结"></a>内容小结</h3><p><strong>1.表单绑定：v-model可以实现双向数据绑定。</strong></p><p>2.双向数据绑定：</p><p><img src="https://js.hnlyx.top/img/image-20210510110020380.png" alt="image-20210510110020380"></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">vue中的data数据改变，视图也会随着改变 --- 单向绑定</span><br><span class="line">视图改变，vue中的data中的数据也会改变</span><br></pre></td></tr></table></figure><p>3.使用格式：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">姓名_双向绑定：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;data中的变量名&quot;</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="9-指令小结"><a href="#9-指令小结" class="headerlink" title="9.指令小结"></a>9.指令小结</h2><p>1.文本插值：将data中的变量名表示的值解析到文本中</p><p>注意：可以解析html标签</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">v-html</span>=<span class="string">&quot;data中的变量名&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">v-html</span>=<span class="string">&quot;username&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">实现效果：</span><br><span class="line"><span class="tag">&lt;<span class="name">div</span>&gt;</span>锁哥<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">data:&#123;</span><br><span class="line">    username:&quot;锁哥&quot;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>2.绑定属性：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">v-bind:属性名</span>=<span class="string">&quot;data中的变量名&quot;</span>/&gt;</span> 可以绑定任意属性</span><br><span class="line">简写：使用较多</span><br><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">:属性名</span>=<span class="string">&quot;data中的变量名&quot;</span> /&gt;</span></span><br></pre></td></tr></table></figure><p>3.条件渲染：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">li</span> <span class="attr">v-if</span>=<span class="string">&quot;条件表达式&quot;</span>&gt;</span>文本1<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">li</span> <span class="attr">v-else-if</span>=<span class="string">&quot;条件表达式&quot;</span>&gt;</span>文本2<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">....</span><br><span class="line"><span class="tag">&lt;<span class="name">li</span> <span class="attr">v-else</span>&gt;</span>文本<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">li</span> <span class="attr">v-show</span>=<span class="string">&quot;条件表达式&quot;</span>&gt;</span>文本<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">如果条件表达式为true则显示文本，为false则给标签添加css样式即display:none 隐藏</span><br></pre></td></tr></table></figure><p>4.列表渲染：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;元素 in 容器或者对象名&quot;</span>&gt;</span></span><br><span class="line">    &#123;&#123;元素&#125;&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;(元素,索引) in 数组名或者对象名&quot;</span>&gt;</span></span><br><span class="line">    &#123;&#123;元素&#125;&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br></pre></td></tr></table></figure><p>5.事件绑定：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:事件名</span>=<span class="string">&quot;调用vue中的函数&quot;</span>&gt;</span></span><br><span class="line">    单击</span><br><span class="line"><span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">简写：经常使用,去掉原生js的事件名中的on</span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> @<span class="attr">事件名</span>=<span class="string">&quot;调用vue中的函数&quot;</span>&gt;</span></span><br><span class="line">    单击</span><br><span class="line"><span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>6.表单绑定 ：实现双向数据绑定。视图改变，data数据改变。data数据改变，视图也改变。</strong></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">v-model</span>=<span class="string">&quot;data中的变量名&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Vue-常用指令-掌握&quot;&gt;&lt;a href=&quot;#Vue-常用指令-掌握&quot; class=&quot;headerlink&quot; title=&quot;Vue 常用指令(掌握)&quot;&gt;&lt;/a&gt;Vue 常用指令(掌握)&lt;/h1&gt;&lt;h2 id=&quot;1-Vue-常用指令介绍&quot;&gt;&lt;a href=&quot;#1-V</summary>
      
    
    
    
    
    <category term="Vue" scheme="https://www.yxliu.cc/tags/Vue/"/>
    
  </entry>
  
  <entry>
    <title>MyBatis学习</title>
    <link href="https://www.yxliu.cc/2022/12/06/a8587907.html"/>
    <id>https://www.yxliu.cc/2022/12/06/a8587907.html</id>
    <published>2022-12-06T10:52:12.000Z</published>
    <updated>2026-02-04T06:42:44.030Z</updated>
    
    <content type="html"><![CDATA[<h1 id="mybatis映射文件配置"><a href="#mybatis映射文件配置" class="headerlink" title="mybatis映射文件配置"></a>mybatis映射文件配置</h1><h2 id="1、传入的参数"><a href="#1、传入的参数" class="headerlink" title="1、传入的参数"></a>1、传入的参数</h2><h3 id="【1】parameterType"><a href="#【1】parameterType" class="headerlink" title="【1】parameterType"></a>【1】parameterType</h3><pre><code>CRUD标签都有一个属性parameterType，底层的statement通过它指定接收的参数类型。入参数据有以下几种类型：HashMap，基本数据类型（包装类），实体类；</code></pre><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">设置传入这条语句的参数类的完全限定名或别名。这个属性是可选的，因为 MyBatis 可以通过类型处理器（TypeHandler） 推断出具体传入语句的参数类型。</span><br></pre></td></tr></table></figure><p><img src="https://js.hnlyx.top/img/1564474377224-164197976098210.png" alt="1564474377224"></p><p>说明：</p><p><strong>在mybatis中入参的数据类型分为2种：</strong></p><ol><li><p>简单数据类型：int,string,long,Date;</p></li><li><p>复杂数据类型：类(JavaBean)和Map;</p><p> 说明：如果传递参数是数组或者集合，底层都会封装到Map集合中。</p></li></ol><p>【示例】</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">UserMapper</span> &#123;</span><br><span class="line">    <span class="comment">//根据id查询</span></span><br><span class="line">    User <span class="title function_">queryById</span><span class="params">(Integer id)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">【基本类型数据】</span><br><span class="line"><span class="comment">&lt;!--根据id查询--&gt;</span></span><br><span class="line"><span class="comment">&lt;!--parameterType=&quot;int&quot; 表示sql语句参数id的类型，int是Integer的别名.MyBatis 可以通过类型处理器（TypeHandler） 根据接口中的方法User queryById(Integer id)参数类型推断出具体传入语句的参数类型。--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryById&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span> <span class="attr">parameterType</span>=<span class="string">&quot;int&quot;</span>&gt;</span></span><br><span class="line">    select * from user where id = #&#123;id&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br><span class="line"></span><br><span class="line">【pojo类型】</span><br><span class="line"><span class="tag">&lt;<span class="name">insert</span> <span class="attr">id</span>=<span class="string">&quot;savetUser&quot;</span> <span class="attr">parameterType</span>=<span class="string">&quot;User&quot;</span>&gt;</span></span><br><span class="line">  INSERT INTO user(...)</span><br><span class="line"><span class="tag">&lt;/<span class="name">insert</span>&gt;</span></span><br></pre></td></tr></table></figure><p>说明：对于parameterType属性可以不书写，那么MyBatis 就会通过类型处理器（TypeHandler） 根据接口中的方法User queryById(Integer id)参数类型推断出具体传入语句的参数类型。</p><h3 id="【2】自增主键回填（了解）"><a href="#【2】自增主键回填（了解）" class="headerlink" title="【2】自增主键回填（了解）"></a>【2】自增主键回填（了解）</h3><p>【需求】</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">新增一条数据成功后，将这条数据的主键封装到实体类中，并查看主键的值。</span><br></pre></td></tr></table></figure><p>【实现】</p><p>测试类代码：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">saveUser</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">User</span>();</span><br><span class="line">    user.setUsername(<span class="string">&quot;蔡徐坤&quot;</span>);</span><br><span class="line">    user.setBirthday(<span class="keyword">new</span> <span class="title class_">Date</span>());</span><br><span class="line">    user.setSex(<span class="string">&quot;男&quot;</span>);</span><br><span class="line">    user.setAddress(<span class="string">&quot;上海&quot;</span>);</span><br><span class="line"></span><br><span class="line">    userMapper.saveUser(user);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//查看新的数据的主键值</span></span><br><span class="line">    System.out.println(user.getId());<span class="comment">//null</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>直接获取的结果是null。</p><p>有两种方式可以实现添加好数据直接将主键封装到实体类对象中，如下：</p><h4 id="实现一：使用insert标签的子标签selectKey实现；-自学，了解，使用不多"><a href="#实现一：使用insert标签的子标签selectKey实现；-自学，了解，使用不多" class="headerlink" title="实现一：使用insert标签的子标签selectKey实现；(自学，了解，使用不多)"></a><strong>实现一：使用insert标签的子标签selectKey实现；(自学，了解，使用不多)</strong></h4><table><thead><tr><th>属性</th><th>说明</th></tr></thead><tbody><tr><td>keyColumn</td><td>主键在表中对应的列名</td></tr><tr><td>keyProperty</td><td>主键在实体类中对应的属性名</td></tr><tr><td>resultType</td><td>主键的数据类型</td></tr><tr><td>order</td><td>BEFORE:会首先选择主键,设置 keyProperty 然后执行插入语句 <br />AFTER: 在添加语句后执行查询主键的语句</td></tr></tbody></table><p>【映射文件】</p><p>mysql中的函数：<strong>last_insert_id()</strong> 得到最后添加的主键</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">添加用户</span></span><br><span class="line"><span class="comment">因为增删改没有查询的结果集，所以不用配置resultType</span></span><br><span class="line"><span class="comment">有返回值，返回影响的行数</span></span><br><span class="line"><span class="comment"> --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">insert</span> <span class="attr">id</span>=<span class="string">&quot;saveUser&quot;</span> <span class="attr">parameterType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">    insert into user values (null,#&#123;username&#125;,#&#123;birthday&#125;,#&#123;sex&#125;,#&#123;address&#125;)</span><br><span class="line">   <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">    keyColumn:主键在表中对应的列名</span></span><br><span class="line"><span class="comment">    keyProperty:主键在实体类中对应的属性名</span></span><br><span class="line"><span class="comment">    resultType:主键的数据类型</span></span><br><span class="line"><span class="comment">    order:</span></span><br><span class="line"><span class="comment">        BEFORE: 在添加语句前执行查询主键的语句</span></span><br><span class="line"><span class="comment">        AFTER: 在添加语句后执行查询主键的语句</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">selectKey</span> <span class="attr">keyColumn</span>=<span class="string">&quot;id&quot;</span> <span class="attr">keyProperty</span>=<span class="string">&quot;id&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;int&quot;</span> <span class="attr">order</span>=<span class="string">&quot;AFTER&quot;</span>&gt;</span></span><br><span class="line">        select last_insert_id()</span><br><span class="line">    <span class="tag">&lt;/<span class="name">selectKey</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">insert</span>&gt;</span></span><br></pre></td></tr></table></figure><p>测试代码</p><p>通过getId()得到新增的主键值</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> 添加1个用户</span></span><br><span class="line"><span class="comment"> 在mybatis中增删改，默认是手动提交事务</span></span><br><span class="line"><span class="comment"> 1. 设置成自动提交 factory.openSession(true);</span></span><br><span class="line"><span class="comment"> 2. 自己手动提交 session.commit();</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">saveUser</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">User</span>();</span><br><span class="line">        user.setUsername(<span class="string">&quot;蔡徐坤&quot;</span>);</span><br><span class="line">        user.setBirthday(<span class="keyword">new</span> <span class="title class_">Date</span>());</span><br><span class="line">        user.setSex(<span class="string">&quot;男&quot;</span>);</span><br><span class="line">        user.setAddress(<span class="string">&quot;上海&quot;</span>);</span><br><span class="line"></span><br><span class="line">        userMapper.saveUser(user);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//查看新的数据的主键值</span></span><br><span class="line">        System.out.println(user.getId());<span class="comment">//8</span></span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><h4 id="实现二：使用insert标签的属性useGeneratedKeys，keyProperty，keyColumn实现；"><a href="#实现二：使用insert标签的属性useGeneratedKeys，keyProperty，keyColumn实现；" class="headerlink" title="实现二：使用insert标签的属性useGeneratedKeys，keyProperty，keyColumn实现；"></a><strong>实现二：使用insert标签的属性useGeneratedKeys，keyProperty，keyColumn实现；</strong></h4><table><thead><tr><th>属性</th><th>说明</th></tr></thead><tbody><tr><td>useGeneratedKeys</td><td>true 获取自动生成的主键，相当于select last_insert_id()</td></tr><tr><td>keyColumn</td><td>表中主键的列名</td></tr><tr><td>keyProperty</td><td>实体类中主键的属性名</td></tr></tbody></table><p>映射文件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">insert</span> <span class="attr">id</span>=<span class="string">&quot;saveUser&quot;</span> <span class="attr">useGeneratedKeys</span>=<span class="string">&quot;true&quot;</span> <span class="attr">keyColumn</span>=<span class="string">&quot;id&quot;</span> <span class="attr">keyProperty</span>=<span class="string">&quot;id&quot;</span>&gt;</span></span><br><span class="line">        insert into user values (null ,#&#123;username&#125;,#&#123;birthday&#125;,#&#123;sex&#125;,#&#123;address&#125;)</span><br><span class="line"><span class="tag">&lt;/<span class="name">insert</span>&gt;</span></span><br></pre></td></tr></table></figure><ul><li>说明：直接在insert标签中增加属性的方式，只适合于支持自动增长主键类型的数据库，比如MySQL或SQL Server。</li></ul><h4 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h4><ol><li><p>添加用户使用哪个标签？</p><p>insert</p></li><li><p>得到主键值有哪两种方式？</p><ol><li>子标签：selectKey</li><li>在insert中添加属性</li></ol></li><li><p>在mysql中得到主键的函数： last_insert_id()</p></li></ol><h3 id="【3】单个参数，多个参数-重点"><a href="#【3】单个参数，多个参数-重点" class="headerlink" title="【3】单个参数，多个参数(重点)"></a>【3】单个参数，多个参数(重点)</h3><p>主要是针对简单类型的数据(int,string,long,Date)等数据进行入参处理。</p><h4 id="【单个参数】"><a href="#【单个参数】" class="headerlink" title="【单个参数】"></a>【单个参数】</h4><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">单个参数：接口方法传入一个参数</span><br></pre></td></tr></table></figure><h5 id="【接口传参】"><a href="#【接口传参】" class="headerlink" title="【接口传参】"></a>【接口传参】</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">User <span class="title function_">queryById</span><span class="params">(Integer id)</span>;</span><br></pre></td></tr></table></figure><h5 id="【接收参数】"><a href="#【接收参数】" class="headerlink" title="【接收参数】"></a>【接收参数】</h5><p><strong>1、通过#{参数名}接收</strong></p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--根据id查询--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryById&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span> <span class="attr">parameterType</span>=<span class="string">&quot;int&quot;</span>&gt;</span></span><br><span class="line">    select *,user_name AS  userName from user where id = #&#123;id&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>2、通过#{任意变量名}接收</strong></p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--根据id查询--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryById&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span> <span class="attr">parameterType</span>=<span class="string">&quot;int&quot;</span>&gt;</span></span><br><span class="line">    select *,user_name AS  userName from user where id = #&#123;abc&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><h5 id="【结论】"><a href="#【结论】" class="headerlink" title="【结论】"></a>【结论】</h5><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">当接口方法传入一个参数时，mybatis不做特殊处理，只需要#&#123;任意变量名&#125;都可接收；</span><br></pre></td></tr></table></figure><h4 id="【多个参数】"><a href="#【多个参数】" class="headerlink" title="【多个参数】"></a>【多个参数】</h4><p>需求：根据用户名和性别查询用户</p><h5 id="【接口传参】-1"><a href="#【接口传参】-1" class="headerlink" title="【接口传参】"></a>【接口传参】</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//根据用户名和性别查询</span></span><br><span class="line">User <span class="title function_">queryByUserNameAndSex</span><span class="params">(String userName, String sex)</span>;</span><br></pre></td></tr></table></figure><p>【UserMapper.xml】</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryByUserNameAndSex&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span>&gt;</span></span><br><span class="line">        select * from user where username=#&#123;username&#125; and sex=#&#123;sex&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>【测试类】</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">queryByUserNameAndSex</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> userMapper.queryByUserNameAndSex(<span class="string">&quot;孙悟空&quot;</span>, <span class="string">&quot;男&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;user = &quot;</span> + user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>【结果】</p><p><img src="https://js.hnlyx.top/img/image-20200605223006691-164197976098211.png" alt="image-20200605223006691"></p><p>上述报异常了，当传入多个参数时，mybatis底层进行了处理。我们需要按照如下几种方式解决异常：</p><h5 id="【接收参数】-1"><a href="#【接收参数】-1" class="headerlink" title="【接收参数】"></a>【接收参数】</h5><p><strong>1、使用参数索引获取：arg0,arg1</strong>(了解)</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--根据用户名和性别查询--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryByUserNameAndSex&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span>&gt;</span></span><br><span class="line">        select * from user where username=#&#123;arg0&#125; and sex=#&#123;arg1&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>说明：</p><p>这里的sql语句的参数书写顺序：select * from user where username&#x3D;#{arg0} and sex&#x3D;#{arg1}</p><p>和User user &#x3D; userMapper.queryByUserNameAndSex(“孙悟空”, “男”); 传递实参顺序一致。</p><p>也就是说：username&#x3D;#{arg0}  —》arg0的值是姓名孙悟空。</p><p>sex&#x3D;#{arg1}—》arg1的值是性别男。</p><p><strong>2、使用参数位置获取：param1,param2</strong>(了解)</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">&lt;!--根据用户名和性别查询--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryByUserNameAndSex&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span>&gt;</span></span><br><span class="line">     select * from user where username=#&#123;param1&#125; and sex=#&#123;param2&#125;</span><br><span class="line"> <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>3、使用命名参数获取，明确指定传入参数的名称：</strong>(掌握)</p><p>  步骤一：在接口中传入参数时通过@Param指定参数名称</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//根据用户名和性别查询</span></span><br><span class="line">User <span class="title function_">queryByUserNameAndSex</span><span class="params">(<span class="meta">@Param(&quot;username&quot;)</span> String userName, <span class="meta">@Param(&quot;sex&quot;)</span> String sex)</span>;</span><br></pre></td></tr></table></figure><p>  步骤二：在接收参数时，通过指定的名称获取参数值；</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--根据用户名和性别查询--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryByUserNameAndSex&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--#&#123;username&#125;这里的username是@Param(&quot;username&quot;)，也就是说@Param(&quot;标识符&quot;)标识符是什么，这里就写什么--&gt;</span></span><br><span class="line">    select * from user where username=#&#123;username&#125; and sex=#&#123;sex&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><h5 id="【小结】"><a href="#【小结】" class="headerlink" title="【小结】"></a>【小结】</h5><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">1、传入多个参数时，mybatis底层处理 ，先放到一个Object数组中，然后放到了Map集合中， Object[] == &gt; Map&lt;Key,Value&gt;  key-param1 key-username</span><br><span class="line">  Key值为：param1,param2......  </span><br><span class="line">  Value值为具体的内容；</span><br><span class="line"></span><br><span class="line">2、多个参数的取值方式：</span><br><span class="line">  参数索引：#&#123;arg0&#125; #&#123;arg1&#125;</span><br><span class="line">    参数位置：#&#123;param1&#125; #&#123;param2&#125; </span><br><span class="line">    命名参数：#&#123;参数名&#125;  </span><br><span class="line">3、无论使用的是单个参数还是多个参数，建议都使用命名参数进行传值；</span><br></pre></td></tr></table></figure><h3 id="【4】pojo参数【重点】"><a href="#【4】pojo参数【重点】" class="headerlink" title="【4】pojo参数【重点】"></a>【4】pojo参数【重点】</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">使用pojo来传递参数</span><br></pre></td></tr></table></figure><p><strong>接口添加方法：</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//新增</span></span><br><span class="line"><span class="keyword">void</span> <span class="title function_">saveUser</span><span class="params">(User user)</span>;</span><br></pre></td></tr></table></figure><p><strong>映射文件：</strong></p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--新增--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">insert</span> <span class="attr">id</span>=<span class="string">&quot;saveUser&quot;</span>&gt;</span></span><br><span class="line">    insert into user values (null ,#&#123;username&#125;,#&#123;birthday&#125;,#&#123;sex&#125;,#&#123;address&#125;)</span><br><span class="line"><span class="tag">&lt;/<span class="name">insert</span>&gt;</span></span><br></pre></td></tr></table></figure><p>说明：接口方法传入pojo类型的数据时，mybatis底层直接使用pojo封装数据。  sql语句中  #{username}取值&#x3D;&#x3D;》到pojo中调用 getUsername(){}</p><p><strong>测试:</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">saveUser</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">User</span>();</span><br><span class="line">    user.setUsername(<span class="string">&quot;蔡徐坤&quot;</span>);</span><br><span class="line">    user.setBirthday(<span class="keyword">new</span> <span class="title class_">Date</span>());</span><br><span class="line">    user.setSex(<span class="string">&quot;男&quot;</span>);</span><br><span class="line">    user.setAddress(<span class="string">&quot;上海&quot;</span>);</span><br><span class="line">    userMapper.saveUser(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="【5】HashMap参数"><a href="#【5】HashMap参数" class="headerlink" title="【5】HashMap参数"></a>【5】HashMap参数</h3><p>需求：模拟用户登录，登录方法参数是Map集合，泛型都是String类型分别表示用户名和性别。</p><p>在UserMapper接口中添加以下方法：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 用户登陆，参数为map</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">User <span class="title function_">login</span><span class="params">(Map&lt;String,String&gt; map)</span>;</span><br></pre></td></tr></table></figure><p><strong>UserMapper配置文件：</strong></p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">   将map的key作为参数名称来传递参数</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;login&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span>&gt;</span></span><br><span class="line">     select * from user where username=#&#123;username&#125; and sex=#&#123;sex&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>测试用例：</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">login</span><span class="params">()</span>&#123;</span><br><span class="line">    Map&lt;String, String&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">    map.put(<span class="string">&quot;username&quot;</span>,<span class="string">&quot;孙悟空&quot;</span>);</span><br><span class="line">    map.put(<span class="string">&quot;sex&quot;</span>,<span class="string">&quot;男&quot;</span>);</span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> userMapper.login(map);</span><br><span class="line">    System.out.println(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>注意事项：</strong></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">参数map中的key值是与SQL语句中 #&#123;&#125; 的取值名称一致。</span><br></pre></td></tr></table></figure><h3 id="【6】入参小结：接口方法传入的参数"><a href="#【6】入参小结：接口方法传入的参数" class="headerlink" title="【6】入参小结：接口方法传入的参数"></a>【6】入参小结：接口方法传入的参数</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">mybatis中能够接收<span class="number">2</span>种类型的参数传入：</span><br><span class="line"></span><br><span class="line">【<span class="number">1</span>】基本类型数据：</span><br><span class="line"> 单个数据： queryById(Integer id);</span><br><span class="line"> mybatis底层不做处理，使用任意变量都可接收   #&#123;abc&#125;</span><br><span class="line"> 多个数据： queryByUsernameAndSex(<span class="meta">@Param(&quot;username&quot;)</span>String username,<span class="meta">@Param(&quot;sex&quot;)</span>String sex);</span><br><span class="line">mybatis底层：</span><br><span class="line">第一步：把多个参数存储进数组最后放到集合map中，Map&#123;arg0,arg1&#125;    #&#123;arg0&#125; #&#123;arg1&#125;</span><br><span class="line">第二步：把数组中的数据转入Map中：</span><br><span class="line">username参数： param1-白骨精   username-白骨精</span><br><span class="line">     多个参数sql取值： #&#123;param1&#125;  #&#123;param2&#125;</span><br><span class="line">#&#123;username&#125;</span><br><span class="line">    最佳实践： 使用命名参数取值   queryByUsernameAndSex(<span class="meta">@Param(&quot;username&quot;)</span>String username);</span><br><span class="line"> sql取值：  #&#123;username&#125; ****</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">【<span class="number">2</span>】复杂数据类型：</span><br><span class="line"><span class="number">1.</span>pojo类型数据：mybatis底层直接使用pojo封装数据</span><br><span class="line">sql取值：  #&#123;pojo的属性名&#125;****   #&#123;username&#125;==&gt;调用pojo的 getUsername()&#123;&#125; </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="number">2.</span>map集合数据：mybatis底层直接使用map封装参数</span><br><span class="line">Map&lt;String,String&gt;  <span class="title function_">put</span><span class="params">(<span class="string">&quot;username&quot;</span>,<span class="string">&quot;白骨精&quot;</span>)</span></span><br><span class="line">              #&#123;username&#125;****</span><br></pre></td></tr></table></figure><h2 id="2、参数值的获取"><a href="#2、参数值的获取" class="headerlink" title="2、参数值的获取"></a>2、参数值的获取</h2><p><img src="https://js.hnlyx.top/img/image-20200606075427516-164197976098212.png" alt="image-20200606075427516"></p><p>说明：我们上述一直在讲解接口中的方法传入的参数，那么接下来我们要讲解如何在sql语句中获取传入的数据，其实我们之前也在一直使用一种方式就是**#{}**的方式。</p><p>参数值的获取指的是，statement获取接口方法中传入的参数。获取参数，有两种方式：<strong>#{}<strong>和</strong>${}</strong>；</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1573118237093-164197976098215.png" alt="1573118237093"> </p><h3 id="【1】-和-取值"><a href="#【1】-和-取值" class="headerlink" title="【1】#{}和${}取值"></a>【1】#{}和${}取值</h3><p><strong><code>#{}</code> 取值：</strong></p><p> <img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1573118237093-164197976098215.png" alt="1573118237093"></p><p>mybatis后台处理：</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1573118291670-164197976098213.png" alt="1573118291670"> </p><p><strong><code>${}</code> 取值：</strong></p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1573118342607-164197976098214.png" alt="1573118342607"> </p><p>mybatis后台处理：</p><p>【接口方法】</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//根据id查询</span></span><br><span class="line">User <span class="title function_">queryById</span><span class="params">(<span class="meta">@Param(&quot;id&quot;)</span> Integer id)</span>;</span><br></pre></td></tr></table></figure><p>【测试类】</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">queryById</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//获取mapper接口的动态代理实现</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> userMapper.queryById(<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;user = &quot;</span> + user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1573118364849-164197976098217.png" alt="1573118364849"> </p><p>【注意】${id} 获取id值时，必须使用命名参数取值：</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1573118417029-164197976098216.png" alt="1573118417029"> </p><p>如果不使用命名参数取值，即不在接口中加入@Param(“id”)，就会报异常：</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/image-20200606085015291-164197976098218.png" alt="image-20200606085015291"></p><p><strong>【小结】</strong></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">1、SQL语句中获取参数的方式：</span><br><span class="line">#&#123;xxx&#125;  sql:select * from user where id = ?</span><br><span class="line">$&#123;xxx&#125; sql:select * from user where id = 1</span><br><span class="line">2、取值的相同点：</span><br><span class="line">都能够获取接口方法传入的参数值</span><br><span class="line">3、取值的不同点：</span><br><span class="line">#&#123;&#125;取值：是以预编译的形式将参数设置到SQL语句中。PreparedStatement 防止SQL注入；</span><br><span class="line">$&#123;&#125;取值：直接把获取到的参数值，拼接到sql语句中，会有安全问题；不能防止SQL注入；</span><br><span class="line">4、小结：</span><br><span class="line">SQL传入参数的获取使用#&#123;&#125;；</span><br><span class="line">拼接参数使用$&#123;&#125;；</span><br></pre></td></tr></table></figure><h3 id="【2】-取值的应用场景"><a href="#【2】-取值的应用场景" class="headerlink" title="【2】${}取值的应用场景"></a>【2】${}取值的应用场景</h3><pre><code>在一些特殊的应用场景中，需要对SQL语句部分（不是参数）进行拼接，这个时候就必须使用${}来进行拼接，不能使用#{}.例如：</code></pre><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">1、企业开发中随着数据量的增大，往往会将数据表按照年份进行分表，如：2017_user，2018_user....，对这些表进行查询就需要动态把年份传入进来，而年份是表名的一部分，并不是参数，JDBC无法对其预编译，所以只能使用$&#123;&#125;进行拼接：  </span><br><span class="line">SELECT * FROM $&#123;year&#125;_user；</span><br><span class="line"></span><br><span class="line">2、根据表名查询数据总记录数：</span><br><span class="line">SELECT COUNT(*) FROM user</span><br><span class="line">SELECT COUNT(*) FROM order</span><br><span class="line">SELECT COUNT(*) FROM  $&#123;tableName&#125;</span><br><span class="line">简言之：如果需要设置到SQL中的不是查询的条件，只能使用$&#123;&#125;拼接；</span><br></pre></td></tr></table></figure><p><strong>示例：</strong></p><p>需求：查询user表中的总记录数。</p><p>【映射文件】：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectCountByTableName&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;int&quot;</span>&gt;</span></span><br><span class="line">     select count(*) from $&#123;tableName&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>【接口】：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//需求：查询user表中的总记录数。</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">selectCountByTableName</span><span class="params">(<span class="meta">@Param(&quot;tableName&quot;)</span> String table)</span>;</span><br></pre></td></tr></table></figure><p>【测试类】</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">selectCountByTableName</span><span class="params">()</span>&#123;</span><br><span class="line">     <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> userMapper.selectCountByTableName(<span class="string">&quot;user&quot;</span>);</span><br><span class="line">     System.out.println(<span class="string">&quot;count = &quot;</span> + count);</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p><strong>小结：</strong></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SQL中非参数部分的拼接使用$&#123;&#125;</span><br><span class="line">举例：</span><br><span class="line">select * from user where username=#&#123;username&#125; and sex=#&#123;sex&#125; 这里 #&#123;username&#125; #&#123;sex&#125; 都属于参数部分，所以是#&#123;&#125;</span><br><span class="line"> select count(*) from $&#123;tableName&#125; 这里$&#123;tableName&#125; 属于表名，不是参数部分，所以使用$&#123;&#125;</span><br></pre></td></tr></table></figure><h3 id="【3】-取值注意事项"><a href="#【3】-取值注意事项" class="headerlink" title="【3】${}取值注意事项"></a>【3】${}取值注意事项</h3><p>**【 ${}获取单个值】**了解</p><pre><code>`${}` 获取单个值时，最好是通过命名参数的形式获取。如果不指定参数的，也可以使用${value}来获取传入的单个值；</code></pre><p>传入参数：没有指定参数名称</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1565610853419-164197976098219.png" alt="1565610853419"> </p><p>获取参数：通过${value获取}</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1565610902438-164197976098220.png" alt="1565610902438"> </p><p><strong>【${}获取配置文件中的值】</strong></p><p>有时候，我们如果非要使用$来接收参数，将login修改如下：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--根据用户名和性别查询--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryByUserNameAndSex&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span>&gt;</span></span><br><span class="line">    SELECT  * FROM  user WHERE  user_name = &#x27;$&#123;username&#125;&#x27; AND  sex = #&#123;sex&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>说明：上述sql语句中：SELECT  * FROM  user WHERE  user_name &#x3D; <strong>‘${username}’</strong> AND  sex &#x3D; #{sex}</p><p>对于 ‘${username}’ 加单引号是因为${}获取数据的方式直接将获取的数据拼接到字符串上，并不会加引号，如果获取的值是数值型，没有问题，但是如果是字符类型就会有问题，所以需要加上引号进行拼接。</p><p>假设${username}获取的值是锁哥，那么不加单引号效果是：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span>  <span class="operator">*</span> <span class="keyword">FROM</span>  <span class="keyword">user</span> <span class="keyword">WHERE</span>  user_name <span class="operator">=</span> 锁哥 <span class="keyword">AND</span>  sex <span class="operator">=</span> #&#123;sex&#125; </span><br><span class="line">显然是不可以的，而加上单引号效果就是：</span><br><span class="line"><span class="keyword">SELECT</span>  <span class="operator">*</span> <span class="keyword">FROM</span>  <span class="keyword">user</span> <span class="keyword">WHERE</span>  user_name <span class="operator">=</span> <span class="string">&#x27;锁哥&#x27;</span> <span class="keyword">AND</span>  sex <span class="operator">=</span> #&#123;sex&#125; </span><br></pre></td></tr></table></figure><p><strong>测试方法：</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">queryByUserNameAndPassword</span><span class="params">( )</span>&#123;</span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> userMapper.queryByUserNameAndSex(<span class="string">&quot;孙悟空&quot;</span>, <span class="string">&quot;男&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;user = &quot;</span> + user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>**执行测试：**发现测试方法中传递的参数明明是孙悟空，却获取到了jdbc.properties资源文件中的root.</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1573118680129-164197976098221.png" alt="1573118680129">                             </p><p><strong>原因：</strong><code>$</code>可以获取资源文件中的数据，比如mybatis-config.xml中使用<code>$</code>获取连接信息就是。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;property name=&quot;driver&quot; value=&quot;$&#123;driver&#125;&quot;/&gt;</span><br></pre></td></tr></table></figure><p>由于映射文件中使用的${username}的参数名称正好和资源文件jdbc.properties中的key相同，因此获取到了资源文件中的数据。</p><pre><code>这种错误发生的根本原因是因为资源文件中的key和参数名称重名了，为了解决这个文件，我们只需要将资源文件中的key设置成唯一的不会被重复的key即可。</code></pre><p>解决方案：在资源文件中的key中添加前缀</p><p><strong>修改资源文件：</strong></p><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jdbc.driverClass</span>=<span class="string">com.mysql.jdbc.Driver</span></span><br><span class="line"><span class="attr">jdbc.url</span>=<span class="string">jdbc:mysql://localhost:3306/heima37</span></span><br><span class="line"><span class="attr">jdbc.username</span>=<span class="string">root</span></span><br><span class="line"><span class="attr">jdbc.password</span>=<span class="string">root</span></span><br></pre></td></tr></table></figure><p><strong>修改mybatis-config.xml：</strong></p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dataSource</span> <span class="attr">type</span>=<span class="string">&quot;POOLED&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 配置连接信息 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;driver&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;jdbc.driverClass&#125;&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;url&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;jdbc.url&#125;&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;jdbc.username&#125;&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;password&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;jdbc.password&#125;&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dataSource</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="【小结】-1"><a href="#【小结】-1" class="headerlink" title="【小结】"></a>【小结】</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">1、#&#123;&#125;和$&#123;&#125;取值的相同点：</span><br><span class="line">  都能够获取传入的命名参数</span><br><span class="line"></span><br><span class="line">2、#&#123;&#125;和$&#123;&#125;取值的不同点：</span><br><span class="line">#&#123;&#125;: 以预编译的方式将参数设置到sql语句中  防止SQL注入 。可以自动加单引号</span><br><span class="line">$&#123;&#125;: 把参数直接拼接到sql语句中  不能够防止sql注入。不能自动加单引号。</span><br><span class="line">3、具体应用：</span><br><span class="line">#&#123;&#125;获取sql语句中的条件参数</span><br><span class="line">$&#123;&#125;应用于sql语句拼接和读取配置文件</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="扩展-mysql自带函数concat拼接使用"><a href="#扩展-mysql自带函数concat拼接使用" class="headerlink" title="扩展 mysql自带函数concat拼接使用"></a>扩展 mysql自带函数concat拼接使用</h3><p>UserMapper接口</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">UserMapper</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">        需求：模糊查询地址中含有 海 的用户</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    List&lt;User&gt; <span class="title function_">queryUsersByAddressLike</span><span class="params">(<span class="meta">@Param(&quot;address&quot;)</span>String address)</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>UserMapper.xml</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">       需求：模糊查询地址中含有 海 的用户</span></span><br><span class="line"><span class="comment">       List&lt;User&gt; queryUsersByAddressLike(@Param(&quot;address&quot;)String address);</span></span><br><span class="line"><span class="comment">       注意：</span></span><br><span class="line"><span class="comment">           1. select * from user where address like &#x27;%#&#123;address&#125;%&#x27; 这里是拼接，不能使用#&#123;&#125;,必须使用$&#123;&#125;</span></span><br><span class="line"><span class="comment">               使用$&#123;&#125;拼接sql语句： select * from user where address like &#x27;%$&#123;address&#125;%&#x27;===select * from user where address like &#x27;%海%&#x27;</span></span><br><span class="line"><span class="comment">               但是我们发现具有sql注入问题</span></span><br><span class="line"><span class="comment">           2.我们实际开发中必须考虑sql注入问题，那么还必须是实现拼接，使用mysql自带拼接函数：concat(数值1,数值2,数值3,....);</span></span><br><span class="line"><span class="comment">                select * from user where address like concat(&#x27;%&#x27;,?,&#x27;%&#x27;)</span></span><br><span class="line"><span class="comment">   --&gt;</span></span><br><span class="line">  <span class="comment">&lt;!-- &lt;select id=&quot;queryUsersByAddressLike&quot; resultType=&quot;User&quot;&gt;</span></span><br><span class="line"><span class="comment">       select * from user where address like &#x27;%$&#123;address&#125;%&#x27;</span></span><br><span class="line"><span class="comment">   &lt;/select&gt;--&gt;</span></span><br><span class="line"></span><br><span class="line">   <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryUsersByAddressLike&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span>&gt;</span></span><br><span class="line">       select * from user where address like concat(&#x27;%&#x27;,#&#123;address&#125;,&#x27;%&#x27;)</span><br><span class="line">   <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>测试类：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">        需求：模糊查询地址中含有 海 的用户</span></span><br><span class="line"><span class="comment">        List&lt;User&gt; queryUsersByAddressLike(@Param(&quot;address&quot;)String address);</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">queryUsersByAddressLike</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">SqlSession</span> <span class="variable">sqlSession</span> <span class="operator">=</span> SqlSessionUtil.getSqlSession();</span><br><span class="line">        <span class="comment">//4.获取接口代理对象</span></span><br><span class="line">        <span class="type">UserMapper</span> <span class="variable">mapper</span> <span class="operator">=</span> sqlSession.getMapper(UserMapper.class);</span><br><span class="line"></span><br><span class="line">        List&lt;User&gt; list = mapper.queryUsersByAddressLike(<span class="string">&quot;海&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;list = &quot;</span> + list);</span><br><span class="line"></span><br><span class="line">        sqlSession.close();</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><h3 id="入参总结："><a href="#入参总结：" class="headerlink" title="入参总结："></a>入参总结：</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">mybatis中能够接收<span class="number">2</span>种类型的参数传入：</span><br><span class="line"></span><br><span class="line">【<span class="number">1</span>】基本类型数据：</span><br><span class="line"> 单个数据： queryById(Integer id);</span><br><span class="line"> mybatis底层不做处理，使用任意变量都可接收   #&#123;abc&#125;</span><br><span class="line"> 多个数据： queryByUsernameAndSex(<span class="meta">@Param(&quot;username&quot;)</span>String username,<span class="meta">@Param(&quot;sex&quot;)</span>String sex);</span><br><span class="line">mybatis底层：</span><br><span class="line">第一步：把多个参数存储进数组最后放到集合map中，Map&#123;arg0,arg1&#125;    #&#123;arg0&#125; #&#123;arg1&#125;</span><br><span class="line">第二步：把数组中的数据转入Map中：</span><br><span class="line">username参数： param1-白骨精   username-白骨精</span><br><span class="line">     多个参数sql取值： #&#123;param1&#125;  #&#123;param2&#125;</span><br><span class="line">#&#123;username&#125;</span><br><span class="line">    最佳实践： 使用命名参数取值   queryByUsernameAndSex(<span class="meta">@Param(&quot;username&quot;)</span>String username);</span><br><span class="line"> sql取值：  #&#123;username&#125; ****</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">【<span class="number">2</span>】复杂数据类型：</span><br><span class="line"><span class="number">1.</span>pojo类型数据：mybatis底层直接使用pojo封装数据</span><br><span class="line">sql取值：  #&#123;pojo的属性名&#125;****   #&#123;username&#125;==&gt;调用pojo的 getUsername()&#123;&#125; </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="number">2.</span>map集合数据：mybatis底层直接使用map封装参数</span><br><span class="line">Map&lt;String,String&gt;  <span class="title function_">put</span><span class="params">(<span class="string">&quot;username&quot;</span>,<span class="string">&quot;白骨精&quot;</span>)</span></span><br><span class="line">              #&#123;username&#125;****</span><br><span class="line"> 【<span class="number">3</span>】#&#123;&#125;和$&#123;&#125;取值的相同点：</span><br><span class="line">  都能够获取传入的命名参数</span><br><span class="line"></span><br><span class="line">  【<span class="number">4</span>】#&#123;&#125;和$&#123;&#125;取值的不同点：</span><br><span class="line">#&#123;&#125;: 以预编译的方式将参数设置到sql语句中  防止SQL注入 。可以自动加单引号</span><br><span class="line">$&#123;&#125;: 把参数直接拼接到sql语句中  不能够防止sql注入。不能自动加单引号。</span><br><span class="line"> 【<span class="number">5</span>】具体应用：</span><br><span class="line">#&#123;&#125;获取sql语句中的条件参数</span><br><span class="line">$&#123;&#125;应用于sql语句拼接和读取配置文件</span><br><span class="line">  【<span class="number">6</span>】如果避免sql注入，并且还是sql的拼接，解决方案：</span><br><span class="line">        此时可以使用mysql自带函数，拼接函数：concat(数值<span class="number">1</span>,数值<span class="number">2</span>,数值<span class="number">3</span>,....) 可以将concat函数中的数据拼接为一个值</span><br><span class="line">                  举例：concat(<span class="string">&#x27;%&#x27;</span>,<span class="string">&#x27;锁哥&#x27;</span>,<span class="string">&#x27;%&#x27;</span>)===》结果是<span class="string">&#x27;%锁哥%&#x27;</span></span><br><span class="line">                        concat(<span class="string">&#x27;%&#x27;</span>,#&#123;userName&#125;,<span class="string">&#x27;%&#x27;</span>) ===&gt;假设#&#123;userName&#125;获取的值是 喆===》<span class="string">&#x27;%喆%&#x27;</span></span><br><span class="line">        </span><br><span class="line">        select * from user where user_name like <span class="title function_">concat</span><span class="params">(<span class="string">&#x27;%&#x27;</span>,#&#123;userName&#125;,<span class="string">&#x27;%&#x27;</span>)</span></span><br><span class="line">        </span><br></pre></td></tr></table></figure><h2 id="3、结果映射"><a href="#3、结果映射" class="headerlink" title="3、结果映射"></a>3、结果映射</h2><p>我们已经学习了入参和获取参数的方式，接下来学习最后的返回值。</p><p><img src="https://js.hnlyx.top/img/image-20200606093702073-164197976098222.png" alt="image-20200606093702073"></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">在使用原生的JDBC操作时，对于结果集ResultSet，需要手动处理。mybatis框架提供了resultType和resultMap来对结果集进行封装。</span><br></pre></td></tr></table></figure><p><strong>注意：只要一个方法有返回值需要处理，那么 resultType和resultMap必须有一个</strong></p><h3 id="【1】resultType"><a href="#【1】resultType" class="headerlink" title="【1】resultType"></a>【1】resultType</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">从sql语句中返回的期望类型的类的完全限定名或别名。 注意如果返回的是集合，那应该设置为集合包含的类型，而不是集合本身。可以使用 resultType 或 resultMap，但不能同时使用。</span><br></pre></td></tr></table></figure><h4 id="1-1返回值是简单类型"><a href="#1-1返回值是简单类型" class="headerlink" title="1.1返回值是简单类型"></a>1.1返回值是简单类型</h4><p>例如 int ,string &#x3D;&#x3D;&#x3D;&gt;resultType&#x3D;”书写对应的基本类型别名或者全名即可”</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/image-20200606103412396-164197976099323.png" alt="image-20200606103412396"></p><h4 id="1-2返回值为一个pojo-User-对象时"><a href="#1-2返回值为一个pojo-User-对象时" class="headerlink" title="1.2返回值为一个pojo(User)对象时"></a>1.2返回值为一个pojo(User)对象时</h4><p>【定义resultType为User】</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1564483479082-164197976099324.png" alt="1564483479082"> </p><p> 【使用User来接收返回值】</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/1564538720710-164197976099325.png" alt="1564538720710"></p><h4 id="1-3返回值为一个List时"><a href="#1-3返回值为一个List时" class="headerlink" title="1.3返回值为一个List时"></a>1.3返回值为一个List<User>时</h4><pre><code>当返回值为List集合时，resultType需要设置成集合中存储的具体的pojo数据类型：</code></pre><p>【映射文件】</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/image-20200606103712740-164197976099327.png" alt="image-20200606103712740"></p><p>【接口】</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/image-20200606103756850-164197976099326.png" alt="image-20200606103756850"></p><p>【测试类】</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1.使用接口对象调用接口中的方法</span></span><br><span class="line">List&lt;User&gt; userList = mapper.findAllUsers();</span><br><span class="line"><span class="comment">//2.遍历集合</span></span><br><span class="line"><span class="keyword">for</span> (User user : userList) &#123;</span><br><span class="line">    System.out.println(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="1-4返回值为map"><a href="#1-4返回值为map" class="headerlink" title="1.4返回值为map"></a>1.4返回值为map</h4><h5 id="【1】返回一条数据，封装到map中"><a href="#【1】返回一条数据，封装到map中" class="headerlink" title="【1】返回一条数据，封装到map中"></a>【1】返回一条数据，封装到map中</h5><p>需求：查询id是1的数据，将查询的结果封装到Map&lt;String,Object&gt;中</p><p>接口方法：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//需求：查询id是1的数据，将查询的结果封装到Map&lt;String,Object&gt;中</span></span><br><span class="line">Map&lt;String,Object&gt; <span class="title function_">selectByIdReturnMap</span><span class="params">(Integer id)</span>;</span><br></pre></td></tr></table></figure><p>SQL语句：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectByIdReturnMap&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;map&quot;</span>&gt;</span></span><br><span class="line">        select * from user where id=#&#123;id&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span> </span><br></pre></td></tr></table></figure><p>测试：原来封装到对象中的数据也能够封装到map中</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">selectByIdReturnMap</span><span class="params">()</span>&#123;</span><br><span class="line">    Map&lt;String, Object&gt; map = userMapper.selectByIdReturnMap(<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;map = &quot;</span> + map);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>结果：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">map = &#123;birthday=<span class="number">1980</span>-<span class="number">10</span>-<span class="number">24</span>, address=花果山水帘洞, sex=男, id=<span class="number">1</span>, username=孙悟空&#125;</span><br></pre></td></tr></table></figure><p>通过上述结果我们发现如果返回一条数据放到Map中，那么列名会作为Map集合的key,结果作为Map集合的value:</p><p><img src="https://js.hnlyx.top/img/image-20200606094904280-164197976099329.png" alt="image-20200606094904280"></p><h5 id="【2】返回多条数据，封装到map中"><a href="#【2】返回多条数据，封装到map中" class="headerlink" title="【2】返回多条数据，封装到map中"></a>【2】返回多条数据，封装到map中</h5><pre><code>需求：查询数据表所有的数据封装到Map&lt;String,User&gt;集合中要求： Key值为一条记录的主键，Value值为pojo的对象.</code></pre><p>​</p><pre><code>如下所示：</code></pre><p><img src="https://js.hnlyx.top/img/1565524547986-164197976099328.png" alt="1565524547986"> </p><p>接口方法：接口方法上面通过注解 @MapKey指定key值封装的列数据</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//需求：查询数据表所有的数据封装到Map&lt;String,User&gt;集合中</span></span><br><span class="line"> <span class="meta">@MapKey(&quot;id&quot;)</span></span><br><span class="line"> Map&lt;String, User&gt; <span class="title function_">selectReturnMap</span><span class="params">()</span>;</span><br></pre></td></tr></table></figure><p>说明：需要在接口的方法上使用注解@MapKey指定数据表中哪一列作为Map集合的key，否则mybatis不知道具体哪个列作为Map集合的key.</p><p>SQL语句：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectReturnMap&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;map&quot;</span>&gt;</span></span><br><span class="line">        select * from user</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>测试代码：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">selectReturnMap</span><span class="params">()</span>&#123;</span><br><span class="line">    Map&lt;String, User&gt; map = userMapper.selectReturnMap();</span><br><span class="line">    System.out.println(<span class="string">&quot;map = &quot;</span> + map);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>结果：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">map = &#123;<span class="number">1</span>=&#123;birthday=<span class="number">1980</span>-<span class="number">10</span>-<span class="number">24</span>, address=花果山水帘洞, sex=男, id=<span class="number">1</span>, username=孙悟空&#125;, <span class="number">2</span>=&#123;birthday=<span class="number">1992</span>-<span class="number">11</span>-<span class="number">12</span>, address=白虎岭白骨洞, sex=女, id=<span class="number">2</span>, username=白骨精&#125;, <span class="number">3</span>=&#123;birthday=<span class="number">1983</span>-<span class="number">05</span>-<span class="number">20</span>, address=福临山云栈洞, sex=男, id=<span class="number">3</span>, username=猪八戒&#125;, <span class="number">4</span>=&#123;birthday=<span class="number">1995</span>-<span class="number">03</span>-<span class="number">22</span>, address=盤丝洞, sex=女, id=<span class="number">4</span>, username=蜘蛛精&#125;, <span class="number">7</span>=&#123;birthday=<span class="number">2020</span>-<span class="number">06</span>-<span class="number">05</span>, address=上海, sex=男, id=<span class="number">7</span>, username=蔡徐坤&#125;, <span class="number">8</span>=&#123;birthday=<span class="number">2020</span>-<span class="number">06</span>-<span class="number">05</span>, address=上海, sex=男, id=<span class="number">8</span>, username=蔡徐坤&#125;, <span class="number">9</span>=&#123;birthday=<span class="number">2020</span>-<span class="number">06</span>-<span class="number">05</span>, address=上海, sex=男, id=<span class="number">9</span>, username=蔡徐坤&#125;, <span class="number">10</span>=&#123;birthday=<span class="number">2020</span>-<span class="number">06</span>-<span class="number">05</span>, address=上海, sex=男, id=<span class="number">10</span>, username=蔡徐坤&#125;, <span class="number">11</span>=&#123;birthday=<span class="number">2020</span>-<span class="number">06</span>-<span class="number">06</span>, address=上海, sex=男, id=<span class="number">11</span>, username=蔡徐坤&#125;&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h4 id="小结-1"><a href="#小结-1" class="headerlink" title="小结"></a>小结</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span>接口方法返回类型是简单类型(除了单列集合)，那么在标签的resultType属性值中书写返回简单类型的类名或者别名</span><br><span class="line">    举例：</span><br><span class="line">    Integer <span class="title function_">show</span><span class="params">()</span>;====&gt; resultType=<span class="string">&quot;int&quot;</span></span><br><span class="line">    String <span class="title function_">show</span><span class="params">()</span>;====&gt; resultType=<span class="string">&quot;string&quot;</span></span><br><span class="line"><span class="number">2.</span>如果接口方法返回类型是简单类型的单列集合，那么在标签的resultType属性值中书写集合的泛型类型</span><br><span class="line">    举例：</span><br><span class="line">    List&lt;User&gt; <span class="title function_">show</span><span class="params">()</span>;====&gt; resultType=<span class="string">&quot;User&quot;</span></span><br><span class="line"><span class="number">3.</span>如果接口方法返回类型是复杂类型的pojo,那么在标签的resultType属性值中书写pojo类型</span><br><span class="line">     举例：</span><br><span class="line">    User <span class="title function_">show</span><span class="params">()</span>;====&gt; resultType=<span class="string">&quot;User&quot;</span></span><br><span class="line"><span class="number">4.</span>如果接口方法返回类型是复杂类型的Map,那么在标签的resultType属性值中书写map类型,但是分为返回的是单行数据还是多行数据：</span><br><span class="line">    如果是单行数据，不用做处理</span><br><span class="line">    如果是多行数据，在方法上使用注解<span class="meta">@MapKey(&quot;数据表字段名&quot;)</span>告知mybatis，哪个字段名的值作为map集合的key</span><br><span class="line">    举例： 如果是多行数据</span><br><span class="line">    <span class="meta">@MapKey(&quot;id&quot;)</span></span><br><span class="line">    Map&lt;Integer,Object&gt; <span class="title function_">show</span><span class="params">()</span>;</span><br></pre></td></tr></table></figure><h3 id="【2】resultMap-掌握"><a href="#【2】resultMap-掌握" class="headerlink" title="【2】resultMap(掌握)"></a>【2】resultMap(掌握)</h3><p>ResultMap是mybatis中最重要最强大的元素，使用ResultMap可以解决两大问题：</p><ol><li>POJO属性名和表结构字段名不一致的问题（有些情况下也不是标准的驼峰格式，比如id和userId）</li><li>完成高级查询，比如说，一对一、一对多、多对多。(后面多表中会涉及到)</li></ol><p> 查询数据的时候，查不到userName的信息，原因：数据库的字段名是user_name，而POJO中的属性名字是userName<br>两端不一致，造成mybatis无法填充对应的字段信息。修改方法：在sql语句中使用别名<br><strong>解决方案1</strong>：在sql语句中使用别名</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryById&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span> <span class="attr">parameterType</span>=<span class="string">&quot;int&quot;</span>&gt;</span></span><br><span class="line">   select *,name as username from user where id = #&#123;id&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>解决方案2</strong>：参考驼峰匹配 — mybatis-config.xml 的时候</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">settings</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">setting</span> <span class="attr">name</span>=<span class="string">&quot;mapUnderscoreToCamelCase&quot;</span> <span class="attr">value</span>=<span class="string">&quot;true&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">settings</span>&gt;</span></span><br></pre></td></tr></table></figure><p>注意：这种解决方案只能解决列名是下划线命名.</p><p><strong>解决方案3</strong>：resultMap自定义映射</p><p>通过案例掌握resultMap的使用方式之一，手动配置实体类中属性和表中字段的映射关系</p><h4 id="【需求】"><a href="#【需求】" class="headerlink" title="【需求】"></a>【需求】</h4><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">使用resultMap完成结果集的封装（resultSet===》JavaBean）</span><br></pre></td></tr></table></figure><h4 id="【实现步骤】"><a href="#【实现步骤】" class="headerlink" title="【实现步骤】"></a>【实现步骤】</h4><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">手动配置实体类属性和表字段映射关系的步骤如下：</span><br><span class="line">1、配置自定义结果集<span class="tag">&lt;<span class="name">resultMap</span>&gt;</span></span><br><span class="line">2、配置id映射</span><br><span class="line">3、配置其他普通属性的映射</span><br></pre></td></tr></table></figure><p>**步骤一：**将驼峰匹配注释掉<br>一旦注释掉驼峰匹配，那么再通过queryUserById查询的结果中，用户名就无法封装了，此时我们可以尝试使用ResultMap来解决这个问题。</p><p>**步骤二：**配置resultMap</p><p>resultMap标签的作用:自定义结果集，自行设置结果集的封装方式</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">id属性：resultMap标签的唯一标识，不能重复，一般是用来被引用的</span><br><span class="line">type属性：结果集的封装类型</span><br><span class="line">autoMapping属性：操作单表时，不配置默认为true,如果pojo对象中的属性名称和表中字段名称相同，则自动映射。</span><br></pre></td></tr></table></figure><p>在映射文件中自定义结果集类型：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">    <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            type=&quot;user&quot; 表示结果集的封装类型是user</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">resultMap</span> <span class="attr">id</span>=<span class="string">&quot;userResultMap&quot;</span> <span class="attr">type</span>=<span class="string">&quot;User&quot;</span> <span class="attr">autoMapping</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">   <span class="comment">&lt;!--配置主键映射关系--&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">id</span> <span class="attr">column</span>=<span class="string">&quot;id&quot;</span> <span class="attr">property</span>=<span class="string">&quot;id&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line">   <span class="comment">&lt;!--配置用户名的映射关系  column 表示数据表列  property表示pojo的属性--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">result</span> <span class="attr">column</span>=<span class="string">&quot;name&quot;</span> <span class="attr">property</span>=<span class="string">&quot;username&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">result</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">resultMap</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>步骤三</strong>：修改查询语句的statement<br>在查询语句的select标签中通过resultMap属性可以引用自定义结果集作为数据的封装方式。</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">     resultMap属性：引用自定义结果集作为数据的封装方式.属性值是自定义resultMap标签的id属性值，这里表示通过id引入自定义的resultMap标签</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryById&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;userResultMap&quot;</span>&gt;</span></span><br><span class="line">    select * from user where id = #&#123;id&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>测试代码：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">queryById</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="comment">//获取mapper接口的动态代理实现</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> userMapper.queryById(<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;user = &quot;</span> + user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>**注意：**测试完记得将驼峰命名的配置重新开启，因为其他的测试方法还要用。</p><h4 id="【小结】-2"><a href="#【小结】-2" class="headerlink" title="【小结】"></a>【小结】</h4><p>resultMap可以用来手动配置属性和字段的映射关系：</p><p><strong>属性：</strong></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">1、id属性</span><br><span class="line">定义唯一标识，用来被sql语句的声明引用的</span><br><span class="line"></span><br><span class="line">2、type属性</span><br><span class="line">配置结果集类型，将查询的数据往哪个类型中封装</span><br><span class="line"></span><br><span class="line">3、autoMapping属性的值</span><br><span class="line">为true时：在字段和属性名称相同时，会进行自动映射。如果不配置，则默认为true。</span><br><span class="line">为false时：只针对resultMap中已经配置的字段作映射。</span><br></pre></td></tr></table></figure><p><strong>子标签：</strong></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">1、id子标签</span><br><span class="line">配置主键的映射关系</span><br><span class="line">2、result子标签</span><br><span class="line">配置其他普通属性和字段的映射关系</span><br></pre></td></tr></table></figure><h2 id="4、动态SQL"><a href="#4、动态SQL" class="headerlink" title="4、动态SQL"></a>4、动态SQL</h2><p>MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验，你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格，还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。</p><p>例如，下面需求就会使用到拼接sql语句：</p><p>【需求】：查询<strong>男性</strong>用户，<strong>如果输入了用户名，按用户名模糊查询</strong>,如果<strong>没有输入用户名，就查询所有男性用户</strong>。</p><p>正常的sql语句：查询男性并且用户名中包含zhang</p><p><img src="https://js.hnlyx.top/img/1552033448416.png" alt="1552033448416"></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_user <span class="keyword">where</span> sex <span class="operator">=</span> &quot;男&quot; <span class="keyword">and</span> user_name <span class="keyword">like</span> <span class="string">&#x27;%zhang%&#x27;</span></span><br></pre></td></tr></table></figure><p><img src="https://js.hnlyx.top/img/1552033532415.png" alt="1552033532415"></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_user <span class="keyword">where</span>  sex <span class="operator">=</span> &quot;男&quot;  </span><br></pre></td></tr></table></figure><pre><code>实现需求时还要判断用户是否输入用户名来做不同的查询要求，而这里似乎没有办法判断是否输入了用户名，因此可以考虑使用动态sql来完成这个功能。动态 SQL 元素和后面学习的 JSTL 或基于之前学习的类似 XML 的文本处理器相似。在 MyBatis 之前的版本中，有很多元素需要花时间了解。MyBatis 3 开始精简了元素种类，现在只需学习原来一半的元素便可。MyBatis 采用功能强大的 OGNL 的表达式来淘汰其它大部分元素。</code></pre><p>常见标签如下：</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">if：判断   if(1 gt 2)&#123;&#125;</span><br><span class="line">choose (when, otherwise)：分支判断    switch:多选一</span><br><span class="line">trim (where, set)：去除</span><br><span class="line">foreach：循环遍历标签</span><br></pre></td></tr></table></figure><p>动态SQL中的业务逻辑判断需要使用到以下运算符： ognl表达式</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">1.   e1 or e2 满足一个即可</span><br><span class="line">2.   e1 and e2 都得满足 </span><br><span class="line">3.    e1 == e2,e1 eq e2 判断是否相等</span><br><span class="line">4.    e1 != e2,e1 neq e2 不相等</span><br><span class="line">5.    e1 lt e2：小于   lt表示less than </span><br><span class="line">6.    e1 lte e2：小于等于，其他gt（大于）,gte（大于等于） gt 表示greater than</span><br><span class="line">7.    e1 in e2 </span><br><span class="line">8.    e1 not in e2</span><br><span class="line">9.    e1 + e2,e1 * e2,e1/e2,e1 - e2,e1<span class="comment">%e2</span></span><br><span class="line">10.   !e,not e：非，求反</span><br><span class="line">11.   e.method(args)调用对象方法</span><br><span class="line">12.   e.property对象属性值</span><br><span class="line">13.   e1[ e2 ]按索引取值，List,数组和Map</span><br><span class="line">14.   @class@method(args)调用类的静态方法</span><br><span class="line">15.   @class@field调用类的静态字段值</span><br></pre></td></tr></table></figure><h3 id="1、if标签"><a href="#1、if标签" class="headerlink" title="1、if标签"></a>1、if标签</h3><p>格式：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"> <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;判断条件&quot;</span>&gt;</span></span><br><span class="line">   满足条件执行的代码</span><br><span class="line"> <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">说明：</span><br><span class="line"> 1）if标签：判断语句，用于进行逻辑判断的。如果判断条件为true，则执行if标签的文本内容</span><br><span class="line"> 2）test属性：用来编写表达式，支持ognl；</span><br></pre></td></tr></table></figure><p>【需求】：查询<strong>男性</strong>用户，<strong>如果输入了用户名，按用户名模糊查询</strong>,如果<strong>没有输入用户名，就查询所有男性用户</strong>。</p><p>正常的sql语句：查询男性并且用户名中包含zhang</p><p><img src="https://js.hnlyx.top/img/1552033448416.png" alt="1552033448416"></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_user <span class="keyword">where</span> sex <span class="operator">=</span> &quot;男&quot; <span class="keyword">and</span> user_name <span class="keyword">like</span> <span class="string">&#x27;%zhang%&#x27;</span></span><br></pre></td></tr></table></figure><p><img src="https://js.hnlyx.top/img/1552033532415.png" alt="1552033532415"></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_user <span class="keyword">where</span>  sex <span class="operator">=</span> &quot;男&quot;  </span><br></pre></td></tr></table></figure><pre><code>实现需求时还要判断用户是否输入用户名来做不同的查询要求，而这里似乎没有办法判断是否输入了用户名，因此可以考虑使用动态sql来完成这个功能。上述动态sql语句部分： and user_name like &#39;%zhang%&#39; </code></pre><h4 id="1-1、定义接口方法"><a href="#1-1、定义接口方法" class="headerlink" title="1.1、定义接口方法"></a>1.1、定义接口方法</h4><pre><code>在UserMapper接口中，定义如下方法：</code></pre><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * 根据用户名模糊查询</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@param</span> userName</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"> List&lt;User&gt; <span class="title function_">queryLikeUserName</span><span class="params">(<span class="meta">@Param(&quot;userName&quot;)</span> String userName)</span>;</span><br></pre></td></tr></table></figure><h4 id="1-2、编写SQL"><a href="#1-2、编写SQL" class="headerlink" title="1.2、编写SQL"></a>1.2、编写SQL</h4><pre><code>在UserMapper.xml文件中编写与方法名同名的sql语句：</code></pre><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryLikeUserName&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">     select * from user where sex=&#x27;男&#x27;</span><br><span class="line">     <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;userName!=null and userName.trim()!=&#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">         and username like &#x27;%$&#123;userName&#125;%&#x27;</span><br><span class="line">     <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>【注】<code>&lt;if&gt;</code> 判断中：</p><p>1、if标签：用来判断；</p><p>2、test属性：使用OGNL表达式，完成具体的判断业务逻辑；</p><p><strong>3、这里使用的字符串拼接，所以这里不能是#取值，只能使用$取值，否则会报错</strong></p><h4 id="1-3、测试"><a href="#1-3、测试" class="headerlink" title="1.3、测试"></a>1.3、测试</h4><p>【userName有值】</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/image-20200606165900500.png" alt="image-20200606165900500"></p><p>对应的SQL语句是：select * from user where sex&#x3D;”男” and username like ‘%孙%’ </p><p>【userName没有值】</p><p><img src="C:/Users/Administrator/Desktop/Hexo/gift95.github.io/source/_posts/img/image-20200606170024096.png" alt="image-20200606170024096"></p><p>对应的SQL语句是：select * from user where sex&#x3D;”男” </p><p>【小结】</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1、if标签：用来在sql中处理判断是否成立的情况；</span><br><span class="line">2、属性：test中书写OGNL表达式，如果结果为true，if标签的文本中的内容会被拼接到SQL中，反之不会被拼接到SQL中；</span><br><span class="line">3、if标签的应用场景：适用于 二选一 </span><br></pre></td></tr></table></figure><h3 id="2、choose，when，otherwise"><a href="#2、choose，when，otherwise" class="headerlink" title="2、choose，when，otherwise"></a>2、choose，when，otherwise</h3><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">choose标签：分支选择（多选一，遇到成立的条件即停止）</span><br><span class="line">when子标签：编写条件，不管有多少个when条件，一旦其中一个条件成立，后面的when条件都不执行。</span><br><span class="line">           test属性：编写ognl表达式</span><br><span class="line">otherwise子标签：当所有条件都不满足时，才会执行该条件。</span><br></pre></td></tr></table></figure><p> 需求：</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">编写一个查询方法，设置两个参数，一个是用户名，一个是住址。</span><br><span class="line"></span><br><span class="line">根据用户名或者住址查询所有男性用户:</span><br><span class="line">如果输入了用户名则按照用户名模糊查找，</span><br><span class="line">否则就按照住址查找，两个条件只能成立一个，</span><br><span class="line">如果都不输入就查找用户名为“孙悟空”的用户。</span><br></pre></td></tr></table></figure><p>【需求分析】</p><p>1、查询所有男性用户,如果输入了用户名则按照用户名模糊查找;</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span>  <span class="keyword">user</span> <span class="keyword">WHERE</span>  sex <span class="operator">=</span> &quot;男&quot; <span class="keyword">AND</span>  username <span class="keyword">LIKE</span>  <span class="string">&#x27;%孙%&#x27;</span>;</span><br></pre></td></tr></table></figure><p>2、查询所有男性用户,如果输入了住址则按照住址查询；</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span>  <span class="keyword">user</span> <span class="keyword">WHERE</span>  sex <span class="operator">=</span> &quot;男&quot; <span class="keyword">AND</span>  address <span class="operator">=</span> &quot;花果山水帘洞&quot;;</span><br></pre></td></tr></table></figure><p>3、查询所有男性用户，如果都不输入就查找用户名为“孙悟空”的用户。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span>  <span class="keyword">user</span> <span class="keyword">WHERE</span>  sex <span class="operator">=</span> &quot;男&quot; <span class="keyword">AND</span> username <span class="operator">=</span> <span class="string">&#x27;孙悟空&#x27;</span>;</span><br></pre></td></tr></table></figure><h4 id="2-1、定义接口方法"><a href="#2-1、定义接口方法" class="headerlink" title="2.1、定义接口方法"></a>2.1、定义接口方法</h4><p>在UserMapper接口中，定义接口方法：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">   查询用户名或者地址</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">List&lt;User&gt; <span class="title function_">queryByUserNameOrAddress</span><span class="params">(<span class="meta">@Param(&quot;userName&quot;)</span> String userName, <span class="meta">@Param(&quot;address&quot;)</span> String address)</span>;</span><br></pre></td></tr></table></figure><h4 id="2-2、编写SQL"><a href="#2-2、编写SQL" class="headerlink" title="2.2、编写SQL"></a>2.2、编写SQL</h4><p>在UserMapper.xml中编写对应的SQL语句</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">        根据用户名或者住址查询所有男性用户:</span></span><br><span class="line"><span class="comment">            如果输入了用户名则按照用户名模糊查找，</span></span><br><span class="line"><span class="comment">            否则就按照住址查找，两个条件只能成立一个，</span></span><br><span class="line"><span class="comment">            如果都不输入就查找用户名为“孙悟空”的用户。</span></span><br><span class="line"><span class="comment">  --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryByUserNameOrAddress&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">        select * from user where sex=&#x27;男&#x27;</span><br><span class="line">        <span class="tag">&lt;<span class="name">choose</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">when</span> <span class="attr">test</span>=<span class="string">&quot;userName!=null and userName.trim()!=&#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">                and username like &#x27;%$&#123;userName&#125;%&#x27;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">when</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">when</span> <span class="attr">test</span>=<span class="string">&quot;address!=null and address.trim()!=&#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">                and address = #&#123;address&#125;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">when</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">otherwise</span>&gt;</span></span><br><span class="line">                and username=&#x27;孙悟空&#x27;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">otherwise</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">choose</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><h4 id="2-3、测试"><a href="#2-3、测试" class="headerlink" title="2.3、测试"></a>2.3、测试</h4><p>编写测试类，对这个方法进行测试：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">queryByUserNameOrAddress</span><span class="params">()</span>&#123;</span><br><span class="line">    List&lt;User&gt; userList = userMapper.queryByUserNameOrAddress(<span class="string">&quot;&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;userList = &quot;</span> + userList);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>【小结】</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1、choose，when，otherwise标签组合的作用类似于java中的switch语句，使用于多选一；</span><br></pre></td></tr></table></figure><h3 id="3、where"><a href="#3、where" class="headerlink" title="3、where"></a>3、where</h3><p> where标签：拼接多条件查询时 1、能够添加where关键字； 2、能够去除多余的and或者or关键字</p><p>案例：按照如下条件查询所有用户，</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">如果输入了用户名按照用户名进行查询，</span><br><span class="line">如果输入住址，按住址进行查询，</span><br><span class="line">如果两者都输入，两个条件都要成立。</span><br></pre></td></tr></table></figure><p>【需求分析】</p><p>1、如果输入了用户名按照用户名进行查询，</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span>  <span class="keyword">user</span> <span class="keyword">WHERE</span> user_name <span class="operator">=</span> <span class="string">&#x27;孙悟空&#x27;</span>;</span><br></pre></td></tr></table></figure><p>2、如果输入住址，按住址进行查询，</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span>  <span class="keyword">user</span> <span class="keyword">WHERE</span> address<span class="operator">=</span><span class="string">&#x27;花果山水帘洞&#x27;</span>;</span><br></pre></td></tr></table></figure><p>3、如果两者都输入，两个条件都要成立。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span>  <span class="keyword">user</span> <span class="keyword">WHERE</span> user_name <span class="operator">=</span> <span class="string">&#x27;孙悟空&#x27;</span> <span class="keyword">AND</span> address<span class="operator">=</span><span class="string">&#x27;花果山水帘洞&#x27;</span>;</span><br></pre></td></tr></table></figure><h4 id="3-1、定义接口方法"><a href="#3-1、定义接口方法" class="headerlink" title="3.1、定义接口方法"></a>3.1、定义接口方法</h4><p>在UserMapper接口中定义如下方法：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;User&gt; <span class="title function_">queryByUserNameAndAge</span><span class="params">(<span class="meta">@Param(&quot;userName&quot;)</span> String userName, <span class="meta">@Param(&quot;address&quot;)</span> String address)</span>;</span><br></pre></td></tr></table></figure><h4 id="3-2、编写SQL"><a href="#3-2、编写SQL" class="headerlink" title="3.2、编写SQL"></a>3.2、编写SQL</h4><p>在UserMapper.xml中编写SQL</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">       如果输入了用户名按照用户名进行查询，</span></span><br><span class="line"><span class="comment">       如果输入住址，按住址进行查询，</span></span><br><span class="line"><span class="comment">       如果两者都输入，两个条件都要成立。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">       说明：如果按照如下写sql语句会有问题，假设用户名username是空，那么用户名的sql语句不参与条件，此时</span></span><br><span class="line"><span class="comment">       sql语句就会变为：SELECT * FROM  user where AND address = #&#123;address&#125;</span></span><br><span class="line"><span class="comment">       where后面直接书写了and显然不满足sql语句语法，这里会报错</span></span><br><span class="line"><span class="comment">       我们可以使用where标签解决上述问题：</span></span><br><span class="line"><span class="comment">            where标签：拼接多条件查询时 1、能够添加where关键字； 2、能够去除多余的and或者or关键字</span></span><br><span class="line"><span class="comment">   --&gt;</span></span><br><span class="line">  <span class="comment">&lt;!-- &lt;select id=&quot;queryByUserNameAndAge&quot; resultType=&quot;user&quot;&gt;</span></span><br><span class="line"><span class="comment">       SELECT * FROM  user where</span></span><br><span class="line"><span class="comment">           &lt;if test=&quot;userName != null and userName.trim()!=&#x27;&#x27;&quot;&gt;</span></span><br><span class="line"><span class="comment">               username = #&#123;userName&#125;</span></span><br><span class="line"><span class="comment">           &lt;/if&gt;</span></span><br><span class="line"><span class="comment">           &lt;if test=&quot;address!=null and address.trim()!=&#x27;&#x27;&quot;&gt;</span></span><br><span class="line"><span class="comment">               AND address = #&#123;address&#125;</span></span><br><span class="line"><span class="comment">           &lt;/if&gt;</span></span><br><span class="line"><span class="comment">   &lt;/select&gt;--&gt;</span></span><br><span class="line">   <span class="comment">&lt;!-- SELECT * FROM user WHERE address = ?</span></span><br><span class="line"><span class="comment">       where子标签将and去掉了</span></span><br><span class="line"><span class="comment">   --&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryByUserNameAndAge&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">       SELECT * FROM  user</span><br><span class="line">       <span class="tag">&lt;<span class="name">where</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;userName != null and userName.trim()!=&#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">               username = #&#123;userName&#125;</span><br><span class="line">           <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;address!=null and address.trim()!=&#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">               AND address = #&#123;address&#125;</span><br><span class="line">           <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;/<span class="name">where</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>说明：</p><p>1.说明：如果按照如下写sql语句会有问题，假设用户名username是空，那么用户名的sql语句不参与条件，此时<br>        sql语句就会变为：SELECT * FROM  user where AND address &#x3D; #{address}<br>        where后面直接书写了and显然不满足sql语句语法，这里会报错<br>        我们可以使用where标签解决上述问题：<br>             where标签：拼接多条件查询时 1、能够添加where关键字； 2、能够去除多余的and或者or关键字</p><p>2.SELECT * FROM user WHERE address &#x3D; ?<br>       where子标签将and去掉了</p><h4 id="3-3、测试"><a href="#3-3、测试" class="headerlink" title="3.3、测试"></a>3.3、测试</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">queryByUserNameAndAge</span><span class="params">()</span> &#123;</span><br><span class="line">        List&lt;User&gt; userList = userMapper.queryByUserNameAndAge(<span class="string">&quot;&quot;</span>, <span class="string">&quot;花果山水帘洞&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;userList = &quot;</span> + userList);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><p><img src="https://js.hnlyx.top/img/image-20200606213846118.png" alt="image-20200606213846118"></p><p>只传入住址，此时where子标签去掉了and.</p><p>【小结】</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1、&lt;where&gt;标签作用：用于拼接多选一或者同时成立的SQL情况；</span><br><span class="line">2、&lt;where&gt;还会根据情况，动态的去掉SQL语句中的AND或者or；</span><br></pre></td></tr></table></figure><h3 id="4、set"><a href="#4、set" class="headerlink" title="4、set"></a>4、set</h3><p>set标签：在update语句中,可以自动添加一个set关键字，并且会将动态sql最后多余的逗号去除。</p><p>案例：修改用户信息，如果参数user中的某个属性为null，则不修改。</p><p>如果在正常编写更新语句时，如下：</p><p><img src="https://js.hnlyx.top/img/image-20200606220512579.png" alt="image-20200606220512579"></p> <figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">update</span> <span class="keyword">user</span> <span class="keyword">SET</span> username <span class="operator">=</span> ?, birthday<span class="operator">=</span>?, sex<span class="operator">=</span>?, <span class="keyword">where</span> id <span class="operator">=</span> ? </span><br></pre></td></tr></table></figure><p>那么一旦在传递的参数中没有address，此时生成的sql语句就会因为多了一个逗号而报错。</p><h4 id="4-1、定义接口方法"><a href="#4-1、定义接口方法" class="headerlink" title="4.1、定义接口方法"></a>4.1、定义接口方法</h4><p>在UserMapper接口中定义如下方法：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">void</span> <span class="title function_">updateSelectiveUser</span><span class="params">(User user)</span>;</span><br></pre></td></tr></table></figure><h4 id="4-2、编写SQL"><a href="#4-2、编写SQL" class="headerlink" title="4.2、编写SQL"></a>4.2、编写SQL</h4><p>在UserMapper.xml文件中编写如下SQL:</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">&lt;!--选择性地对user数据进行修改--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">update</span> <span class="attr">id</span>=<span class="string">&quot;updateSelectiveUser&quot;</span>&gt;</span></span><br><span class="line">     update user</span><br><span class="line">     <span class="tag">&lt;<span class="name">set</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;username != null and username.trim()!=&#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">             username = #&#123;username&#125;,</span><br><span class="line">         <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;birthday != null&quot;</span>&gt;</span></span><br><span class="line">             birthday=#&#123;birthday&#125;,</span><br><span class="line">         <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;sex != null and sex.trim()!=&#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">             sex=#&#123;sex&#125;,</span><br><span class="line">         <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;address != null and address.trim()!=&#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">             address=#&#123;address&#125;</span><br><span class="line">         <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br><span class="line">     where id = #&#123;id&#125;</span><br><span class="line"> <span class="tag">&lt;/<span class="name">update</span>&gt;</span></span><br></pre></td></tr></table></figure><h4 id="4-3、测试"><a href="#4-3、测试" class="headerlink" title="4.3、测试"></a>4.3、测试</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">updateSelectiveUser</span><span class="params">()</span> &#123;</span><br><span class="line">       <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">User</span>();</span><br><span class="line">       user.setUsername(<span class="string">&quot;锁哥1&quot;</span>);</span><br><span class="line">       user.setBirthday(<span class="keyword">new</span> <span class="title class_">Date</span>());</span><br><span class="line">       user.setSex(<span class="string">&quot;男&quot;</span>);</span><br><span class="line">       user.setAddress(<span class="string">&quot;&quot;</span>);</span><br><span class="line"></span><br><span class="line">       user.setId(<span class="number">7</span>);</span><br><span class="line">       userMapper.updateSelectiveUser(user);</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure><p>【结果】</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">update</span> <span class="keyword">user</span> <span class="keyword">SET</span> username <span class="operator">=</span> ?, birthday<span class="operator">=</span>?, sex<span class="operator">=</span>? <span class="keyword">where</span> id <span class="operator">=</span> ? </span><br></pre></td></tr></table></figure><p>【小结】</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1、&lt;set&gt;标签替代了sql语句中的set关键字；</span><br><span class="line">2、&lt;set&gt;标签还能把sql中多余的,去掉；</span><br></pre></td></tr></table></figure><h3 id="5、foreach"><a href="#5、foreach" class="headerlink" title="5、foreach"></a>5、foreach</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">foreach标签：遍历集合或者数组</span><br><span class="line"><span class="tag">&lt;<span class="name">foreach</span> <span class="attr">collection</span>=<span class="string">&quot;集合名或者数组名&quot;</span> <span class="attr">item</span>=<span class="string">&quot;元素&quot;</span> <span class="attr">separator</span>=<span class="string">&quot;标签分隔符&quot;</span> <span class="attr">open</span>=<span class="string">&quot;以什么开始&quot;</span> <span class="attr">close</span>=<span class="string">&quot;以什么结束&quot;</span>&gt;</span></span><br><span class="line">   #&#123;元素&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">foreach</span>&gt;</span></span><br><span class="line">collection属性：接收的集合或者数组,集合名或者数组名</span><br><span class="line">item属性：集合或者数组参数中的每一个元素 </span><br><span class="line">separator属性：标签分隔符 </span><br><span class="line">open属性：以什么开始 </span><br><span class="line">close属性：以什么结束</span><br></pre></td></tr></table></figure><p>需求：按照id值是1，2，3来查询用户数据；</p><h4 id="5-1、定义接口方法"><a href="#5-1、定义接口方法" class="headerlink" title="5.1、定义接口方法"></a>5.1、定义接口方法</h4><p>在UserMapper接口中定义如下方法：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;User&gt; <span class="title function_">queryByIds</span><span class="params">(<span class="meta">@Param(&quot;arrIds&quot;)</span> Integer[] arrIds)</span>;</span><br></pre></td></tr></table></figure><p><strong>这里一定加@Param(“arrIds”)，否则报错</strong></p><h4 id="5-2、编写SQL"><a href="#5-2、编写SQL" class="headerlink" title="5.2、编写SQL"></a>5.2、编写SQL</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--根据多个id值查询--&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryByIds&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">       SELECT * FROM  user WHERE id IN</span><br><span class="line">       <span class="tag">&lt;<span class="name">foreach</span> <span class="attr">collection</span>=<span class="string">&quot;arrIds&quot;</span> <span class="attr">item</span>=<span class="string">&quot;ID&quot;</span> <span class="attr">separator</span>=<span class="string">&quot;,&quot;</span> <span class="attr">open</span>=<span class="string">&quot;(&quot;</span> <span class="attr">close</span>=<span class="string">&quot;)&quot;</span>&gt;</span></span><br><span class="line">           #&#123;ID&#125;</span><br><span class="line">       <span class="tag">&lt;/<span class="name">foreach</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><h4 id="5-3、测试"><a href="#5-3、测试" class="headerlink" title="5.3、测试"></a>5.3、测试</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">queryByIds</span><span class="params">()</span> &#123;</span><br><span class="line">    Integer[] arrIds = &#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>&#125;;</span><br><span class="line">    List&lt;User&gt; userList = userMapper.queryByIds(arrIds);</span><br><span class="line">    System.out.println(<span class="string">&quot;userList = &quot;</span> + userList);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://js.hnlyx.top/img/1551344599980.png" alt="1551344599980"></p><p>【小结】</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;foreach&gt;标签的作用：用于对查询参数进行遍历取值；</span><br></pre></td></tr></table></figure><h3 id="6、小结"><a href="#6、小结" class="headerlink" title="6、小结"></a>6、小结</h3><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">If标签：条件判断</span><br><span class="line">test属性：编写ognl表达式</span><br><span class="line"></span><br><span class="line">where标签：用于sql动态条件拼接，添加where关键字，可以将动态sql多余的第一个and或者or去除。</span><br><span class="line"></span><br><span class="line">set标签: 用于更新语句的拼接，添加set关键字，并可以将动态sql中多余的逗号去除</span><br><span class="line"></span><br><span class="line">foreach标签：用于遍历参数中的数组或者集合</span><br><span class="line">collection属性：参数中的数组或者集合</span><br><span class="line">item属性：表示数组或者集合中的某个元素，取出数据使用<span class="params">#</span>&#123;item的属性值&#125;</span><br><span class="line">separator属性：分隔符</span><br><span class="line">open:以什么开始</span><br><span class="line">close:以什么结束</span><br></pre></td></tr></table></figure><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">一、映射文件配置</span><br><span class="line">【1】作用：配置sql相关信息 </span><br><span class="line"> 1、CRUD四类标签：</span><br><span class="line"> 2、sql标签：sql片段</span><br><span class="line"> 3、resultMap：</span><br><span class="line">【2】CRUD四类标签：</span><br><span class="line">增： <span class="tag">&lt;<span class="name">insert</span>&gt;</span><span class="tag">&lt;/<span class="name">insert</span>&gt;</span></span><br><span class="line">删： <span class="tag">&lt;<span class="name">delete</span>&gt;</span><span class="tag">&lt;/<span class="name">delete</span>&gt;</span></span><br><span class="line">改：<span class="tag">&lt;<span class="name">update</span>&gt;</span><span class="tag">&lt;/<span class="name">update</span>&gt;</span></span><br><span class="line">查：<span class="tag">&lt;<span class="name">select</span>&gt;</span><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br><span class="line"></span><br><span class="line">【3】入参相关：<span class="tag">&lt;<span class="name">select</span> <span class="attr">resultType</span>=<span class="string">&quot;User&quot;</span> <span class="attr">paramType</span>=<span class="string">&quot;int&quot;</span>&gt;</span></span><br><span class="line">      SELECT * FROM user WHERE id = #&#123;id&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br><span class="line"></span><br><span class="line">paramType：设置传入的参数的类型，可以省略</span><br><span class="line">insert语句相关：自增主键回填--数据插入到数据库之后，返回这条数据在数据库中的主键值</span><br><span class="line">【1】子标签：<span class="tag">&lt;<span class="name">selectKey</span>&gt;</span><span class="tag">&lt;/<span class="name">selectKey</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">selectKey</span> <span class="attr">keyColumn</span>=<span class="string">&quot;id&quot;</span> <span class="attr">keyProperty</span>=<span class="string">&quot;id&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;int&quot;</span> <span class="attr">order</span>=<span class="string">&quot;AFTER&quot;</span>&gt;</span></span><br><span class="line">            SELECT LAST_INSERT_ID() ;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">selectKey</span>&gt;</span></span><br><span class="line">【2】属性：</span><br><span class="line">useGeneratedKeys=&quot;true&quot; keyColumn=&quot;id&quot; keyProperty=&quot;id&quot; </span><br><span class="line"></span><br><span class="line"></span><br><span class="line">【4】sql参数传入：</span><br><span class="line">能够接收的参数类型： 基本类型数据，pojo，map</span><br><span class="line"></span><br><span class="line">【5】传入基本类型数据：string,int</span><br><span class="line"> 单个数据传入： queryById(Integer id)        WHERE id = #&#123;id&#125;</span><br><span class="line">多个数据传入：queryByNameAndSex(String name,String sex):  </span><br><span class="line">WHERE username=#&#123;&#125; and sex= #&#123;&#125;</span><br><span class="line">最佳实践：命名参数取值  </span><br><span class="line">queryByNameAndSex(@Param(&quot;name&quot;)String name,@Param(&quot;sex&quot;)String sex):  </span><br><span class="line">WHERE username=#&#123;name&#125; and sex= #&#123;sex&#125;</span><br><span class="line"></span><br><span class="line">【6】传入pojo和map数据：</span><br><span class="line">pojo： User&#123;id,username&#125;   #&#123;username&#125;</span><br><span class="line">map:  Map&lt;Key,Value&gt;      #&#123;key&#125;</span><br><span class="line"></span><br><span class="line">     【7】映射文件中sql语句取值： #&#123;&#125;  $&#123;&#125;</span><br><span class="line">              相同点：都能够获取命名参数值</span><br><span class="line">              不同点：</span><br><span class="line">              #&#123;&#125; 取值使用预编译方式设置参数</span><br><span class="line">              $&#123;&#125; 直接标签获取的参数拼接到sql语句中</span><br><span class="line">           最佳实践： 获取查询参数，防止SQL注入 使用  #&#123;&#125;取值</span><br><span class="line">              </span><br><span class="line">      【8】$&#123;&#125;应用场景： 拼接SQL语句</span><br><span class="line">       </span><br><span class="line">       </span><br><span class="line">       【9】sql返回值处理：</span><br><span class="line">              resultType:基本类型数据，pojo，map</span><br><span class="line">              基本类型数据： resultType=&quot;int&quot;</span><br><span class="line">              pojo类型：</span><br><span class="line">              单个pojo，多个pojo：   resultType=&quot;pojo&quot;</span><br><span class="line">              map：</span><br><span class="line">              单条数据：map  默认    resulteType=&quot;map&quot;</span><br><span class="line">              多条数据：map    @MapKey(&quot;id&quot;)</span><br><span class="line">             </span><br><span class="line">              resultMap:</span><br><span class="line">【1】设置数据库的列名  和  实体类的属性名之间  映射关系</span><br><span class="line">               【2】多表关联配置：</span><br><span class="line">              </span><br><span class="line">         【10】动态sql：</span><br><span class="line">              判断： if，分支</span><br><span class="line">              trim： where，set</span><br><span class="line">              foreach：遍历</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="高级查询"><a href="#高级查询" class="headerlink" title="高级查询"></a>高级查询</h2><h3 id="1、一对一查询"><a href="#1、一对一查询" class="headerlink" title="1、一对一查询"></a>1、一对一查询</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">association：配置关联对象（User）的映射关系</span><br><span class="line"> &lt;association property=<span class="string">&quot;user&quot;</span> javaType=<span class="string">&quot;User&quot;</span> autoMapping=<span class="string">&quot;true&quot;</span>&gt;</span><br><span class="line">           </span><br><span class="line">  &lt;/association&gt;</span><br><span class="line">属性：</span><br><span class="line">property：关联对象在主表实体类中的属性名；property=<span class="string">&quot;user&quot;</span> 表示在Order类中的引用的User类的对象   成员变量名</span><br><span class="line">javaType：关联对象的类型；javaType=<span class="string">&quot;User&quot;</span> 表示引用的user对象属于User类型</span><br></pre></td></tr></table></figure><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span> ?&gt;</span></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">mapper</span></span></span><br><span class="line"><span class="meta">        <span class="keyword">PUBLIC</span> <span class="string">&quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;</span></span></span><br><span class="line"><span class="meta">        <span class="string">&quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">映射文件</span></span><br><span class="line"><span class="comment">namespace 指定接口的类全名</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">mapper</span> <span class="attr">namespace</span>=<span class="string">&quot;com.itheima.sh.dao.OrderMapper&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">        1.autoMapping=&quot;true&quot; 表示只需要给当前表的id然后自动映射当前表的其他列值到</span></span><br><span class="line"><span class="comment">        对应实体类的属性中，这属于偷懒行为，开发中我们最好都书写出来</span></span><br><span class="line"><span class="comment">        2.id标签表示id的映射关系</span></span><br><span class="line"><span class="comment">        3.result标签表示其他列和pojo类的属性映射关系</span></span><br><span class="line"><span class="comment">        4.一对一映射关系使用子标签association来表示引用的另一个pojo类的对象</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">resultMap</span> <span class="attr">id</span>=<span class="string">&quot;orderAndUserResultRelative&quot;</span> <span class="attr">type</span>=<span class="string">&quot;Order&quot;</span> <span class="attr">autoMapping</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--主表主键--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">id</span> <span class="attr">column</span>=<span class="string">&quot;id&quot;</span> <span class="attr">property</span>=<span class="string">&quot;id&quot;</span>/&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--关联关系--&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            1.property=&quot;user&quot; 表示在Order类中的引用的User类的对象成员变量名</span></span><br><span class="line"><span class="comment">            2.javaType=&quot;User&quot; 表示引用的user对象属于User类型</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">association</span> <span class="attr">property</span>=<span class="string">&quot;user&quot;</span> <span class="attr">javaType</span>=<span class="string">&quot;User&quot;</span> <span class="attr">autoMapping</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--从表主键--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">id</span> <span class="attr">column</span>=<span class="string">&quot;id&quot;</span> <span class="attr">property</span>=<span class="string">&quot;id&quot;</span>/&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--&lt;result column=&quot;user_name&quot; property=&quot;userName&quot;/&gt;--&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">association</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">resultMap</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--多表关联查询：一对一--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;queryOrderAndUserByOrderNumber2&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;orderAndUserResultRelative&quot;</span>&gt;</span></span><br><span class="line">        SELECT</span><br><span class="line">            *</span><br><span class="line">        FROM</span><br><span class="line">            tb_order tbo</span><br><span class="line">            INNER JOIN tb_user tbu ON tbo.user_id = tbu.id</span><br><span class="line">        WHERE</span><br><span class="line">            tbo.order_number = #&#123;orderNumber&#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">mapper</span>&gt;</span></span><br></pre></td></tr></table></figure><p>说明：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>、由于queryOrderAndUserByOrderNumber2查询的结果Order对象中需要封装User信息，所以返回值不能够再使用单纯的resultType来操作；</span><br><span class="line"></span><br><span class="line"><span class="number">2</span>、定义resultMap进行关联查询的配置，其中：</span><br><span class="line">属性：</span><br><span class="line">id：标识这个resultMap；</span><br><span class="line">type：返回的结果类型</span><br><span class="line">    autoMapping=<span class="string">&quot;true&quot;</span>： 表示只需要给当前表的id然后自动映射当前表的其他列值到对应实体类的属性中，这  属于偷懒行为，开发中我们最好都书写出来</span><br><span class="line">子元素：</span><br><span class="line">id：主表主键映射</span><br><span class="line">result：主表普通字段的映射</span><br><span class="line">association:关联对象的映射配置</span><br><span class="line"></span><br><span class="line"><span class="number">3</span>、association：配置关联对象（User）的映射关系</span><br><span class="line">属性：</span><br><span class="line">property：关联对象在主表实体类中的属性名；property=<span class="string">&quot;user&quot;</span> 表示在Order类中的引用的User类的对象   成员变量名</span><br><span class="line">javaType：关联对象的类型；javaType=<span class="string">&quot;User&quot;</span> 表示引用的user对象属于User类型</span><br></pre></td></tr></table></figure><h5 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h5><p>通过上述测试结果，我们发现User的id是错误的，不是3，正确结果是1：</p><p><img src="https://js.hnlyx.top/img/image-20200607103247424-164204273873711.png" alt="image-20200607103247424"></p><p>因为tb_user表的主键是id，tb_order的主键也是id。查询的结果中有两列相同的id字段。在将查询结果封装到实体类的过程中就会封装错误。</p><p>注意：user表查询的是id不是id1,由于SQLyog图形化界面显示的原因。可以在cmd窗口查看结果：</p><p><img src="https://js.hnlyx.top/img/image-20200607104119140-164204273873712.png" alt="image-20200607104119140"></p><p>【解决方案】</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1、建议将所要查询的所有字段显示地写出来；</span><br><span class="line">2、将多表关联查询结果中，相同的字段名取不同的别名；</span><br></pre></td></tr></table></figure><p><img src="https://js.hnlyx.top/img/image-20200607104753543-164204273873713.png" alt="image-20200607104753543"></p><p>resultMap中应该如下配置：</p><p><img src="https://js.hnlyx.top/img/image-20200607105105346-164204273873715.png" alt="image-20200607105105346"></p><p>【正确结果】</p><p><img src="https://js.hnlyx.top/img/image-20200607105210595-164204273873716.png" alt="image-20200607105210595"></p><h5 id="【小结】-3"><a href="#【小结】-3" class="headerlink" title="【小结】"></a>【小结】</h5><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">一对一关联查询：</span><br><span class="line">1、需要在Order实体类中关联User对象；最终将数据封装到Order中；</span><br><span class="line">2、在OrderMapper.xml文件中书写关联语句并配置关系；</span><br><span class="line">3、关联关系配置：</span><br><span class="line">    <span class="tag">&lt;<span class="name">resultMap</span> <span class="attr">id</span>=<span class="string">&quot;orderAndUserResultRelative&quot;</span> <span class="attr">type</span>=<span class="string">&quot;Order&quot;</span> <span class="attr">autoMapping</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--主表主键--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">id</span> <span class="attr">column</span>=<span class="string">&quot;oid&quot;</span> <span class="attr">property</span>=<span class="string">&quot;id&quot;</span>/&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--关联关系--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">association</span> <span class="attr">property</span>=<span class="string">&quot;user&quot;</span> <span class="attr">javaType</span>=<span class="string">&quot;User&quot;</span> <span class="attr">autoMapping</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">                <span class="comment">&lt;!--从表主键--&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">id</span> <span class="attr">column</span>=<span class="string">&quot;uid&quot;</span> <span class="attr">property</span>=<span class="string">&quot;id&quot;</span>/&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">association</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">resultMap</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="2、一对多查询"><a href="#2、一对多查询" class="headerlink" title="2、一对多查询"></a>2、一对多查询</h3><p>在<strong>UserMapper.xml</strong>文件中编写SQL语句完成一对多的关联查询；</p><p>说明：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">1.一对多使用collection子标签进行关联多方Order</span><br><span class="line">  <span class="tag">&lt;<span class="name">collection</span> <span class="attr">property</span>=<span class="string">&quot;类中引用多方的成员变量名&quot;</span> <span class="attr">javaType</span>=<span class="string">&quot;存放多方容器的类型&quot;</span> <span class="attr">ofType</span>=<span class="string">&quot;多方类型&quot;</span> <span class="attr">autoMapping</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">collection</span>&gt;</span></span><br><span class="line">2.属性：</span><br><span class="line">    1）property=&quot;orders&quot; 这里的orders表示User类的成员变量orders</span><br><span class="line">    2）javaType=&quot;List&quot; 表示User类的成员变量orders存储的Order对象使用的类型，这里是List 一般不书写</span><br><span class="line">    3) ofType=&quot;Order&quot; 表示List集合中存储数据的类型 Order</span><br><span class="line">3.一定要记住这里给user表的id起别名是uid,order表的id起别名是oid.在resultMap标签的id子标签中的column属性值书写对应的uid和oid.</span><br></pre></td></tr></table></figure><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--自定义结果集--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">resultMap</span> <span class="attr">id</span>=<span class="string">&quot;oneToManyResult&quot;</span> <span class="attr">type</span>=<span class="string">&quot;User&quot;</span> <span class="attr">autoMapping</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--User的主键--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">id</span> <span class="attr">column</span>=<span class="string">&quot;uid&quot;</span> <span class="attr">property</span>=<span class="string">&quot;id&quot;</span>/&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--Order关联映射--&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">        1.一对多使用collection子标签进行关联多方Order</span></span><br><span class="line"><span class="comment">        2.属性：</span></span><br><span class="line"><span class="comment">            1）property=&quot;orders&quot; 这里的orders表示User类的成员变量orders</span></span><br><span class="line"><span class="comment">            2）javaType=&quot;List&quot; 表示User类的成员变量orders存储的Order对象使用的类型，这里是List，可以不配置</span></span><br><span class="line"><span class="comment">            3) ofType=&quot;Order&quot; 表示List集合中存储数据的类型 Order</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">collection</span> <span class="attr">property</span>=<span class="string">&quot;orders&quot;</span> <span class="attr">javaType</span>=<span class="string">&quot;List&quot;</span> <span class="attr">ofType</span>=<span class="string">&quot;Order&quot;</span> <span class="attr">autoMapping</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--Order的主键--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">id</span> <span class="attr">column</span>=<span class="string">&quot;oid&quot;</span> <span class="attr">property</span>=<span class="string">&quot;id&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">collection</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">resultMap</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!--根据用户ID查询用户及其订单数据--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;oneToManyQuery&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;oneToManyResult&quot;</span>&gt;</span></span><br><span class="line">    SELECT</span><br><span class="line">        tbo.id as oid,</span><br><span class="line">        tbo.order_number,</span><br><span class="line">        tbu.id as uid,</span><br><span class="line">        tbu.user_name,</span><br><span class="line">        tbu.password,</span><br><span class="line">        tbu.name,</span><br><span class="line">        tbu.age,</span><br><span class="line">        tbu.sex</span><br><span class="line">    FROM</span><br><span class="line">        tb_user tbu</span><br><span class="line">        INNER JOIN tb_order tbo ON tbu.id = tbo.user_id</span><br><span class="line">    WHERE</span><br><span class="line">        tbu.id = #&#123;id&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure><p>在用户的测试类中</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MybatisTest01</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">UserMapper</span> <span class="variable">mapper</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@BeforeClass</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">beforeClass</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="comment">//1.构建SessionFactory</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">resouce</span> <span class="operator">=</span> <span class="string">&quot;mybatis-config.xml&quot;</span>;</span><br><span class="line">        <span class="type">InputStream</span> <span class="variable">is</span> <span class="operator">=</span> Resources.getResourceAsStream(resouce);</span><br><span class="line">        <span class="type">SqlSessionFactory</span> <span class="variable">build</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">SqlSessionFactoryBuilder</span>().build(is);</span><br><span class="line">        <span class="comment">//2.获取session</span></span><br><span class="line">        <span class="type">SqlSession</span> <span class="variable">sqlSession</span> <span class="operator">=</span> build.openSession(<span class="literal">true</span>);</span><br><span class="line">        <span class="comment">//3.获取接口对象</span></span><br><span class="line">        mapper = sqlSession.getMapper(UserMapper.class);</span><br><span class="line">    &#125;  </span><br><span class="line"><span class="comment">//根据用户ID查询用户及其订单数据</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">oneToManyQuery</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> mapper.oneToManyQuery(<span class="number">1L</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;user = &quot;</span> + user);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://js.hnlyx.top/img/image-20200607124912217-164204273873718.png" alt="image-20200607124912217"></p><h5 id="【小结】-4"><a href="#【小结】-4" class="headerlink" title="【小结】"></a>【小结】</h5><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">一对多关系配置：</span><br><span class="line">1、在对象中添加映射关系；</span><br><span class="line">2、编写接口方法，编写SQL；</span><br><span class="line">3、编写resultMap处理数据库字段和实体类之间数据的封装；</span><br></pre></td></tr></table></figure><h2 id="高级查询小结"><a href="#高级查询小结" class="headerlink" title="高级查询小结"></a>高级查询小结</h2><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">resutlType无法帮助我们自动的去完成映射，所以只有使用resultMap手动的进行映射</span><br><span class="line">resultMap: </span><br><span class="line">属性：</span><br><span class="line">        type 结果集对应的数据类型  Order</span><br><span class="line">        id 唯一标识，被引用的时候，进行指定</span><br><span class="line">        autoMapping 开启自动映射</span><br><span class="line">        extends 继承</span><br><span class="line">子标签：</span><br><span class="line"> id:配置id属性</span><br><span class="line"> result:配置其他属性</span><br><span class="line">      association：配置一对一的映射</span><br><span class="line">          property 定义对象的属性名</span><br><span class="line">          javaType 属性的类型</span><br><span class="line">          autoMapping 开启自动映射</span><br><span class="line">      collection：配置一对多的映射</span><br><span class="line">          property 定义对象的属性名</span><br><span class="line">          javaType 集合的类型</span><br><span class="line">          ofType 集合中的元素类型 泛型</span><br><span class="line">    autoMapping 开启自动映射</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;mybatis映射文件配置&quot;&gt;&lt;a href=&quot;#mybatis映射文件配置&quot; class=&quot;headerlink&quot; title=&quot;mybatis映射文件配置&quot;&gt;&lt;/a&gt;mybatis映射文件配置&lt;/h1&gt;&lt;h2 id=&quot;1、传入的参数&quot;&gt;&lt;a href=&quot;#1、</summary>
      
    
    
    
    
    <category term="MyBatis" scheme="https://www.yxliu.cc/tags/MyBatis/"/>
    
  </entry>
  
  <entry>
    <title>shell学习</title>
    <link href="https://www.yxliu.cc/2022/12/05/f8d5cfbe.html"/>
    <id>https://www.yxliu.cc/2022/12/05/f8d5cfbe.html</id>
    <published>2022-12-05T02:46:38.000Z</published>
    <updated>2026-02-04T06:42:44.031Z</updated>
    
    <content type="html"><![CDATA[<h1 id="shell学习"><a href="#shell学习" class="headerlink" title="shell学习"></a>shell学习</h1><h2 id="shell-变量"><a href="#shell-变量" class="headerlink" title="shell 变量"></a>shell 变量</h2><table><thead><tr><th>特殊变量</th><th></th></tr></thead><tbody><tr><td>特殊变量</td><td>作用说明</td></tr><tr><td>$0</td><td>如果是：利用bash和sh执行脚本。则输入什么就输出什么；<br/>如果是：利用.&#x2F;或者是绝对路径执行脚本。则输入什么就输出什么；<br/>如果是：利用source或. 执行脚本。则输出-bash。</td></tr><tr><td>$n(n&gt;0)</td><td>获取当前执行的shell脚本的第n个参数值，n&#x3D;1..9，如果n大于9用大括号括起来{10}，参数以空格隔开。</td></tr><tr><td>$#</td><td>获取当前执行的shell脚本后面接的参数的总个数</td></tr><tr><td>$?</td><td>上一个命令的执行结果（返回值）。0表示执行正确，1表示执行失败。2表示没有找到文件。这个变量最常用</td></tr><tr><td>$$</td><td>获取当前shell的进程号</td></tr><tr><td>$*</td><td>获取当前shell的所有传参的参数，不加引号同$@;如果给$*加上双引号，例如: “$*“    ,则表示将所有的参数视为单个字符串，相当于”12$3”。</td></tr><tr><td>$@</td><td>获取当前shell的所有传参的参数，不加引号同$*;如果给$@加上双引号，例如: “$@&quot;,则表示将所有参数视为不同的独立字符串，相当于”$1&quot; “$2&quot; “$3&quot; “……”，这是将参数传递给其他程序的最佳方式，因为他会保留所有内嵌在每个参数里的任何空白。</td></tr></tbody></table><h2 id="读取文件"><a href="#读取文件" class="headerlink" title="读取文件"></a>读取文件</h2><h4 id="do…done-config"><a href="#do…done-config" class="headerlink" title="do…done &lt; $config"></a>do…done &lt; $config</h4><p>一个shell脚本：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">config=/usr/config.ini</span><br><span class="line"></span><br><span class="line">...</span><br><span class="line"></span><br><span class="line">while read server ip</span><br><span class="line"></span><br><span class="line">...</span><br><span class="line"></span><br><span class="line">done &lt; $config</span><br></pre></td></tr></table></figure><p>while循环结构如下：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">while 条件</span><br><span class="line">do</span><br><span class="line">...</span><br><span class="line">done</span><br></pre></td></tr></table></figure><p>应该前面还有个do的。这是固定结构，满足条件就会一直循环下去。</p><p>因为最后有输入重定向符号&lt;，将整个while循环条件的输入指定为config变量定义的文件。所以，read会逐行读取这个文件中的字段（每行两个字段）分别作为server和ip。 </p><p>需要注意的是，config.ini文件中的标题行也会被读入。 </p><p>man read，说明中可以看到，如果读成功的话，read返回读取的字节数；读到文件的末尾则返回0。而对于while来讲，条件为0表示为false，则退出循环。  </p><h2 id="linux-shell-字符串操作详解-（长度，读取，替换，截取，连接，对比，删除，位置-）"><a href="#linux-shell-字符串操作详解-（长度，读取，替换，截取，连接，对比，删除，位置-）" class="headerlink" title="linux shell 字符串操作详解 （长度，读取，替换，截取，连接，对比，删除，位置 ）"></a>linux shell 字符串操作详解 （长度，读取，替换，截取，连接，对比，删除，位置 ）</h2><p><img src="https://js.hnlyx.top/img/202212081114174.jpg"></p><p><img src="https://js.hnlyx.top/img/202212081114783.jpg"></p><h3 id="1-Linux-shell-截取字符变量的前8位"><a href="#1-Linux-shell-截取字符变量的前8位" class="headerlink" title="1.Linux shell 截取字符变量的前8位"></a>1.Linux shell 截取字符变量的前8位</h3><p>实现方法有如下几种：  </p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">- expr substr “$a” 1 8</span><br><span class="line">- echo $a|awk ‘&#123;print substr(,1,8)&#125;’</span><br><span class="line">- echo $a|cut -c1-8</span><br><span class="line">- echo $</span><br><span class="line">- expr $a : ‘\(.\\).*’</span><br><span class="line">- echo $a|dd bs=1 count=8 2&gt;/dev/null</span><br></pre></td></tr></table></figure><h3 id="2-按指定的字符串截取"><a href="#2-按指定的字符串截取" class="headerlink" title="2.按指定的字符串截取"></a>2.按指定的字符串截取</h3><p>(1)第一种方法:  </p><p>从左向右截取最后一个string后的字符串  </p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$</span><span class="language-bash">&#123;varible##*string&#125;</span> </span><br><span class="line">从左向右截取第一个string后的字符串 $&#123;varible#*string&#125;  </span><br><span class="line">从右向左截取最后一个string后的字符串  </span><br><span class="line"><span class="meta prompt_">$</span><span class="language-bash">&#123;varible%%string*&#125;</span> </span><br><span class="line">从右向左截取第一个string后的字符串 $&#123;varible%string*&#125;  </span><br><span class="line">“*”只是一个通配符可以不要</span><br></pre></td></tr></table></figure><p>请看下面的例子：  </p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">MYVAR=foodforthought.jpg</span> </span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">echo</span> <span class="variable">$&#123;MYVAR##*fo&#125;</span></span></span><br><span class="line">rthought.jpg </span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">echo</span> <span class="variable">$&#123;MYVAR#*fo&#125;</span></span></span><br><span class="line">odforthought.jpg</span><br></pre></td></tr></table></figure><p>(2)第二种方法：  </p><p>${varible:n1:n2}:截取变量varible从n1开始的n2个字符，组成一个子字符串。可以根据特定字符偏移和长度，使用另一种形式的变量扩展，来选择特定子字符串。试着在 bash 中输入以下行：  </p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">EXCLAIM=cowabunga</span> </span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">echo</span> <span class="variable">$&#123;EXCLAIM:0:3&#125;</span></span></span><br><span class="line">cow </span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">echo</span> <span class="variable">$&#123;EXCLAIM:3:7&#125;</span></span></span><br><span class="line">abunga</span><br></pre></td></tr></table></figure><p>这种形式的字符串截断非常简便，只需用冒号分开来指定起始字符和子字符串长度。  </p><h3 id="3-按照指定要求分割："><a href="#3-按照指定要求分割：" class="headerlink" title="3.按照指定要求分割："></a>3.按照指定要求分割：</h3><p>比如获取后缀名</p><p>ls -al | cut -d “.” -f2</p><p>小结：shell对应字符串的处理方法很多，根据需求灵活选择。</p><p>在做shell批处理程序时候，经常会涉及到字符串相关操作。有很多命令语句，如：awk,sed都可以做字符串各种操作。 其实shell内置一系列操作符号，可以达到类似效果，大家知道，使用内部操作符会省略启动外部程序等时间，因此速度会非常的快。</p><h4 id="一、判断读取字符串值"><a href="#一、判断读取字符串值" class="headerlink" title="一、判断读取字符串值"></a><strong>一、判断读取字符串值</strong></h4><blockquote><p>表达式 含义</p><table><thead><tr><th>${var}</th><th>变量var的值, 与$var相同</th></tr></thead><tbody><tr><td>${var-DEFAULT}</td><td>如果var没有被声明, 那么就以$DEFAULT作为其值 *</td></tr><tr><td>${var:-DEFAULT}</td><td>如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *</td></tr><tr><td>${var&#x3D;DEFAULT}</td><td>如果var没有被声明, 那么就以$DEFAULT作为其值 *</td></tr><tr><td>${var:&#x3D;DEFAULT}</td><td>如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *</td></tr><tr><td>${var+OTHER}</td><td>如果var声明了, 那么其值就是$OTHER, 否则就为null字符串</td></tr><tr><td>${var:+OTHER}</td><td>如果var被设置了, 那么其值就是$OTHER, 否则就为null字符串</td></tr><tr><td>${var?ERR_MSG}</td><td>如果var没被声明, 那么就打印$ERR_MSG *</td></tr><tr><td>${var:?ERR_MSG}</td><td>如果var没被设置, 那么就打印$ERR_MSG *</td></tr><tr><td>${!varprefix*}</td><td>匹配之前所有以varprefix开头进行声明的变量</td></tr><tr><td>${!varprefix@}</td><td>匹配之前所有以varprefix开头进行声明的变量</td></tr></tbody></table></blockquote><p>加入了“*”  不是意思是： 当然, 如果变量var已经被设置的话, 那么其值就是$var.</p><h4 id="二、字符串操作（长度，读取，替换）"><a href="#二、字符串操作（长度，读取，替换）" class="headerlink" title="二、字符串操作（长度，读取，替换）"></a><strong>二、字符串操作（长度，读取，替换）</strong></h4><blockquote><p>表达式 </p><table><thead><tr><th>${<code>#</code>string}</th><th>$string的长度</th></tr></thead><tbody><tr><td>${string:position}</td><td>在$string中, 从位置$position开始提取子串</td></tr><tr><td>${string:position:length}</td><td>在$string中, 从位置$position开始提取长度为$length的子串</td></tr><tr><td>${string#substring}</td><td>从变量$string的开头, 删除最短匹配$substring的子串</td></tr><tr><td>${string##substring}</td><td>从变量$string的开头, 删除最长匹配$substring的子串</td></tr><tr><td>${string%substring}</td><td>从变量$string的结尾, 删除最短匹配$substring的子串</td></tr><tr><td>${string%%substring}</td><td>从变量$string的结尾, 删除最长匹配$substring的子串</td></tr><tr><td>${string&#x2F;substring&#x2F;replacement}</td><td>使用$replacement, 来代替第一个匹配的$substring</td></tr><tr><td>${string&#x2F;&#x2F;substring&#x2F;replacement}</td><td>使用$replacement, 代替<em>所有</em>匹配的$substring</td></tr><tr><td>${string&#x2F;#substring&#x2F;replacement}</td><td>如果$string的<em>前缀</em>匹配$substring, 那么就用$replacement来代替匹配到的$substring</td></tr><tr><td>${string&#x2F;%substring&#x2F;replacement}</td><td>如果$string的<em>后缀</em>匹配$substring, 那么就用$replacement来代替匹配到的$substring</td></tr></tbody></table></blockquote><p> 实例：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">1. $ echo $&#123;abc-&#x27;ok&#x27;&#125;  </span><br><span class="line"></span><br><span class="line">2. ok  </span><br><span class="line"></span><br><span class="line">3. $ echo $abc  </span><br><span class="line"></span><br><span class="line">4. $ echo $&#123;abc=&#x27;ok&#x27;&#125;  </span><br><span class="line"></span><br><span class="line">5. ok  </span><br><span class="line"></span><br><span class="line">6. $ echo $abc  </span><br><span class="line"></span><br><span class="line">7. ok  </span><br><span class="line"></span><br><span class="line">8. #如果abc 没有声明“=&quot; 还会给abc赋值。  </span><br><span class="line"></span><br><span class="line">9. $ var1=11;var2=12;var3=  </span><br><span class="line"></span><br><span class="line">10. $ echo $&#123;!v@&#125;             </span><br><span class="line"></span><br><span class="line">11. var1 var2 var3  </span><br><span class="line"></span><br><span class="line">12. $ echo $&#123;!v*&#125;  </span><br><span class="line"></span><br><span class="line">13. var1 var2 var3  </span><br><span class="line"></span><br><span class="line">14. #$&#123;!varprefix*&#125;与$&#123;!varprefix@&#125;相似，可以通过变量名前缀字符，搜索已经定义的变量,无论是否为空值。  </span><br></pre></td></tr></table></figure><h5 id="1，取得字符串长度"><a href="#1，取得字符串长度" class="headerlink" title="1，取得字符串长度"></a><strong>1，取得字符串长度</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">- string=abc12342341          //等号二边不要有空格  </span><br><span class="line">- echo $&#123;#string&#125;             //结果11  </span><br><span class="line">- expr length $string         //结果11  </span><br><span class="line">- expr &quot;$string&quot; : &quot;.*&quot;       //结果11 分号二边要有空格,这里的:根match的用法差不多</span><br></pre></td></tr></table></figure><h5 id="2，字符串所在位置"><a href="#2，字符串所在位置" class="headerlink" title="2，字符串所在位置"></a><strong>2，字符串所在位置</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">1. expr index $string &#x27;123&#x27;    //结果4 字符串对应的下标是从1开始的   </span><br><span class="line"></span><br><span class="line">1. str=&quot;abc&quot;  </span><br><span class="line">2. expr index $str &quot;a&quot;  # 1  </span><br><span class="line">3. expr index $str &quot;b&quot;  # 2  </span><br><span class="line">4. expr index $str &quot;x&quot;  # 0  </span><br><span class="line">5. expr index $str &quot;&quot;   # 0</span><br></pre></td></tr></table></figure><p>这个方法让我想起来了js的indexOf，各种语言对字符串的操作方法大方向都差不多，如果有语言基础的话，学习shell会很快的。</p><h5 id="3，从字符串开头到子串的最大长度"><a href="#3，从字符串开头到子串的最大长度" class="headerlink" title="3，从字符串开头到子串的最大长度"></a><strong>3，从字符串开头到子串的最大长度</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1. expr match $string &#x27;abc.*3&#x27; //结果9    </span><br></pre></td></tr></table></figure><p> </p><p>个人觉得这个函数的用处不大，为什么要从开头开始呢。</p><h5 id="4，字符串截取"><a href="#4，字符串截取" class="headerlink" title="4，字符串截取"></a><strong>4，字符串截取</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">1. echo $&#123;string:4&#125;      //2342341  从第4位开始截取后面所有字符串    </span><br><span class="line"></span><br><span class="line">2. echo $&#123;string:3:3&#125;    //123      从第3位开始截取后面3位    </span><br><span class="line"></span><br><span class="line">3. echo $&#123;string:3:6&#125;    //123423   从第3位开始截取后面6位    </span><br><span class="line"></span><br><span class="line">4. echo $&#123;string: -4&#125;    //2341  ：右边有空格   截取后4位    </span><br><span class="line"></span><br><span class="line">5. echo $&#123;string:(-4)&#125;   //2341  同上    </span><br><span class="line"></span><br><span class="line">6. expr substr $string 3 3   //123  从第3位开始截取后面3位    </span><br><span class="line"></span><br><span class="line">7. str=&quot;abcdef&quot;  </span><br><span class="line"></span><br><span class="line">8. expr substr &quot;$str&quot; 1 3  # 从第一个位置开始取3个字符， abc  </span><br><span class="line"></span><br><span class="line">9. expr substr &quot;$str&quot; 2 5  # 从第二个位置开始取5个字符， bcdef   </span><br><span class="line"></span><br><span class="line">10. expr substr &quot;$str&quot; 4 5  # 从第四个位置开始取5个字符， def  </span><br><span class="line"></span><br><span class="line">11. echo $&#123;str:2&#125;           # 从第二个位置开始提取字符串， bcdef  </span><br><span class="line"></span><br><span class="line">12. echo $&#123;str:2:3&#125;         # 从第二个位置开始提取3个字符, bcd  </span><br><span class="line"></span><br><span class="line">13. echo $&#123;str:(-6):5&#125;        # 从倒数第二个位置向左提取字符串, abcde  </span><br><span class="line"></span><br><span class="line">14. echo $&#123;str:(-4):3&#125;      # 从倒数第二个位置向左提取6个字符, cde  </span><br></pre></td></tr></table></figure><p>上面的方法让我想起了，php的substr函数，后面截取的规则是一样的。</p><h5 id="5，匹配显示内容"><a href="#5，匹配显示内容" class="headerlink" title="5，匹配显示内容"></a><strong>5，匹配显示内容</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">1. //例3中也有match和这里的match不同，上面显示的是匹配字符的长度，而下面的是匹配的内容    </span><br><span class="line">2. expr match $string &#x27;\([a-c]*[0-9]*\)&#x27;  //abc12342341    </span><br><span class="line">3. expr $string : &#x27;\([a-c]*[0-9]\)&#x27;       //abc1    </span><br><span class="line">4. expr $string : &#x27;.*\([0-9][0-9][0-9]\)&#x27; //341 显示括号中匹配的内容    </span><br></pre></td></tr></table></figure><p>这里括号的用法，是不是根其他的括号用法有相似之处呢，</p><h5 id="6，截取不匹配的内容"><a href="#6，截取不匹配的内容" class="headerlink" title="6，截取不匹配的内容"></a><strong>6，截取不匹配的内容</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">1. echo $&#123;string#a*3&#125;     //42341  从$string左边开始，去掉最短匹配子串    </span><br><span class="line">2. echo $&#123;string#c*3&#125;     //abc12342341  这样什么也没有匹配到    </span><br><span class="line">3. echo $&#123;string#*c1*3&#125;   //42341  从$string左边开始，去掉最短匹配子串    </span><br><span class="line">4. echo $&#123;string##a*3&#125;    //41     从$string左边开始，去掉最长匹配子串    </span><br><span class="line">5. echo $&#123;string%3*1&#125;     //abc12342  从$string右边开始，去掉最短匹配子串    </span><br><span class="line">6. echo $&#123;string%%3*1&#125;    //abc12     从$string右边开始，去掉最长匹配子串    </span><br><span class="line"></span><br><span class="line">1. str=&quot;abbc,def,ghi,abcjkl&quot;  </span><br><span class="line"></span><br><span class="line">2. echo $&#123;str#a*c&#125;     # 输出,def,ghi,abcjkl  一个井号(#) 表示从左边截取掉最短的匹配 (这里把abbc字串去掉）  </span><br><span class="line"></span><br><span class="line">3. echo $&#123;str##a*c&#125;    # 输出jkl，             两个井号(##) 表示从左边截取掉最长的匹配 (这里把abbc,def,ghi,abc字串去掉)  </span><br><span class="line"></span><br><span class="line">4. echo $&#123;str#&quot;a*c&quot;&#125;   # 输出abbc,def,ghi,abcjkl 因为str中没有&quot;a*c&quot;子串  </span><br><span class="line"></span><br><span class="line">5. echo $&#123;str##&quot;a*c&quot;&#125;  # 输出abbc,def,ghi,abcjkl 同理  </span><br><span class="line"></span><br><span class="line">6. echo $&#123;str#*a*c*&#125;   # 空  </span><br><span class="line"></span><br><span class="line">7. echo $&#123;str##*a*c*&#125;  # 空  </span><br><span class="line"></span><br><span class="line">8. echo $&#123;str#d*f)     # 输出abbc,def,ghi,abcjkl,   </span><br><span class="line"></span><br><span class="line">9. echo $&#123;str#*d*f&#125;    # 输出,ghi,abcjkl     </span><br><span class="line"></span><br><span class="line">10. echo $&#123;str%a*l&#125;     # abbc,def,ghi  一个百分号(%)表示从右边截取最短的匹配   </span><br><span class="line"></span><br><span class="line">11. echo $&#123;str%%b*l&#125;    # a             两个百分号表示(%%)表示从右边截取最长的匹配  </span><br><span class="line"></span><br><span class="line">12. echo $&#123;str%a*c&#125;     # abbc,def,ghi,abcjkl    </span><br></pre></td></tr></table></figure><p>这里要注意，必须从字符串的第一个字符开始，或者从最后一个开始，可以这样记忆, 井号（#）通常用于表示一个数字，它是放在前面的；百分号（%）卸载数字的后面; 或者这样记忆，在键盘布局中，井号(#)总是位于百分号（%）的左边(即前面)  。</p><h5 id="7，匹配并且替换"><a href="#7，匹配并且替换" class="headerlink" title="7，匹配并且替换"></a><strong>7，匹配并且替换</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">1. echo $&#123;string/23/bb&#125;   //abc1bb42341  替换一次    </span><br><span class="line"></span><br><span class="line">2. echo $&#123;string//23/bb&#125;  //abc1bb4bb41  双斜杠替换所有匹配    </span><br><span class="line"></span><br><span class="line">3. echo $&#123;string/#abc/bb&#125; //bb12342341   #以什么开头来匹配，根php中的^有点像    </span><br><span class="line"></span><br><span class="line">4. echo $&#123;string/%41/bb&#125;  //abc123423bb  %以什么结尾来匹配，根php中的$有点像   </span><br><span class="line"></span><br><span class="line">5. str=&quot;apple, tree, apple tree&quot;  </span><br><span class="line"></span><br><span class="line">6. echo $&#123;str/apple/APPLE&#125;   # 替换第一次出现的apple  </span><br><span class="line"></span><br><span class="line">7. echo $&#123;str//apple/APPLE&#125;  # 替换所有apple  </span><br><span class="line"></span><br><span class="line">8. echo $&#123;str/#apple/APPLE&#125;  # 如果字符串str以apple开头，则用APPLE替换它  </span><br><span class="line"></span><br><span class="line">9. echo $&#123;str/%apple/APPLE&#125;  # 如果字符串str以apple结尾，则用APPLE替换它  </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">1. $ test=&#x27;c:/windows/boot.ini&#x27;  </span><br><span class="line"></span><br><span class="line">2. $ echo $&#123;test/\//\\&#125;  </span><br><span class="line"></span><br><span class="line">3. c:\windows/boot.ini  </span><br><span class="line"></span><br><span class="line">4. $ echo $&#123;test//\//\\&#125;  </span><br><span class="line"></span><br><span class="line">5. c:\windows\boot.ini  </span><br><span class="line"></span><br><span class="line">6. #$&#123;变量/查找/替换值&#125; 一个“/”表示替换第一个，”//”表示替换所有,当查找中出现了：”/”请加转义符”\/”表示。  </span><br></pre></td></tr></table></figure><h5 id="8-比较"><a href="#8-比较" class="headerlink" title="8. 比较"></a><strong>8. 比较</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">[[ &quot;a.txt&quot; == a* ]]        # 逻辑真 (pattern matching)  </span><br><span class="line">[[ &quot;a.txt&quot; =~ .*\.txt ]]   # 逻辑真 (regex matching)  </span><br><span class="line">[[ &quot;abc&quot; == &quot;abc&quot; ]]       # 逻辑真 (string comparision)   </span><br><span class="line">[[ &quot;11&quot; &lt; &quot;2&quot; ]]           # 逻辑真 (string comparision), 按ascii值比较</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">在shell脚本中，使用-eq、-ne、-gt、-ge、-lt、-le进行整数的比较。</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">这些符号只能用于整数的比较，不能用于字符串。</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">英文意思分别为：</span></span><br><span class="line">-eq ：equal（相等）</span><br><span class="line">-ne ：not equal（不等） </span><br><span class="line">-gt  ：greater than（大于）</span><br><span class="line">-ge ：greater than or equal（大于或等于）</span><br><span class="line">-lt   ：less than（小于）</span><br><span class="line">-le  ：less than or equal（小于或等于）</span><br></pre></td></tr></table></figure><p> </p><h5 id="9-连接"><a href="#9-连接" class="headerlink" title="9. 连接"></a><strong>9. 连接</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1. s1=&quot;hello&quot;  </span><br><span class="line">2. s2=&quot;world&quot;  </span><br><span class="line">3. echo $&#123;s1&#125;$&#123;s2&#125;   # 当然这样写 $s1$s2 也行，但最好加上大括号  </span><br></pre></td></tr></table></figure><h5 id="10-字符串删除"><a href="#10-字符串删除" class="headerlink" title="10. 字符串删除"></a><strong>10. 字符串删除</strong></h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">1. $ test=&#x27;c:/windows/boot.ini&#x27;  </span><br><span class="line"></span><br><span class="line">2. $ echo $&#123;test#/&#125;  </span><br><span class="line"></span><br><span class="line">3. c:/windows/boot.ini  </span><br><span class="line"></span><br><span class="line">4. $ echo $&#123;test#*/&#125;  </span><br><span class="line"></span><br><span class="line">5. windows/boot.ini  </span><br><span class="line"></span><br><span class="line">6. $ echo $&#123;test##*/&#125;  </span><br><span class="line"></span><br><span class="line">7. boot.ini  </span><br><span class="line"></span><br><span class="line">8. $ echo $&#123;test%/*&#125; </span><br><span class="line"></span><br><span class="line">9. c:/windows </span><br><span class="line"></span><br><span class="line">10. $ echo $&#123;test%%/*&#125; </span><br><span class="line"></span><br><span class="line">11. #$&#123;变量名#substring正则表达式&#125;从字符串开头开始配备substring,删除匹配上的表达式。 </span><br><span class="line"></span><br><span class="line">12. #$&#123;变量名%substring正则表达式&#125;从字符串结尾开始配备substring,删除匹配上的表达式。 </span><br><span class="line"></span><br><span class="line">13. #注意：$&#123;test##*/&#125;,$&#123;test%/*&#125; 分别是得到文件名，或者目录地址最简单方法。</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;shell学习&quot;&gt;&lt;a href=&quot;#shell学习&quot; class=&quot;headerlink&quot; title=&quot;shell学习&quot;&gt;&lt;/a&gt;shell学习&lt;/h1&gt;&lt;h2 id=&quot;shell-变量&quot;&gt;&lt;a href=&quot;#shell-变量&quot; class=&quot;headerli</summary>
      
    
    
    
    <category term="Linux" scheme="https://www.yxliu.cc/categories/Linux/"/>
    
    
    <category term="Shell" scheme="https://www.yxliu.cc/tags/Shell/"/>
    
  </entry>
  
  <entry>
    <title>MYSQL学习</title>
    <link href="https://www.yxliu.cc/2022/12/04/6ef88858.html"/>
    <id>https://www.yxliu.cc/2022/12/04/6ef88858.html</id>
    <published>2022-12-04T06:59:26.000Z</published>
    <updated>2026-02-04T06:42:44.027Z</updated>
    
    <content type="html"><![CDATA[<h2 id="1、事务的四大特性-ACID-面试"><a href="#1、事务的四大特性-ACID-面试" class="headerlink" title="1、事务的四大特性(ACID)(面试)"></a>1、事务的四大特性(ACID)(面试)</h2><h3 id="目标"><a href="#目标" class="headerlink" title="目标"></a>目标</h3><p>了解事务的四大特性</p><h3 id="讲解"><a href="#讲解" class="headerlink" title="讲解"></a>讲解</h3><p>数据库的事务必须具备ACID特性，ACID是指 Atomicity（原子性）、Consistensy（一致性）、Isolation（隔离性）和Durability（持久性）的英文缩写。</p><p><strong>1、隔离性（Isolation）</strong></p><p>多个用户并发的访问数据库时，一个用户的事务不能被其他用户的事务干扰，多个并发的事务之间要相互隔离。</p><p> 一个事务的成功或者失败对于其他的事务是没有影响。2个事务应该相互独立。</p><p>举例：</p><p>a 给b转账 –&gt;叫做事务A</p><p>c 给d 转账 –&gt;叫做事务B</p><p>事务A和事务B之间不会相互影响。</p><p><strong>2、持久性（Durability）</strong></p><p>指一个事务一旦被提交，它对数据库的改变将是永久性的，哪怕数据库发生异常，重启之后数据亦然存在。</p><p>举例：</p><p>a&#x3D;1000、b&#x3D;1000转账</p><p>开启事务</p><p>a-100</p><p>b+100</p><p>提交</p><p>结果： a 900 b 1100</p><p>即使事务提交以后再发生异常，a和b的数据依然不会变。a就是900  b就是1100。</p><p><strong>3、原子性（Atomicity）</strong> </p><p><strong>原子性是指事务</strong>包装的一组sql(一组业务逻辑)是一个不可分割的工作单位，事务中的操作要么都发生，要么都不发生。</p><p><strong>4、一致性（Consistency）</strong></p><p>一个事务在执行之前和执行之后 数据库都必须处于一致性状态。</p><p>如果事务成功的完成，那么数据库的所有变化将生效。</p><p>如果事务执行出现错误，那么数据库的所有变化将会被回滚（撤销），返回到原始状态。</p><p><strong>事务的成功与失败，最终数据库的数据都是符合实际生活的业务逻辑。一致性绝大多数依赖业务逻辑和原子性。</strong></p><p>举例1： a&#x3D;1000、b&#x3D;1000 转账 100</p><p>a - 100</p><p>b + 100</p><p>结果： a + b &#x3D; 2000</p><p>如果a转账失败了，那么b也得失败。不能因为a失败了，a依然是1000.但是b却成功了，b却变成了1100.那么结果是2100了，这样是不符合事务的一致性的。</p><h3 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h3><p>事务四个特性？<br>原子性<br>一致性<br>隔离性<br>持久性</p><table><thead><tr><th>事务特性</th><th>含义</th></tr></thead><tbody><tr><td>一致性（Consistency）</td><td>事务前后数据的完整性必须保持一致</td></tr><tr><td>原子性（Atomicity）</td><td>事务是一个不可分割的工作单位，事务中的操作要么都发生，要么都不发生。</td></tr><tr><td>隔离性（Isolation）</td><td>是指多个用户并发访问数据库时，一个用户的事务不能被其它用户的事务所干扰，多个并发事务之间数据要相互隔离，不能相互影响。</td></tr><tr><td>持久性（Durability）</td><td>指一个事务一旦被提交，它对数据库中数据的改变就是永久性的，接下来即使数据库发生故障也不应该对其有任何影响</td></tr></tbody></table><h2 id="2、事务的并发访问引发的三个问题-面试"><a href="#2、事务的并发访问引发的三个问题-面试" class="headerlink" title="2、事务的并发访问引发的三个问题(面试)"></a>2、事务的并发访问引发的三个问题(面试)</h2><h3 id="目标-1"><a href="#目标-1" class="headerlink" title="目标"></a>目标</h3><p>能够理解并发访问的三个问题</p><h3 id="讲解-1"><a href="#讲解-1" class="headerlink" title="讲解"></a>讲解</h3><p>事务在操作时的理想状态：多个事务之间互不影响，如果隔离级别设置不当就可能引发并发访问问题。</p><table><thead><tr><th>并发访问的问题</th><th>含义</th></tr></thead><tbody><tr><td>脏读</td><td>一个事务读取到了另一个事务中尚<strong>未提交的数据</strong>。最严重，杜绝发生。</td></tr><tr><td>不可重复读</td><td>一个事务中两次读取的<strong>数据内容</strong>不一致，要求的是一个事务中多次读取时数据是不一致的，这是事务<strong>update时</strong>引发的问题</td></tr><tr><td>幻读(虚读)</td><td>一个事务内读取到了别的<strong>事务插入或者删除的数据</strong>，导致前后读取记录行数不同。这是<strong>insert或delete</strong>时引发的问题</td></tr></tbody></table><p>   <strong>1.脏读：指一个事务读取了另外一个事务未提交的数据。(非常危险)</strong></p><pre><code>脏读具体解释如下图所示：注意脏读的前提是没有事务的隔离性。</code></pre><p><img src="https://js.hnlyx.top/img/%E8%84%8F%E8%AF%BB.bmp"></p><p>说明：事务a首先执行转账操作，然后事务a还没有提交数据的情况下，事务b读取了数据库的数据。紧接着事务a执行回滚操作，导致事务b读取的结果和数据库的实际数据是不一样的。</p><p>一个事务读取了另一个事务未提交的数据叫做脏读。</p><p>举例：</p><p>a 转账 给b  100，未提交</p><p>b 查询账户多了100</p><p>a 回滚</p><p>b 查询账户那100不见了。 </p><p>一个事务读取了另一个事务没有提交的数据，非常严重，必须避免脏读。</p><p><strong>2.不可重复读：在一个事务内多次读取表中的数据，多次读取的结果不同。</strong></p><p><img src="https://js.hnlyx.top/img/%E4%B8%8D%E5%8F%AF%E9%87%8D%E5%A4%8D%E8%AF%BB.bmp"></p><p>说明：事务b首先读取数据库的数据，然后事务a对数据修改并提交。之后事务b对数据库再次进行读取。这时发现在事务b中2次读取的结果不一致。</p><p>一个事务内读取了另一个事务提交的数据。这个叫做不可重复读。</p><p>不可重复读和脏读的区别：</p><p>脏读：强调的是读取了未提交的数据。</p><p>不可重复读：一个事务内2次读取，其中一次读取了另一个事务提交了的数据。</p><p>例如: 银行想查询A账户的余额，第一次查询的结果是200元，A向账户中又存了100元。此时，银行再次查询的结果变成了300元。两次查询的结果不一致，银行就会很困惑，以哪次为准。</p><p>和脏读不同的是：脏读读取的是前一事务未提交的数据，不可重复度 读取的是前一事务已提交的事务。</p><p>很多人认为这有啥好困惑的，肯定是以后面的结果为准了。我们需要考虑这样一种情况，查询A账户的余额，一个打印到控制台，一个输出到硬盘上，同一个事务中只是顺序不同，两次查询结果不一致，到底以哪个为准，你会不会困惑呢？</p><p>当前事务查询A账户的余额为100元，另外一个事务更新余额为300元并提交，导致当前事务使用同一查询结果却变成了300元。</p><p><strong>3.幻读（虚读）:一个事务内读取到了别的事务插入或者删除的数据，导致前后读取记录行数不同</strong></p><p><img src="https://js.hnlyx.top/img/%E5%B9%BB%E8%AF%BB.bmp"></p><p>说明：事务b首先读取数据的数量，然后事务a添加了一条数据，并且提交了。接着事务b再次读取了数据的数量。2次读取不一致。</p><p>同一个事务内，2次读取的数据的数量不一致，叫做幻读或者虚读。</p><p>虚读(幻读)和不可重复读的区别：</p><p>不可重复读：强调的是数据内容的不一致。另一个事务是update操作。</p><p>虚读(幻读)：强调的数据的数量(记录数)的不一致。另一个事务是insert或者delete操作。</p><p>注意：</p><p>指在一个事务中 读取 另一个事务 插入或删除 数据记录，导致当前事务读取数据的记录数前后不一致。</p><p>一个事务读取另一个事务已经提交的数据，强调的是记录数的变化，常用sql类型为 insert和 delete。</p><h3 id="小结-1"><a href="#小结-1" class="headerlink" title="小结"></a>小结</h3><ol><li>能够理解并发访问的三个问题<br>赃读:一个事务读取另一个事务还没有提交的数据,一定避免。<br>不可重复读:一个事务读取多次数据内容不一样，主要是update语句。事务已经提交了。 可以发生的。<br>幻读:一个事务读取多次数量不一样，主要是delete或者insert语句。事务已经提交了。可以发生的。</li></ol><h2 id="3、事务的隔离级别"><a href="#3、事务的隔离级别" class="headerlink" title="3、事务的隔离级别"></a>3、事务的隔离级别</h2><h3 id="目标-2"><a href="#目标-2" class="headerlink" title="目标"></a>目标</h3><p>能够说出mysql的四种隔离级别</p><h3 id="讲解-2"><a href="#讲解-2" class="headerlink" title="讲解"></a>讲解</h3><p>1、通过以上问题演示，我们发现如果不考虑事务的隔离性，会遇到脏读、不可重复读和虚读等问题。所以在数据库中我们要对上述三种问题进行解决。MySQL数据库规范规定了4种隔离级别，分别用于描述两个事务并发的所有情况。</p><p>上面的级别最低，下面的级别最高。“是”表示会出现这种问题，“否”表示不会出现这种问题。</p><table><thead><tr><th>级别</th><th>名字</th><th>隔离级别</th><th>脏读</th><th>不可重复读</th><th>幻读</th><th>数据库默认隔离级别</th></tr></thead><tbody><tr><td>1</td><td>读未提交</td><td>read uncommitted</td><td>是</td><td>是</td><td>是</td><td></td></tr><tr><td>2</td><td>读已提交</td><td>read committed</td><td>否</td><td>是</td><td>是</td><td>Oracle和SQL Server</td></tr><tr><td>3</td><td>可重复读</td><td>repeatable read</td><td>否</td><td>否</td><td>是</td><td>MySQL</td></tr><tr><td>4</td><td>串行化</td><td>serializable</td><td>否</td><td>否</td><td>否</td><td></td></tr></tbody></table><p>2、安全和性能对比</p><p>安全性：serializable &gt; repeatable read &gt; read committed &gt; read uncommitted</p><p>性能 ： serializable &lt; repeatable read &lt; read committed &lt; read uncommitted</p><p>3、注意：其实三个问题，开发中最严重的问题就是脏读，这个问题一定要避免，而关于不可重复读和虚读其实只是感官上的错误，并不是逻辑上的错误。就是数据的时效性，所以这种问题并不属于很严重的错误。如果对于数据的时效性要求不是很高的情况下，我们是可以接受不可重复读和虚读的情况发生的。</p><h3 id="小结-2"><a href="#小结-2" class="headerlink" title="小结"></a>小结</h3><p>能够说出mysql的四种隔离级别<br>读未提交:read uncommitted<br><strong>读已提交:read committed 可以避免脏读</strong><br><strong>可重复读:repeatable read mysql默认的，可以避免脏读 和不可重复读</strong><br>串行化:serializable</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;1、事务的四大特性-ACID-面试&quot;&gt;&lt;a href=&quot;#1、事务的四大特性-ACID-面试&quot; class=&quot;headerlink&quot; title=&quot;1、事务的四大特性(ACID)(面试)&quot;&gt;&lt;/a&gt;1、事务的四大特性(ACID)(面试)&lt;/h2&gt;&lt;h3 id=&quot;目</summary>
      
    
    
    
    <category term="Sql" scheme="https://www.yxliu.cc/categories/Sql/"/>
    
    
    <category term="MYSQL" scheme="https://www.yxliu.cc/tags/MYSQL/"/>
    
  </entry>
  
  <entry>
    <title>Java基础</title>
    <link href="https://www.yxliu.cc/2022/12/03/4b1fec93.html"/>
    <id>https://www.yxliu.cc/2022/12/03/4b1fec93.html</id>
    <published>2022-12-03T09:20:00.000Z</published>
    <updated>2026-02-04T06:42:44.027Z</updated>
    
    <content type="html"><![CDATA[<h2 id="JAVA基础运算符"><a href="#JAVA基础运算符" class="headerlink" title="JAVA基础运算符"></a>JAVA基础运算符</h2><h3 id="和"><a href="#和" class="headerlink" title="&amp;和&amp;&amp;"></a>&amp;和&amp;&amp;</h3><p>Java中&amp;和&amp;&amp;都是逻辑与，需要左右两边同时满足条件才可以得到true的结果。但是，它们之间也有区别：</p><p>1、&amp;&amp;也叫短路与，当&amp;&amp;左边的条件不满足时，就不会判定右边的条件。而&amp;不一样，无论‘&amp;’左边的条件是否满足，它都会判定右边的条件。</p><p>2、&amp;可用于位运算，当左右两边的条件不是布尔型，而是数字时，它会进行位运算。</p><p>​2 &amp; 3就是合法的，会进行位运算。</p><p>&amp;与&amp;&amp;的异同点。<br>相同点：二者都表示与操作，当且仅当运算符两边的操作数都为true时，其结果才为true，否则为false。</p><p>不同点：在使用&amp;进行运算时，不论左边为true或者false，右边的表达式都会进行运算。如果使用&amp;&amp;进行运算时，当左边为false时，右边的表达式不会进行运算，因此&amp;&amp;被称作短路与。</p><h3 id="和-1"><a href="#和-1" class="headerlink" title="| 和 ||"></a>| 和 ||</h3><p>|与||的相同点：二者都表示或操作，当运算符两边的操作数任何一边的值为true时，其结果为true，当两边的值都为false时，其结果才为false。</p><p>同与操作类似，||表示短路或，当运算符左边的值为true时，右边的表达式不会进行运算。 和&amp; 与&amp;&amp; 不同点相同</p><p>在使用 | 进行运算时，不论左边为true或者false，右边的表达式都会进行运算。如果使用 || 进行运算时，当左边为false时，右边的表达式不会进行运算，因此&amp;&amp;被称作短路与。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">x</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">  <span class="type">int</span> <span class="variable">y</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(x++==<span class="number">2</span> &amp; ++y==<span class="number">2</span>)&#123;</span><br><span class="line">      x =<span class="number">7</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  System.out.println(<span class="string">&quot;使用&amp;时 x=&quot;</span>+x+<span class="string">&quot;,y=&quot;</span>+y);</span><br><span class="line"></span><br><span class="line">  x = <span class="number">1</span>;y = <span class="number">1</span>;</span><br><span class="line">  <span class="keyword">if</span>(x++==<span class="number">2</span> &amp;&amp; ++y==<span class="number">2</span>)&#123;</span><br><span class="line">      x =<span class="number">7</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  System.out.println(<span class="string">&quot;使用&amp;&amp;时 x=&quot;</span>+x+<span class="string">&quot;,y=&quot;</span>+y);</span><br><span class="line"></span><br><span class="line">  x = <span class="number">1</span>;y = <span class="number">1</span>;</span><br><span class="line">  <span class="keyword">if</span>(x++==<span class="number">1</span> | ++y==<span class="number">1</span>)&#123;</span><br><span class="line">      x =<span class="number">7</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  System.out.println(<span class="string">&quot;使用 | 时 x=&quot;</span>+x+<span class="string">&quot;,y=&quot;</span>+y);</span><br><span class="line"></span><br><span class="line">  x = <span class="number">1</span>;y = <span class="number">1</span>;</span><br><span class="line">  <span class="keyword">if</span>(x++==<span class="number">1</span> || ++y==<span class="number">1</span>)&#123;</span><br><span class="line">      x =<span class="number">7</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  System.out.println(<span class="string">&quot;使用 || 时 x=&quot;</span>+x+<span class="string">&quot;,y=&quot;</span>+y);</span><br></pre></td></tr></table></figure><p>结果：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">使用&amp;时 x=<span class="number">2</span>,y=<span class="number">2</span></span><br><span class="line">使用&amp;&amp;时 x=<span class="number">2</span>,y=<span class="number">1</span></span><br><span class="line">使用 | 时 x=<span class="number">7</span>,y=<span class="number">2</span></span><br><span class="line">使用 || 时 x=<span class="number">7</span>,y=<span class="number">1</span></span><br></pre></td></tr></table></figure><p>Java基本数据类型</p><p><img src="https://js.hnlyx.top/img/%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E8%8C%83%E5%9B%B4.jpg"></p><h3 id="运算符优先级"><a href="#运算符优先级" class="headerlink" title="运算符优先级"></a>运算符优先级</h3><p><img src="https://js.hnlyx.top/img/1553858424335.png" alt="1553858424335"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;JAVA基础运算符&quot;&gt;&lt;a href=&quot;#JAVA基础运算符&quot; class=&quot;headerlink&quot; title=&quot;JAVA基础运算符&quot;&gt;&lt;/a&gt;JAVA基础运算符&lt;/h2&gt;&lt;h3 id=&quot;和&quot;&gt;&lt;a href=&quot;#和&quot; class=&quot;headerlink&quot; ti</summary>
      
    
    
    
    
    <category term="JAVA基础" scheme="https://www.yxliu.cc/tags/JAVA%E5%9F%BA%E7%A1%80/"/>
    
  </entry>
  
  <entry>
    <title>SQL多表查询</title>
    <link href="https://www.yxliu.cc/2022/11/18/5e1a317e.html"/>
    <id>https://www.yxliu.cc/2022/11/18/5e1a317e.html</id>
    <published>2022-11-18T02:07:24.000Z</published>
    <updated>2026-02-04T06:42:44.030Z</updated>
    
    <content type="html"><![CDATA[<p>多表查询，也称为关联查询，指两个或更多个表一起完成查询操作。</p><p>前提条件：这些一起查询的表之间是有关系的（一对一、一对多），它们之间一定是有关联字段，这个关联字段可能建立了外键，也可能没有建立外键。比如：员工表和部门表，这两个表依靠“部门编号”进行关联。</p><h2 id="1-一个案例引发的多表连接"><a href="#1-一个案例引发的多表连接" class="headerlink" title="1. 一个案例引发的多表连接"></a>1. 一个案例引发的多表连接</h2><h3 id="1-1-案例说明"><a href="#1-1-案例说明" class="headerlink" title="1.1 案例说明"></a>1.1 案例说明</h3><p>从多个表中获取数据：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#案例：查询员工的姓名及其部门名称</span><br><span class="line">SELECT last_name, department_name</span><br><span class="line">FROM employees, departments;</span><br></pre></td></tr></table></figure><p>查询结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">+-----------+----------------------+</span><br><span class="line">| last_name | department_name      |</span><br><span class="line">+-----------+----------------------+</span><br><span class="line">| King      | Administration       |</span><br><span class="line">| King      | Marketing            |</span><br><span class="line">| King      | Purchasing           |</span><br><span class="line">| King      | Human Resources      |</span><br><span class="line">| King      | Shipping             |</span><br><span class="line">| King      | IT                   |</span><br><span class="line">| King      | Public Relations     |</span><br><span class="line">| King      | Sales                |</span><br><span class="line">| King      | Executive            |</span><br><span class="line">| King      | Finance              |</span><br><span class="line">| King      | Accounting           |</span><br><span class="line">| King      | Treasury             |</span><br><span class="line">...</span><br><span class="line">| Gietz     | IT Support           |</span><br><span class="line">| Gietz     | NOC                  |</span><br><span class="line">| Gietz     | IT Helpdesk          |</span><br><span class="line">| Gietz     | Government Sales     |</span><br><span class="line">| Gietz     | Retail Sales         |</span><br><span class="line">| Gietz     | Recruiting           |</span><br><span class="line">| Gietz     | Payroll              |</span><br><span class="line">+-----------+----------------------+</span><br><span class="line">2889 rows in set (0.01 sec)</span><br></pre></td></tr></table></figure><p><strong>分析错误情况：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SELECT COUNT(employee_id) FROM employees;</span><br><span class="line">#输出107行</span><br><span class="line"></span><br><span class="line">SELECT COUNT(department_id)FROM departments;</span><br><span class="line">#输出27行</span><br><span class="line"></span><br><span class="line">SELECT 107*27 FROM dual;</span><br></pre></td></tr></table></figure><p>我们把上述多表查询中出现的问题称为：笛卡尔积的错误。</p><h3 id="1-2-笛卡尔积（或交叉连接）的理解"><a href="#1-2-笛卡尔积（或交叉连接）的理解" class="headerlink" title="1.2 笛卡尔积（或交叉连接）的理解"></a>1.2 笛卡尔积（或交叉连接）的理解</h3><p>笛卡尔乘积是一个数学运算。假设我有两个集合 X 和 Y，那么 X 和 Y 的笛卡尔积就是 X 和 Y 的所有可能组合，也就是第一个对象来自于 X，第二个对象来自于 Y 的所有可能。组合的个数即为两个集合中元素个数的乘积数。</p><p><img src="https://images0.cnblogs.com/i/595518/201403/302046364841977.jpg" alt="img"></p><p>SQL92中，笛卡尔积也称为<code>交叉连接</code>，英文是 <code>CROSS JOIN</code>。在 SQL99 中也是使用 CROSS JOIN表示交叉连接。它的作用就是可以把任意表进行连接，即使这两张表不相关。在MySQL中如下情况会出现笛卡尔积：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">#查询员工姓名和所在部门名称</span><br><span class="line">SELECT last_name,department_name FROM employees,departments;</span><br><span class="line">SELECT last_name,department_name FROM employees CROSS JOIN departments;</span><br><span class="line">SELECT last_name,department_name FROM employees INNER JOIN departments;</span><br><span class="line">SELECT last_name,department_name FROM employees JOIN departments;</span><br></pre></td></tr></table></figure><h3 id="1-3-案例分析与问题解决"><a href="#1-3-案例分析与问题解决" class="headerlink" title="1.3 案例分析与问题解决"></a>1.3 案例分析与问题解决</h3><ul><li><p><strong>笛卡尔积的错误会在下面条件下产生</strong>：</p><ul><li>省略多个表的连接条件（或关联条件）</li><li>连接条件（或关联条件）无效</li><li>所有表中的所有行互相连接</li></ul></li><li><p>为了避免笛卡尔积， 可以<strong>在 WHERE 加入有效的连接条件。</strong></p></li><li><p>加入连接条件后，查询语法：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SELECT    table1.column, table2.column</span><br><span class="line">FROM    table1, table2</span><br><span class="line">WHERE    table1.column1 = table2.column2;  #连接条件</span><br></pre></td></tr></table></figure><ul><li><strong>在 WHERE子句中写入连接条件。</strong></li></ul></li><li><p>正确写法：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#案例：查询员工的姓名及其部门名称</span><br><span class="line">SELECT last_name, department_name</span><br><span class="line">FROM employees, departments</span><br><span class="line">WHERE employees.department_id = departments.department_id;</span><br></pre></td></tr></table></figure></li><li><p><strong>在表中有相同列时，在列名之前加上表名前缀。</strong></p></li></ul><h2 id="2-多表查询分类讲解"><a href="#2-多表查询分类讲解" class="headerlink" title="2. 多表查询分类讲解"></a>2. 多表查询分类讲解</h2><h3 id="分类1：等值连接-vs-非等值连接"><a href="#分类1：等值连接-vs-非等值连接" class="headerlink" title="分类1：等值连接 vs 非等值连接"></a>分类1：等值连接 vs 非等值连接</h3><h4 id="等值连接"><a href="#等值连接" class="headerlink" title="等值连接"></a>等值连接</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">SELECT employees.employee_id, employees.last_name, </span><br><span class="line">       employees.department_id, departments.department_id,</span><br><span class="line">       departments.location_id</span><br><span class="line">FROM   employees, departments</span><br><span class="line">WHERE  employees.department_id = departments.department_id;</span><br></pre></td></tr></table></figure><p><strong>拓展1：多个连接条件与 AND 操作符</strong></p><p><strong>拓展2：区分重复的列名</strong></p><ul><li><strong>多个表中有相同列时，必须在列名之前加上表名前缀。</strong></li><li>在不同表中具有相同列名的列可以用<code>表名</code>加以区分。</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SELECT employees.last_name, departments.department_name,employees.department_id</span><br><span class="line">FROM employees, departments</span><br><span class="line">WHERE employees.department_id = departments.department_id;</span><br></pre></td></tr></table></figure><p><strong>拓展3：表的别名</strong></p><ul><li><p>使用别名可以简化查询。</p></li><li><p>列名前使用表名前缀可以提高查询效率。</p></li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT e.employee_id, e.last_name, e.department_id,</span><br><span class="line">       d.department_id, d.location_id</span><br><span class="line">FROM   employees e , departments d</span><br><span class="line">WHERE  e.department_id = d.department_id;</span><br></pre></td></tr></table></figure><blockquote><p>需要注意的是，如果我们使用了表的别名，在查询字段中、过滤条件中就只能使用别名进行代替，不能使用原有的表名，否则就会报错。</p></blockquote><blockquote><p><code>阿里开发规范</code>：</p><p>【<code>强制</code>】对于数据库中表记录的查询和变更，只要涉及多个表，都需要在列名前加表的别名（或 表名）进行限定。</p><p><code>说明</code>：对多表进行查询记录、更新记录、删除记录时，如果对操作列没有限定表的别名（或表名），并且操作列在多个表中存在时，就会抛异常。</p><p><code>正例</code>：select t1.name from table_first as t1 , table_second as t2 where t1.id&#x3D;t2.id;</p><p><code>反例</code>：在某业务中，由于多表关联查询语句没有加表的别名（或表名）的限制，正常运行两年后，最近在 某个表中增加一个同名字段，在预发布环境做数据库变更后，线上查询语句出现出 1052 异常：Column ‘name’ in field list is ambiguous。</p></blockquote><p><strong>拓展4：连接多个表</strong></p><p>**总结：连接 n个表,至少需要n-1个连接条件。**比如，连接三个表，至少需要两个连接条件。</p><p>练习：查询出公司员工的 last_name,department_name, city</p><h4 id="非等值连接"><a href="#非等值连接" class="headerlink" title="非等值连接"></a>非等值连接</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SELECT e.last_name, e.salary, j.grade_level</span><br><span class="line">FROM   employees e, job_grades j</span><br><span class="line">WHERE  e.salary BETWEEN j.lowest_sal AND j.highest_sal;</span><br></pre></td></tr></table></figure><h3 id="分类2：自连接-vs-非自连接"><a href="#分类2：自连接-vs-非自连接" class="headerlink" title="分类2：自连接 vs 非自连接"></a>分类2：自连接 vs 非自连接</h3><ul><li>当table1和table2本质上是同一张表，只是用取别名的方式虚拟成两张表以代表不同的意义。然后两个表再进行内连接，外连接等查询。</li></ul><p><strong>题目：查询employees表，返回“Xxx works for Xxx”</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT CONCAT(worker.last_name ,&#x27; works for &#x27; </span><br><span class="line">       , manager.last_name)</span><br><span class="line">FROM   employees worker, employees manager</span><br><span class="line">WHERE  worker.manager_id = manager.employee_id ;</span><br></pre></td></tr></table></figure><p>练习：查询出last_name为 ‘Chen’ 的员工的 manager 的信息。</p><h3 id="分类3：内连接-vs-外连接"><a href="#分类3：内连接-vs-外连接" class="headerlink" title="分类3：内连接 vs 外连接"></a>分类3：内连接 vs 外连接</h3><p>除了查询满足条件的记录以外，外连接还可以查询某一方不满足条件的记录。</p><ul><li><p>内连接: 合并具有同一列的两个以上的表的行, <strong>结果集中不包含一个表与另一个表不匹配的行</strong></p></li><li><p>外连接: 两个表在连接过程中除了返回满足连接条件的行以外<strong>还返回左（或右）表中不满足条件的行</strong> <strong>，这种连接称为左（或右） 外连接</strong>。没有匹配的行时, 结果表中相应的列为空(NULL)。</p></li><li><p>如果是左外连接，则连接条件中左边的表也称为<code>主表</code>，右边的表称为<code>从表</code>。</p><p>如果是右外连接，则连接条件中右边的表也称为<code>主表</code>，左边的表称为<code>从表</code>。</p></li></ul><h4 id="SQL92：使用-创建连接"><a href="#SQL92：使用-创建连接" class="headerlink" title="SQL92：使用(+)创建连接"></a>SQL92：使用(+)创建连接</h4><ul><li><p>在 SQL92 中采用（+）代表从表所在的位置。即左或右外连接中，(+) 表示哪个是从表。</p></li><li><p>Oracle 对 SQL92 支持较好，而 MySQL 则不支持 SQL92 的外连接。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">#左外连接</span><br><span class="line">SELECT last_name,department_name</span><br><span class="line">FROM employees ,departments</span><br><span class="line">WHERE employees.department_id = departments.department_id(+);</span><br><span class="line"></span><br><span class="line">#右外连接</span><br><span class="line">SELECT last_name,department_name</span><br><span class="line">FROM employees ,departments</span><br><span class="line">WHERE employees.department_id(+) = departments.department_id;</span><br></pre></td></tr></table></figure></li><li><p>而且在 SQL92 中，只有左外连接和右外连接，没有满（或全）外连接。</p></li></ul><h2 id="3-SQL99语法实现多表查询"><a href="#3-SQL99语法实现多表查询" class="headerlink" title="3. SQL99语法实现多表查询"></a>3. SQL99语法实现多表查询</h2><h3 id="3-1-基本语法"><a href="#3-1-基本语法" class="headerlink" title="3.1 基本语法"></a>3.1 基本语法</h3><ul><li><p>使用JOIN…ON子句创建连接的语法结构：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT table1.column, table2.column,table3.column</span><br><span class="line">FROM table1</span><br><span class="line">    JOIN table2 ON table1 和 table2 的连接条件</span><br><span class="line">        JOIN table3 ON table2 和 table3 的连接条件</span><br></pre></td></tr></table></figure><p>它的嵌套逻辑类似我们使用的 FOR 循环：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">for t1 in table1:</span><br><span class="line">    for t2 in table2:</span><br><span class="line">       if condition1:</span><br><span class="line">           for t3 in table3:</span><br><span class="line">              if condition2:</span><br><span class="line">                  output t1 + t2 + t3</span><br></pre></td></tr></table></figure><p>SQL99 采用的这种嵌套结构非常清爽、层次性更强、可读性更强，即使再多的表进行连接也都清晰可见。如果你采用 SQL92，可读性就会大打折扣。</p></li><li><p>语法说明：</p><ul><li><strong>可以使用</strong> <strong>ON</strong> <strong>子句指定额外的连接条件</strong>。</li><li>这个连接条件是与其它条件分开的。</li><li><strong>ON</strong> <strong>子句使语句具有更高的易读性</strong>。</li><li>关键字 JOIN、INNER JOIN、CROSS JOIN 的含义是一样的，都表示内连接</li></ul></li></ul><h3 id="3-2-内连接-INNER-JOIN-的实现"><a href="#3-2-内连接-INNER-JOIN-的实现" class="headerlink" title="3.2 内连接(INNER JOIN)的实现"></a>3.2 内连接(INNER JOIN)的实现</h3><ul><li>语法：</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT 字段列表</span><br><span class="line">FROM A表 INNER JOIN B表</span><br><span class="line">ON 关联条件</span><br><span class="line">WHERE 等其他子句;</span><br></pre></td></tr></table></figure><p>题目1：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT e.employee_id, e.last_name, e.department_id, </span><br><span class="line">       d.department_id, d.location_id</span><br><span class="line">FROM   employees e JOIN departments d</span><br><span class="line">ON     (e.department_id = d.department_id);</span><br></pre></td></tr></table></figure><p>题目2：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">SELECT employee_id, city, department_name</span><br><span class="line">FROM   employees e </span><br><span class="line">JOIN   departments d</span><br><span class="line">ON     d.department_id = e.department_id </span><br><span class="line">JOIN   locations l</span><br><span class="line">ON     d.location_id = l.location_id;</span><br></pre></td></tr></table></figure><h3 id="3-3-外连接-OUTER-JOIN-的实现"><a href="#3-3-外连接-OUTER-JOIN-的实现" class="headerlink" title="3.3 外连接(OUTER JOIN)的实现"></a>3.3 外连接(OUTER JOIN)的实现</h3><h4 id="3-3-1-左外连接-LEFT-OUTER-JOIN"><a href="#3-3-1-左外连接-LEFT-OUTER-JOIN" class="headerlink" title="3.3.1 左外连接(LEFT OUTER JOIN)"></a>3.3.1 左外连接(LEFT OUTER JOIN)</h4><ul><li>语法：</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">#实现查询结果是A</span><br><span class="line">SELECT 字段列表</span><br><span class="line">FROM A表 LEFT JOIN B表</span><br><span class="line">ON 关联条件</span><br><span class="line">WHERE 等其他子句;</span><br></pre></td></tr></table></figure><ul><li>举例：</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT e.last_name, e.department_id, d.department_name</span><br><span class="line">FROM   employees e</span><br><span class="line">LEFT OUTER JOIN departments d</span><br><span class="line">ON   (e.department_id = d.department_id) ;</span><br></pre></td></tr></table></figure><h4 id="3-3-2-右外连接-RIGHT-OUTER-JOIN"><a href="#3-3-2-右外连接-RIGHT-OUTER-JOIN" class="headerlink" title="3.3.2 右外连接(RIGHT OUTER JOIN)"></a>3.3.2 右外连接(RIGHT OUTER JOIN)</h4><ul><li>语法：</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">#实现查询结果是B</span><br><span class="line">SELECT 字段列表</span><br><span class="line">FROM A表 RIGHT JOIN B表</span><br><span class="line">ON 关联条件</span><br><span class="line">WHERE 等其他子句;</span><br></pre></td></tr></table></figure><ul><li>举例：</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT e.last_name, e.department_id, d.department_name</span><br><span class="line">FROM   employees e</span><br><span class="line">RIGHT OUTER JOIN departments d</span><br><span class="line">ON    (e.department_id = d.department_id) ;</span><br></pre></td></tr></table></figure><blockquote><p>需要注意的是，LEFT JOIN 和 RIGHT JOIN 只存在于 SQL99 及以后的标准中，在 SQL92 中不存在，只能用 (+) 表示。</p></blockquote><h4 id="3-3-3-满外连接-FULL-OUTER-JOIN"><a href="#3-3-3-满外连接-FULL-OUTER-JOIN" class="headerlink" title="3.3.3 满外连接(FULL OUTER JOIN)"></a>3.3.3 满外连接(FULL OUTER JOIN)</h4><ul><li>满外连接的结果 &#x3D; 左右表匹配的数据 + 左表没有匹配到的数据 + 右表没有匹配到的数据。</li><li>SQL99是支持满外连接的。使用FULL JOIN 或 FULL OUTER JOIN来实现。</li><li>需要注意的是，MySQL不支持FULL JOIN，但是可以用 LEFT JOIN <strong>UNION</strong> RIGHT join代替。</li></ul><h2 id="4-UNION的使用"><a href="#4-UNION的使用" class="headerlink" title="4. UNION的使用"></a>4. UNION的使用</h2><p><strong>合并查询结果</strong> 利用UNION关键字，可以给出多条SELECT语句，并将它们的结果组合成单个结果集。合并时，两个表对应的列数和数据类型必须相同，并且相互对应。各个SELECT语句之间使用UNION或UNION ALL关键字分隔。</p><p>语法格式：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SELECT column,... FROM table1</span><br><span class="line">UNION [ALL]</span><br><span class="line">SELECT column,... FROM table2</span><br></pre></td></tr></table></figure><p><strong>UNION操作符</strong></p><p>UNION 操作符返回两个查询的结果集的并集，去除重复记录。</p><p><strong>UNION ALL操作符</strong></p><p>UNION ALL操作符返回两个查询的结果集的并集。对于两个结果集的重复部分，不去重。</p><blockquote><p>注意：执行UNION ALL语句时所需要的资源比UNION语句少。如果明确知道合并数据后的结果数据不存在重复数据，或者不需要去除重复的数据，则尽量使用UNION ALL语句，以提高数据查询的效率。</p></blockquote><p>举例：查询部门编号&gt;90或邮箱包含a的员工信息</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">#方式1</span><br><span class="line">SELECT * FROM employees WHERE email LIKE &#x27;%a%&#x27; OR department_id&gt;90;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#方式2</span><br><span class="line">SELECT * FROM employees  WHERE email LIKE &#x27;%a%&#x27;</span><br><span class="line">UNION</span><br><span class="line">SELECT * FROM employees  WHERE department_id&gt;90;</span><br></pre></td></tr></table></figure><p>举例：查询中国用户中男性的信息以及美国用户中年男性的用户信息</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SELECT id,cname FROM t_chinamale WHERE csex=&#x27;男&#x27;</span><br><span class="line">UNION ALL</span><br><span class="line">SELECT id,tname FROM t_usmale WHERE tGender=&#x27;male&#x27;;</span><br></pre></td></tr></table></figure><h2 id="5-7种SQL-JOINS的实现"><a href="#5-7种SQL-JOINS的实现" class="headerlink" title="5. 7种SQL JOINS的实现"></a>5. 7种SQL JOINS的实现</h2><h3 id="5-7-1-代码实现"><a href="#5-7-1-代码实现" class="headerlink" title="5.7.1 代码实现"></a>5.7.1 代码实现</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#中图：内连接 A∩B</span><br><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#左上图：左外连接</span><br><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e LEFT JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#右上图：右外连接</span><br><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e RIGHT JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">#左中图：A - A∩B</span><br><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e LEFT JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`</span><br><span class="line">WHERE d.`department_id` IS NULL</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">#右中图：B-A∩B</span><br><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e RIGHT JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`</span><br><span class="line">WHERE e.`department_id` IS NULL</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">#左下图：满外连接</span><br><span class="line"># 左中图 + 右上图  A∪B</span><br><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e LEFT JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`</span><br><span class="line">WHERE d.`department_id` IS NULL</span><br><span class="line">UNION ALL  #没有去重操作，效率高</span><br><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e RIGHT JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">#右下图</span><br><span class="line">#左中图 + 右中图  A ∪B- A∩B 或者 (A -  A∩B) ∪ （B - A∩B）</span><br><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e LEFT JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`</span><br><span class="line">WHERE d.`department_id` IS NULL</span><br><span class="line">UNION ALL</span><br><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e RIGHT JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`</span><br><span class="line">WHERE e.`department_id` IS NULL</span><br></pre></td></tr></table></figure><h3 id="5-7-2-语法格式小结"><a href="#5-7-2-语法格式小结" class="headerlink" title="5.7.2 语法格式小结"></a>5.7.2 语法格式小结</h3><ul><li>左中图</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">#实现A -  A∩B</span><br><span class="line">select 字段列表</span><br><span class="line">from A表 left join B表</span><br><span class="line">on 关联条件</span><br><span class="line">where 从表关联字段 is null and 等其他子句;</span><br></pre></td></tr></table></figure><ul><li>右中图</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">#实现B -  A∩B</span><br><span class="line">select 字段列表</span><br><span class="line">from A表 right join B表</span><br><span class="line">on 关联条件</span><br><span class="line">where 从表关联字段 is null and 等其他子句;</span><br></pre></td></tr></table></figure><ul><li>左下图</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">#实现查询结果是A∪B</span><br><span class="line">#用左外的A，union 右外的B</span><br><span class="line">select 字段列表</span><br><span class="line">from A表 left join B表</span><br><span class="line">on 关联条件</span><br><span class="line">where 等其他子句</span><br><span class="line"></span><br><span class="line">union </span><br><span class="line"></span><br><span class="line">select 字段列表</span><br><span class="line">from A表 right join B表</span><br><span class="line">on 关联条件</span><br><span class="line">where 等其他子句;</span><br></pre></td></tr></table></figure><ul><li>右下图</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">#实现A∪B -  A∩B  或   (A -  A∩B) ∪ （B - A∩B）</span><br><span class="line">#使用左外的 (A -  A∩B)  union 右外的（B - A∩B）</span><br><span class="line">select 字段列表</span><br><span class="line">from A表 left join B表</span><br><span class="line">on 关联条件</span><br><span class="line">where 从表关联字段 is null and 等其他子句</span><br><span class="line"></span><br><span class="line">union</span><br><span class="line"></span><br><span class="line">select 字段列表</span><br><span class="line">from A表 right join B表</span><br><span class="line">on 关联条件</span><br><span class="line">where 从表关联字段 is null and 等其他子句</span><br></pre></td></tr></table></figure><h2 id="6-SQL99语法新特性"><a href="#6-SQL99语法新特性" class="headerlink" title="6. SQL99语法新特性"></a>6. SQL99语法新特性</h2><h3 id="6-1-自然连接"><a href="#6-1-自然连接" class="headerlink" title="6.1 自然连接"></a>6.1 自然连接</h3><p>SQL99 在 SQL92 的基础上提供了一些特殊语法，比如 <code>NATURAL JOIN</code> 用来表示自然连接。我们可以把自然连接理解为 SQL92 中的等值连接。它会帮你自动查询两张连接表中<code>所有相同的字段</code>，然后进行<code>等值连接</code>。</p><p>在SQL92标准中：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e JOIN departments d</span><br><span class="line">ON e.`department_id` = d.`department_id`</span><br><span class="line">AND e.`manager_id` = d.`manager_id`;</span><br></pre></td></tr></table></figure><p>在 SQL99 中你可以写成：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e NATURAL JOIN departments d;</span><br></pre></td></tr></table></figure><h3 id="6-2-USING连接"><a href="#6-2-USING连接" class="headerlink" title="6.2 USING连接"></a>6.2 USING连接</h3><p>当我们进行连接的时候，SQL99还支持使用 USING 指定数据表里的<code>同名字段</code>进行等值连接。但是只能配合JOIN一起使用。比如：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e JOIN departments d</span><br><span class="line">USING (department_id);</span><br></pre></td></tr></table></figure><p>你能看出与自然连接 NATURAL JOIN 不同的是，USING 指定了具体的相同的字段名称，你需要在 USING 的括号 () 中填入要指定的同名字段。同时使用 <code>JOIN...USING</code> 可以简化 JOIN ON 的等值连接。它与下面的 SQL 查询结果是相同的：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SELECT employee_id,last_name,department_name</span><br><span class="line">FROM employees e ,departments d</span><br><span class="line">WHERE e.department_id = d.department_id;</span><br></pre></td></tr></table></figure><h2 id="7-章节小结"><a href="#7-章节小结" class="headerlink" title="7. 章节小结"></a>7. 章节小结</h2><p>表连接的约束条件可以有三种方式：WHERE, ON, USING</p><ul><li><p>WHERE：适用于所有关联查询</p></li><li><p><code>ON</code>：只能和JOIN一起使用，只能写关联条件。虽然关联条件可以并到WHERE中和其他条件一起写，但分开写可读性更好。</p></li><li><p>USING：只能和JOIN一起使用，而且要求<strong>两个</strong>关联字段在关联表中名称一致，而且只能表示关联字段值相等</p></li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">#关联条件</span><br><span class="line">#把关联条件写在where后面</span><br><span class="line">SELECT last_name,department_name </span><br><span class="line">FROM employees,departments </span><br><span class="line">WHERE employees.department_id = departments.department_id;</span><br><span class="line"></span><br><span class="line">#把关联条件写在on后面，只能和JOIN一起使用</span><br><span class="line">SELECT last_name,department_name </span><br><span class="line">FROM employees INNER JOIN departments </span><br><span class="line">ON employees.department_id = departments.department_id;</span><br><span class="line"></span><br><span class="line">SELECT last_name,department_name </span><br><span class="line">FROM employees CROSS JOIN departments </span><br><span class="line">ON employees.department_id = departments.department_id;</span><br><span class="line"></span><br><span class="line">SELECT last_name,department_name  </span><br><span class="line">FROM employees JOIN departments </span><br><span class="line">ON employees.department_id = departments.department_id;</span><br><span class="line"></span><br><span class="line">#把关联字段写在using()中，只能和JOIN一起使用</span><br><span class="line">#而且两个表中的关联字段必须名称相同，而且只能表示=</span><br><span class="line">#查询员工姓名与基本工资</span><br><span class="line">SELECT last_name,job_title</span><br><span class="line">FROM employees INNER JOIN jobs USING(job_id);</span><br><span class="line"></span><br><span class="line">#n张表关联，需要n-1个关联条件</span><br><span class="line">#查询员工姓名，基本工资，部门名称</span><br><span class="line">SELECT last_name,job_title,department_name FROM employees,departments,jobs </span><br><span class="line">WHERE employees.department_id = departments.department_id </span><br><span class="line">AND employees.job_id = jobs.job_id;</span><br><span class="line"></span><br><span class="line">SELECT last_name,job_title,department_name </span><br><span class="line">FROM employees INNER JOIN departments INNER JOIN jobs </span><br><span class="line">ON employees.department_id = departments.department_id </span><br><span class="line">AND employees.job_id = jobs.job_id;</span><br></pre></td></tr></table></figure><p><strong>注意：</strong></p><p>我们要<code>控制连接表的数量</code>。多表连接就相当于嵌套 for 循环一样，非常消耗资源，会让 SQL 查询性能下降得很严重，因此不要连接不必要的表。在许多 DBMS 中，也都会有最大连接表的限制。</p><blockquote><p>【强制】超过三个表禁止 join。需要 join 的字段，数据类型保持绝对一致；多表关联查询时， 保证被关联的字段需要有索引。</p><p>说明：即使双表 join 也要注意表索引、SQL 性能。</p><p>来源：阿里巴巴《Java开发手册》</p></blockquote><h2 id="附录：常用的-SQL-标准有哪些"><a href="#附录：常用的-SQL-标准有哪些" class="headerlink" title="附录：常用的 SQL 标准有哪些"></a>附录：常用的 SQL 标准有哪些</h2><p>在正式开始讲连接表的种类时，我们首先需要知道 SQL 存在不同版本的标准规范，因为不同规范下的表连接操作是有区别的。</p><p>SQL 有两个主要的标准，分别是 <code>SQL92</code> 和 <code>SQL99</code>。92 和 99 代表了标准提出的时间，SQL92 就是 92 年提出的标准规范。当然除了 SQL92 和 SQL99 以外，还存在 SQL-86、SQL-89、SQL:2003、SQL:2008、SQL:2011 和 SQL:2016 等其他的标准。</p><p>这么多标准，到底该学习哪个呢？<strong>实际上最重要的 SQL 标准就是 SQL92 和 SQL99</strong>。一般来说 SQL92 的形式更简单，但是写的 SQL 语句会比较长，可读性较差。而 SQL99 相比于 SQL92 来说，语法更加复杂，但可读性更强。我们从这两个标准发布的页数也能看出，SQL92 的标准有 500 页，而 SQL99 标准超过了 1000 页。实际上从 SQL99 之后，很少有人能掌握所有内容，因为确实太多了。就好比我们使用 Windows、Linux 和 Office 的时候，很少有人能掌握全部内容一样。我们只需要掌握一些核心的功能，满足日常工作的需求即可。</p><p>**SQL92 和 SQL99 是经典的 SQL 标准，也分别叫做 SQL-2 和 SQL-3 标准。**也正是在这两个标准发布之后，SQL 影响力越来越大，甚至超越了数据库领域。现如今 SQL 已经不仅仅是数据库领域的主流语言，还是信息领域中信息处理的主流语言。在图形检索、图像检索以及语音检索中都能看到 SQL 语言的使用。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;多表查询，也称为关联查询，指两个或更多个表一起完成查询操作。&lt;/p&gt;
&lt;p&gt;前提条件：这些一起查询的表之间是有关系的（一对一、一对多），它们之间一定是有关联字段，这个关联字段可能建立了外键，也可能没有建立外键。比如：员工表和部门表，这两个表依靠“部门编号”进行关联。&lt;/p&gt;</summary>
      
    
    
    
    <category term="Sql" scheme="https://www.yxliu.cc/categories/Sql/"/>
    
    
    <category term="Oracle" scheme="https://www.yxliu.cc/tags/Oracle/"/>
    
    <category term="Mysql" scheme="https://www.yxliu.cc/tags/Mysql/"/>
    
  </entry>
  
</feed>
