<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>holicCode&#39;s blog</title>
  
  <subtitle>Engineer in training</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://yoursite.com/"/>
  <updated>2019-08-26T03:58:02.090Z</updated>
  <id>http://yoursite.com/</id>
  
  <author>
    <name>holicCode</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>浅谈Netty</title>
    <link href="http://yoursite.com/2019/08/25/%E6%B5%85%E8%B0%88Netty/"/>
    <id>http://yoursite.com/2019/08/25/浅谈Netty/</id>
    <published>2019-08-25T06:17:54.186Z</published>
    <updated>2019-08-26T03:58:02.090Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、Netty简介"><a href="#一、Netty简介" class="headerlink" title="一、Netty简介"></a>一、Netty简介</h1><h2 id="1-1-概念"><a href="#1-1-概念" class="headerlink" title="1.1 概念"></a>1.1 概念</h2><p>​    Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、时间驱动网络应用程序框架和工具，用以快速开发高性能、高可靠的网络服务和客户端程序。</p><p>​    也就是说，Netty是一个基于NIO的客户、服务器端编程框架，使用Netty可以确保你快速和简单的开发出一个网络应用，例如实现了某种协议的客户，服务端应用。Netty相当简化和流线化了网络应用的编程开发过程，例如，TCP和UDP的socket服务开发。</p><h2 id="1-2-线程模型"><a href="#1-2-线程模型" class="headerlink" title="1.2 线程模型"></a>1.2 线程模型</h2><h3 id="1-2-1-单线程模型"><a href="#1-2-1-单线程模型" class="headerlink" title="1.2.1 单线程模型"></a>1.2.1 单线程模型</h3><p>​    在ServerBootstrap调用方法group的时候，传递的参数是同一个线程组，且在构造线程组的时候，构造参数为1，这种开发方式，就是一个单线程模型。</p><p>​    使用场景：个人机开发测试使用。不推荐。</p><h3 id="1-2-2-多线程模型"><a href="#1-2-2-多线程模型" class="headerlink" title="1.2.2 多线程模型"></a>1.2.2 多线程模型</h3><p>​    在ServerBootstrap调用方法group的时候，传递的参数是两个不同的线程组。负责监听的acceptor线程组，线程数为1，也就是构造参数为1。负责处理客户任务的线程组，线程数大于1，也就是构造参数大于1。这种开发方式，就是多线程模型。</p><p>​    使用场景：长连接，且客户端数量较少，连接持续时间较长情况下使用。如：企业内部交流应用。</p><h3 id="1-2-3-主从多线程模型"><a href="#1-2-3-主从多线程模型" class="headerlink" title="1.2.3 主从多线程模型"></a>1.2.3 主从多线程模型</h3><p>​    在ServerBootstrap调用方法group的时候，传递的参数是两个不同的线程组。负责监听的acceptor线程组，线程数大于1，也就是构造参数大于1。负责处理客户端任务的线程组，线程数大于 1，也就是构造参数大于 1。这种开发方式，就是主从多线程模型。</p><p>​    使用场景：长连接，客户端数量相对较多，连接持续时间比较长的情况下使用。如：对外提供服务的相册服务器。</p><h1 id="二、Netty拆包粘包问题"><a href="#二、Netty拆包粘包问题" class="headerlink" title="二、Netty拆包粘包问题"></a>二、Netty拆包粘包问题</h1><h2 id="2-1-粘包问题的原因"><a href="#2-1-粘包问题的原因" class="headerlink" title="2.1 粘包问题的原因"></a>2.1 粘包问题的原因</h2><p>​    Netty使用TCP/IP协议传输数据。而TCP/IP协议类似水流一样的数据传输方式，并且Netty是基于NIO（非阻塞式IO）。多次访问的时候就有可能出现多条数据粘连，造成数据的错误和不完整，这就是Netty的粘包问题。</p><h2 id="2-2-粘包问题的解决"><a href="#2-2-粘包问题的解决" class="headerlink" title="2.2 粘包问题的解决"></a>2.2 粘包问题的解决</h2><h3 id="2-2-1-定长数据流"><a href="#2-2-1-定长数据流" class="headerlink" title="2.2.1 定长数据流"></a>2.2.1 定长数据流</h3><p>​    客户端和服务器，提前协调好，每个消息长度固定。（如：长度 10）。如果客户端或服<br>务器写出的数据不足 10，则使用空白字符补足（如：使用空格）。</p><h3 id="2-2-2-特殊结束符"><a href="#2-2-2-特殊结束符" class="headerlink" title="2.2.2 特殊结束符"></a>2.2.2 特殊结束符</h3><p>​    客户端和服务器，协商定义一个特殊的分隔符号，分隔符号长度自定义。如：‘#’、‘$_$’、‘AA@’。在通讯的时候，只要没有发送分隔符号，则代表一条数据没有结束。</p><h3 id="2-2-3-协议"><a href="#2-2-3-协议" class="headerlink" title="2.2.3 协议"></a>2.2.3 协议</h3><p>​    相对最成熟的数据传递方式。有服务器的开发者提供一个固定格式的协议标准。客户端和服务器发送数据和接受数据的时候，都依据协议制定和解析消息。</p><h1 id="三、定时断线重连"><a href="#三、定时断线重连" class="headerlink" title="三、定时断线重连"></a>三、定时断线重连</h1><p>​    客户端断线重连机制。<br>​    客户端数量多，且需要传递的数据量级较大。可以周期性的发送数据的时候使用。要求对数据的即时性不高的时候，才可使用。<br>​    优点： 可以使用数据缓存。不是每条数据进行一次数据交互。可以定时回收资源，对资源利用率高。相对来说，即时性可以通过其他方式保证。如： 120 秒自动断线。数据变化 1000 次请求服务器一次。300 秒中自动发送不足 1000 次的变化数据。</p><h1 id="四、心跳监测"><a href="#四、心跳监测" class="headerlink" title="四、心跳监测"></a>四、心跳监测</h1><h2 id="4-1心跳监测"><a href="#4-1心跳监测" class="headerlink" title="4.1心跳监测"></a>4.1心跳监测</h2><p>​    使用定时发送消息的方式，实现硬件检测，达到心态检测的目的。<br>​    心跳监测是用于检测电脑硬件和软件信息的一种技术。如：CPU 使用率，磁盘使用率，内存使用率，进程情况，线程情况等。</p><h2 id="4-2-sigar"><a href="#4-2-sigar" class="headerlink" title="4.2 sigar"></a>4.2 sigar</h2><p>​    需要下载一个 zip 压缩包。内部包含若干 sigar 需要的操作系统文件。sigar 插件是通过JVM 访问操作系统，读取计算机硬件的一个插件库。读取计算机硬件过程中，必须由操作系统提供硬件信息。硬件信息是通过操作系统提供的。zip 压缩包中是 sigar 编写的操作系统文件，如：windows 中的动态链接库文件。<br>​    解压需要的操作系统文件，将操作系统文件赋值到${Java_home}/bin 目录中。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;一、Netty简介&quot;&gt;&lt;a href=&quot;#一、Netty简介&quot; class=&quot;headerlink&quot; title=&quot;一、Netty简介&quot;&gt;&lt;/a&gt;一、Netty简介&lt;/h1&gt;&lt;h2 id=&quot;1-1-概念&quot;&gt;&lt;a href=&quot;#1-1-概念&quot; class=&quot;head
      
    
    </summary>
    
      <category term="Netty" scheme="http://yoursite.com/categories/Netty/"/>
    
    
      <category term="Netty" scheme="http://yoursite.com/tags/Netty/"/>
    
  </entry>
  
  <entry>
    <title>MySQL读写分离</title>
    <link href="http://yoursite.com/2019/08/23/MySQL%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/"/>
    <id>http://yoursite.com/2019/08/23/MySQL读写分离/</id>
    <published>2019-08-23T15:10:11.113Z</published>
    <updated>2019-08-23T15:12:32.123Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、MySQL的读写分离"><a href="#一、MySQL的读写分离" class="headerlink" title="一、MySQL的读写分离"></a>一、MySQL的读写分离</h1><h2 id="1-1-为什么要使用MySQL的读写分离？"><a href="#1-1-为什么要使用MySQL的读写分离？" class="headerlink" title="1.1 为什么要使用MySQL的读写分离？"></a>1.1 为什么要使用MySQL的读写分离？</h2><p>​    在高并发的场景下，当用户发起大量请求时，缓存肯定放不下所有数据，那么这些请求就会落到数据库上，当数据库的读写请求太高（2000次/s）时，数据库就会报警，磁盘IO开始变慢，CPU负载过高，内存使用率过高。当数据库读写请求达到4000/s，5000/s，8000/s时，数据库就会直接宕机，所以为了解决这种问题就诞生了MySQL的读写分离。</p><h2 id="1-2-MySQL的读写分离怎么实现"><a href="#1-2-MySQL的读写分离怎么实现" class="headerlink" title="1.2 MySQL的读写分离怎么实现"></a>1.2 MySQL的读写分离怎么实现</h2><p>​    通过MySQL的主从复制</p><p>​    就是基于主从复制架构，简单的来说，就是搞一个主库，挂多个从库，然后我们就单单只是写主库，然后主库会自动把数据给同步到从库上去。</p><h1 id="二、主从复制"><a href="#二、主从复制" class="headerlink" title="二、主从复制"></a>二、主从复制</h1><h2 id="2-1-MySQL主从复制原理是啥？"><a href="#2-1-MySQL主从复制原理是啥？" class="headerlink" title="2.1 MySQL主从复制原理是啥？"></a>2.1 MySQL主从复制原理是啥？</h2><p><img src="G:%5C%E9%BB%91%E9%A9%AC%E5%BF%85%E7%9C%8B%E8%A7%86%E9%A2%91%5CJava%E5%B7%A5%E7%A8%8B%E5%B8%88%E9%9D%A2%E8%AF%95%E7%AA%81%E5%87%BB%E7%AC%AC1%E5%AD%A3%EF%BC%88%E5%8F%AF%E8%83%BD%E6%98%AF%E5%8F%B2%E4%B8%8A%E6%9C%80%E5%A5%BD%E7%9A%84Java%E9%9D%A2%E8%AF%95%E7%AA%81%E5%87%BB%E8%AF%BE%E7%A8%8B%EF%BC%89-%E4%B8%AD%E5%8D%8E%E7%9F%B3%E6%9D%89%E8%80%81%E5%B8%88%5C51_%E8%AF%B4%E8%AF%B4MySQL%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB%E7%9A%84%E5%8E%9F%E7%90%86%EF%BC%9F%E4%B8%BB%E4%BB%8E%E5%90%8C%E6%AD%A5%E5%BB%B6%E6%97%B6%E5%92%8B%E8%A7%A3%E5%86%B3%EF%BC%9F%5C02_MySQL%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%E5%8E%9F%E7%90%86.png" alt="02_MySQL主从复制原理"></p><p>​                                                                图片来自“石杉码农学院”</p><p>原理：用户发来一个写请求后，主库将变更数据，然后写binlog日志，然后从库连接到主库之后，从库有一个IO线程，将主库额binlog日志拷贝到自己本地，写入relay日志，接着从库中有一个SQL线程会从relay日志读取变更，然后执行变更的内容，也就是说在自己本地再次执行一遍SQL，这样就可以保证自己跟主库的数据是一样的。</p><h2 id="2-2-主从复制带来的问题"><a href="#2-2-主从复制带来的问题" class="headerlink" title="2.2 主从复制带来的问题"></a>2.2 主从复制带来的问题</h2><p>​    首先要明确一点，就是从库同步主库数据的过程是串行化的，就就是说主库上并行操作，在从库上会串行执行。</p><p>​    所以这样就会引出一个问题：由于从库从主库拷贝日志以及串行串行执行SQL的特点，在搞并打场景下，从库的数据一定会比主库慢一些，是有延时的。所以经常会出现，刚写入主库的数据可能读不到，要过个几十毫秒，甚至几百毫秒才能读取到。即<strong>主从延迟</strong>。</p><p>​    </p><p>在实际生产中就有这种场景：</p><ul><li>​    数据已全部同步到从库后，主库突然发生了宕机<ul><li>​    解决：将从库变更为主库</li></ul></li><li>​    数据还没有全部同步到从库中时，主库突然发生了宕机<ul><li>​    解决：<ul><li>​    提前开启MySQL所支持的<strong>半同步机制</strong>。所谓半同步机制就是指：当用户发送一个写请求后，如果主库还没有同步到从库时，那么系统会认为这个写操作是失败的，然后给客户反馈一个失败的信息，然后客户重新发送，在这期间系统就将从库变更为了主库。</li><li>​    <strong>并行复制</strong>：MySQL5.7支持的新特性，从库开启多个线程，并行读取relay日志中不同库的日志，然后并行重放不同库的日志，这是库级别的并行。</li></ul></li></ul></li></ul><h2 id="2-3-当主从延迟比较严重时如何解决？"><a href="#2-3-当主从延迟比较严重时如何解决？" class="headerlink" title="2.3 当主从延迟比较严重时如何解决？"></a>2.3 当主从延迟比较严重时如何解决？</h2><p>​    先看一个场景：当你写业务代码时，先在数据库中插入一条数据，这时在立马将该数据查询出来，然后对其进行修改。</p><p>​    分析上述场景：在数据库中插入数据是在主库中修改，然后由于主从延迟问题该数据还没有同步到从库，然后你又立马查询就会查不到结果，然后你的修改起始就也是无效的。</p><p>​    解决：</p><ol><li>分库，将一个主库拆分成为4个主库，每个主库的写并发就降低了，此时的主从延迟就可以忽略不计</li><li>打开MySQL支持的并行复制，多个库并行复制，如果说某个库的写入并发就是特别高，单库写并发达到了2000次/s，并行复制的意义其实不是很大</li><li>重写代码，插入数据之后直接修改，那么这两个操作就都是在主库中进行的了</li><li>如果业务上是存在这种必须先插入，立马查询，在修改的业务逻辑，那么就可以对这个操作设置<strong>直连主库</strong>。不推荐使用，因为这样导致读写分离的意义丧失了</li></ol><h1 id="三、在什么场景下使用MySQL的主从同步"><a href="#三、在什么场景下使用MySQL的主从同步" class="headerlink" title="三、在什么场景下使用MySQL的主从同步"></a>三、在什么场景下使用MySQL的主从同步</h1><p>​    建议是一般在读远远多去写，而且读的时候一般对数据时效性要求没那么高的时候，使用</p><blockquote><p>本文参考自：石杉码农学院的中华石杉老师的 “java工程师面试突击第一季”</p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;一、MySQL的读写分离&quot;&gt;&lt;a href=&quot;#一、MySQL的读写分离&quot; class=&quot;headerlink&quot; title=&quot;一、MySQL的读写分离&quot;&gt;&lt;/a&gt;一、MySQL的读写分离&lt;/h1&gt;&lt;h2 id=&quot;1-1-为什么要使用MySQL的读写分离？&quot;&gt;&lt;a
      
    
    </summary>
    
      <category term="MySQL" scheme="http://yoursite.com/categories/MySQL/"/>
    
    
      <category term="MySQL" scheme="http://yoursite.com/tags/MySQL/"/>
    
  </entry>
  
  <entry>
    <title>浅谈shell</title>
    <link href="http://yoursite.com/2019/08/16/%E6%B5%85%E8%B0%88shell/"/>
    <id>http://yoursite.com/2019/08/16/浅谈shell/</id>
    <published>2019-08-15T16:16:54.323Z</published>
    <updated>2019-08-16T15:10:13.822Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>本文参考自《菜鸟教程》</p></blockquote><h1 id="一、什么是shell？"><a href="#一、什么是shell？" class="headerlink" title="一、什么是shell？"></a>一、什么是shell？</h1><h2 id="1-1-shell概念"><a href="#1-1-shell概念" class="headerlink" title="1.1 shell概念"></a>1.1 shell概念</h2><p>Shell是一个用c语言编写的程序，它是用户使用Linux的桥梁；是一个脚本语言。</p><h2 id="1-2-第一个shell脚本"><a href="#1-2-第一个shell脚本" class="headerlink" title="1.2 第一个shell脚本"></a>1.2 第一个shell脚本</h2><p>打开文本编译器（可以使用vi/vim命令来创建文件），新建一个文件test.sh，扩展名为sh（sh代表shell），扩展名并不影响脚本执行，见名知意就好</p><figure class="highlight shell"><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="meta">#</span>!/bin/bash</span><br><span class="line">echo "Hello Shell"</span><br></pre></td></tr></table></figure><p>#! 是一个约定的标记, 他告诉系统这个脚本需要什么解释器来执行, 即使用哪一种Shell</p><p>echo 命令用于向chuangko输出文本</p><h2 id="1-3-如何运行shell脚本"><a href="#1-3-如何运行shell脚本" class="headerlink" title="1.3 如何运行shell脚本"></a>1.3 如何运行shell脚本</h2><h3 id="1-3-1-作为可执行程序"><a href="#1-3-1-作为可执行程序" class="headerlink" title="1.3.1 作为可执行程序"></a>1.3.1 作为可执行程序</h3><p>将上面的代码保存为 test.sh，并 cd 到相应目录：</p><figure class="highlight shell"><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">chmod +x ./test.sh  #使脚本具有执行权限</span><br><span class="line">./test.sh  #执行脚本</span><br></pre></td></tr></table></figure><p>注意，一定要写成 <strong>./test.sh</strong>，而不是 <strong>test.sh</strong>，运行其它二进制的程序也一样，直接写 test.sh，linux 系统会去 PATH 里寻找有没有叫 test.sh 的，而只有 /bin, /sbin, /usr/bin，/usr/sbin 等在 PATH 里，你的当前目录通常不在 PATH 里，所以写成 test.sh 是会找不到命令的，要用 ./test.sh 告诉系统说，就在当前目录找。</p><h3 id="1-3-2-作为解释器参数"><a href="#1-3-2-作为解释器参数" class="headerlink" title="1.3.2 作为解释器参数"></a>1.3.2 作为解释器参数</h3><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></pre></td><td class="code"><pre><span class="line">/bin/sh test.sh</span><br><span class="line">/bin/php test.php</span><br></pre></td></tr></table></figure><p>这种方式运行的脚本，不需要在第一行指定解释器信息，写了也没用。</p><h1 id="二、shell变量"><a href="#二、shell变量" class="headerlink" title="二、shell变量"></a>二、shell变量</h1><h2 id="2-1-shell变量的规则"><a href="#2-1-shell变量的规则" class="headerlink" title="2.1 shell变量的规则"></a>2.1 shell变量的规则</h2><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">your_name="holicCode.com"</span><br></pre></td></tr></table></figure><p>注意，变量名和等号之间不能有空格。</p><p>同时，变量名的命名须遵循如下规则：</p><ul><li>命名只能使用英文字母，数字和下划线，首个字符不能以数字开头。</li><li>中间不能有空格，可以使用下划线（_）。</li><li>不能使用标点符号。</li><li>不能使用bash里的关键字（可用help命令查看保留关键字）。</li></ul><h2 id="2-2-变量的类型"><a href="#2-2-变量的类型" class="headerlink" title="2.2 变量的类型"></a>2.2 变量的类型</h2><p>运行shell时，会同时存在三种变量：</p><ul><li><strong>1) 局部变量</strong> 局部变量在脚本或命令中定义，仅在当前shell实例中有效，其他shell启动的程序不能访问局部变量。</li><li><strong>2) 环境变量</strong> 所有的程序，包括shell启动的程序，都能访问环境变量，有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。</li><li><strong>3) shell变量</strong> shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量，有一部分是局部变量，这些变量保证了shell的正常运行</li></ul><h2 id="2-3-shell变量的使用"><a href="#2-3-shell变量的使用" class="headerlink" title="2.3 shell变量的使用"></a>2.3 shell变量的使用</h2><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></pre></td><td class="code"><pre><span class="line">your_name="holicCode.com"</span><br><span class="line">echo $your_name</span><br><span class="line">echo $&#123;your_name&#125;</span><br></pre></td></tr></table></figure><p>变量名外面的花括号是可选的，加不加都行，加话括号是为了帮助解释器识别变量的边界</p><h2 id="2-4-设置只读变量"><a href="#2-4-设置只读变量" class="headerlink" title="2.4 设置只读变量"></a>2.4 设置只读变量</h2><p>使用readonly命令可以将变量定义为只读变量，只读变量的值不能被改变。</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></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span>!/bin/bash</span><br><span class="line">myUrl="https://holicCode.github.io"</span><br><span class="line">readonly myUrl</span><br></pre></td></tr></table></figure><h2 id="2-5-删除变量"><a href="#2-5-删除变量" class="headerlink" title="2.5 删除变量"></a>2.5 删除变量</h2><p>使用unset命令可以删除变量</p><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">unset your_name</span><br></pre></td></tr></table></figure><p>变量被删除后不能再次使用；unset命令不能删除只读变量</p><h1 id="三、shell字符串"><a href="#三、shell字符串" class="headerlink" title="三、shell字符串"></a>三、shell字符串</h1><p>字符串是shell编程中最常用的数据类型，字符串可以用单引号，也可以用双引号，也可以不用引号</p><h2 id="3-1-单引号"><a href="#3-1-单引号" class="headerlink" title="3.1 单引号"></a>3.1 单引号</h2><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">str='this is a string'</span><br></pre></td></tr></table></figure><p>单引号字符串的限制：</p><ul><li>单引号里的任何字符都会原样输出，单引号字符串中的变量是无效的；</li><li>单引号字串中不能出现单独一个的单引号（对单引号使用转义符后也不行），但可成对出现，作为字符串拼接使用。</li></ul><h2 id="3-2-双引号"><a href="#3-2-双引号" class="headerlink" title="3.2 双引号"></a>3.2 双引号</h2><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">your_name='holicCode'</span><br><span class="line">str="Hello, I know you are \"$your_name\"! \n"</span><br><span class="line">echo -e $str</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></pre></td><td class="code"><pre><span class="line">Hello, I know you are "holicCode"!</span><br></pre></td></tr></table></figure><p>双引号的优点：</p><ul><li>双引号里可以有变量</li><li>双引号里可以出现转义字符</li></ul><h2 id="3-3-拼接字符串"><a href="#3-3-拼接字符串" class="headerlink" title="3.3 拼接字符串"></a>3.3 拼接字符串</h2><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">your_name="holicCode"</span><br><span class="line"><span class="meta">#</span> 使用双引号拼接</span><br><span class="line">greeting="hello, "$your_name" !"</span><br><span class="line">greeting_1="hello, $&#123;your_name&#125; !"</span><br><span class="line">echo $greeting  $greeting_1</span><br><span class="line"><span class="meta">#</span> 使用单引号拼接</span><br><span class="line">greeting_2='hello, '$your_name' !'</span><br><span class="line">greeting_3='hello, $&#123;your_name&#125; !'</span><br><span class="line">echo $greeting_2  $greeting_3</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></pre></td><td class="code"><pre><span class="line">hello, holicCode ! hello, holicCode !</span><br><span class="line">hello, holicCode ! hello, $&#123;your_name&#125; !</span><br></pre></td></tr></table></figure><h2 id="3-4-获取字符串长度"><a href="#3-4-获取字符串长度" class="headerlink" title="3.4 获取字符串长度"></a>3.4 获取字符串长度</h2><figure class="highlight shell"><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">string="abcd"</span><br><span class="line">echo $&#123;#string&#125; #输出 4</span><br></pre></td></tr></table></figure><h2 id="3-5-提取子字符串"><a href="#3-5-提取子字符串" class="headerlink" title="3.5 提取子字符串"></a>3.5 提取子字符串</h2><p>以下实例从字符串第 <strong>2</strong> 个字符开始截取 <strong>4</strong> 个字符：</p><figure class="highlight shell"><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">string="holicCode is a great site"</span><br><span class="line">echo $&#123;string:1:4&#125; # 输出 olic</span><br></pre></td></tr></table></figure><h2 id="3-6-查找子字符串"><a href="#3-6-查找子字符串" class="headerlink" title="3.6 查找子字符串"></a>3.6 查找子字符串</h2><p>查找字符 <strong>i</strong> 或 <strong>o</strong> 的位置(哪个字母先出现就计算哪个)：</p><figure class="highlight shell"><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">string="holicCode is a great site"</span><br><span class="line">echo `expr index "$string" io`  # 输出 2</span><br></pre></td></tr></table></figure><h1 id="三、shell基本运算符"><a href="#三、shell基本运算符" class="headerlink" title="三、shell基本运算符"></a>三、shell基本运算符</h1><p>shell编程支持</p><ul><li>算数运算符</li><li>关系运算符</li><li>布尔运算符</li><li>字符串运算符</li><li>文件测试运算符</li></ul><h1 id="四、shell的流程控制"><a href="#四、shell的流程控制" class="headerlink" title="四、shell的流程控制"></a>四、shell的流程控制</h1><h2 id="4-1-if条件语句"><a href="#4-1-if条件语句" class="headerlink" title="4.1 if条件语句"></a>4.1 if条件语句</h2><p>if else-if else</p><p>if else-if else 语法格式：</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">if condition1</span><br><span class="line">then</span><br><span class="line">    command1</span><br><span class="line">elif condition2 </span><br><span class="line">then </span><br><span class="line">    command2</span><br><span class="line">else</span><br><span class="line">    commandN</span><br><span class="line">fi</span><br></pre></td></tr></table></figure><h2 id="4-2-for循环"><a href="#4-2-for循环" class="headerlink" title="4.2 for循环"></a>4.2 for循环</h2><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">for var in item1 item2 ... itemN</span><br><span class="line">do</span><br><span class="line">    command1</span><br><span class="line">    command2</span><br><span class="line">    ...</span><br><span class="line">    commandN</span><br><span class="line">done</span><br></pre></td></tr></table></figure><h2 id="4-3-while语句"><a href="#4-3-while语句" class="headerlink" title="4.3 while语句"></a>4.3 while语句</h2><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 condition</span><br><span class="line">do</span><br><span class="line">    command</span><br><span class="line">done</span><br></pre></td></tr></table></figure><h2 id="4-4-无限循环"><a href="#4-4-无限循环" class="headerlink" title="4.4 无限循环"></a>4.4 无限循环</h2><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">    command</span><br><span class="line">done</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></pre></td><td class="code"><pre><span class="line">while true</span><br><span class="line">do</span><br><span class="line">    command</span><br><span class="line">done</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></pre></td><td class="code"><pre><span class="line">for (( ; ; ))</span><br></pre></td></tr></table></figure><h1 id="五、shell函数"><a href="#五、shell函数" class="headerlink" title="五、shell函数"></a>五、shell函数</h1><p>linux shell 可以用户定义函数，然后在shell脚本中可以随便调用。</p><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">[ function ] funname [()]</span><br><span class="line"></span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line">    action;</span><br><span class="line"></span><br><span class="line">    [return int;]</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>说明：</p><ul><li>1、可以带function fun() 定义，也可以直接fun() 定义,不带任何参数。</li><li>2、参数返回，可以显示加：return 返回，如果不加，将以最后一条命令运行结果，作为返回值。 return后跟数值n(0-255）</li></ul>]]></content>
    
    <summary type="html">
    
      
      
        &lt;blockquote&gt;
&lt;p&gt;本文参考自《菜鸟教程》&lt;/p&gt;
&lt;/blockquote&gt;
&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;一、什么是sh
      
    
    </summary>
    
      <category term="shell" scheme="http://yoursite.com/categories/shell/"/>
    
    
      <category term="shell" scheme="http://yoursite.com/tags/shell/"/>
    
  </entry>
  
  <entry>
    <title>MongoDB相关知识</title>
    <link href="http://yoursite.com/2019/08/14/MongoDB%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/"/>
    <id>http://yoursite.com/2019/08/14/MongoDB相关知识/</id>
    <published>2019-08-14T15:59:47.596Z</published>
    <updated>2019-08-14T15:59:48.253Z</updated>
    
    <content type="html"><![CDATA[<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">本文参考自：https://github.com/0voice/interview_internal_reference/tree/master/11.MongoDB%E7%AF%87</span><br></pre></td></tr></table></figure><h1 id="一、MongoDB的基本概念？"><a href="#一、MongoDB的基本概念？" class="headerlink" title="一、MongoDB的基本概念？"></a>一、MongoDB的基本概念？</h1><h2 id="1-1-什么是MongoDB？"><a href="#1-1-什么是MongoDB？" class="headerlink" title="1.1 什么是MongoDB？"></a>1.1 什么是MongoDB？</h2><p>MongoDB是一个文档数据库，提供好的性能，领先的非关系型数据库</p><h2 id="1-2-MongoDB是由哪种语言写的？"><a href="#1-2-MongoDB是由哪种语言写的？" class="headerlink" title="1.2 MongoDB是由哪种语言写的？"></a>1.2 MongoDB是由哪种语言写的？</h2><p>MongoDB用 C++ 编写</p><h2 id="1-3-MongoDB有哪些优势？"><a href="#1-3-MongoDB有哪些优势？" class="headerlink" title="1.3 MongoDB有哪些优势？"></a>1.3 MongoDB有哪些优势？</h2><p>面向文档的存储：以JSON格式的文档保存数据</p><ul><li>任何属性都可以建立索引</li><li>复制以及高可扩展性</li><li>自动分片</li><li>丰富的查询功能</li><li>快速的即时更新</li></ul><h2 id="1-4-什么是-mongod？"><a href="#1-4-什么是-mongod？" class="headerlink" title="1.4 什么是 mongod？"></a>1.4 什么是 mongod？</h2><p>mongod是处理MongoDB系统的主要进程。它处理数据请求，管理数据存储，和执行后台管理操作。当我们运行mongod命令意味着正在启动MongoDB进程,并且在后台运行。</p><h2 id="1-5-为什么用MongoDB？"><a href="#1-5-为什么用MongoDB？" class="headerlink" title="1.5 为什么用MongoDB？"></a>1.5 为什么用MongoDB？</h2><ul><li>架构简单</li><li>没有复杂的连接</li><li>深度查询能力,MongoDB支持动态查询。</li><li>容易调试</li><li>容易扩展</li><li>不需要转化/映射应用对象到数据库对象</li><li>使用内部内存作为存储工作区,以便更快的存取数据。</li></ul><h2 id="1-6-MongoDB支持的数据类型？"><a href="#1-6-MongoDB支持的数据类型？" class="headerlink" title="1.6 MongoDB支持的数据类型？"></a>1.6 MongoDB支持的数据类型？</h2><p>String；Integer；Boolean；Double；Min/Max keys；Array；Timestamp；Object；Null；Symbol；Date；Object ID；Binary Data；Code；Regular expression</p><p><img src="C:%5CUsers%5C%E5%86%B7%E7%9E%B3%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1565796177040.png" alt="1565796177040"></p><h1 id="二、MongoDB复制（副本集）"><a href="#二、MongoDB复制（副本集）" class="headerlink" title="二、MongoDB复制（副本集）"></a>二、MongoDB复制（副本集）</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">MongoDB复制是将数据同步在多个服务器的过程。</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><h2 id="2-1-MongoDB复制有什么好处"><a href="#2-1-MongoDB复制有什么好处" class="headerlink" title="2.1 MongoDB复制有什么好处?"></a>2.1 MongoDB复制有什么好处?</h2><ul><li>保障数据的安全性</li><li>数据高可用性 (24*7)</li><li>灾难恢复</li><li>无需停机维护（如备份，重建索引，压缩）</li><li>分布式读取数据</li></ul><h2 id="2-2-MongoDB复制原理"><a href="#2-2-MongoDB复制原理" class="headerlink" title="2.2 MongoDB复制原理?"></a>2.2 MongoDB复制原理?</h2><p>mongodb的复制至少需要两个节点。其中一个主节点，负责处理客户端请求，其余的都是从节点，负责复制主节点上的数据；</p><p>mongodb各个节点常见的搭配方式为：一主一从、一主多从；</p><p>主节点记录在其上所有操作oplog，从节点定期轮询主节点获取这些操作，然后对自己的数据副本执行这些操作，从而保证节点的数据与节点一致；</p><p>客户端从主节点读取数据，在客户端写入数据到主节点时，主节点与从节点进行数据交互保障数据的一致性</p><h2 id="2-3-副本集的特征？"><a href="#2-3-副本集的特征？" class="headerlink" title="2.3 副本集的特征？"></a>2.3 副本集的特征？</h2><ul><li>N 个节点的集群</li><li>任何节点可作为主节点</li><li>所有写入操作都在主节点上</li><li>自动故障转移</li><li>自动恢复</li></ul><h1 id="三、MongoDB分片"><a href="#三、MongoDB分片" class="headerlink" title="三、MongoDB分片"></a>三、MongoDB分片</h1><figure class="highlight plain"><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">在Mongodb里面存在另一种集群，就是分片技术,可以满足MongoDB数据量大量增长的需求。</span><br><span class="line"></span><br><span class="line">当MongoDB存储海量的数据时，一台机器可能不足以存储数据，也可能不足以提供可接受的读写吞吐量。这时，我们就可以通过在多台机器上分割数据，使得数据库系统能存储和处理更多的数据。</span><br></pre></td></tr></table></figure><h2 id="3-1-为什么使用分片？"><a href="#3-1-为什么使用分片？" class="headerlink" title="3.1 为什么使用分片？"></a>3.1 为什么使用分片？</h2><ul><li>复制所有的写入操作到主节点</li><li>延迟的敏感数据会在主节点查询</li><li>单个副本集限制在12个节点</li><li>当请求量巨大时会出现内存不足。</li><li>本地磁盘不足</li><li>垂直扩展价格昂贵</li></ul><h1 id="四、MongoDB备份（mongodump）与恢复（mongorestore）"><a href="#四、MongoDB备份（mongodump）与恢复（mongorestore）" class="headerlink" title="四、MongoDB备份（mongodump）与恢复（mongorestore）"></a>四、MongoDB备份（mongodump）与恢复（mongorestore）</h1><h2 id="4-1-数据的备份"><a href="#4-1-数据的备份" class="headerlink" title="4.1 数据的备份"></a>4.1 数据的备份</h2><blockquote><p>mongodump -h dbhost -d dbname -o dbdirectory</p></blockquote><ul><li><p>-h：</p><p>MongDB所在服务器地址，例如：127.0.0.1，当然也可以指定端口号：127.0.0.1:27017</p></li><li><p>-d：</p><p>需要备份的数据库实例，例如：test</p></li><li><p>-o：</p><p>备份的数据存放位置，例如：c:\data\dump，当然该目录需要提前建立，在备份完成后，系统自动在dump目录下建立一个test目录，这个目录里面存放该数据库实例的备份数据。</p></li></ul><h2 id="4-2-数据恢复"><a href="#4-2-数据恢复" class="headerlink" title="4.2 数据恢复"></a>4.2 数据恢复</h2><blockquote><p>mongorestore -h <hostname>&lt;:port&gt; -d dbname <path></path></hostname></p></blockquote><ul><li><p>–host &lt;:port&gt;, -h &lt;:port&gt;：</p><p>MongoDB所在服务器地址，默认为： localhost:27017</p></li><li><p>–db , -d ：</p><p>需要恢复的数据库实例，例如：test，当然这个名称也可以和备份时候的不一样，比如test2</p></li><li><p>–drop：</p><p>恢复的时候，先删除当前数据，然后恢复备份的数据。就是说，恢复后，备份后添加修改的数据都会被删除，慎用哦！</p></li><li><p><path>：</path></p><p>mongorestore 最后的一个参数，设置备份数据所在位置，例如：c:\data\dump\test。</p><p>你不能同时指定 <path> 和 –dir 选项，–dir也可以设置备份目录。</path></p></li><li><p>–dir：</p><p>指定备份的目录</p><p>你不能同时指定 <path> 和 –dir 选项。</path></p></li></ul><h1 id="五、MongoDB-Java"><a href="#五、MongoDB-Java" class="headerlink" title="五、MongoDB Java"></a>五、MongoDB Java</h1><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> com.mongodb.MongoClient;</span><br><span class="line"><span class="keyword">import</span> com.mongodb.client.MongoDatabase;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MongoDBJDBC</span></span>&#123;</span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">( String args[] )</span></span>&#123;</span><br><span class="line">      <span class="keyword">try</span>&#123;   </span><br><span class="line">         <span class="comment">// 连接到 mongodb 服务</span></span><br><span class="line">         MongoClient mongoClient = <span class="keyword">new</span> MongoClient( <span class="string">"localhost"</span> , <span class="number">27017</span> );</span><br><span class="line">       </span><br><span class="line">         <span class="comment">// 连接到数据库</span></span><br><span class="line">         MongoDatabase mongoDatabase = mongoClient.getDatabase(<span class="string">"mycol"</span>);  </span><br><span class="line">        System.out.println(<span class="string">"Connect to database successfully"</span>);</span><br><span class="line">        </span><br><span class="line">      &#125;<span class="keyword">catch</span>(Exception e)&#123;</span><br><span class="line">        System.err.println( e.getClass().getName() + <span class="string">": "</span> + e.getMessage() );</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>]]></content>
    
    <summary type="html">
    
      
      
        &lt;figure class=&quot;highlight plain&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;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span cla
      
    
    </summary>
    
      <category term="MongoDB" scheme="http://yoursite.com/categories/MongoDB/"/>
    
    
      <category term="MongoDB" scheme="http://yoursite.com/tags/MongoDB/"/>
    
  </entry>
  
  <entry>
    <title>Linux的相关知识</title>
    <link href="http://yoursite.com/2019/08/10/Linux%E7%9A%84%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/"/>
    <id>http://yoursite.com/2019/08/10/Linux的相关知识/</id>
    <published>2019-08-09T16:26:11.823Z</published>
    <updated>2019-08-09T16:35:14.281Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、Linux的目录结构"><a href="#一、Linux的目录结构" class="headerlink" title="一、Linux的目录结构"></a>一、Linux的目录结构</h1><p><img src="file:///C:%5CUsers%5C%E5%86%B7%E7%9E%B3%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image002.jpg" alt="img"></p><h1 id="二、Linux的常用命令"><a href="#二、Linux的常用命令" class="headerlink" title="二、Linux的常用命令"></a>二、Linux的常用命令</h1><h2 id="2-1-切换目录命令【cd】"><a href="#2-1-切换目录命令【cd】" class="headerlink" title="2.1 切换目录命令【cd】"></a>2.1 切换目录命令【cd】</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">cd app切换到app目录 </span><br><span class="line">cd ..切换到上一层目录 </span><br><span class="line">cd /切换到系统根目录 </span><br><span class="line">cd ~切换到用户主目录 </span><br><span class="line">cd -切换到上一个所在目录</span><br></pre></td></tr></table></figure><h2 id="2-2-列出文件列表【ls、ll、dir】"><a href="#2-2-列出文件列表【ls、ll、dir】" class="headerlink" title="2.2 列出文件列表【ls、ll、dir】"></a>2.2 列出文件列表【ls、ll、dir】</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">ls(list)是一个非常有用的命令，用来显示当前目录下的内容。配合参数的使用，能以不同的方式显示目录内容。     格式：ls[参数] [路径或文件名]</span><br><span class="line"></span><br><span class="line">常用：</span><br><span class="line">在linux中以 . 开头的文件都是隐藏的文件</span><br><span class="line"></span><br><span class="line">* ls</span><br><span class="line">* ls -a  显示所有文件或目录（包含隐藏的文件）</span><br><span class="line">* ls -l  缩写成ll</span><br></pre></td></tr></table></figure><h2 id="2-3-创建目录和移除目录【mkdir、rmdir】"><a href="#2-3-创建目录和移除目录【mkdir、rmdir】" class="headerlink" title="2.3 创建目录和移除目录【mkdir、rmdir】"></a>2.3 创建目录和移除目录【mkdir、rmdir】</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">mkdir(make directory)命令可用来创建子目录。 </span><br><span class="line">mkdir app  在当前目录下创建app目录 </span><br><span class="line">mkdir –p app2/test  级联创建aap2以及test目录</span><br><span class="line"></span><br><span class="line">rmdir(remove directory)命令可用来删除“空”的子目录： </span><br><span class="line">rmdir app  删除app目录</span><br></pre></td></tr></table></figure><h2 id="2-4-浏览文件【cat、more、less、tail】"><a href="#2-4-浏览文件【cat、more、less、tail】" class="headerlink" title="2.4 浏览文件【cat、more、less、tail】"></a>2.4 浏览文件【cat、more、less、tail】</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">cat </span><br><span class="line">用于显示文件的内容。 </span><br><span class="line">格式：cat[参数]&lt;文件名&gt;</span><br><span class="line">* cat yum.conf </span><br><span class="line">more </span><br><span class="line">一般用于要显示的内容会超过一个画面长度的情况。按空格键显示下一个画面。</span><br><span class="line">回车显示下一行内容。</span><br><span class="line">按 q 键退出查看。</span><br><span class="line">* more yum.conf</span><br><span class="line">   * 空格显示下一页数据  回车显示下一行的数据 </span><br><span class="line">less </span><br><span class="line">用法和more类似，不同的是less可以通过PgUp、PgDn键来控制。</span><br><span class="line">    * less yum.conf</span><br><span class="line">        * PgUp 和 PgDn 进行上下翻页.</span><br><span class="line">tail</span><br><span class="line">命令是在实际使用过程中使用非常多的一个命令，它的功能是：用于显示文件后几行的内容。</span><br><span class="line">用法:</span><br><span class="line">tail -10 /etc/passwd  查看后10行数据</span><br><span class="line">tail -f catalina.log  动态查看日志(*****)</span><br><span class="line"></span><br><span class="line">ctrl+c 结束查看</span><br></pre></td></tr></table></figure><h2 id="2-5-文件操作"><a href="#2-5-文件操作" class="headerlink" title="2.5 文件操作"></a>2.5 文件操作</h2><h3 id="【rm】"><a href="#【rm】" class="headerlink" title="【rm】"></a>【rm】</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">rm  删除文件</span><br><span class="line">用法：rm [选项]... 文件...</span><br><span class="line"> rm a.txt    删除a.txt文件</span><br><span class="line"> 删除需要用户确认，y/n </span><br><span class="line">rm 删除不询问</span><br><span class="line">rm -f a.txt  不询问，直接删除 </span><br><span class="line">rm 删除目录</span><br><span class="line">rm -r a  递归删除 </span><br><span class="line">不询问递归删除（慎用）</span><br><span class="line">rm -rf  a    不询问递归删除</span><br><span class="line">rm -rf *     删除所有文件</span><br><span class="line">rm -rf /*    自杀</span><br></pre></td></tr></table></figure><h3 id="【cp、mv】"><a href="#【cp、mv】" class="headerlink" title="【cp、mv】"></a>【cp、mv】</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">cp(copy)命令可以将文件从一处复制到另一处。一般在使用cp命令时将一个文件复制成另一个文件或复制到某目录时，需要指定源文件名与目标文件名或目录。</span><br><span class="line">cp a.txt b.txt   将a.txt复制为b.txt文件</span><br><span class="line">cp a.txt ../     将a.txt文件复制到上一层目录中 </span><br><span class="line"></span><br><span class="line">mv 移动或者重命名</span><br><span class="line">mv a.txt ../      将a.txt文件移动到上一层目录中</span><br><span class="line">mv a.txt b.txt    将a.txt文件重命名为b.txt</span><br></pre></td></tr></table></figure><h3 id="【tar】"><a href="#【tar】" class="headerlink" title="【tar】"></a>【tar】</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">tar命令位于/bin目录下，它能够将用户所指定的文件或目录打包成一个文件，但不做压缩。一般Linux上常用的压缩方式是选用tar将许多文件打包成一个文件，再以gzip压缩命令压缩成xxx.tar.gz(或称为xxx.tgz)的文件。  </span><br><span class="line">常用参数： </span><br><span class="line">-c：创建一个新tar文件 </span><br><span class="line">-v：显示运行过程的信息 </span><br><span class="line">-f：指定文件名 </span><br><span class="line">-z：调用gzip压缩命令进行压缩 </span><br><span class="line">-t：查看压缩文件的内容 </span><br><span class="line">-x：解开tar文件</span><br><span class="line"></span><br><span class="line">打包：</span><br><span class="line">tar –cvf xxx.tar ./*</span><br><span class="line">打包并且压缩：</span><br><span class="line">tar –zcvf xxx.tar.gz ./* </span><br><span class="line"></span><br><span class="line">解压 </span><br><span class="line">    tar –xvf xxx.tar</span><br><span class="line">tar -xvf xxx.tar.gz -C /usr/aaa</span><br></pre></td></tr></table></figure><h3 id="【grep】"><a href="#【grep】" class="headerlink" title="【grep】"></a>【grep】</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">用法: grep [选项]... PATTERN [FILE]... </span><br><span class="line">示例：</span><br><span class="line">grep lang anaconda-ks.cfg  在文件中查找lang</span><br><span class="line">grep lang anaconda-ks.cfg –color  高亮显示</span><br></pre></td></tr></table></figure><h2 id="2-6-其他常用命令"><a href="#2-6-其他常用命令" class="headerlink" title="2.6 其他常用命令"></a>2.6 其他常用命令</h2><h3 id="【pwd】"><a href="#【pwd】" class="headerlink" title="【pwd】"></a>【pwd】</h3><blockquote><p>显示当前所在目录</p></blockquote><h3 id="【touch】"><a href="#【touch】" class="headerlink" title="【touch】"></a>【touch】</h3><blockquote><p>创建一个空文件</p><p>​    touch a.txt</p></blockquote><h3 id="【ll-h】"><a href="#【ll-h】" class="headerlink" title="【ll -h】"></a>【ll -h】</h3><blockquote><p>友好显示文件大小</p></blockquote><h3 id="【wget】"><a href="#【wget】" class="headerlink" title="【wget】"></a>【wget】</h3><blockquote><p>下载资料</p><p>​    wget 资料的url</p></blockquote><h1 id="三、Vi和Vim编译器"><a href="#三、Vi和Vim编译器" class="headerlink" title="三、Vi和Vim编译器"></a>三、Vi和Vim编译器</h1><h2 id="3-1-Vim编译器"><a href="#3-1-Vim编译器" class="headerlink" title="3.1 Vim编译器"></a>3.1 Vim编译器</h2><p>在Linux下一般使用vi编辑器来编辑文件。</p><p>vi既可以查看文件也可以编辑文件。</p><p>三种模式：命令行、插入、底行模式。</p><p>切换到命令行模式：按Esc键；</p><p>切换到插入模式：按 i 、o、a键；</p><p>​    i 在当前位置生前插入</p><p>​    I 在当前行首插入</p><p>​    a 在当前位置后插入</p><p>​    A 在当前行尾插入</p><p>​    o 在当前行之后插入一行</p><p>​    O 在当前行之前插入一行</p><p>切换到底行模式：按 :（冒号）；</p><p>更多详细用法，查询文档《Vim命令合集.docx》和《vi使用方法详细介绍.docx》</p><p>打开文件：vim file</p><p>退出：esc à :q</p><p>修改文件：输入i进入插入模式</p><p>保存并退出：esc——&gt;wq</p><p>不保存退出：esc——&gt;q!</p><p>3中进入插入模式：</p><p>​    i:在当前的光标所在处插入</p><p>​    o:在当前光标所在的行的下一行插入</p><p>​    a:在光标所在的下一个字符插入</p><p>快捷键：</p><p>​    dd – 快速删除一行</p><p>​    R – 替换</p><h2 id="3-2-重定向输出-gt-和-gt-gt"><a href="#3-2-重定向输出-gt-和-gt-gt" class="headerlink" title="3.2 重定向输出 &gt; 和 &gt;&gt;"></a>3.2 重定向输出 &gt; 和 &gt;&gt;</h2><p>&gt; 重定向输出，覆盖原有内容；</p><p>&gt;&gt; 重定向输出，又追加功能；</p><p>示例：</p><p>​    cat /etc/passwd &gt; a.txt  将输出定向到a.txt中</p><p>​    cat /etc/passwd &gt;&gt; a.txt  输出并且追加</p><p>​    ifconfig &gt; ifconfig.txt</p><h2 id="3-3-管道"><a href="#3-3-管道" class="headerlink" title="3.3 管道"></a>3.3 管道</h2><p>管道是Linux命令中重要的一个概念，其作用是将一个命令的输出用作另一个命令的输入。</p><p>示例</p><p>​    ls –help | more  分页查询帮助信息</p><p>​    ps –ef | grep java  查询名称中包含java的进程</p><p>​    ifconfig | more</p><p>​    cat index.html | more</p><p>​    ps –ef | grep aio</p><h2 id="3-4-amp-amp-命令执行控制"><a href="#3-4-amp-amp-命令执行控制" class="headerlink" title="3.4 &amp;&amp;命令执行控制"></a>3.4 &amp;&amp;命令执行控制</h2><p>命令之间使用 &amp;&amp; 连接，实现逻辑与的功能。 </p><p>​    只有在 &amp;&amp; 左边的命令返回真（命令返回值 $? == 0），&amp;&amp; 右边的命令才会被执行。 </p><p>​    只要有一个命令返回假（命令返回值 $? == 1），后面的命令就不会被执行。</p><pre><code>mkdir test &amp;&amp; cd test</code></pre><h2 id="3-5-网络通讯命令"><a href="#3-5-网络通讯命令" class="headerlink" title="3.5 网络通讯命令"></a>3.5 网络通讯命令</h2><p>ifconfig  显示或设置网络设备。</p><p>ifconfig  显示网络设备</p><p>ifconfig eth0 up 启用eth0网卡</p><p>ifconfig eth0 down  停用eth0网卡</p><p>ping   探测网络是否通畅。</p><p>ping 192.168.0.1</p><p>netstat 查看网络端口。</p><p>netstat -an | grep 3306 查询3306端口占用情况</p><h2 id="3-6-系统管理命令"><a href="#3-6-系统管理命令" class="headerlink" title="3.6 系统管理命令"></a>3.6 系统管理命令</h2><p>date 显示或设置系统时间</p><p>​    date  显示当前系统时间</p><p>​    date -s “2014-01-01 10:10:10“  设置系统时间</p><p>df 显示磁盘信息</p><p>​    df –h  友好显示大小</p><p>free 显示内存状态</p><p>​    free –m 以mb单位显示内存组昂头</p><p>top 显示，管理执行中的程序</p><p>clear 清屏幕</p><p>ps 正在运行的某个进程的状态</p><p>​    ps –ef  查看所有进程</p><p>​    ps –ef | grep ssh 查找某一进程</p><p>kill 杀掉某一进程</p><p>​    kill 2868  杀掉2868编号的进程</p><p>​    kill -9 2868  强制杀死进程</p><p>du 显示目录或文件的大小。</p><p>​    du –h 显示当前目录的大小</p><p>who 显示目前登入系统的用户信息。</p><p>hostname 查看当前主机名</p><p>修改：vi /etc/sysconfig/network</p><p>uname 显示系统信息。</p><p>​    uname -a 显示本机详细信息。</p><p>依次为：内核名称(类别)，主机名，内核版本号，内核版本，内核编译日期，硬件名，处理器类型，硬件平台类型，操作系统名称</p><h1 id="四、Linux的权限命令"><a href="#四、Linux的权限命令" class="headerlink" title="四、Linux的权限命令"></a>四、Linux的权限命令</h1><h2 id="4-1-Linux的三种文件类型"><a href="#4-1-Linux的三种文件类型" class="headerlink" title="4.1 Linux的三种文件类型"></a>4.1 Linux的三种文件类型</h2><p>普通文件： 包括文本文件、数据文件、可执行的二进制程序文件等。 </p><p>目录文件： Linux系统把目录看成是一种特殊的文件，利用它构成文件系统的树型结构。  </p><p>设备文件： Linux系统把每一个设备都看成是一个文件</p><h2 id="4-2-文件类型标识"><a href="#4-2-文件类型标识" class="headerlink" title="4.2 文件类型标识"></a>4.2 文件类型标识</h2><p>普通文件（-）</p><p>目录（d）</p><p>符号链接（l）</p><p>* 进入etc可以查看，相当于快捷方式</p><p>字符设备文件（c）</p><p>块设备文件（s）</p><p>套接字（s）</p><p>命名管道（p）</p><h2 id="4-3-文件权限管理"><a href="#4-3-文件权限管理" class="headerlink" title="4.3 文件权限管理"></a>4.3 文件权限管理</h2><p>chmod 变更文件或目录的权限。</p><p>​    chmod 755 a.txt </p><p>​    chmod u=rwx,g=rx,o=rx a.txt</p><p>​    chmod 000 a.txt  / chmod 777 a.txt</p><p>chown 变更文件或目录改文件所属用户和组</p><p>​    chown u1:public a.txt  ：变更当前的目录或文件的所属用户和组</p><p>​    chown -R u1:public dir ：变更目录中的所有的子目录及文件的所属用户和组</p><h1 id="五、Linux面试有关知识"><a href="#五、Linux面试有关知识" class="headerlink" title="五、Linux面试有关知识"></a>五、Linux面试有关知识</h1><h2 id="5-1-如何避免开发过程中Linux和Windows下路径拼接不一致问题？"><a href="#5-1-如何避免开发过程中Linux和Windows下路径拼接不一致问题？" class="headerlink" title="5.1 如何避免开发过程中Linux和Windows下路径拼接不一致问题？"></a>5.1 如何避免开发过程中Linux和Windows下路径拼接不一致问题？</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">统一使用File.separator</span><br></pre></td></tr></table></figure><h2 id="5-2-buffer和cache如何区分？"><a href="#5-2-buffer和cache如何区分？" class="headerlink" title="5.2 buffer和cache如何区分？"></a>5.2 buffer和cache如何区分？</h2><figure class="highlight plain"><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">CPU写数据到磁盘时，磁盘速度比较慢，所以CPU先把数据存进buffer，然后CPU去执行其他任务，buffer中的数据会定期写入磁盘。</span><br><span class="line">CPU从磁盘读入数据时，由于磁盘速度比较慢，把即将用到的数据提前存入cache，CPU直接从cache中拿数据要快的多。</span><br></pre></td></tr></table></figure><h2 id="5-3-自定义解析域名的时候，我们可以编辑哪个文件？是否可以一个ip对应多个域名？是否可以一个域名对用多个ip？"><a href="#5-3-自定义解析域名的时候，我们可以编辑哪个文件？是否可以一个ip对应多个域名？是否可以一个域名对用多个ip？" class="headerlink" title="5.3 自定义解析域名的时候，我们可以编辑哪个文件？是否可以一个ip对应多个域名？是否可以一个域名对用多个ip？"></a>5.3 自定义解析域名的时候，我们可以编辑哪个文件？是否可以一个ip对应多个域名？是否可以一个域名对用多个ip？</h2><figure class="highlight plain"><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">编辑 /etc/hosts；</span><br><span class="line">可以一个ip对应多个域名；</span><br><span class="line">不可以一个域名对应多个ip。</span><br></pre></td></tr></table></figure><h2 id="5-4-DHCP"><a href="#5-4-DHCP" class="headerlink" title="5.4 DHCP"></a>5.4 DHCP</h2><figure class="highlight plain"><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">DHCP是动态主机配置协议的简称</span><br><span class="line">作用：为网络中的主机分配IP地址</span><br></pre></td></tr></table></figure><h2 id="未完，待补充……"><a href="#未完，待补充……" class="headerlink" title="未完，待补充……"></a>未完，待补充……</h2>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;一、Linux的目录结构&quot;&gt;&lt;a href=&quot;#一、Linux的目录结构&quot; class=&quot;headerlink&quot; title=&quot;一、Linux的目录结构&quot;&gt;&lt;/a&gt;一、Linux的目录结构&lt;/h1&gt;&lt;p&gt;&lt;img src=&quot;file:///C:%5CUsers%5
      
    
    </summary>
    
      <category term="Linux" scheme="http://yoursite.com/categories/Linux/"/>
    
    
      <category term="Linux" scheme="http://yoursite.com/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>HTML&amp;CSS&amp;jQuery</title>
    <link href="http://yoursite.com/2019/08/08/HTML&amp;CSS&amp;jQuery/"/>
    <id>http://yoursite.com/2019/08/08/HTML&amp;CSS&amp;jQuery/</id>
    <published>2019-08-07T17:23:03.436Z</published>
    <updated>2019-08-07T17:33:53.358Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、HTML"><a href="#一、HTML" class="headerlink" title="一、HTML"></a>一、HTML</h1><h2 id="1-概念"><a href="#1-概念" class="headerlink" title="1. 概念"></a>1. 概念</h2><p>是最基础的网页开发语言<br>    * Hyper Text Markup Language 超文本标记语言<br>        * 超文本:<br>            * 超文本是用超链接的方法，将各种不同空间的文字信息组织在一起的网状文本.<br>        * 标记语言:<br>            * 由标签构成的语言。&lt;标签名称&gt; 如 html，xml<br>            * 标记语言不是编程语言</p><h2 id="2-快速入门"><a href="#2-快速入门" class="headerlink" title="2. 快速入门"></a>2. 快速入门</h2><ul><li><p>语法：</p><pre><code>1. html文档后缀名 .html 或者 .htm2. 标签分为    1. 围堵标签：有开始标签和结束标签。如 &lt;html&gt; &lt;/html&gt;    2. 自闭和标签：开始标签和结束标签在一起。如 &lt;br/&gt;3. 标签可以嵌套：    需要正确嵌套，不能你中有我，我中有你    错误：&lt;a&gt;&lt;b&gt;&lt;/a&gt;&lt;/b&gt;    正确：&lt;a&gt;&lt;b&gt;&lt;/b&gt;&lt;/a&gt;4. 在开始标签中可以定义属性。属性是由键值对构成，值需要用引号(单双都可)引起来5. html的标签不区分大小写，但是建议使用小写。</code></pre><ul><li><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></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">html</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">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><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">FONT</span> <span class="attr">color</span>=<span class="string">'red'</span>&gt;</span>Hello World<span class="tag">&lt;/<span class="name">font</span>&gt;</span><span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">font</span> <span class="attr">color</span>=<span class="string">'green'</span>&gt;</span>Hello World<span class="tag">&lt;/<span class="name">font</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><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure></li></ul></li></ul><h2 id="3-标签"><a href="#3-标签" class="headerlink" title="3. 标签"></a>3. 标签</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></pre></td><td class="code"><pre><span class="line">1. 文件标签：构成html最基本的标签</span><br><span class="line">* html:html文档的根标签</span><br><span class="line">* head：头标签。用于指定html文档的一些属性。引入外部的资源</span><br><span class="line">* title：标题标签。</span><br><span class="line">* body：体标签</span><br><span class="line">* <span class="meta">&lt;!DOCTYPE html&gt;</span>：html5中定义该文档是html文档</span><br><span class="line">2. 文本标签：和文本有关的标签</span><br><span class="line">* 注释：<span class="comment">&lt;!-- 注释内容 --&gt;</span></span><br><span class="line">* <span class="tag">&lt;<span class="name">h1</span>&gt;</span> to <span class="tag">&lt;<span class="name">h6</span>&gt;</span>：标题标签</span><br><span class="line">* h1~h6:字体大小逐渐递减</span><br><span class="line">* <span class="tag">&lt;<span class="name">p</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">hr</span>&gt;</span>：展示一条水平线</span><br><span class="line">* 属性：</span><br><span class="line">* color：颜色</span><br><span class="line">* width：宽度</span><br><span class="line">* size：高度</span><br><span class="line">* align：对其方式</span><br><span class="line">* center：居中</span><br><span class="line">* left：左对齐</span><br><span class="line">* right：右对齐</span><br><span class="line">* <span class="tag">&lt;<span class="name">b</span>&gt;</span>：字体加粗</span><br><span class="line">* <span class="tag">&lt;<span class="name">i</span>&gt;</span>：字体斜体</span><br><span class="line">* <span class="tag">&lt;<span class="name">font</span>&gt;</span>:字体标签</span><br><span class="line">* <span class="tag">&lt;<span class="name">center</span>&gt;</span>:文本居中</span><br><span class="line">* 属性：</span><br><span class="line">* color：颜色</span><br><span class="line">* size：大小</span><br><span class="line">* face：字体</span><br><span class="line"></span><br><span class="line">* 属性定义：</span><br><span class="line">* color：</span><br><span class="line">1. 英文单词：red,green,blue</span><br><span class="line">2. rgb(值1，值2，值3)：值的范围：0~255  如  rgb(0,0,255)</span><br><span class="line">3. #值1值2值3：值的范围：00~FF之间。如： #FF00FF</span><br><span class="line">* width：</span><br><span class="line">1. 数值：width='20' ,数值的单位，默认是 px(像素)</span><br><span class="line">2. 数值%：占比相对于父元素的比例</span><br></pre></td></tr></table></figure><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><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><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><span class="line">3. 图片标签：</span><br><span class="line">* img：展示图片</span><br><span class="line">* 属性：</span><br><span class="line">* src：指定图片的位置</span><br><span class="line"></span><br><span class="line">* 代码：</span><br><span class="line"> <span class="comment">&lt;!--展示一张图片 img--&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">"image/jingxuan_2.jpg"</span> <span class="attr">align</span>=<span class="string">"right"</span> <span class="attr">alt</span>=<span class="string">"古镇"</span> <span class="attr">width</span>=<span class="string">"500"</span> <span class="attr">height</span>=<span class="string">"500"</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">        相对路径</span></span><br><span class="line"><span class="comment">            * 以.开头的路径</span></span><br><span class="line"><span class="comment">                * ./：代表当前目录  ./image/1.jpg</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><br><span class="line">    <span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./image/jiangwai_1.jpg"</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">"../image/jiangwai_1.jpg"</span>&gt;</span></span><br><span class="line">4. 列表标签：</span><br><span class="line">* 有序列表：</span><br><span class="line">* ol:</span><br><span class="line">* li:</span><br><span class="line">* 无序列表：</span><br><span class="line">* ul:</span><br><span class="line">* li:</span><br><span class="line">5. 链接标签：</span><br><span class="line">* a:定义一个超链接</span><br><span class="line">* 属性：</span><br><span class="line">* href：指定访问资源的URL(统一资源定位符)</span><br><span class="line">* target：指定打开资源的方式</span><br><span class="line">* _self:默认值，在当前页面打开</span><br><span class="line">* _blank：在空白页面打开</span><br><span class="line"></span><br><span class="line">* 代码：</span><br><span class="line"> <span class="comment">&lt;!--超链接  a--&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"http://www.itcast.cn"</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><br><span class="line">    <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"http://www.itcast.cn"</span> <span class="attr">target</span>=<span class="string">"_self"</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="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"http://www.itcast.cn"</span> <span class="attr">target</span>=<span class="string">"_blank"</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><br><span class="line">    <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"./5_列表标签.html"</span>&gt;</span>列表标签<span class="tag">&lt;/<span class="name">a</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">a</span> <span class="attr">href</span>=<span class="string">"mailto:itcast@itcast.cn"</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="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"http://www.itcast.cn"</span>&gt;</span><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">"image/jiangwai_1.jpg"</span>&gt;</span><span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line">6. div和span：</span><br><span class="line">* div:每一个div占满一整行。块级标签</span><br><span class="line">    * span：文本信息在一行展示，行内标签 内联标签</span><br><span class="line"></span><br><span class="line">7. 语义化标签：html5中为了提高程序的可读性，提供了一些标签。</span><br><span class="line">1. <span class="tag">&lt;<span class="name">header</span>&gt;</span>：页眉</span><br><span class="line">2. <span class="tag">&lt;<span class="name">footer</span>&gt;</span>：页脚</span><br><span class="line">8. 表格标签：</span><br><span class="line">* table：定义表格</span><br><span class="line">* width：宽度</span><br><span class="line">* border：边框</span><br><span class="line">* cellpadding：定义内容和单元格的距离</span><br><span class="line">* cellspacing：定义单元格之间的距离。如果指定为0，则单元格的线会合为一条、</span><br><span class="line">* bgcolor：背景色</span><br><span class="line">* align：对齐方式</span><br><span class="line">* tr：定义行</span><br><span class="line">* bgcolor：背景色</span><br><span class="line">* align：对齐方式</span><br><span class="line">* td：定义单元格</span><br><span class="line">* colspan：合并列</span><br><span class="line">* rowspan：合并行</span><br><span class="line">* th：定义表头单元格</span><br><span class="line">* <span class="tag">&lt;<span class="name">caption</span>&gt;</span>：表格标题</span><br><span class="line">* <span class="tag">&lt;<span class="name">thead</span>&gt;</span>：表示表格的头部分</span><br><span class="line">* <span class="tag">&lt;<span class="name">tbody</span>&gt;</span>：表示表格的体部分</span><br><span class="line">* <span class="tag">&lt;<span class="name">tfoot</span>&gt;</span>：表示表格的脚部分</span><br></pre></td></tr></table></figure><h1 id="二、CSS：页面美化和布局控制"><a href="#二、CSS：页面美化和布局控制" class="headerlink" title="二、CSS：页面美化和布局控制"></a>二、CSS：页面美化和布局控制</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><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. 概念： Cascading Style Sheets 层叠样式表</span><br><span class="line">* 层叠：多个样式可以作用在同一个html的元素上，同时生效</span><br><span class="line"></span><br><span class="line">2. 好处：</span><br><span class="line">1. 功能强大</span><br><span class="line">2. 将内容展示和样式控制分离</span><br><span class="line">* 降低耦合度。解耦</span><br><span class="line">* 让分工协作更容易</span><br><span class="line">* 提高开发效率</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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></pre></td><td class="code"><pre><span class="line">3. CSS的使用：CSS与html结合方式</span><br><span class="line">1. 内联样式</span><br><span class="line"> * 在标签内使用style属性指定css代码</span><br><span class="line"> * 如：&lt;div style=&quot;color:red;&quot;&gt;hello css&lt;/div&gt;</span><br><span class="line">2. 内部样式</span><br><span class="line">* 在head标签内，定义style标签，style标签的标签体内容就是css代码</span><br><span class="line">* 如：</span><br><span class="line">&lt;style&gt;</span><br><span class="line">        div&#123;</span><br><span class="line">            color:blue;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &lt;/style&gt;</span><br><span class="line">&lt;div&gt;hello css&lt;/div&gt;</span><br><span class="line">3. 外部样式</span><br><span class="line">1. 定义css资源文件。</span><br><span class="line">2. 在head标签内，定义link标签，引入外部的资源文件</span><br><span class="line">* 如：</span><br><span class="line">    * a.css文件：</span><br><span class="line">div&#123;</span><br><span class="line">    color:green;</span><br><span class="line">&#125;</span><br><span class="line">&lt;link rel=&quot;stylesheet&quot; href=&quot;css/a.css&quot;&gt;</span><br><span class="line">&lt;div&gt;hello css&lt;/div&gt;</span><br><span class="line">&lt;div&gt;hello css&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">* 注意：</span><br><span class="line">* 1,2,3种方式 css作用范围越来越大</span><br><span class="line">* 1方式不常用，后期常用2,3</span><br><span class="line">* 3种格式可以写为：</span><br><span class="line">&lt;style&gt;</span><br><span class="line">        @import &quot;css/a.css&quot;;</span><br><span class="line">    &lt;/style&gt;</span><br><span class="line"></span><br><span class="line">4. css语法：</span><br><span class="line">* 格式：</span><br><span class="line">选择器 &#123;</span><br><span class="line">属性名1:属性值1;</span><br><span class="line">属性名2:属性值2;</span><br><span class="line">...</span><br><span class="line">&#125;</span><br><span class="line">* 选择器:筛选具有相似特征的元素</span><br><span class="line">* 注意：</span><br><span class="line">* 每一对属性需要使用；隔开，最后一对属性可以不加；</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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></pre></td><td class="code"><pre><span class="line">5. 选择器：筛选具有相似特征的元素</span><br><span class="line">* 分类：</span><br><span class="line">1. 基础选择器</span><br><span class="line">1. id选择器：选择具体的id属性值的元素.建议在一个html页面中id值唯一</span><br><span class="line">        * 语法：#id属性值&#123;&#125;</span><br><span class="line">    2. 元素选择器：选择具有相同标签名称的元素</span><br><span class="line">        * 语法： 标签名称&#123;&#125;</span><br><span class="line">        * 注意：id选择器优先级高于元素选择器</span><br><span class="line">    3. 类选择器：选择具有相同的class属性值的元素。</span><br><span class="line">        * 语法：.class属性值&#123;&#125;</span><br><span class="line">        * 注意：类选择器选择器优先级高于元素选择器</span><br><span class="line">2. 扩展选择器：</span><br><span class="line">1. 选择所有元素：</span><br><span class="line">* 语法： *&#123;&#125;</span><br><span class="line">2. 并集选择器：</span><br><span class="line">* 选择器1,选择器2&#123;&#125;</span><br><span class="line"></span><br><span class="line">3. 子选择器：筛选选择器1元素下的选择器2元素</span><br><span class="line">* 语法：  选择器1 选择器2&#123;&#125;</span><br><span class="line">4. 父选择器：筛选选择器2的父元素选择器1</span><br><span class="line">* 语法：  选择器1 &gt; 选择器2&#123;&#125;</span><br><span class="line"></span><br><span class="line">5. 属性选择器：选择元素名称，属性名=属性值的元素</span><br><span class="line">* 语法：  元素名称[属性名=&quot;属性值&quot;]&#123;&#125;</span><br><span class="line"></span><br><span class="line">6. 伪类选择器：选择一些元素具有的状态</span><br><span class="line">* 语法： 元素:状态&#123;&#125;</span><br><span class="line">* 如： &lt;a&gt;</span><br><span class="line">* 状态：</span><br><span class="line">* link：初始化的状态</span><br><span class="line">* visited：被访问过的状态</span><br><span class="line">* active：正在访问状态</span><br><span class="line">* hover：鼠标悬浮状态</span><br><span class="line">6. 属性</span><br><span class="line">1. 字体、文本</span><br><span class="line">* font-size：字体大小</span><br><span class="line">* color：文本颜色</span><br><span class="line">* text-align：对其方式</span><br><span class="line">* line-height：行高 </span><br><span class="line">2. 背景</span><br><span class="line">* background：</span><br><span class="line">3. 边框</span><br><span class="line">* border：设置边框，符合属性</span><br><span class="line">4. 尺寸</span><br><span class="line">* width：宽度</span><br><span class="line">* height：高度</span><br><span class="line">5. 盒子模型：控制布局</span><br><span class="line">* margin：外边距</span><br><span class="line">* padding：内边距</span><br><span class="line">* 默认情况下内边距会影响整个盒子的大小</span><br><span class="line">* box-sizing: border-box;  设置盒子的属性，让width和height就是最终盒子的大小</span><br><span class="line"></span><br><span class="line">* float：浮动</span><br><span class="line">* left</span><br><span class="line">* right</span><br></pre></td></tr></table></figure><h1 id="三、jQuery"><a href="#三、jQuery" class="headerlink" title="三、jQuery"></a>三、jQuery</h1><h2 id="1-jQuery基础"><a href="#1-jQuery基础" class="headerlink" title="1. jQuery基础"></a>1. jQuery基础</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1. 概念： 一个JavaScript框架。简化JS开发</span><br><span class="line">* jQuery是一个快速、简洁的JavaScript框架，是继Prototype之后又一个优秀的JavaScript代码库（或JavaScript框架）。jQuery设计的宗旨是“write Less，Do More”，即倡导写更少的代码，做更多的事情。它封装JavaScript常用的功能代码，提供一种简便的JavaScript设计模式，优化HTML文档操作、事件处理、动画设计和Ajax交互。</span><br><span class="line"></span><br><span class="line">* JavaScript框架：本质上就是一些js文件，封装了js的原生代码而已</span><br><span class="line">2. 快速入门</span><br><span class="line">1. 步骤：</span><br><span class="line">1. 下载JQuery</span><br><span class="line">* 目前jQuery有三个大版本：</span><br><span class="line">1.x：兼容ie678,使用最为广泛的，官方只做BUG维护，</span><br><span class="line"> 功能不再新增。因此一般项目来说，使用1.x版本就可以了，</span><br><span class="line"> 最终版本：1.12.4 (2016年5月20日)</span><br><span class="line">2.x：不兼容ie678，很少有人使用，官方只做BUG维护，</span><br><span class="line"> 功能不再新增。如果不考虑兼容低版本的浏览器可以使用2.x，</span><br><span class="line"> 最终版本：2.2.4 (2016年5月20日)</span><br><span class="line">3.x：不兼容ie678，只支持最新的浏览器。除非特殊要求，</span><br><span class="line"> 一般不会使用3.x版本的，很多老的jQuery插件不支持这个版本。</span><br><span class="line"> 目前该版本是官方主要更新维护的版本。最新版本：3.2.1（2017年3月20日）</span><br><span class="line">* jquery-xxx.js 与 jquery-xxx.min.js区别：</span><br><span class="line">1. jquery-xxx.js：开发版本。给程序员看的，有良好的缩进和注释。体积大一些</span><br><span class="line">2. jquery-xxx.min.js：生产版本。程序中使用，没有缩进。体积小一些。程序加载更快</span><br><span class="line"></span><br><span class="line">2. 导入JQuery的js文件：导入min.js文件</span><br><span class="line">3. 使用</span><br><span class="line">var div1 = $(&quot;#div1&quot;);</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">3. JQuery对象和JS对象区别与转换</span><br><span class="line">1. JQuery对象在操作时，更加方便。</span><br><span class="line">    2. JQuery对象和js对象方法不通用的.</span><br><span class="line">    3. 两者相互转换</span><br><span class="line">        * jq -- &gt; js : jq对象[索引] 或者 jq对象.get(索引)</span><br><span class="line">        * js -- &gt; jq : $(js对象)</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">4. 选择器：筛选具有相似特征的元素(标签)</span><br><span class="line"></span><br><span class="line">1. 基本操作学习：</span><br><span class="line">1. 事件绑定</span><br><span class="line">//1.获取b1按钮</span><br><span class="line">            $(&quot;#b1&quot;).click(function()&#123;</span><br><span class="line">                alert(&quot;abc&quot;);</span><br><span class="line">            &#125;);</span><br><span class="line">2. 入口函数</span><br><span class="line"> $(function () &#123;</span><br><span class="line">           </span><br><span class="line">    &#125;);</span><br><span class="line"> window.onload  和 $(function) 区别</span><br><span class="line">                 * window.onload 只能定义一次,如果定义多次，后边的会将前边的覆盖掉</span><br><span class="line">                 * $(function)可以定义多次的。</span><br><span class="line">3. 样式控制：css方法</span><br><span class="line"> // $(&quot;#div1&quot;).css(&quot;background-color&quot;,&quot;red&quot;);</span><br><span class="line">      $(&quot;#div1&quot;).css(&quot;backgroundColor&quot;,&quot;pink&quot;);</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line">2. 分类</span><br><span class="line">1. 基本选择器</span><br><span class="line">1. 标签选择器（元素选择器）</span><br><span class="line">* 语法： $(&quot;html标签名&quot;) 获得所有匹配标签名称的元素</span><br><span class="line">2. id选择器 </span><br><span class="line">* 语法： $(&quot;#id的属性值&quot;) 获得与指定id属性值匹配的元素</span><br><span class="line">3. 类选择器</span><br><span class="line">* 语法： $(&quot;.class的属性值&quot;) 获得与指定的class属性值匹配的元素</span><br><span class="line">4. 并集选择器：</span><br><span class="line">* 语法： $(&quot;选择器1,选择器2....&quot;) 获取多个选择器选中的所有元素</span><br><span class="line">2. 层级选择器</span><br><span class="line">1. 后代选择器</span><br><span class="line">* 语法： $(&quot;A B &quot;) 选择A元素内部的所有B元素</span><br><span class="line">2. 子选择器</span><br><span class="line">* 语法： $(&quot;A &gt; B&quot;) 选择A元素内部的所有B子元素</span><br><span class="line">3. 属性选择器</span><br><span class="line">1. 属性名称选择器 </span><br><span class="line">* 语法： $(&quot;A[属性名]&quot;) 包含指定属性的选择器</span><br><span class="line">2. 属性选择器</span><br><span class="line">* 语法： $(&quot;A[属性名=&apos;值&apos;]&quot;) 包含指定属性等于指定值的选择器</span><br><span class="line">3. 复合属性选择器</span><br><span class="line">* 语法： $(&quot;A[属性名=&apos;值&apos;][]...&quot;) 包含多个属性条件的选择器</span><br><span class="line">4. 过滤选择器</span><br><span class="line">1. 首元素选择器 </span><br><span class="line">* 语法： :first 获得选择的元素中的第一个元素</span><br><span class="line">2. 尾元素选择器 </span><br><span class="line">* 语法： :last 获得选择的元素中的最后一个元素</span><br><span class="line">3. 非元素选择器</span><br><span class="line">* 语法： :not(selector) 不包括指定内容的元素</span><br><span class="line">4. 偶数选择器</span><br><span class="line">* 语法： :even 偶数，从 0 开始计数</span><br><span class="line">5. 奇数选择器</span><br><span class="line">* 语法： :odd 奇数，从 0 开始计数</span><br><span class="line">6. 等于索引选择器</span><br><span class="line">* 语法： :eq(index) 指定索引元素</span><br><span class="line">7. 大于索引选择器 </span><br><span class="line">* 语法： :gt(index) 大于指定索引元素</span><br><span class="line">8. 小于索引选择器 </span><br><span class="line">* 语法： :lt(index) 小于指定索引元素</span><br><span class="line">9. 标题选择器</span><br><span class="line">* 语法： :header 获得标题（h1~h6）元素，固定写法</span><br><span class="line">5. 表单过滤选择器</span><br><span class="line">1. 可用元素选择器 </span><br><span class="line">* 语法： :enabled 获得可用元素</span><br><span class="line">2. 不可用元素选择器 </span><br><span class="line">* 语法： :disabled 获得不可用元素</span><br><span class="line">3. 选中选择器 </span><br><span class="line">* 语法： :checked 获得单选/复选框选中的元素</span><br><span class="line">4. 选中选择器 </span><br><span class="line">* 语法： :selected 获得下拉框选中的元素</span><br><span class="line"></span><br><span class="line">5. DOM操作</span><br><span class="line">1. 内容操作</span><br><span class="line">1. html(): 获取/设置元素的标签体内容   &lt;a&gt;&lt;font&gt;内容&lt;/font&gt;&lt;/a&gt;  --&gt; &lt;font&gt;内容&lt;/font&gt;</span><br><span class="line">2. text(): 获取/设置元素的标签体纯文本内容   &lt;a&gt;&lt;font&gt;内容&lt;/font&gt;&lt;/a&gt; --&gt; 内容</span><br><span class="line">3. val()： 获取/设置元素的value属性值</span><br><span class="line">2. 属性操作</span><br><span class="line">1. 通用属性操作</span><br><span class="line">1. attr(): 获取/设置元素的属性</span><br><span class="line">2. removeAttr():删除属性</span><br><span class="line">3. prop():获取/设置元素的属性</span><br><span class="line">4. removeProp():删除属性</span><br><span class="line"></span><br><span class="line">* attr和prop区别？</span><br><span class="line">1. 如果操作的是元素的固有属性，则建议使用prop</span><br><span class="line">2. 如果操作的是元素自定义的属性，则建议使用attr</span><br><span class="line">2. 对class属性操作</span><br><span class="line">1. addClass():添加class属性值</span><br><span class="line">2. removeClass():删除class属性值</span><br><span class="line">3. toggleClass():切换class属性</span><br><span class="line">* toggleClass(&quot;one&quot;): </span><br><span class="line">* 判断如果元素对象上存在class=&quot;one&quot;，则将属性值one删除掉。  如果元素对象上不存在class=&quot;one&quot;，则添加</span><br><span class="line">4. css():</span><br><span class="line">3. CRUD操作:</span><br><span class="line">1. append():父元素将子元素追加到末尾</span><br><span class="line">* 对象1.append(对象2): 将对象2添加到对象1元素内部，并且在末尾</span><br><span class="line">2. prepend():父元素将子元素追加到开头</span><br><span class="line">* 对象1.prepend(对象2):将对象2添加到对象1元素内部，并且在开头</span><br><span class="line">3. appendTo():</span><br><span class="line">* 对象1.appendTo(对象2):将对象1添加到对象2内部，并且在末尾</span><br><span class="line">4. prependTo()：</span><br><span class="line">* 对象1.prependTo(对象2):将对象1添加到对象2内部，并且在开头</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">5. after():添加元素到元素后边</span><br><span class="line">* 对象1.after(对象2)： 将对象2添加到对象1后边。对象1和对象2是兄弟关系</span><br><span class="line">6. before():添加元素到元素前边</span><br><span class="line">* 对象1.before(对象2)： 将对象2添加到对象1前边。对象1和对象2是兄弟关系</span><br><span class="line">7. insertAfter()</span><br><span class="line">* 对象1.insertAfter(对象2)：将对象2添加到对象1后边。对象1和对象2是兄弟关系</span><br><span class="line">8. insertBefore()</span><br><span class="line">* 对象1.insertBefore(对象2)： 将对象2添加到对象1前边。对象1和对象2是兄弟关系</span><br><span class="line"></span><br><span class="line">9. remove():移除元素</span><br><span class="line">* 对象.remove():将对象删除掉</span><br><span class="line">10. empty():清空元素的所有后代元素。</span><br><span class="line">* 对象.empty():将对象的后代元素全部清空，但是保留当前对象以及其属性节点</span><br></pre></td></tr></table></figure><h2 id="2-jQuery高级"><a href="#2-jQuery高级" class="headerlink" title="2. jQuery高级"></a>2. jQuery高级</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1. 动画</span><br><span class="line">1. 三种方式显示和隐藏元素</span><br><span class="line">1. 默认显示和隐藏方式</span><br><span class="line">1. show([speed,[easing],[fn]])</span><br><span class="line">1. 参数：</span><br><span class="line">1. speed：动画的速度。三个预定义的值(&quot;slow&quot;,&quot;normal&quot;, &quot;fast&quot;)或表示动画时长的毫秒数值(如：1000)</span><br><span class="line">2. easing：用来指定切换效果，默认是&quot;swing&quot;，可用参数&quot;linear&quot;</span><br><span class="line">* swing：动画执行时效果是 先慢，中间快，最后又慢</span><br><span class="line">* linear：动画执行时速度是匀速的</span><br><span class="line">3. fn：在动画完成时执行的函数，每个元素执行一次。</span><br><span class="line"></span><br><span class="line">2. hide([speed,[easing],[fn]])</span><br><span class="line">3. toggle([speed],[easing],[fn])</span><br><span class="line"></span><br><span class="line">2. 滑动显示和隐藏方式</span><br><span class="line">1. slideDown([speed],[easing],[fn])</span><br><span class="line">2. slideUp([speed,[easing],[fn]])</span><br><span class="line">3. slideToggle([speed],[easing],[fn])</span><br><span class="line"></span><br><span class="line">3. 淡入淡出显示和隐藏方式</span><br><span class="line">1. fadeIn([speed],[easing],[fn])</span><br><span class="line">2. fadeOut([speed],[easing],[fn])</span><br><span class="line">3. fadeToggle([speed,[easing],[fn]])</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">2. 遍历</span><br><span class="line">1. js的遍历方式</span><br><span class="line">* for(初始化值;循环结束条件;步长)</span><br><span class="line">2. jq的遍历方式</span><br><span class="line">1. jq对象.each(callback)</span><br><span class="line">1. 语法：</span><br><span class="line">jquery对象.each(function(index,element)&#123;&#125;);</span><br><span class="line">* index:就是元素在集合中的索引</span><br><span class="line">* element：就是集合中的每一个元素对象</span><br><span class="line"></span><br><span class="line">* this：集合中的每一个元素对象</span><br><span class="line">2. 回调函数返回值：</span><br><span class="line">* true:如果当前function返回为false，则结束循环(break)。</span><br><span class="line">* false:如果当前function返回为true，则结束本次循环，继续下次循环(continue)</span><br><span class="line">2. $.each(object, [callback])</span><br><span class="line">3. for..of: jquery 3.0 版本之后提供的方式</span><br><span class="line">for(元素对象 of 容器对象)</span><br><span class="line"></span><br><span class="line">3. 事件绑定</span><br><span class="line">1. jquery标准的绑定方式</span><br><span class="line">* jq对象.事件方法(回调函数)；</span><br><span class="line">* 注：如果调用事件方法，不传递回调函数，则会触发浏览器默认行为。</span><br><span class="line">* 表单对象.submit();//让表单提交</span><br><span class="line">2. on绑定事件/off解除绑定</span><br><span class="line">* jq对象.on(&quot;事件名称&quot;,回调函数)</span><br><span class="line">* jq对象.off(&quot;事件名称&quot;)</span><br><span class="line">* 如果off方法不传递任何参数，则将组件上的所有事件全部解绑</span><br><span class="line">3. 事件切换：toggle</span><br><span class="line">* jq对象.toggle(fn1,fn2...)</span><br><span class="line">* 当单击jq对象对应的组件后，会执行fn1.第二次点击会执行fn2.....</span><br><span class="line"></span><br><span class="line">* 注意：1.9版本 .toggle() 方法删除,jQuery Migrate（迁移）插件可以恢复此功能。</span><br><span class="line"> &lt;script src=&quot;../js/jquery-migrate-1.0.0.js&quot; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">4. 案例</span><br><span class="line">1. 广告显示和隐藏</span><br><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">    &lt;meta charset=&quot;UTF-8&quot;&gt;</span><br><span class="line">    &lt;title&gt;广告的自动显示与隐藏&lt;/title&gt;</span><br><span class="line">    &lt;style&gt;</span><br><span class="line">        #content&#123;width:100%;height:500px;background:#999&#125;</span><br><span class="line">    &lt;/style&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!--引入jquery--&gt;</span><br><span class="line">    &lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery-3.3.1.min.js&quot;&gt;&lt;/script&gt;</span><br><span class="line">    &lt;script&gt;</span><br><span class="line">        /*</span><br><span class="line">            需求：</span><br><span class="line">                1. 当页面加载完，3秒后。自动显示广告</span><br><span class="line">                2. 广告显示5秒后，自动消失。</span><br><span class="line"></span><br><span class="line">            分析：</span><br><span class="line">                1. 使用定时器来完成。setTimeout (执行一次定时器)</span><br><span class="line">                2. 分析发现JQuery的显示和隐藏动画效果其实就是控制display</span><br><span class="line">                3. 使用  show/hide方法来完成广告的显示</span><br><span class="line">         */</span><br><span class="line"></span><br><span class="line">        //入口函数，在页面加载完成之后，定义定时器，调用这两个方法</span><br><span class="line">        $(function () &#123;</span><br><span class="line">           //定义定时器，调用adShow方法 3秒后执行一次</span><br><span class="line">           setTimeout(adShow,3000);</span><br><span class="line">           //定义定时器，调用adHide方法，8秒后执行一次</span><br><span class="line">            setTimeout(adHide,8000);</span><br><span class="line">        &#125;);</span><br><span class="line">        //显示广告</span><br><span class="line">        function adShow() &#123;</span><br><span class="line">            //获取广告div，调用显示方法</span><br><span class="line">            $(&quot;#ad&quot;).show(&quot;slow&quot;);</span><br><span class="line">        &#125;</span><br><span class="line">        //隐藏广告</span><br><span class="line">        function adHide() &#123;</span><br><span class="line">            //获取广告div，调用隐藏方法</span><br><span class="line">            $(&quot;#ad&quot;).hide(&quot;slow&quot;);</span><br><span class="line">        &#125;</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">    &lt;/script&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">&lt;!-- 整体的DIV --&gt;</span><br><span class="line">&lt;div&gt;</span><br><span class="line">    &lt;!-- 广告DIV --&gt;</span><br><span class="line">    &lt;div id=&quot;ad&quot; style=&quot;display: none;&quot;&gt;</span><br><span class="line">        &lt;img style=&quot;width:100%&quot; src=&quot;../img/adv.jpg&quot; /&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- 下方正文部分 --&gt;</span><br><span class="line">    &lt;div id=&quot;content&quot;&gt;</span><br><span class="line">        正文部分</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">2. 抽奖</span><br><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">    &lt;meta charset=&quot;UTF-8&quot;&gt;</span><br><span class="line">    &lt;title&gt;jquery案例之抽奖&lt;/title&gt;</span><br><span class="line">    &lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery-3.3.1.min.js&quot;&gt;&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">    &lt;script language=&apos;javascript&apos; type=&apos;text/javascript&apos;&gt;</span><br><span class="line"></span><br><span class="line">        /*</span><br><span class="line">            分析：</span><br><span class="line">                1. 给开始按钮绑定单击事件</span><br><span class="line">                    1.1 定义循环定时器</span><br><span class="line">                    1.2 切换小相框的src属性</span><br><span class="line">                        * 定义数组，存放图片资源路径</span><br><span class="line">                        * 生成随机数。数组索引</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">        2. 给结束按钮绑定单击事件</span><br><span class="line">            1.1 停止定时器</span><br><span class="line">            1.2 给大相框设置src属性</span><br><span class="line"></span><br><span class="line"> */</span><br><span class="line">var imgs = [&quot;../img/man00.jpg&quot;,</span><br><span class="line">            &quot;../img/man01.jpg&quot;,</span><br><span class="line">            &quot;../img/man02.jpg&quot;,</span><br><span class="line">            &quot;../img/man03.jpg&quot;,</span><br><span class="line">            &quot;../img/man04.jpg&quot;,</span><br><span class="line">            &quot;../img/man05.jpg&quot;,</span><br><span class="line">            &quot;../img/man06.jpg&quot;,</span><br><span class="line">            ];</span><br><span class="line">var startId;//开始定时器的id</span><br><span class="line">var index;//随机角标</span><br><span class="line">$(function () &#123;</span><br><span class="line">    //处理按钮是否可以使用的效果</span><br><span class="line">    $(&quot;#startID&quot;).prop(&quot;disabled&quot;,false);</span><br><span class="line">    $(&quot;#stopID&quot;).prop(&quot;disabled&quot;,true);</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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. 给开始按钮绑定单击事件</span><br><span class="line"> $(&quot;#startID&quot;).click(function () &#123;</span><br><span class="line">     // 1.1 定义循环定时器 20毫秒执行一次</span><br><span class="line">     startId = setInterval(function () &#123;</span><br><span class="line">         //处理按钮是否可以使用的效果</span><br><span class="line">         $(&quot;#startID&quot;).prop(&quot;disabled&quot;,true);</span><br><span class="line">         $(&quot;#stopID&quot;).prop(&quot;disabled&quot;,false);</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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.2生成随机角标 0-6</span><br><span class="line">        index = Math.floor(Math.random() * 7);//0.000--0.999 --&gt; * 7 --&gt; 0.0-----6.9999</span><br><span class="line">        //1.3设置小相框的src属性</span><br><span class="line">        $(&quot;#img1ID&quot;).prop(&quot;src&quot;,imgs[index]);</span><br><span class="line"></span><br><span class="line">    &#125;,20);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">//2. 给结束按钮绑定单击事件</span><br><span class="line">$(&quot;#stopID&quot;).click(function () &#123;</span><br><span class="line">    //处理按钮是否可以使用的效果</span><br><span class="line">    $(&quot;#startID&quot;).prop(&quot;disabled&quot;,false);</span><br><span class="line">    $(&quot;#stopID&quot;).prop(&quot;disabled&quot;,true);</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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.1 停止定时器</span><br><span class="line">        clearInterval(startId);</span><br><span class="line">       // 1.2 给大相框设置src属性</span><br><span class="line">        $(&quot;#img2ID&quot;).prop(&quot;src&quot;,imgs[index]).hide();</span><br><span class="line">        //显示1秒之后</span><br><span class="line">        $(&quot;#img2ID&quot;).show(1000);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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></pre></td><td class="code"><pre><span class="line">    &lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- 小像框 --&gt;</span><br><span class="line">&lt;div style=&quot;border-style:dotted;width:160px;height:100px&quot;&gt;</span><br><span class="line">    &lt;img id=&quot;img1ID&quot; src=&quot;../img/man00.jpg&quot; style=&quot;width:160px;height:100px&quot;/&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- 大像框 --&gt;</span><br><span class="line">&lt;div</span><br><span class="line">        style=&quot;border-style:double;width:800px;height:500px;position:absolute;left:500px;top:10px&quot;&gt;</span><br><span class="line">    &lt;img id=&quot;img2ID&quot; src=&quot;../img/man00.jpg&quot; width=&quot;800px&quot; height=&quot;500px&quot;/&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- 开始按钮 --&gt;</span><br><span class="line">&lt;input</span><br><span class="line">        id=&quot;startID&quot;</span><br><span class="line">        type=&quot;button&quot;</span><br><span class="line">        value=&quot;点击开始&quot;</span><br><span class="line">        style=&quot;width:150px;height:150px;font-size:22px&quot;&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- 停止按钮 --&gt;</span><br><span class="line">&lt;input</span><br><span class="line">        id=&quot;stopID&quot;</span><br><span class="line">        type=&quot;button&quot;</span><br><span class="line">        value=&quot;点击停止&quot;</span><br><span class="line">        style=&quot;width:150px;height:150px;font-size:22px&quot;&gt;</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br><span class="line"></span><br><span class="line">5. 插件：增强JQuery的功能</span><br><span class="line">1. 实现方式：</span><br><span class="line">1. $.fn.extend(object) </span><br><span class="line">* 增强通过Jquery获取的对象的功能  $(&quot;#id&quot;)</span><br><span class="line">2. $.extend(object)</span><br><span class="line">* 增强JQeury对象自身的功能  $/jQuery</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;一、HTML&quot;&gt;&lt;a href=&quot;#一、HTML&quot; class=&quot;headerlink&quot; title=&quot;一、HTML&quot;&gt;&lt;/a&gt;一、HTML&lt;/h1&gt;&lt;h2 id=&quot;1-概念&quot;&gt;&lt;a href=&quot;#1-概念&quot; class=&quot;headerlink&quot; title=&quot;1
      
    
    </summary>
    
      <category term="HTML&amp;CSS&amp;jQuery" scheme="http://yoursite.com/categories/HTML-CSS-jQuery/"/>
    
    
      <category term="HTML&amp;CSS&amp;jQuery" scheme="http://yoursite.com/tags/HTML-CSS-jQuery/"/>
    
  </entry>
  
  <entry>
    <title>AJAX&amp;JSON</title>
    <link href="http://yoursite.com/2019/08/08/AJAX&amp;JSON/"/>
    <id>http://yoursite.com/2019/08/08/AJAX&amp;JSON/</id>
    <published>2019-08-07T17:05:18.218Z</published>
    <updated>2019-08-07T17:34:41.525Z</updated>
    
    <content type="html"><![CDATA[<h1 id="AJAX："><a href="#AJAX：" class="headerlink" title="AJAX："></a>AJAX：</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><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><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br></pre></td><td class="code"><pre><span class="line">1. 概念： ASynchronous JavaScript And XML异步的JavaScript 和 XML</span><br><span class="line">1. 异步和同步：客户端和服务器端相互通信的基础上</span><br><span class="line">* 客户端必须等待服务器端的响应。在等待的期间客户端不能做其他操作。</span><br><span class="line">* 客户端不需要等待服务器端的响应。在服务器处理请求的过程中，客户端可以进行其他的操作。</span><br><span class="line"></span><br><span class="line">Ajax 是一种在无需重新加载整个网页的情况下，能够更新部分网页的技术。 [1] </span><br><span class="line">通过在后台与服务器进行少量数据交换，Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下，对网页的某部分进行更新。</span><br><span class="line">传统的网页（不使用 Ajax）如果需要更新内容，必须重载整个网页页面。</span><br><span class="line"></span><br><span class="line">提升用户的体验</span><br><span class="line"></span><br><span class="line">2. 实现方式：</span><br><span class="line">1. 原生的JS实现方式（了解）</span><br><span class="line"> //1.创建核心对象</span><br><span class="line">            var xmlhttp;</span><br><span class="line">            if (window.XMLHttpRequest)</span><br><span class="line">            &#123;// code for IE7+, Firefox, Chrome, Opera, Safari</span><br><span class="line">                xmlhttp=new XMLHttpRequest();</span><br><span class="line">            &#125;</span><br><span class="line">            else</span><br><span class="line">            &#123;// code for IE6, IE5</span><br><span class="line">                xmlhttp=new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            //2. 建立连接</span><br><span class="line">            /*</span><br><span class="line">                参数：</span><br><span class="line">                    1. 请求方式：GET、POST</span><br><span class="line">                        * get方式，请求参数在URL后边拼接。send方法为空参</span><br><span class="line">                        * post方式，请求参数在send方法中定义</span><br><span class="line">                    2. 请求的URL：</span><br><span class="line">                    3. 同步或异步请求：true（异步）或 false（同步）</span><br><span class="line"></span><br><span class="line">             */</span><br><span class="line">            xmlhttp.open(&quot;GET&quot;,&quot;ajaxServlet?username=tom&quot;,true);</span><br><span class="line"></span><br><span class="line">            //3.发送请求</span><br><span class="line">            xmlhttp.send();</span><br><span class="line"></span><br><span class="line">            //4.接受并处理来自服务器的响应结果</span><br><span class="line">            //获取方式 ：xmlhttp.responseText</span><br><span class="line">            //什么时候获取？当服务器响应成功后再获取</span><br><span class="line"></span><br><span class="line">            //当xmlhttp对象的就绪状态改变时，触发事件onreadystatechange。</span><br><span class="line">            xmlhttp.onreadystatechange=function()</span><br><span class="line">            &#123;</span><br><span class="line">                //判断readyState就绪状态是否为4，判断status响应状态码是否为200</span><br><span class="line">                if (xmlhttp.readyState==4 &amp;&amp; xmlhttp.status==200)</span><br><span class="line">                &#123;</span><br><span class="line">                   //获取服务器的响应结果</span><br><span class="line">                    var responseText = xmlhttp.responseText;</span><br><span class="line">                    alert(responseText);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">2. JQeury实现方式</span><br><span class="line">1. $.ajax()</span><br><span class="line">* 语法：$.ajax(&#123;键值对&#125;);</span><br><span class="line"> //使用$.ajax()发送异步请求</span><br><span class="line">            $.ajax(&#123;</span><br><span class="line">                url:&quot;ajaxServlet1111&quot; , // 请求路径</span><br><span class="line">                type:&quot;POST&quot; , //请求方式</span><br><span class="line">                //data: &quot;username=jack&amp;age=23&quot;,//请求参数</span><br><span class="line">                data:&#123;&quot;username&quot;:&quot;jack&quot;,&quot;age&quot;:23&#125;,</span><br><span class="line">                success:function (data) &#123;</span><br><span class="line">                    alert(data);</span><br><span class="line">                &#125;,//响应成功后的回调函数</span><br><span class="line">                error:function () &#123;</span><br><span class="line">                    alert(&quot;出错啦...&quot;)</span><br><span class="line">                &#125;,//表示如果请求响应出现错误，会执行的回调函数</span><br><span class="line"></span><br><span class="line">                dataType:&quot;text&quot;//设置接受到的响应数据的格式</span><br><span class="line">            &#125;);</span><br><span class="line">2. $.get()：发送get请求</span><br><span class="line">* 语法：$.get(url, [data], [callback], [type])</span><br><span class="line">* 参数：</span><br><span class="line">* url：请求路径</span><br><span class="line">* data：请求参数</span><br><span class="line">* callback：回调函数</span><br><span class="line">* type：响应结果的类型</span><br><span class="line"></span><br><span class="line">3. $.post()：发送post请求</span><br><span class="line">* 语法：$.post(url, [data], [callback], [type])</span><br><span class="line">* 参数：</span><br><span class="line">* url：请求路径</span><br><span class="line">* data：请求参数</span><br><span class="line">* callback：回调函数</span><br><span class="line">* type：响应结果的类型</span><br></pre></td></tr></table></figure><h1 id="JSON："><a href="#JSON：" class="headerlink" title="JSON："></a>JSON：</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1. 概念： JavaScript Object NotationJavaScript对象表示法</span><br><span class="line">Person p = new Person();</span><br><span class="line">p.setName(&quot;张三&quot;);</span><br><span class="line">p.setAge(23);</span><br><span class="line">p.setGender(&quot;男&quot;);</span><br><span class="line"></span><br><span class="line">var p = &#123;&quot;name&quot;:&quot;张三&quot;,&quot;age&quot;:23,&quot;gender&quot;:&quot;男&quot;&#125;;</span><br><span class="line"></span><br><span class="line">* json现在多用于存储和交换文本信息的语法</span><br><span class="line">* 进行数据的传输</span><br><span class="line">* JSON 比 XML 更小、更快，更易解析。</span><br><span class="line"></span><br><span class="line">2. 语法：</span><br><span class="line">1. 基本规则</span><br><span class="line">* 数据在名称/值对中：json数据是由键值对构成的</span><br><span class="line">* 键用引号(单双都行)引起来，也可以不使用引号</span><br><span class="line">* 值得取值类型：</span><br><span class="line">1. 数字（整数或浮点数）</span><br><span class="line">2. 字符串（在双引号中）</span><br><span class="line">3. 逻辑值（true 或 false）</span><br><span class="line">4. 数组（在方括号中）&#123;&quot;persons&quot;:[&#123;&#125;,&#123;&#125;]&#125;</span><br><span class="line">5. 对象（在花括号中） &#123;&quot;address&quot;:&#123;&quot;province&quot;：&quot;陕西&quot;....&#125;&#125;</span><br><span class="line">6. null</span><br><span class="line">* 数据由逗号分隔：多个键值对由逗号分隔</span><br><span class="line">* 花括号保存对象：使用&#123;&#125;定义json 格式</span><br><span class="line">* 方括号保存数组：[]</span><br><span class="line">2. 获取数据:</span><br><span class="line">1. json对象.键名</span><br><span class="line">2. json对象[&quot;键名&quot;]</span><br><span class="line">3. 数组对象[索引]</span><br><span class="line">4. 遍历</span><br><span class="line"> //1.定义基本格式</span><br><span class="line">        var person = &#123;&quot;name&quot;: &quot;张三&quot;, age: 23, &apos;gender&apos;: true&#125;;</span><br><span class="line"></span><br><span class="line">        var ps = [&#123;&quot;name&quot;: &quot;张三&quot;, &quot;age&quot;: 23, &quot;gender&quot;: true&#125;,</span><br><span class="line">            &#123;&quot;name&quot;: &quot;李四&quot;, &quot;age&quot;: 24, &quot;gender&quot;: true&#125;,</span><br><span class="line">            &#123;&quot;name&quot;: &quot;王五&quot;, &quot;age&quot;: 25, &quot;gender&quot;: false&#125;];</span><br></pre></td></tr></table></figure><p>​<br>​<br>​            </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><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"> //获取person对象中所有的键和值</span><br><span class="line"> //for in 循环</span><br><span class="line">/* for(var key in person)&#123;</span><br><span class="line">     //这样的方式获取不行。因为相当于  person.&quot;name&quot;</span><br><span class="line">     //alert(key + &quot;:&quot; + person.key);</span><br><span class="line">     alert(key+&quot;:&quot;+person[key]);</span><br><span class="line"> &#125;*/</span><br><span class="line"></span><br><span class="line">//获取ps中的所有值</span><br><span class="line"> for (var i = 0; i &lt; ps.length; i++) &#123;</span><br><span class="line">     var p = ps[i];</span><br><span class="line">     for(var key in p)&#123;</span><br><span class="line">         alert(key+&quot;:&quot;+p[key]);</span><br><span class="line">     &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">3. JSON数据和Java对象的相互转换</span><br><span class="line"></span><br><span class="line">* JSON解析器：</span><br><span class="line">* 常见的解析器：Jsonlib，Gson，fastjson，jackson</span><br><span class="line"></span><br><span class="line">1. JSON转为Java对象</span><br><span class="line">1. 导入jackson的相关jar包</span><br><span class="line">2. 创建Jackson核心对象 ObjectMapper</span><br><span class="line">3. 调用ObjectMapper的相关方法进行转换</span><br><span class="line">1. readValue(json字符串数据,Class)</span><br><span class="line">2. Java对象转换JSON</span><br><span class="line">1. 使用步骤：</span><br><span class="line">1. 导入jackson的相关jar包</span><br><span class="line">2. 创建Jackson核心对象 ObjectMapper</span><br><span class="line">3. 调用ObjectMapper的相关方法进行转换</span><br><span class="line">1. 转换方法：</span><br><span class="line">* writeValue(参数1，obj):</span><br><span class="line">                    参数1：</span><br><span class="line">                        File：将obj对象转换为JSON字符串，并保存到指定的文件中</span><br><span class="line">                        Writer：将obj对象转换为JSON字符串，并将json数据填充到字符输出流中</span><br><span class="line">                        OutputStream：将obj对象转换为JSON字符串，并将json数据填充到字节输出流中</span><br><span class="line">                * writeValueAsString(obj):将对象转为json字符串</span><br><span class="line"></span><br><span class="line">2. 注解：</span><br><span class="line">1. @JsonIgnore：排除属性。</span><br><span class="line">2. @JsonFormat：属性值得格式化</span><br><span class="line">* @JsonFormat(pattern = &quot;yyyy-MM-dd&quot;)</span><br><span class="line"></span><br><span class="line">3. 复杂java对象转换</span><br><span class="line">1. List：数组</span><br><span class="line">2. Map：对象格式一致</span><br></pre></td></tr></table></figure><h1 id="案例："><a href="#案例：" class="headerlink" title="案例："></a>案例：</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1. 服务器响应的数据，在客户端使用时，要想当做json数据格式使用。有两种解决方案：</span><br><span class="line">1. $.get(type):将最后一个参数type指定为&quot;json&quot;</span><br><span class="line">2. 在服务器端设置MIME类型</span><br><span class="line">response.setContentType(&quot;application/json;charset=utf-8&quot;);</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;AJAX：&quot;&gt;&lt;a href=&quot;#AJAX：&quot; class=&quot;headerlink&quot; title=&quot;AJAX：&quot;&gt;&lt;/a&gt;AJAX：&lt;/h1&gt;&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;
      
    
    </summary>
    
      <category term="AJAX&amp;JSON" scheme="http://yoursite.com/categories/AJAX-JSON/"/>
    
    
      <category term="AJAX&amp;JSON" scheme="http://yoursite.com/tags/AJAX-JSON/"/>
    
  </entry>
  
  <entry>
    <title>SpringBoot相关知识</title>
    <link href="http://yoursite.com/2019/08/08/SpringBoot%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/"/>
    <id>http://yoursite.com/2019/08/08/SpringBoot相关知识/</id>
    <published>2019-08-07T16:43:46.748Z</published>
    <updated>2019-08-07T17:31:08.796Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、SpringBoot简介"><a href="#一、SpringBoot简介" class="headerlink" title="一、SpringBoot简介"></a>一、SpringBoot简介</h1><h2 id="1-1-原有Spring优缺点分析"><a href="#1-1-原有Spring优缺点分析" class="headerlink" title="1.1 原有Spring优缺点分析"></a>1.1 原有Spring优缺点分析</h2><h3 id="1-1-1-Spring的优点分析"><a href="#1-1-1-Spring的优点分析" class="headerlink" title="1.1.1 Spring的优点分析"></a>1.1.1 Spring的优点分析</h3><p>Spring是java企业版（Java Enterprise Edition，JEE，也称为J2EE）的轻量级替代品。无需开发重量级的Enterprise JavaBean（EJB），Spring为企业级Java开发提供了一种相对简单的方法，通过依赖注入（IoC）和面向切面编程（AOP），用简单的Java对象（Plain Old Java Object，POJO）实现EJB的功能。</p><h3 id="1-1-2-Spring的缺点分析"><a href="#1-1-2-Spring的缺点分析" class="headerlink" title="1.1.2 Spring的缺点分析"></a>1.1.2 Spring的缺点分析</h3><p>虽然Spring的组件代码是轻量级的，但它的配置却是重量级的。一开始，Spring用XML配置，而且是很多XML配置。Spring 2.5引入了基于注解的组件扫描，这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了基于Java的配置，这是一种类型安全的可重构配置方式，可以代替XML。</p><p>所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换，所以编写配置挤占了编写应用程序逻辑的时间。和所有框架一样，Spring实用，但与此同时它要求的回报也不少。</p><p>除此之外，项目的依赖管理也是一件耗时耗力的事情。在环境搭建时，需要分析要导入哪些库的坐标，而且还需要分析导入与之有依赖关系的其他库的坐标，一旦选错了依赖的版本，随之而来的不兼容问题就会严重阻碍项目的开发进度。</p><h2 id="1-2-SpringBoot的概述"><a href="#1-2-SpringBoot的概述" class="headerlink" title="1.2 SpringBoot的概述"></a>1.2 SpringBoot的概述</h2><h3 id="1-2-1-SpringBoot解决上述Spring的缺点"><a href="#1-2-1-SpringBoot解决上述Spring的缺点" class="headerlink" title="1.2.1 SpringBoot解决上述Spring的缺点"></a>1.2.1 SpringBoot解决上述Spring的缺点</h3><p>SpringBoot对上述Spring的缺点进行的改善和优化，基于约定优于配置的思想，可以让开发人员不必在配置与逻辑业务之间进行思维的切换，全身心的投入到逻辑业务的代码编程中，从而大大提高了开发的效率，一定程度上缩短了项目的周期。</p><h3 id="1-2-2-SpringBoot的特点"><a href="#1-2-2-SpringBoot的特点" class="headerlink" title="1.2.2 SpringBoot的特点"></a>1.2.2 SpringBoot的特点</h3><ul><li>为基于Spring的开发提供更快的入门体验</li><li>开箱即用，没有代码生成，与无需XML配置。同时也可以修改默认值来满足特点的需求</li><li>提供了一些大型项目中常见的非功能特性，如嵌入式服务器、安全、指标，健康体侧、外部配置等</li><li>SpringBoot不是Spring功能上的增强，而是提供了一种快速使用Spring的方式</li></ul><h3 id="1-2-3-SpringBoot的核心功能"><a href="#1-2-3-SpringBoot的核心功能" class="headerlink" title="1.2.3 SpringBoot的核心功能"></a>1.2.3 SpringBoot的核心功能</h3><ul><li><p>起步依赖</p><p>起步依赖本质上是一个Maven项目对象模型（Project Object Model，POM），定义了对其他库的传递依赖，这些东西加在一起即支持某项功能。</p><p>简单的说，起步依赖就是将具备某种功能的坐标打包到一起，并提供一些默认的功能。</p></li><li><p>自动配置</p><p>Spring Boot的自动配置是一个运行时（更准确地说，是应用程序启动时）的过程，考虑了众多因素，才决定Spring配置应该用哪个，不该用哪个。该过程是Spring自动完成的。</p></li></ul><h1 id="二、SpringBoot原理分析"><a href="#二、SpringBoot原理分析" class="headerlink" title="二、SpringBoot原理分析"></a>二、SpringBoot原理分析</h1><h2 id="2-1-起步依赖原理分析"><a href="#2-1-起步依赖原理分析" class="headerlink" title="2.1 起步依赖原理分析"></a>2.1 起步依赖原理分析</h2><h3 id="2-1-1-分析spring-boot-starter-parent"><a href="#2-1-1-分析spring-boot-starter-parent" class="headerlink" title="2.1.1 分析spring-boot-starter-parent"></a>2.1.1 分析spring-boot-starter-parent</h3><p>spring-boot-starter-parent的pom.xml，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></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-dependencies<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">relativePath</span>&gt;</span>../../spring-boot-dependencies<span class="tag">&lt;/<span class="name">relativePath</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br></pre></td></tr></table></figure><p>spring-boot-starter-dependencies的pom.xml，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><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></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">properties</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">activemq.version</span>&gt;</span>5.15.3<span class="tag">&lt;/<span class="name">activemq.version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">antlr2.version</span>&gt;</span>2.7.7<span class="tag">&lt;/<span class="name">antlr2.version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">appengine-sdk.version</span>&gt;</span>1.9.63<span class="tag">&lt;/<span class="name">appengine-sdk.version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">artemis.version</span>&gt;</span>2.4.0<span class="tag">&lt;/<span class="name">artemis.version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">aspectj.version</span>&gt;</span>1.8.13<span class="tag">&lt;/<span class="name">aspectj.version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">assertj.version</span>&gt;</span>3.9.1<span class="tag">&lt;/<span class="name">assertj.version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">atomikos.version</span>&gt;</span>4.0.6<span class="tag">&lt;/<span class="name">atomikos.version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bitronix.version</span>&gt;</span>2.1.4<span class="tag">&lt;/<span class="name">bitronix.version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">build-helper-maven-plugin.version</span>&gt;</span>3.0.0<span class="tag">&lt;/<span class="name">build-helper-maven-plugin.version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">byte-buddy.version</span>&gt;</span>1.7.11<span class="tag">&lt;/<span class="name">byte-buddy.version</span>&gt;</span></span><br><span class="line">  ... ... ...</span><br><span class="line"><span class="tag">&lt;/<span class="name">properties</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-test<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">      ... ... ...</span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">build</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">pluginManagement</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">plugins</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.jetbrains.kotlin<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>kotlin-maven-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;kotlin.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.jooq<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jooq-codegen-maven<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;jooq.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-maven-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">          ... ... ...</span><br><span class="line">    <span class="tag">&lt;/<span class="name">plugins</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">pluginManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">build</span>&gt;</span></span><br></pre></td></tr></table></figure><p>从上面的spring-boot-starter-dependencies的pom.xml中我们可以发现，一部分坐标的版本、依赖管理、插件管理已经定义好，所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了。所以起步依赖的作用就是进行依赖的传递。</p><h3 id="2-1-2-分析spring-boot-starter-web"><a href="#2-1-2-分析spring-boot-starter-web" class="headerlink" title="2.1.2 分析spring-boot-starter-web"></a>2.1.2 分析spring-boot-starter-web</h3><p>spring-boot-starter-web的pom.xml，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><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="meta">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span> <span class="attr">xmlns</span>=<span class="string">"http://maven.apache.org/POM/4.0.0"</span></span></span><br><span class="line"><span class="tag">    <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">modelVersion</span>&gt;</span>4.0.0<span class="tag">&lt;/<span class="name">modelVersion</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starters<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">name</span>&gt;</span>Spring Boot Web Starter<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line">  </span><br><span class="line">  <span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">scope</span>&gt;</span>compile<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-json<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">scope</span>&gt;</span>compile<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-tomcat<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">scope</span>&gt;</span>compile<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.hibernate.validator<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>hibernate-validator<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">version</span>&gt;</span>6.0.9.Final<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">scope</span>&gt;</span>compile<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-web<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.0.5.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">scope</span>&gt;</span>compile<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-webmvc<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.0.5.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">scope</span>&gt;</span>compile<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">project</span>&gt;</span></span><br></pre></td></tr></table></figure><p>从上面的spring-boot-starter-web的pom.xml中我们可以发现，spring-boot-starter-web就是将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”，这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了，同样体现了依赖传递的作用。</p><h2 id="2-2-自动配置原理解析"><a href="#2-2-自动配置原理解析" class="headerlink" title="2.2 自动配置原理解析"></a>2.2 自动配置原理解析</h2><p>按住Ctrl点击查看启动类MySpringBootApplication上的注解@SpringBootApplication</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">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MySpringBootApplication</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        SpringApplication.run(MySpringBootApplication.class);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>注解@SpringBootApplication的源码</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="meta">@Target</span>(ElementType.TYPE)</span><br><span class="line"><span class="meta">@Retention</span>(RetentionPolicy.RUNTIME)</span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="meta">@Inherited</span></span><br><span class="line"><span class="meta">@SpringBootConfiguration</span></span><br><span class="line"><span class="meta">@EnableAutoConfiguration</span></span><br><span class="line"><span class="meta">@ComponentScan</span>(excludeFilters = &#123;</span><br><span class="line"><span class="meta">@Filter</span>(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),</span><br><span class="line"><span class="meta">@Filter</span>(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) &#125;)</span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> SpringBootApplication &#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Exclude specific auto-configuration classes such that they will never be applied.</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> the classes to exclude</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@AliasFor</span>(annotation = EnableAutoConfiguration.class)</span><br><span class="line">Class&lt;?&gt;[] exclude() <span class="keyword">default</span> &#123;&#125;;</span><br><span class="line"></span><br><span class="line">... ... ...</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>其中，</p><p>@SpringBootConfiguration：等同与@Configuration，既标注该类是Spring的一个配置类</p><p>@EnableAutoConfiguration：SpringBoot自动配置功能开启</p><p>按住Ctrl点击查看注解@EnableAutoConfiguration</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">@Target</span>(ElementType.TYPE)</span><br><span class="line"><span class="meta">@Retention</span>(RetentionPolicy.RUNTIME)</span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="meta">@Inherited</span></span><br><span class="line"><span class="meta">@AutoConfigurationPackage</span></span><br><span class="line"><span class="meta">@Import</span>(AutoConfigurationImportSelector.class)</span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> EnableAutoConfiguration &#123;</span><br><span class="line">... ... ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>其中，@Import(AutoConfigurationImportSelector.class) 导入了AutoConfigurationImportSelector类</p><p>按住Ctrl点击查看AutoConfigurationImportSelector源码</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> String[] selectImports(AnnotationMetadata annotationMetadata) &#123;</span><br><span class="line">        ... ... ...</span><br><span class="line">        List&lt;String&gt; configurations = getCandidateConfigurations(annotationMetadata,</span><br><span class="line">                                                                   attributes);</span><br><span class="line">        configurations = removeDuplicates(configurations);</span><br><span class="line">        Set&lt;String&gt; exclusions = getExclusions(annotationMetadata, attributes);</span><br><span class="line">        checkExcludedClasses(configurations, exclusions);</span><br><span class="line">        configurations.removeAll(exclusions);</span><br><span class="line">        configurations = filter(configurations, autoConfigurationMetadata);</span><br><span class="line">        fireAutoConfigurationImportEvents(configurations, exclusions);</span><br><span class="line">        <span class="keyword">return</span> StringUtils.toStringArray(configurations);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> List&lt;String&gt; <span class="title">getCandidateConfigurations</span><span class="params">(AnnotationMetadata metadata,</span></span></span><br><span class="line"><span class="function"><span class="params">AnnotationAttributes attributes)</span> </span>&#123;</span><br><span class="line">List&lt;String&gt; configurations = SpringFactoriesLoader.loadFactoryNames(</span><br><span class="line">getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> configurations;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>其中，SpringFactoriesLoader.loadFactoryNames 方法的作用就是从META-INF/spring.factories文件中读取指定类对应的类名称列表 </p><p><img src="G:/%E9%BB%91%E9%A9%AC%E5%BF%85%E7%9C%8B%E8%A7%86%E9%A2%91/%E8%AE%B2%E4%B9%89+%E7%AC%94%E8%AE%B0+%E8%B5%84%E6%96%99/%E6%B5%81%E8%A1%8C%E6%A1%86%E6%9E%B6/63.%E4%BC%9A%E5%91%98%E7%89%88(2.0)-%E5%B0%B1%E4%B8%9A%E8%AF%BE(2.0)-Spring%20Boot/SpringBoot%E5%9F%BA%E7%A1%80/%E8%AE%B2%E4%B9%89(md,pdf)/img/11.png" alt></p><p>spring.factories 文件中有关自动配置的配置信息如下：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><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"></span><br><span class="line">org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\</span><br><span class="line">org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\</span><br><span class="line">org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\</span><br><span class="line">org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\</span><br><span class="line">org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\</span><br><span class="line">org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\</span><br><span class="line"></span><br><span class="line">... ... ...</span><br></pre></td></tr></table></figure><p>上面配置文件存在大量的以Configuration为结尾的类名称，这些类就是存有自动配置信息的类，而SpringApplication在获取这些类名后再加载</p><p>我们以ServletWebServerFactoryAutoConfiguration为例来分析源码：</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@AutoConfigureOrder</span>(Ordered.HIGHEST_PRECEDENCE)</span><br><span class="line"><span class="meta">@ConditionalOnClass</span>(ServletRequest.class)</span><br><span class="line"><span class="meta">@ConditionalOnWebApplication</span>(type = Type.SERVLET)</span><br><span class="line"><span class="meta">@EnableConfigurationProperties</span>(ServerProperties.class)</span><br><span class="line"><span class="meta">@Import</span>(&#123; ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,</span><br><span class="line">ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,</span><br><span class="line">ServletWebServerFactoryConfiguration.EmbeddedJetty.class,</span><br><span class="line">ServletWebServerFactoryConfiguration.EmbeddedUndertow.class &#125;)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ServletWebServerFactoryAutoConfiguration</span> </span>&#123;</span><br><span class="line">... ... ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>其中，</p><p>@EnableConfigurationProperties(ServerProperties.class) 代表加载ServerProperties服务器配置属性类</p><p>进入ServerProperties.class源码如下：</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">@ConfigurationProperties</span>(prefix = <span class="string">"server"</span>, ignoreUnknownFields = <span class="keyword">true</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ServerProperties</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Server HTTP port.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">private</span> Integer port;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Network address to which the server should bind.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">private</span> InetAddress address;</span><br><span class="line">  </span><br><span class="line">  ... ... ...</span><br><span class="line">  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>其中，</p><p>prefix = “server” 表示SpringBoot配置文件中的前缀，SpringBoot会将配置文件中以server开始的属性映射到该类的字段中。映射关系如下：</p><p><img src="G:/%E9%BB%91%E9%A9%AC%E5%BF%85%E7%9C%8B%E8%A7%86%E9%A2%91/%E8%AE%B2%E4%B9%89+%E7%AC%94%E8%AE%B0+%E8%B5%84%E6%96%99/%E6%B5%81%E8%A1%8C%E6%A1%86%E6%9E%B6/63.%E4%BC%9A%E5%91%98%E7%89%88(2.0)-%E5%B0%B1%E4%B8%9A%E8%AF%BE(2.0)-Spring%20Boot/SpringBoot%E5%9F%BA%E7%A1%80/%E8%AE%B2%E4%B9%89(md,pdf)/img/12.png" alt></p><h1 id="三、SpringBoot的配置文件"><a href="#三、SpringBoot的配置文件" class="headerlink" title="三、SpringBoot的配置文件"></a>三、SpringBoot的配置文件</h1><h2 id="3-1-SpringBoot配置文件类型"><a href="#3-1-SpringBoot配置文件类型" class="headerlink" title="3.1 SpringBoot配置文件类型"></a>3.1 SpringBoot配置文件类型</h2><h3 id="3-1-1-SpringBoot配置文件类型和作用"><a href="#3-1-1-SpringBoot配置文件类型和作用" class="headerlink" title="3.1.1 SpringBoot配置文件类型和作用"></a>3.1.1 SpringBoot配置文件类型和作用</h3><p>SpringBoot是基于约定的，所以很多配置都有默认值，但如果想使用自己的配置替换默认配置的话，就可以使用application.properties或者application.yml（application.yaml）进行配置。</p><p>SpringBoot默认会从Resources目录下加载application.properties或application.yml（application.yaml）文件</p><p>其中，application.properties文件是键值对类型的文件，之前一直在使用，所以此处不在对properties文件的格式进行阐述。除了properties文件外，SpringBoot还可以使用yml文件进行配置，下面对yml文件进行讲解。</p><h3 id="3-1-2-application-yml配置文件"><a href="#3-1-2-application-yml配置文件" class="headerlink" title="3.1.2 application.yml配置文件"></a>3.1.2 application.yml配置文件</h3><h4 id="3-1-2-1-yml配置文件简介"><a href="#3-1-2-1-yml配置文件简介" class="headerlink" title="3.1.2.1 yml配置文件简介"></a>3.1.2.1 yml配置文件简介</h4><p>YML文件格式是YAML (YAML Aint Markup Language)编写的文件格式，YAML是一种直观的能够被电脑识别的的数据数据序列化格式，并且容易被人类阅读，容易和脚本语言交互的，可以被支持YAML库的不同的编程语言程序导入，比如： C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的，比传统的xml方式更加简洁。</p><p>YML文件的扩展名可以使用.yml或者.yaml。</p><h4 id="3-1-2-2-yml配置文件的语法"><a href="#3-1-2-2-yml配置文件的语法" class="headerlink" title="3.1.2.2 yml配置文件的语法"></a>3.1.2.2 yml配置文件的语法</h4><h5 id="3-1-2-2-1-配置普通数据"><a href="#3-1-2-2-1-配置普通数据" class="headerlink" title="3.1.2.2.1  配置普通数据"></a>3.1.2.2.1  配置普通数据</h5><ul><li><p>语法： key: value</p></li><li><p>示例代码：</p></li><li><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">haohao</span></span><br></pre></td></tr></table></figure></li><li><p>注意：value之前有一个空格</p></li></ul><h5 id="3-1-2-2-2-配置对象数据"><a href="#3-1-2-2-2-配置对象数据" class="headerlink" title="3.1.2.2.2  配置对象数据"></a>3.1.2.2.2  配置对象数据</h5><ul><li><p>语法： </p><p>​    key: </p><p>​        key1: value1</p><p>​        key2: value2</p><p>​    或者：</p><p>​    key: {key1: value1,key2: value2}</p></li><li><p>示例代码：</p></li><li><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">person:</span></span><br><span class="line"><span class="attr">  name:</span> <span class="string">haohao</span></span><br><span class="line"><span class="attr">  age:</span> <span class="number">31</span></span><br><span class="line"><span class="attr">  addr:</span> <span class="string">beijing</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#或者</span></span><br><span class="line"></span><br><span class="line"><span class="attr">person:</span> <span class="string">&#123;name:</span> <span class="string">haohao,age:</span> <span class="number">31</span><span class="string">,addr:</span> <span class="string">beijing&#125;</span></span><br></pre></td></tr></table></figure></li><li><p>注意：key1前面的空格个数不限定，在yml语法中，相同缩进代表同一个级别</p></li></ul><h5 id="3-1-2-2-2-配置Map数据"><a href="#3-1-2-2-2-配置Map数据" class="headerlink" title="3.1.2.2.2  配置Map数据"></a>3.1.2.2.2  配置Map数据</h5><p>同上面的对象写法</p><h5 id="3-1-2-2-3-配置数组（List、Set）数据"><a href="#3-1-2-2-3-配置数组（List、Set）数据" class="headerlink" title="3.1.2.2.3  配置数组（List、Set）数据"></a>3.1.2.2.3  配置数组（List、Set）数据</h5><ul><li><p>语法： </p><p>​    key: </p><p>​        - value1</p><p>​        - value2</p><p>或者：</p><p>​    key: [value1,value2]</p></li><li><p>示例代码：</p></li><li><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><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="attr">city:</span></span><br><span class="line"><span class="bullet">  -</span> <span class="string">beijing</span></span><br><span class="line"><span class="bullet">  -</span> <span class="string">tianjin</span></span><br><span class="line"><span class="bullet">  -</span> <span class="string">shanghai</span></span><br><span class="line"><span class="bullet">  -</span> <span class="string">chongqing</span></span><br><span class="line">  </span><br><span class="line"><span class="comment">#或者</span></span><br><span class="line"></span><br><span class="line"><span class="attr">city:</span> <span class="string">[beijing,tianjin,shanghai,chongqing]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#集合中的元素是对象形式</span></span><br><span class="line"><span class="attr">student:</span></span><br><span class="line"><span class="attr">  - name:</span> <span class="string">zhangsan</span></span><br><span class="line"><span class="attr">    age:</span> <span class="number">18</span></span><br><span class="line"><span class="attr">    score:</span> <span class="number">100</span></span><br><span class="line"><span class="attr">  - name:</span> <span class="string">lisi</span></span><br><span class="line"><span class="attr">    age:</span> <span class="number">28</span></span><br><span class="line"><span class="attr">    score:</span> <span class="number">88</span></span><br><span class="line"><span class="attr">  - name:</span> <span class="string">wangwu</span></span><br><span class="line"><span class="attr">    age:</span> <span class="number">38</span></span><br><span class="line"><span class="attr">    score:</span> <span class="number">90</span></span><br></pre></td></tr></table></figure></li><li><p>注意：value1与之间的 - 之间存在一个空格</p></li></ul><h3 id="3-1-3-SpringBoot配置信息的查询"><a href="#3-1-3-SpringBoot配置信息的查询" class="headerlink" title="3.1.3 SpringBoot配置信息的查询"></a>3.1.3 SpringBoot配置信息的查询</h3><p>上面提及过，SpringBoot的配置文件，主要的目的就是对配置信息进行修改的，但在配置时的key从哪里去查询呢？我们可以查阅SpringBoot的官方文档</p><p>文档URL：<a href="https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#common-application-properties" target="_blank" rel="noopener">https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#common-application-properties</a></p><p>常用的配置摘抄如下：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><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></pre></td><td class="code"><pre><span class="line"># QUARTZ SCHEDULER (QuartzProperties)</span><br><span class="line">spring.quartz.jdbc.initialize-schema=embedded # Database schema initialization mode.</span><br><span class="line">spring.quartz.jdbc.schema=classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.sql # Path to the SQL file to use to initialize the database schema.</span><br><span class="line">spring.quartz.job-store-type=memory # Quartz job store type.</span><br><span class="line">spring.quartz.properties.*= # Additional Quartz Scheduler properties.</span><br><span class="line"></span><br><span class="line"># ----------------------------------------</span><br><span class="line"># WEB PROPERTIES</span><br><span class="line"># ----------------------------------------</span><br><span class="line"></span><br><span class="line"># EMBEDDED SERVER CONFIGURATION (ServerProperties)</span><br><span class="line">server.port=8080 # Server HTTP port.</span><br><span class="line">server.servlet.context-path= # Context path of the application.</span><br><span class="line">server.servlet.path=/ # Path of the main dispatcher servlet.</span><br><span class="line"></span><br><span class="line"># HTTP encoding (HttpEncodingProperties)</span><br><span class="line">spring.http.encoding.charset=UTF-8 # Charset of HTTP requests and responses. Added to the &quot;Content-Type&quot; header if not set explicitly.</span><br><span class="line"></span><br><span class="line"># JACKSON (JacksonProperties)</span><br><span class="line">spring.jackson.date-format= # Date format string or a fully-qualified date format class name. For instance, `yyyy-MM-dd HH:mm:ss`.</span><br><span class="line"></span><br><span class="line"># SPRING MVC (WebMvcProperties)</span><br><span class="line">spring.mvc.servlet.load-on-startup=-1 # Load on startup priority of the dispatcher servlet.</span><br><span class="line">spring.mvc.static-path-pattern=/** # Path pattern used for static resources.</span><br><span class="line">spring.mvc.view.prefix= # Spring MVC view prefix.</span><br><span class="line">spring.mvc.view.suffix= # Spring MVC view suffix.</span><br><span class="line"></span><br><span class="line"># DATASOURCE (DataSourceAutoConfiguration &amp; DataSourceProperties)</span><br><span class="line">spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.</span><br><span class="line">spring.datasource.password= # Login password of the database.</span><br><span class="line">spring.datasource.url= # JDBC URL of the database.</span><br><span class="line">spring.datasource.username= # Login username of the database.</span><br><span class="line"></span><br><span class="line"># JEST (Elasticsearch HTTP client) (JestProperties)</span><br><span class="line">spring.elasticsearch.jest.password= # Login password.</span><br><span class="line">spring.elasticsearch.jest.proxy.host= # Proxy host the HTTP client should use.</span><br><span class="line">spring.elasticsearch.jest.proxy.port= # Proxy port the HTTP client should use.</span><br><span class="line">spring.elasticsearch.jest.read-timeout=3s # Read timeout.</span><br><span class="line">spring.elasticsearch.jest.username= # Login username.</span><br></pre></td></tr></table></figure><p>我们可以通过配置application.poperties 或者 application.yml 来修改SpringBoot的默认配置</p><p>例如：</p><p>application.properties文件</p><figure class="highlight plain"><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">server.port=8888</span><br><span class="line">server.servlet.context-path=demo</span><br></pre></td></tr></table></figure><p>application.yml文件</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></pre></td><td class="code"><pre><span class="line"><span class="attr">server:</span></span><br><span class="line"><span class="attr">  port:</span> <span class="number">8888</span></span><br><span class="line"><span class="attr">  servlet:</span></span><br><span class="line"><span class="attr">    context-path:</span> <span class="string">/demo</span></span><br></pre></td></tr></table></figure><h2 id="3-2-配置文件与配置类的属性映射方式"><a href="#3-2-配置文件与配置类的属性映射方式" class="headerlink" title="3.2 配置文件与配置类的属性映射方式"></a>3.2 配置文件与配置类的属性映射方式</h2><h3 id="3-2-1-使用注解-Value映射"><a href="#3-2-1-使用注解-Value映射" class="headerlink" title="3.2.1 使用注解@Value映射"></a>3.2.1 使用注解@Value映射</h3><p>我们可以通过@Value注解将配置文件中的值映射到一个Spring管理的Bean的字段上</p><p>例如：</p><p>application.properties配置如下：</p><figure class="highlight plain"><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">person:</span><br><span class="line">  name: zhangsan</span><br><span class="line">  age: 18</span><br></pre></td></tr></table></figure><p>或者，application.yml配置如下：</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></pre></td><td class="code"><pre><span class="line"><span class="attr">person:</span></span><br><span class="line"><span class="attr">  name:</span> <span class="string">zhangsan</span></span><br><span class="line"><span class="attr">  age:</span> <span class="number">18</span></span><br></pre></td></tr></table></figure><p>实体Bean代码如下：</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">@Controller</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">QuickStartController</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"$&#123;person.name&#125;"</span>)</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"$&#123;person.age&#125;"</span>)</span><br><span class="line">    <span class="keyword">private</span> Integer age;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="meta">@RequestMapping</span>(<span class="string">"/quick"</span>)</span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">quick</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"springboot 访问成功! name="</span>+name+<span class="string">",age="</span>+age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="3-2-2-使用注解-ConfigurationProperties映射"><a href="#3-2-2-使用注解-ConfigurationProperties映射" class="headerlink" title="3.2.2 使用注解@ConfigurationProperties映射"></a>3.2.2 使用注解@ConfigurationProperties映射</h3><p>通过注解@ConfigurationProperties(prefix=”配置文件中的key的前缀”)可以将配置文件中的配置自动与实体进行映射</p><p>application.properties配置如下：</p><figure class="highlight plain"><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">person:</span><br><span class="line">  name: zhangsan</span><br><span class="line">  age: 18</span><br></pre></td></tr></table></figure><p>或者，application.yml配置如下：</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></pre></td><td class="code"><pre><span class="line"><span class="attr">person:</span></span><br><span class="line"><span class="attr">  name:</span> <span class="string">zhangsan</span></span><br><span class="line"><span class="attr">  age:</span> <span class="number">18</span></span><br></pre></td></tr></table></figure><p>实体Bean代码如下：</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="meta">@Controller</span></span><br><span class="line"><span class="meta">@ConfigurationProperties</span>(prefix = <span class="string">"person"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">QuickStartController</span> </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> Integer age;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@RequestMapping</span>(<span class="string">"/quick"</span>)</span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">quick</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"springboot 访问成功! name="</span>+name+<span class="string">",age="</span>+age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAge</span><span class="params">(Integer age)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.age = age;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>注意：使用@ConfigurationProperties方式可以进行配置文件与实体字段的自动映射，但需要字段必须提供set方法才可以，而使用@Value注解修饰的字段不需要提供set方法</p><h1 id="四、SpringBoot与整合其他技术"><a href="#四、SpringBoot与整合其他技术" class="headerlink" title="四、SpringBoot与整合其他技术"></a>四、SpringBoot与整合其他技术</h1><h2 id="4-1-SpringBoot整合Mybatis"><a href="#4-1-SpringBoot整合Mybatis" class="headerlink" title="4.1 SpringBoot整合Mybatis"></a>4.1 SpringBoot整合Mybatis</h2><h3 id="4-1-1-添加Mybatis的起步依赖"><a href="#4-1-1-添加Mybatis的起步依赖" class="headerlink" title="4.1.1 添加Mybatis的起步依赖"></a>4.1.1 添加Mybatis的起步依赖</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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--mybatis起步依赖--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.mybatis.spring.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>mybatis-spring-boot-starter<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.1.1<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="4-1-2-添加数据库驱动坐标"><a href="#4-1-2-添加数据库驱动坐标" class="headerlink" title="4.1.2 添加数据库驱动坐标"></a>4.1.2 添加数据库驱动坐标</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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- MySQL连接驱动 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>mysql<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>mysql-connector-java<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="4-1-3-添加数据库连接信息"><a href="#4-1-3-添加数据库连接信息" class="headerlink" title="4.1.3 添加数据库连接信息"></a>4.1.3 添加数据库连接信息</h3><p>在application.properties中添加数据量的连接信息</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">#DB Configuration:</span><br><span class="line">spring.datasource.driverClassName=com.mysql.jdbc.Driver</span><br><span class="line">spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&amp;characterEncoding=utf8</span><br><span class="line">spring.datasource.username=root</span><br><span class="line">spring.datasource.password=root</span><br></pre></td></tr></table></figure><h3 id="4-1-4-创建user表"><a href="#4-1-4-创建user表" class="headerlink" title="4.1.4 创建user表"></a>4.1.4 创建user表</h3><p>在test数据库中创建user表</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><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">-- ----------------------------</span></span><br><span class="line"><span class="comment">-- Table structure for `user`</span></span><br><span class="line"><span class="comment">-- ----------------------------</span></span><br><span class="line"><span class="keyword">DROP</span> <span class="keyword">TABLE</span> <span class="keyword">IF</span> <span class="keyword">EXISTS</span> <span class="string">`user`</span>;</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> <span class="string">`user`</span> (</span><br><span class="line">  <span class="string">`id`</span> <span class="built_in">int</span>(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> AUTO_INCREMENT,</span><br><span class="line">  <span class="string">`username`</span> <span class="built_in">varchar</span>(<span class="number">50</span>) <span class="keyword">DEFAULT</span> <span class="literal">NULL</span>,</span><br><span class="line">  <span class="string">`password`</span> <span class="built_in">varchar</span>(<span class="number">50</span>) <span class="keyword">DEFAULT</span> <span class="literal">NULL</span>,</span><br><span class="line">  <span class="string">`name`</span> <span class="built_in">varchar</span>(<span class="number">50</span>) <span class="keyword">DEFAULT</span> <span class="literal">NULL</span>,</span><br><span class="line">  PRIMARY <span class="keyword">KEY</span> (<span class="string">`id`</span>)</span><br><span class="line">) <span class="keyword">ENGINE</span>=<span class="keyword">InnoDB</span> AUTO_INCREMENT=<span class="number">10</span> <span class="keyword">DEFAULT</span> <span class="keyword">CHARSET</span>=utf8;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- ----------------------------</span></span><br><span class="line"><span class="comment">-- Records of user</span></span><br><span class="line"><span class="comment">-- ----------------------------</span></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="string">`user`</span> <span class="keyword">VALUES</span> (<span class="string">'1'</span>, <span class="string">'zhangsan'</span>, <span class="string">'123'</span>, <span class="string">'张三'</span>);</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="string">`user`</span> <span class="keyword">VALUES</span> (<span class="string">'2'</span>, <span class="string">'lisi'</span>, <span class="string">'123'</span>, <span class="string">'李四'</span>);</span><br></pre></td></tr></table></figure><h3 id="4-1-5-创建实体Bean"><a href="#4-1-5-创建实体Bean" class="headerlink" title="4.1.5 创建实体Bean"></a>4.1.5 创建实体Bean</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 主键</span></span><br><span class="line">    <span class="keyword">private</span> Long id;</span><br><span class="line">    <span class="comment">// 用户名</span></span><br><span class="line">    <span class="keyword">private</span> String username;</span><br><span class="line">    <span class="comment">// 密码</span></span><br><span class="line">    <span class="keyword">private</span> String password;</span><br><span class="line">    <span class="comment">// 姓名</span></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">  </span><br><span class="line">    <span class="comment">//此处省略getter和setter方法 .. ..</span></span><br><span class="line">    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="4-1-6-编写Mapper"><a href="#4-1-6-编写Mapper" class="headerlink" title="4.1.6 编写Mapper"></a>4.1.6 编写Mapper</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Mapper</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">UserMapper</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;User&gt; <span class="title">queryUserList</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>注意：@Mapper标记该类是一个mybatis的mapper接口，可以被spring boot自动扫描到spring上下文中</p><h3 id="4-1-7-配置Mapper映射文件"><a href="#4-1-7-配置Mapper映射文件" class="headerlink" title="4.1.7 配置Mapper映射文件"></a>4.1.7 配置Mapper映射文件</h3><p>在src\main\resources\mapper路径下加入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></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version="1.0" encoding="utf-8" ?&gt;</span></span><br><span class="line"><span class="meta">&lt;!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" &gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">mapper</span> <span class="attr">namespace</span>=<span class="string">"com.itheima.mapper.UserMapper"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">"queryUserList"</span> <span class="attr">resultType</span>=<span class="string">"user"</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><span class="line"><span class="tag">&lt;/<span class="name">mapper</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="4-1-8-在application-properties中添加mybatis的信息"><a href="#4-1-8-在application-properties中添加mybatis的信息" class="headerlink" title="4.1.8 在application.properties中添加mybatis的信息"></a>4.1.8 在application.properties中添加mybatis的信息</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">#spring集成Mybatis环境</span><br><span class="line">#pojo别名扫描包</span><br><span class="line">mybatis.type-aliases-package=com.itheima.domain</span><br><span class="line">#加载Mybatis映射文件</span><br><span class="line">mybatis.mapper-locations=classpath:mapper/*Mapper.xml</span><br></pre></td></tr></table></figure><h3 id="4-1-9-编写测试Controller"><a href="#4-1-9-编写测试Controller" class="headerlink" title="4.1.9 编写测试Controller"></a>4.1.9 编写测试Controller</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MapperController</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> UserMapper userMapper;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@RequestMapping</span>(<span class="string">"/queryUser"</span>)</span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> List&lt;User&gt; <span class="title">queryUser</span><span class="params">()</span></span>&#123;</span><br><span class="line">        List&lt;User&gt; users = userMapper.queryUserList();</span><br><span class="line">        <span class="keyword">return</span> users;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="4-2-SpringBoot整合Junit"><a href="#4-2-SpringBoot整合Junit" class="headerlink" title="4.2 SpringBoot整合Junit"></a>4.2 SpringBoot整合Junit</h2><h3 id="4-2-1-添加Junit的起步依赖"><a href="#4-2-1-添加Junit的起步依赖" class="headerlink" title="4.2.1 添加Junit的起步依赖"></a>4.2.1 添加Junit的起步依赖</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></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">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-test<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">scope</span>&gt;</span>test<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="4-2-2-编写测试类"><a href="#4-2-2-编写测试类" class="headerlink" title="4.2.2 编写测试类"></a>4.2.2 编写测试类</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.holicCode.test;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.holicCode.MySpringBootApplication;</span><br><span class="line"><span class="keyword">import</span> com.holicCode.domain.User;</span><br><span class="line"><span class="keyword">import</span> com.holicCode.mapper.UserMapper;</span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.junit.runner.RunWith;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.test.context.SpringBootTest;</span><br><span class="line"><span class="keyword">import</span> org.springframework.test.context.junit4.SpringRunner;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="meta">@RunWith</span>(SpringRunner.class)</span><br><span class="line"><span class="meta">@SpringBootTest</span>(classes = MySpringBootApplication.class)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MapperTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> UserMapper userMapper;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        List&lt;User&gt; users = userMapper.queryUserList();</span><br><span class="line">        System.out.println(users);</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>其中，</p><p>SpringRunner继承自SpringJUnit4ClassRunner，使用哪一个Spring提供的测试测试引擎都可以</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">public</span> <span class="keyword">final</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringRunner</span> <span class="keyword">extends</span> <span class="title">SpringJUnit4ClassRunner</span></span></span><br></pre></td></tr></table></figure><p>@SpringBootTest的属性指定的是引导类的字节码对象</p><h2 id="4-3-SpringBoot整合Spring-Data-JPA"><a href="#4-3-SpringBoot整合Spring-Data-JPA" class="headerlink" title="4.3 SpringBoot整合Spring Data JPA"></a>4.3 SpringBoot整合Spring Data JPA</h2><h3 id="4-3-1-添加Spring-Data-JPA的起步依赖"><a href="#4-3-1-添加Spring-Data-JPA的起步依赖" class="headerlink" title="4.3.1 添加Spring Data JPA的起步依赖"></a>4.3.1 添加Spring Data JPA的起步依赖</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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- springBoot JPA的起步依赖 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-data-jpa<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="4-3-2-添加数据库驱动依赖"><a href="#4-3-2-添加数据库驱动依赖" class="headerlink" title="4.3.2 添加数据库驱动依赖"></a>4.3.2 添加数据库驱动依赖</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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- MySQL连接驱动 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>mysql<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>mysql-connector-java<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="4-3-3-在application-properties中配置数据库和jpa的相关属性"><a href="#4-3-3-在application-properties中配置数据库和jpa的相关属性" class="headerlink" title="4.3.3 在application.properties中配置数据库和jpa的相关属性"></a>4.3.3 在application.properties中配置数据库和jpa的相关属性</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">#DB Configuration:</span><br><span class="line">spring.datasource.driverClassName=com.mysql.jdbc.Driver</span><br><span class="line">spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&amp;characterEncoding=utf8</span><br><span class="line">spring.datasource.username=root</span><br><span class="line">spring.datasource.password=root</span><br><span class="line"></span><br><span class="line">#JPA Configuration:</span><br><span class="line">spring.jpa.database=MySQL</span><br><span class="line">spring.jpa.show-sql=true</span><br><span class="line">spring.jpa.generate-ddl=true</span><br><span class="line">spring.jpa.hibernate.ddl-auto=update</span><br><span class="line">spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy</span><br></pre></td></tr></table></figure><h3 id="4-3-4-创建实体配置实体"><a href="#4-3-4-创建实体配置实体" class="headerlink" title="4.3.4 创建实体配置实体"></a>4.3.4 创建实体配置实体</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Entity</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 主键</span></span><br><span class="line">    <span class="meta">@Id</span></span><br><span class="line">    <span class="meta">@GeneratedValue</span>(strategy = GenerationType.IDENTITY)</span><br><span class="line">    <span class="keyword">private</span> Long id;</span><br><span class="line">    <span class="comment">// 用户名</span></span><br><span class="line">    <span class="keyword">private</span> String username;</span><br><span class="line">    <span class="comment">// 密码</span></span><br><span class="line">    <span class="keyword">private</span> String password;</span><br><span class="line">    <span class="comment">// 姓名</span></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"> </span><br><span class="line">    <span class="comment">//此处省略setter和getter方法... ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="4-3-5-编写UserRepository"><a href="#4-3-5-编写UserRepository" class="headerlink" title="4.3.5 编写UserRepository"></a>4.3.5 编写UserRepository</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">UserRepository</span> <span class="keyword">extends</span> <span class="title">JpaRepository</span>&lt;<span class="title">User</span>,<span class="title">Long</span>&gt;</span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> List&lt;User&gt; <span class="title">findAll</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="4-3-6-编写测试类"><a href="#4-3-6-编写测试类" class="headerlink" title="4.3.6 编写测试类"></a>4.3.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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RunWith</span>(SpringRunner.class)</span><br><span class="line"><span class="meta">@SpringBootTest</span>(classes=MySpringBootApplication.class)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JpaTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> UserRepository userRepository;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test</span><span class="params">()</span></span>&#123;</span><br><span class="line">        List&lt;User&gt; users = userRepository.findAll();</span><br><span class="line">        System.out.println(users);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="4-3-7-控制台打印信息"><a href="#4-3-7-控制台打印信息" class="headerlink" title="4.3.7 控制台打印信息"></a>4.3.7 控制台打印信息</h3><p>注意：如果是jdk9，执行报错如下：</p><p><img src="G:/%E9%BB%91%E9%A9%AC%E5%BF%85%E7%9C%8B%E8%A7%86%E9%A2%91/%E8%AE%B2%E4%B9%89+%E7%AC%94%E8%AE%B0+%E8%B5%84%E6%96%99/%E6%B5%81%E8%A1%8C%E6%A1%86%E6%9E%B6/63.%E4%BC%9A%E5%91%98%E7%89%88(2.0)-%E5%B0%B1%E4%B8%9A%E8%AF%BE(2.0)-Spring%20Boot/SpringBoot%E5%9F%BA%E7%A1%80/%E8%AE%B2%E4%B9%89(md,pdf)/img/17.png" alt></p><p>原因：jdk缺少相应的jar</p><p>解决方案：手动导入对应的maven坐标，如下：</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;!--jdk9需要导入如下坐标--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>javax.xml.bind<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jaxb-api<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.3.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="4-4-SpringBoot整合Redis"><a href="#4-4-SpringBoot整合Redis" class="headerlink" title="4.4 SpringBoot整合Redis"></a>4.4 SpringBoot整合Redis</h2><h3 id="4-4-1-添加redis的起步依赖"><a href="#4-4-1-添加redis的起步依赖" class="headerlink" title="4.4.1 添加redis的起步依赖"></a>4.4.1 添加redis的起步依赖</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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 配置使用redis启动器 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-data-redis<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="4-4-2-配置redis的连接信息"><a href="#4-4-2-配置redis的连接信息" class="headerlink" title="4.4.2 配置redis的连接信息"></a>4.4.2 配置redis的连接信息</h3><figure class="highlight plain"><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">#Redis</span><br><span class="line">spring.redis.host=127.0.0.1</span><br><span class="line">spring.redis.port=6379</span><br></pre></td></tr></table></figure><h3 id="4-4-3-注入RedisTemplate测试redis操作"><a href="#4-4-3-注入RedisTemplate测试redis操作" class="headerlink" title="4.4.3 注入RedisTemplate测试redis操作"></a>4.4.3 注入RedisTemplate测试redis操作</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RunWith</span>(SpringRunner.class)</span><br><span class="line"><span class="meta">@SpringBootTest</span>(classes = SpringbootJpaApplication.class)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> UserRepository userRepository;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> RedisTemplate&lt;String, String&gt; redisTemplate;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test</span><span class="params">()</span> <span class="keyword">throws</span> JsonProcessingException </span>&#123;</span><br><span class="line">        <span class="comment">//从redis缓存中获得指定的数据</span></span><br><span class="line">        String userListData = redisTemplate.boundValueOps(<span class="string">"user.findAll"</span>).get();</span><br><span class="line">        <span class="comment">//如果redis中没有数据的话</span></span><br><span class="line">        <span class="keyword">if</span>(<span class="keyword">null</span>==userListData)&#123;</span><br><span class="line">            <span class="comment">//查询数据库获得数据</span></span><br><span class="line">            List&lt;User&gt; all = userRepository.findAll();</span><br><span class="line">            <span class="comment">//转换成json格式字符串</span></span><br><span class="line">            ObjectMapper om = <span class="keyword">new</span> ObjectMapper();</span><br><span class="line">            userListData = om.writeValueAsString(all);</span><br><span class="line">            <span class="comment">//将数据存储到redis中，下次在查询直接从redis中获得数据，不用在查询数据库</span></span><br><span class="line">            redisTemplate.boundValueOps(<span class="string">"user.findAll"</span>).set(userListData);</span><br><span class="line">            System.out.println(<span class="string">"===============从数据库获得数据==============="</span>);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            System.out.println(<span class="string">"===============从redis缓存中获得数据==============="</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        System.out.println(userListData);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;一、SpringBoot简介&quot;&gt;&lt;a href=&quot;#一、SpringBoot简介&quot; class=&quot;headerlink&quot; title=&quot;一、SpringBoot简介&quot;&gt;&lt;/a&gt;一、SpringBoot简介&lt;/h1&gt;&lt;h2 id=&quot;1-1-原有Spring优缺点分析
      
    
    </summary>
    
      <category term="SpringBoot" scheme="http://yoursite.com/categories/SpringBoot/"/>
    
    
      <category term="SpringBoot" scheme="http://yoursite.com/tags/SpringBoot/"/>
    
  </entry>
  
  <entry>
    <title>Maven的相关知识</title>
    <link href="http://yoursite.com/2019/08/01/Maven%E7%9A%84%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/"/>
    <id>http://yoursite.com/2019/08/01/Maven的相关知识/</id>
    <published>2019-07-31T16:32:00.479Z</published>
    <updated>2019-07-31T16:32:00.776Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Maven的使用"><a href="#Maven的使用" class="headerlink" title="Maven的使用"></a>Maven的使用</h1><h2 id="什么是Maven"><a href="#什么是Maven" class="headerlink" title="什么是Maven?"></a>什么是Maven?</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Maven 是一个项目管理工具，它包含了一个项目对象模型 (POM：Project Object Model)，一组标准集合，一个项目生命周期(Project Lifecycle)，一个依赖管理系统(Dependency Management System)，和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。</span><br></pre></td></tr></table></figure><h2 id="Maven的作用"><a href="#Maven的作用" class="headerlink" title="Maven的作用"></a>Maven的作用</h2><h3 id="Maven的依赖管理"><a href="#Maven的依赖管理" class="headerlink" title="Maven的依赖管理"></a>Maven的依赖管理</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Maven 的一个核心特性就是依赖管理。当我们涉及到多模块的项目（包含成百个模块或者子项目），管理依赖就变成一项困难的任务。Maven 展示出了它对处理这种情形的高度控制。</span><br></pre></td></tr></table></figure><p><img src="C:%5CUsers%5C%E5%86%B7%E7%9E%B3%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1564589901277.png" alt="1564589901277"></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">maven 工程中不直接将 jar 包导入到工程中，而是通过在 pom.xml 文件中添加所需 jar包的坐标，这样就很好的避免了 jar 直接引入进来，在需要用到 jar 包的时候，只要查找 pom.xml 文件，再通过 pom.xml 文件中的坐标，到一个专门用于”存放 jar 包的仓库”(maven 仓库)中根据坐标从而找到这些 jar 包，再把这些 jar 包拿去运行。</span><br></pre></td></tr></table></figure><h3 id="项目的一键构建"><a href="#项目的一键构建" class="headerlink" title="项目的一键构建"></a>项目的一键构建</h3><figure class="highlight plain"><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">指的是项目从编译、测试、运行、打包、安装 ，部署整个过程都交给 maven 进行管理，这个过程称为构建。一键构建指的是整个构建过程，使用 maven 一个命令可以轻松完成整个工作。</span><br></pre></td></tr></table></figure><p><img src="C:%5CUsers%5C%E5%86%B7%E7%9E%B3%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1564590043915.png" alt="1564590043915"></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">通过 tomcat:run 的这个命令，我们发现现在的工程编译，测试，运行都变得非常简单。</span><br></pre></td></tr></table></figure><h2 id="Maven仓库"><a href="#Maven仓库" class="headerlink" title="Maven仓库"></a>Maven仓库</h2><h3 id="Maven仓库的分类"><a href="#Maven仓库的分类" class="headerlink" title="Maven仓库的分类"></a>Maven仓库的分类</h3><p><img src="C:%5CUsers%5C%E5%86%B7%E7%9E%B3%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1564590131948.png" alt="1564590131948"></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">本地仓库 ：用来存储从远程仓库或中央仓库下载的插件和 jar 包，项目使用一些插件或 jar 包，优先从本地仓库查找默认本地仓库位置在 $&#123;user.dir&#125;/.m2/repository，$&#123;user.dir&#125;表示 windows 用户目录。</span><br><span class="line"></span><br><span class="line">远程仓库：如果本地需要插件或者 jar 包，本地仓库没有，默认去远程仓库下载。远程仓库可以在互联网内也可以在局域网内。</span><br><span class="line"></span><br><span class="line">中央仓库 ：在 maven 软件中内置一个远程仓库地址 http://repo1.maven.org/maven2 ，它是中央仓库，服务于整个互联网，它是由 Maven 团队自己维护，里面存储了非常全的 jar 包，它包含了世界上大部分流行的开源项目构件。</span><br></pre></td></tr></table></figure><h2 id="Maven工程的认识"><a href="#Maven工程的认识" class="headerlink" title="Maven工程的认识"></a>Maven工程的认识</h2><h3 id="Maven工程的目录结构"><a href="#Maven工程的目录结构" class="headerlink" title="Maven工程的目录结构"></a>Maven工程的目录结构</h3><p><img src="C:%5CUsers%5C%E5%86%B7%E7%9E%B3%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1564590283084.png" alt="1564590283084"></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">作为一个 maven 工程，它的 src 目录和 pom.xml 是必备的。进入 src 目录后，我们发现它里面的目录结构如下：</span><br></pre></td></tr></table></figure><p><img src="C:%5CUsers%5C%E5%86%B7%E7%9E%B3%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1564590308664.png" alt="1564590308664"></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">src/main/java —— 存放项目的.java 文件</span><br><span class="line">src/main/resources —— 存放项目资源文件，如 spring, hibernate 配置文件</span><br><span class="line">src/test/java —— 存放所有单元测试.java 文件，如 JUnit 测试类</span><br><span class="line">src/test/resources —— 测试资源文件</span><br><span class="line">target —— 项目输出位置，编译后的 class 文件会输出到此目录</span><br><span class="line">pom.xml——maven 项目核心配置文件</span><br><span class="line">注意：如果是普通的 java 项目，那么就没有 webapp 目录。</span><br></pre></td></tr></table></figure><h3 id="Maven工程的运行"><a href="#Maven工程的运行" class="headerlink" title="Maven工程的运行"></a>Maven工程的运行</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">进入 maven 工程目录（当前目录有 pom.xml 文件），运行 tomcat:run 命令。</span><br></pre></td></tr></table></figure><h2 id="Maven常用命令"><a href="#Maven常用命令" class="headerlink" title="Maven常用命令"></a>Maven常用命令</h2><h3 id="compile"><a href="#compile" class="headerlink" title="compile"></a>compile</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">compile 是 maven 工程的编译命令，作用是将 src/main/java 下的文件编译为 class 文件输出到 target目录下。</span><br></pre></td></tr></table></figure><h3 id="test"><a href="#test" class="headerlink" title="test"></a>test</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">test 是 maven 工程的测试命令 mvn test，会执行 src/test/java 下的单元测试类。</span><br></pre></td></tr></table></figure><h3 id="clean"><a href="#clean" class="headerlink" title="clean"></a>clean</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">clean 是 maven 工程的清理命令，执行 clean 会删除 target 目录及内容。</span><br></pre></td></tr></table></figure><h3 id="package"><a href="#package" class="headerlink" title="package"></a>package</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">package 是 maven 工程的打包命令，对于 java 工程执行 package 打成 jar 包，对于 web 工程打成 war包。</span><br></pre></td></tr></table></figure><h3 id="install"><a href="#install" class="headerlink" title="install"></a>install</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">install 是 maven 工程的安装命令，执行 install 将 maven 打成 jar 包或 war 包发布到本地仓库。</span><br></pre></td></tr></table></figure><h3 id="Maven指令的生命周期"><a href="#Maven指令的生命周期" class="headerlink" title="Maven指令的生命周期"></a>Maven指令的生命周期</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">maven 对项目构建过程分为三套相互独立的生命周期，请注意这里说的是“三套”，而且“相互独立”，这三套生命周期分别是：</span><br><span class="line">Clean Lifecycle 在进行真正的构建之前进行一些清理工作。</span><br><span class="line">Default Lifecycle 构建的核心部分，编译，测试，打包，部署等等。</span><br><span class="line">Site Lifecycle 生成项目报告，站点，发布站点。</span><br></pre></td></tr></table></figure><h2 id="pom的基本配置"><a href="#pom的基本配置" class="headerlink" title="pom的基本配置"></a>pom的基本配置</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">pom.xml 是 Maven 项目的核心配置文件，位于每个工程的根目录，基本配置如下：</span><br><span class="line">&lt;project &gt; ：文件的根节点 .</span><br><span class="line">&lt;modelversion &gt; ： pom.xml 使用的对象模型版本</span><br><span class="line">&lt;groupId &gt; ：项目名称，一般写项目的域名</span><br><span class="line">&lt;artifactId &gt; ：模块名称，子项目名或模块名称</span><br><span class="line">&lt;version &gt; ：产品的版本号 .</span><br><span class="line">&lt;packaging &gt; ：打包类型，一般有 jar、war、pom 等</span><br><span class="line">&lt;name &gt; ：项目的显示名，常用于 Maven 生成的文档。</span><br><span class="line">&lt;description &gt; ：项目描述，常用于 Maven 生成的文档</span><br><span class="line">&lt;dependencies&gt; ：项目依赖构件配置，配置项目依赖构件的坐标</span><br><span class="line">&lt;build&gt; ：项目构建配置，配置编译、运行插件等。</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;Maven的使用&quot;&gt;&lt;a href=&quot;#Maven的使用&quot; class=&quot;headerlink&quot; title=&quot;Maven的使用&quot;&gt;&lt;/a&gt;Maven的使用&lt;/h1&gt;&lt;h2 id=&quot;什么是Maven&quot;&gt;&lt;a href=&quot;#什么是Maven&quot; class=&quot;head
      
    
    </summary>
    
      <category term="Maven" scheme="http://yoursite.com/categories/Maven/"/>
    
    
      <category term="Maven" scheme="http://yoursite.com/tags/Maven/"/>
    
  </entry>
  
  <entry>
    <title>有关MySQL的几道必会面试题</title>
    <link href="http://yoursite.com/2019/07/27/%E6%9C%89%E5%85%B3MySQL%E7%9A%84%E5%87%A0%E9%81%93%E5%BF%85%E4%BC%9A%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <id>http://yoursite.com/2019/07/27/有关MySQL的几道必会面试题/</id>
    <published>2019-07-27T15:20:18.959Z</published>
    <updated>2019-08-11T02:10:02.414Z</updated>
    
    <content type="html"><![CDATA[<h1 id="MySQL必会知识点"><a href="#MySQL必会知识点" class="headerlink" title="MySQL必会知识点"></a>MySQL必会知识点</h1><h2 id="说说你对与MySQL常见的两种存储引擎：MyISAM与InnoDB的理解"><a href="#说说你对与MySQL常见的两种存储引擎：MyISAM与InnoDB的理解" class="headerlink" title="说说你对与MySQL常见的两种存储引擎：MyISAM与InnoDB的理解"></a>说说你对与MySQL常见的两种存储引擎：MyISAM与InnoDB的理解</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1.count运算上的区别：因为MyISAM缓存有表meta-data（行数等），因此在做COUNT（*）时对于一个结构很好的查询时不需要消耗多少资源的。而对于InnoDB来说，则没有这种缓存。</span><br><span class="line">2.是否支持事务和崩溃后的安全恢复：MyISAM强调的是性能，每次查询具有原子性，其执行行速度比InnoDB类型更快，但是不支持事务。但是InnoDB提供事务的支持，外键等高级数据库功能。具有事务提交（commit）、回滚（rollback）和崩溃修复能力的事务安全（ACID）型表。</span><br><span class="line">3.是否支持外键： MyISAM不支持，而InnoDB支持。</span><br><span class="line"></span><br><span class="line">MyISAM更适合读密集的表，而InnoDB更适合写密集的表。在数据库做主从分离的情况下，经常选择MyISAM做为主库的存储引擎。一般来说，如果需要事务支持，并且有较高的并发读取频率(MyISAM的表锁的粒度太大，所以当该表写并发量较高时，要等待的查询就会很多了)，InnoDB是不错的选择。如果你的数据量很大（MyISAM支持压缩特性可以减少磁盘的空间占用），而且不需要支持事务时，MyISAM是最好的选择。</span><br></pre></td></tr></table></figure><h2 id="为什么要用-ORM-和-JDBC-有何不一样"><a href="#为什么要用-ORM-和-JDBC-有何不一样" class="headerlink" title="为什么要用 ORM?  和 JDBC 有何不一样?"></a>为什么要用 ORM?  和 JDBC 有何不一样?</h2><figure class="highlight plain"><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">orm是一种思想，就是把object转变成数据库中的记录，或者把数据库中的记录转变成object，我们可以用jdbc来实现这种思想，其实，如果我们的项目是严格按照oop方式编写的话，我们的jdbc程序不管是有意还是无意，就已经在实现orm的工作了。</span><br><span class="line">现在有许多orm工具，它们底层调用jdbc来实现了orm工作，我们直接使用这些工具，就省去了直接使用jdbc的繁琐细节，提高了开发效率，现在用的较多的orm工具是hibernate。也听说一些其他orm工具，如toplink,ojb等。</span><br></pre></td></tr></table></figure><h2 id="存储过程与触发器的区别？"><a href="#存储过程与触发器的区别？" class="headerlink" title="存储过程与触发器的区别？"></a>存储过程与触发器的区别？</h2><figure class="highlight plain"><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">触发器与存储过程非常相似，触发器也是SQL语句集，两者唯一的区别是触发器不能用EXECUTE语句调用，而是在用户执行Transact-SQL语句时自动触发（激活）执行。</span><br><span class="line">触发器是在一个修改了指定表中的数据时执行的存储过程。通常通过创建触发器来强制实现不同表中的逻辑相关数据的引用完整性和一致性。由于用户不能绕过触发器，所以可以用它来强制实施复杂的业务规则，以确保数据的完整性。</span><br><span class="line">触发器不同于存储过程，触发器主要是通过事件执行触发而被执行的，而存储过程可以通过存储过程名称名字而直接调用。当对某一表进行诸如UPDATE、INSERT、DELETE这些操作时，SQLSERVER就会自动执行触发器所定义的SQL语句，从而确保对数据的处理必须符合这些SQL语句所定义的规则。</span><br></pre></td></tr></table></figure><h2 id="Mysql如何为表字段添加索引？？？"><a href="#Mysql如何为表字段添加索引？？？" class="headerlink" title="Mysql如何为表字段添加索引？？？"></a>Mysql如何为表字段添加索引？？？</h2><p>1.添加PRIMARY KEY（主键索引）</p><blockquote><p>ALTER TABLE <code>table_name</code> ADD PRIMARY KEY ( <code>column</code> )</p></blockquote><p>2.添加UNIQUE(唯一索引)</p><blockquote><p>ALTER TABLE <code>table_name</code> ADD UNIQUE ( <code>column</code> )</p></blockquote><p>3.添加INDEX(普通索引)</p><blockquote><p>ALTER TABLE <code>table_name</code> ADD INDEX index_name ( <code>column</code> )</p></blockquote><p>4.添加FULLTEXT(全文索引)</p><blockquote><p>ALTER TABLE <code>table_name</code> ADD FULLTEXT ( <code>column</code>)</p></blockquote><p>5.添加多列索引</p><blockquote><p>ALTER TABLE <code>table_name</code> ADD INDEX index_name ( <code>column1</code>, <code>column2</code>, <code>column3</code> )</p></blockquote><h2 id="为什么要使用索引"><a href="#为什么要使用索引" class="headerlink" title="为什么要使用索引?"></a>为什么要使用索引?</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1.通过创建唯一性索引，可以保证数据库中每一行的数据的唯一性</span><br><span class="line">2.可以大大加快数据的检索速度（大大减少了检索的数据量），这也是创建索引的最主要的原因</span><br><span class="line">3.帮助服务器避免排序和临时表</span><br><span class="line">4.将随机IO变为顺序IO</span><br><span class="line">5.可以加快表与表之间的连接，特别是在实现数据的参考完整性方面有特别的意义</span><br></pre></td></tr></table></figure><h2 id="索引这么多优点，为什么不对表中的每一个列创建一个索引？"><a href="#索引这么多优点，为什么不对表中的每一个列创建一个索引？" class="headerlink" title="索引这么多优点，为什么不对表中的每一个列创建一个索引？"></a>索引这么多优点，为什么不对表中的每一个列创建一个索引？</h2><figure class="highlight plain"><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.当对表中的数据进行增加、删除和修改的时候，索引也要动态的维护，这样就降低了数据的维护速度</span><br><span class="line">2.索引需要占物理空间，除了数据表占数据空间之外，每一个索引还要占一定的物理空间，如果要建立聚集索引，那么需要的空间就会更大</span><br><span class="line">3.创建索引和维护索引要耗费时间，这种时间随着数据量的增加而增加</span><br></pre></td></tr></table></figure><h2 id="索引是如何提高查询速度的？"><a href="#索引是如何提高查询速度的？" class="headerlink" title="索引是如何提高查询速度的？"></a>索引是如何提高查询速度的？</h2><figure class="highlight plain"><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><h2 id="使用索引的注意事项"><a href="#使用索引的注意事项" class="headerlink" title="使用索引的注意事项"></a>使用索引的注意事项</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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.在经常需要搜索的列上，可以加快搜索的速度</span><br><span class="line">2.在经常使用在where子句中的列上面创建索引，加快条件的判断速度</span><br><span class="line">3.在经常需要排序的列上创建索引，因为索引已经排序，这样查询可以利用索引的排序，加快排序的查询时间</span><br><span class="line">4.对于中、大型表索引都是非常有效的，但是特大型表的话维护开销会很大，不适合建索引</span><br><span class="line">5.在经常用在连接的列上，这些列主要是一些外键，可以加快连接的速度</span><br><span class="line"></span><br><span class="line">6.避免where子句中对字段施加函数这回造成无法命中索引</span><br><span class="line">7.在使用InnoDB时使用与业务无关的自增主键作为主键，即使用逻辑主键，而不要使用业务主键</span><br><span class="line">8.将打算加索引的列设置为NOT NULL，否则将导致引擎放弃使用索引而进行全表扫描</span><br><span class="line">9.删除长期未使用的索引，不用的索引的存在会造成不必要的性能损耗——MySQL5.7可以通过查询sys库的chema_unused_indexes视图来查询那些索引从未被使用</span><br><span class="line">10.在使用limit offset查询缓存时,可以借助索引来提高性能</span><br></pre></td></tr></table></figure><h2 id="MySQL索引主要使用的两个数据结构"><a href="#MySQL索引主要使用的两个数据结构" class="headerlink" title="MySQL索引主要使用的两个数据结构"></a>MySQL索引主要使用的两个数据结构</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1.哈希索引</span><br><span class="line">对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引</span><br><span class="line"></span><br><span class="line">2.BTree索引</span><br><span class="line">MySQL的BTree索引使用的是B树中的B+Tree。但对于主要的两种存储（MyISAM和InnoDB）的实现方式是不同的</span><br></pre></td></tr></table></figure><h2 id="MyISAM和InnoDB实现BTree索引方式的区别"><a href="#MyISAM和InnoDB实现BTree索引方式的区别" class="headerlink" title="MyISAM和InnoDB实现BTree索引方式的区别"></a>MyISAM和InnoDB实现BTree索引方式的区别</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1.MyISAM</span><br><span class="line">B+Tree叶节点的data域存放的是数据记录的地址。在索引检索的时候，首先按照B+Tree搜索算法来搜索索引，如果指定的key存在，则取出其data域的值，然后以data域的值为地址读取相应的数据记录。这被称为“非聚集索引”。</span><br><span class="line"></span><br><span class="line">2.InnoDB</span><br><span class="line">其数据文件本身就是索引文件。相比MyISAM索引文件和数据文件是分离的，其表数据文件本身就是按B+Tree组织的一个索引结构，树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键，因此InnoDB表数据文件本身就是主索引。这被称为“聚簇索引（或聚集索引）”，而其余的索引都作为辅助索引，辅助索引的data域存储相应记录主键的值而不是地址，这也是和MyISAM不同的地方。在根据主索引搜索时，直接找到key所在的节点即可取出数据；在根据辅助索引查找时，则需要先取出主键的值，在走一遍主索引。 因此，在设计表的时候，不建议使用过长的字段作为主键，也不建议使用非单调的字段作为主键，这样会造成主索引频繁分裂。 PS：整理自《Java工程师修炼之道》</span><br></pre></td></tr></table></figure><h2 id="覆盖索引"><a href="#覆盖索引" class="headerlink" title="覆盖索引"></a>覆盖索引</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1.什么是覆盖索引</span><br><span class="line">如果一个索引包含（或者说覆盖）所有需要查询的字段的值，我们就称之为“覆盖索引”。我们知道在InnoDB存储引擎中，如果不是主键索引，叶子节点存储的是主键+列值。最终还是要“回表”，也就是要通过主键再查找一次。这样就会比较慢覆盖索引就是把要查询出的列和索引是对应的，不做回表操作！</span><br><span class="line"></span><br><span class="line">2.覆盖索引使用实例</span><br><span class="line">现在我创建了索引(username,age)，在查询数据的时候：select username , age from user where username = &apos;Java&apos; and age = 22。要查询出的列在叶子节点都存在！所以，就不用回表。</span><br></pre></td></tr></table></figure><h2 id="选择索引和编写利用这些索引的查询的3个原则"><a href="#选择索引和编写利用这些索引的查询的3个原则" class="headerlink" title="选择索引和编写利用这些索引的查询的3个原则"></a>选择索引和编写利用这些索引的查询的3个原则</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1. 单行访问是很慢的。特别是在机械硬盘存储中(SSD的随机I/O要快很多，不过这一点仍然成立）。如果服务器从存储中读取一个数据块只是为了获取其中一行，那么就浪费了很多工作。最好读取的块中能包含尽可能多所需要的行。使用索引可以创建位置引，用以提升效率。</span><br><span class="line"></span><br><span class="line">2. 按顺序访问范围数据是很快的，这有两个原因。第一，顺序1/0不需要多次磁盘寻道，所以比随机I/O要快很多（特别是对机械硬盘）。第二，如果服务器能够按需要顺序读取数据，那么就不再需要额外的排序操作，并且GROUPBY查询也无须再做排序和将行按组进行聚合计算了。</span><br><span class="line"></span><br><span class="line">3. 索引覆盖查询是很快的。如果一个索引包含了查询需要的所有列，那么存储引擎就不需要再回表查找行。这避免了大量的单行访问，而上面的第1点已经写明单行访问是很慢的。</span><br></pre></td></tr></table></figure><h2 id="你有没有做MySQL读写分离？如何实现MySQL的读写分离？MySQL主从复制原理的是啥？如何解决mysql主从同步的延时问题？"><a href="#你有没有做MySQL读写分离？如何实现MySQL的读写分离？MySQL主从复制原理的是啥？如何解决mysql主从同步的延时问题？" class="headerlink" title="你有没有做MySQL读写分离？如何实现MySQL的读写分离？MySQL主从复制原理的是啥？如何解决mysql主从同步的延时问题？"></a>你有没有做MySQL读写分离？如何实现MySQL的读写分离？MySQL主从复制原理的是啥？如何解决mysql主从同步的延时问题？</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1、基于主从复制架构；搞一个主库，挂多个从库，然后我们就单单只是写主库，然后主库会自动把数据给同步到从库上去。</span><br><span class="line">2、主库将变更写binlog日志，然后从库连接到主库之后，从库有一个IO线程，将主库的binlog日志拷贝到自己本地，写入一个中继日志中。接着从库中有一个SQL线程会从中继日志读取binlog日志，然后执行binlog日志中的内容，也就是在自己本地再执行一遍SQL，这样就可以保证自己跟主库的数据是一样的。</span><br><span class="line">这里有一个非常重要的一点，就是从库同步主库数据的过程是串行化的，也就是说主库上并行的操作，在从库上会串行执行。所以这就是一个非常重要的点了，由于从库从主库拷贝日志以及串行执行SQL的特点，在搞并发场景下，从库的数据一定会比主库慢一些，是有延时的。所以经常出现，刚写入主库的数据可能是读不到的，要过几十毫秒，甚至几百毫秒才能读取到。</span><br><span class="line">而且这里还有另一个问题，就是如果主库突然宕机，然后恰好数据还没同步到从库，那么有些数据可能在从库上是没有的，有些数据可能就丢失了。</span><br><span class="line">所以MySQL实际上在这一块有两个机制，一个是半同步复制，用来解决主从数据丢失问题；一个是并行复制，用来解决主从同步延时问题。</span><br><span class="line">半同步复制（semi-sync复制）：指的是主库写入binlog日志以后，就将会强制此时立即将数据同步到从库，从库将日志写入自己本地的relay log 之后，接着会返回一个ack个主库，主库接收到至少一个从库的ack之后才会认为写操作完成了。</span><br><span class="line">并行复制：指的是从库开启多个线程，并行读取relay log中不同库的日志，然后并行重放不同库的日志，这是库级别的并行。</span><br><span class="line"></span><br><span class="line">3、show status，Seconds_Behind_Master，你可以看到从库复制主库的数据落后了几ms</span><br><span class="line">1、分库，将一个主库拆分为4个主库，每个主库的写并发就500/s，此时主从延迟可以忽略不计</span><br><span class="line">2、打开mysql支持的并行复制，多个库并行复制，如果说某个库的写入并发就是特别高，单库写并发达到了2000/s，并行复制还是没意义。28法则，很多时候比如说，就是少数的几个订单表，写入了2000/s，其他几十个表10/s。</span><br><span class="line">3、重写代码，写代码时要慎重，插入数据之后，直接就更新，不要查询</span><br><span class="line">4、如果确实是存在必须先插入，立马要求就查询到，然后立马就要反过来执行一些操作，对这个查询设置直连主库。不推荐这种方法，你这么搞导致读写分离的意义就丧失了</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;MySQL必会知识点&quot;&gt;&lt;a href=&quot;#MySQL必会知识点&quot; class=&quot;headerlink&quot; title=&quot;MySQL必会知识点&quot;&gt;&lt;/a&gt;MySQL必会知识点&lt;/h1&gt;&lt;h2 id=&quot;说说你对与MySQL常见的两种存储引擎：MyISAM与InnoDB
      
    
    </summary>
    
      <category term="面试题, MySQL" scheme="http://yoursite.com/categories/%E9%9D%A2%E8%AF%95%E9%A2%98-MySQL/"/>
    
    
      <category term="MySQL, 面试题" scheme="http://yoursite.com/tags/MySQL-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    
  </entry>
  
  <entry>
    <title>Redis的相关知识</title>
    <link href="http://yoursite.com/2019/07/27/Redis%E7%9A%84%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/"/>
    <id>http://yoursite.com/2019/07/27/Redis的相关知识/</id>
    <published>2019-07-27T12:15:27.889Z</published>
    <updated>2019-08-14T02:46:28.067Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、概念：redis是一款高性能的NoSQL系列的非关系型数据库"><a href="#一、概念：redis是一款高性能的NoSQL系列的非关系型数据库" class="headerlink" title="一、概念：redis是一款高性能的NoSQL系列的非关系型数据库"></a>一、概念：redis是一款高性能的NoSQL系列的非关系型数据库</h1><h2 id="1-1什么是NoSQL"><a href="#1-1什么是NoSQL" class="headerlink" title="1.1什么是NoSQL"></a>1.1什么是NoSQL</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1.1.什么是NoSQL</span><br><span class="line">NoSQL(NoSQL = Not Only SQL)，意即“不仅仅是SQL”，是一项全新的数据库理念，泛指非关系型的数据库。</span><br><span class="line">随着互联网web2.0网站的兴起，传统的关系数据库在应付web2.0网站，特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心，暴露了很多难以克服的问题，而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战，尤其是大数据应用难题。</span><br><span class="line"></span><br><span class="line">1.1.1.NoSQL和关系型数据库比较</span><br><span class="line">优点：</span><br><span class="line">1）成本：nosql数据库简单易部署，基本都是开源软件，不需要像使用oracle那样花费大量成本购买使用，相比关系型数据库价格便宜。</span><br><span class="line">2）查询速度：nosql数据库将数据存储于缓存之中，关系型数据库将数据存储在硬盘中，自然查询速度远不及nosql数据库。</span><br><span class="line">3）存储数据的格式：nosql的存储格式是key,value形式、文档形式、图片形式等等，所以可以存储基础类型以及对象或者是集合等各种格式，而数据库则只支持基础类型。</span><br><span class="line">4）扩展性：关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。</span><br><span class="line"></span><br><span class="line">缺点：</span><br><span class="line">1）维护的工具和资料有限，因为nosql是属于新的技术，不能和关系型数据库十几年的技术同日而语。</span><br><span class="line">2）不提供对sql的支持，如果不支持sql这样的工业标准，将产生一定用户的学习和使用成本。</span><br><span class="line">3）不提供关系型数据库对事务的处理。</span><br><span class="line"></span><br><span class="line">1.1.2.非关系型数据库的优势：</span><br><span class="line">1）性能NoSQL是基于键值对的，可以想象成表中的主键和值的对应关系，而且不需要经过SQL层的解析，所以性能非常高。</span><br><span class="line">2）可扩展性同样也是因为基于键值对，数据之间没有耦合性，所以非常容易水平扩展。</span><br><span class="line"></span><br><span class="line">1.1.3.关系型数据库的优势：</span><br><span class="line">1）复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。</span><br><span class="line">2）事务支持使得对于安全性能很高的数据访问要求得以实现。对于这两类数据库，对方的优势就是自己的弱势，反之亦然。</span><br><span class="line"></span><br><span class="line">1.1.4.总结</span><br><span class="line">关系型数据库与NoSQL数据库并非对立而是互补的关系，即通常情况下使用关系型数据库，在适合使用NoSQL的时候使用NoSQL数据库，</span><br><span class="line">让NoSQL数据库对关系型数据库的不足进行弥补。</span><br><span class="line">一般会将数据存储在关系型数据库中，在Nosql数据库中备份存储关系型数据库的数据</span><br></pre></td></tr></table></figure><h2 id="1-2主流的NoSQL产品"><a href="#1-2主流的NoSQL产品" class="headerlink" title="1.2主流的NoSQL产品"></a>1.2主流的NoSQL产品</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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.2.主流的NOSQL产品</span><br><span class="line">•键值(Key-Value)存储数据库</span><br><span class="line">    相关产品： Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB</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><span class="line">    相关产品：Cassandra, HBase, Riak</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><span class="line">    相关产品：CouchDB、MongoDB</span><br><span class="line">    典型应用：Web应用（与Key-Value类似，Value是结构化的）</span><br><span class="line">    数据模型： 一系列键值对</span><br><span class="line">    优势：数据结构要求不严格</span><br><span class="line">    劣势： 查询性能不高，而且缺乏统一的查询语法</span><br><span class="line">•图形(Graph)数据库</span><br><span class="line">    相关数据库：Neo4J、InfoGrid、Infinite Graph</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><h2 id="1-3什么是Redis"><a href="#1-3什么是Redis" class="headerlink" title="1.3什么是Redis"></a>1.3什么是Redis</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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.3 什么是Redis</span><br><span class="line">    Redis是用C语言开发的一个开源的高性能键值对（key-value）数据库，官方提供测试数据，50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ，且Redis通过提供多种键值数据类型来适应不同场景下的存储需求，目前为止Redis支持的键值数据类型如下：</span><br><span class="line">    1) 字符串类型 string</span><br><span class="line">    2) 哈希类型 hash</span><br><span class="line">    3) 列表类型 list</span><br><span class="line">    4) 集合类型 set</span><br><span class="line">    5) 有序集合类型 sortedset</span><br><span class="line">1.3.1 redis的应用场景</span><br><span class="line">    •缓存（数据查询、短连接、新闻内容、商品内容等等）</span><br><span class="line">    •聊天室的在线好友列表</span><br><span class="line">    •任务队列。（秒杀、抢购、12306等等）</span><br><span class="line">    •应用排行榜</span><br><span class="line">    •网站访问统计</span><br><span class="line">    •数据过期处理（可以精确到毫秒）</span><br><span class="line">    •分布式集群架构中的session分离</span><br></pre></td></tr></table></figure><h1 id="二、关于Redis中的一些操作"><a href="#二、关于Redis中的一些操作" class="headerlink" title="二、关于Redis中的一些操作"></a>二、关于Redis中的一些操作</h1><h2 id="2-1下载安装"><a href="#2-1下载安装" class="headerlink" title="2.1下载安装"></a>2.1下载安装</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1. 官网：https://redis.io</span><br><span class="line">2. 中文网：http://www.redis.net.cn/</span><br><span class="line">3. 解压直接可以使用：</span><br><span class="line">    * redis.windows.conf：配置文件</span><br><span class="line">    * redis-cli.exe：redis的客户端</span><br><span class="line">    * redis-server.exe：redis服务器端</span><br></pre></td></tr></table></figure><h2 id="2-2命令操作"><a href="#2-2命令操作" class="headerlink" title="2.2命令操作"></a>2.2命令操作</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre></td><td class="code"><pre><span class="line">1. redis的数据结构：</span><br><span class="line">* redis存储的是：key,value格式的数据，其中key都是字符串，value有5种不同的数据结构</span><br><span class="line">    * value的数据结构：</span><br><span class="line">        1) 字符串类型 string</span><br><span class="line">        2) 哈希类型 hash ： map格式  </span><br><span class="line">        3) 列表类型 list ： linkedlist格式。支持重复元素</span><br><span class="line">        4) 集合类型 set  ： 不允许重复元素</span><br><span class="line">        5) 有序集合类型 sortedset：不允许重复元素，且元素有顺序</span><br><span class="line"></span><br><span class="line">2. 字符串类型 string</span><br><span class="line">    1. 存储： set key value</span><br><span class="line">    2. 获取： get key</span><br><span class="line">    3. 删除： del key</span><br><span class="line">3. 哈希类型 hash</span><br><span class="line">    1. 存储： hset key field value</span><br><span class="line">        127.0.0.1:6379&gt; hset myhash username lisi</span><br><span class="line">        (integer) 1</span><br><span class="line">        127.0.0.1:6379&gt; hset myhash password 123</span><br><span class="line">        (integer) 1</span><br><span class="line">    2. 获取： </span><br><span class="line">        * hget key field: 获取指定的field对应的值</span><br><span class="line">        127.0.0.1:6379&gt; hget myhash username</span><br><span class="line">        &quot;lisi&quot;</span><br><span class="line">        * hgetall key：获取所有的field和value</span><br><span class="line">        127.0.0.1:6379&gt; hgetall myhash</span><br><span class="line">        1) &quot;username&quot;</span><br><span class="line">        2) &quot;lisi&quot;</span><br><span class="line">        3) &quot;password&quot;</span><br><span class="line">        4) &quot;123&quot;</span><br><span class="line"></span><br><span class="line">    3. 删除： hdel key field</span><br><span class="line">        127.0.0.1:6379&gt; hdel myhash username</span><br><span class="line">        (integer) 1</span><br><span class="line"></span><br><span class="line">4. 列表类型 list:可以添加一个元素到列表的头部（左边）或者尾部（右边）</span><br><span class="line">    1. 添加：</span><br><span class="line">        1. lpush key value: 将元素加入列表左表</span><br><span class="line"></span><br><span class="line">        2. rpush key value：将元素加入列表右边</span><br><span class="line"></span><br><span class="line">        127.0.0.1:6379&gt; lpush myList a</span><br><span class="line">        (integer) 1</span><br><span class="line">        127.0.0.1:6379&gt; lpush myList b</span><br><span class="line">        (integer) 2</span><br><span class="line">        127.0.0.1:6379&gt; rpush myList c</span><br><span class="line">        (integer) 3</span><br><span class="line">    2. 获取：</span><br><span class="line">        * lrange key start end ：范围获取</span><br><span class="line">        127.0.0.1:6379&gt; lrange myList 0 -1</span><br><span class="line">        1) &quot;b&quot;</span><br><span class="line">        2) &quot;a&quot;</span><br><span class="line">        3) &quot;c&quot;</span><br><span class="line">    3. 删除：</span><br><span class="line">        * lpop key： 删除列表最左边的元素，并将元素返回</span><br><span class="line">        * rpop key： 删除列表最右边的元素，并将元素返回</span><br><span class="line">5. 集合类型 set ： 不允许重复元素</span><br><span class="line">    1. 存储：sadd key value</span><br><span class="line">        127.0.0.1:6379&gt; sadd myset a</span><br><span class="line">        (integer) 1</span><br><span class="line">        127.0.0.1:6379&gt; sadd myset a</span><br><span class="line">        (integer) 0</span><br><span class="line">    2. 获取：smembers key:获取set集合中所有元素</span><br><span class="line">        127.0.0.1:6379&gt; smembers myset</span><br><span class="line">        1) &quot;a&quot;</span><br><span class="line">3. 删除：srem key value:删除set集合中的某个元素</span><br><span class="line">        127.0.0.1:6379&gt; srem myset a</span><br><span class="line">        (integer) 1</span><br><span class="line">6. 有序集合类型 sortedset：不允许重复元素，且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。</span><br><span class="line"></span><br><span class="line">1. 存储：zadd key score value</span><br><span class="line">        127.0.0.1:6379&gt; zadd mysort 60 zhangsan</span><br><span class="line">        (integer) 1</span><br><span class="line">        127.0.0.1:6379&gt; zadd mysort 50 lisi</span><br><span class="line">        (integer) 1</span><br><span class="line">        127.0.0.1:6379&gt; zadd mysort 80 wangwu</span><br><span class="line">        (integer) 1</span><br><span class="line">2. 获取：zrange key start end [withscores]</span><br><span class="line">        127.0.0.1:6379&gt; zrange mysort 0 -1</span><br><span class="line">        1) &quot;lisi&quot;</span><br><span class="line">        2) &quot;zhangsan&quot;</span><br><span class="line">        3) &quot;wangwu&quot;</span><br><span class="line"></span><br><span class="line">    127.0.0.1:6379&gt; zrange mysort 0 -1 withscores</span><br><span class="line">        1) &quot;zhangsan&quot;</span><br><span class="line">        2) &quot;60&quot;</span><br><span class="line">        3) &quot;wangwu&quot;</span><br><span class="line">        4) &quot;80&quot;</span><br><span class="line">        5) &quot;lisi&quot;</span><br><span class="line">        6) &quot;500&quot;</span><br><span class="line">    3. 删除：zrem key value</span><br><span class="line">        127.0.0.1:6379&gt; zrem mysort lisi</span><br><span class="line">        (integer) 1</span><br><span class="line"></span><br><span class="line">7. 通用命令</span><br><span class="line">    1. keys * : 查询所有的键</span><br><span class="line">    2. type key ： 获取键对应的value的类型</span><br><span class="line">    3. del key：删除指定的key value</span><br></pre></td></tr></table></figure><h1 id="三、Redis的持久化"><a href="#三、Redis的持久化" class="headerlink" title="三、Redis的持久化"></a>三、Redis的持久化</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1. redis是一个内存数据库，当redis服务器重启，获取电脑重启，数据会丢失，我们可以将redis内存中的数据持久化保存到硬盘的文件中。</span><br><span class="line">2. redis持久化机制：</span><br><span class="line">1. RDB：默认方式，不需要进行配置，默认就使用这种机制</span><br><span class="line">    * 在一定的间隔时间中，检测key的变化情况，然后持久化数据</span><br><span class="line">        1. 编辑redis.windwos.conf文件</span><br><span class="line">        #   after 900 sec (15 min) if at least 1 key changed</span><br><span class="line">        save 900 1</span><br><span class="line">        #   after 300 sec (5 min) if at least 10 keys changed</span><br><span class="line">        save 300 10</span><br><span class="line">        #   after 60 sec if at least 10000 keys changed</span><br><span class="line">        save 60 10000</span><br><span class="line"></span><br><span class="line">    2. 重新启动redis服务器，并指定配置文件名称</span><br><span class="line">        redis-2.8.9&gt;redis-server.exe redis.windows.conf</span><br><span class="line"></span><br><span class="line">2. AOF：日志记录的方式，可以记录每一条命令的操作。可以每一次命令操作后，持久化数据</span><br><span class="line">         1. 编辑redis.windwos.conf文件</span><br><span class="line">            appendonly no（关闭aof） --&gt; appendonly yes （开启aof）</span><br><span class="line"></span><br><span class="line">            appendfsync always ：    每一次操作都进行持久化</span><br><span class="line">            appendfsync everysec ：  每隔一秒进行一次持久化</span><br><span class="line">            appendfsync no ： 不进行持久化</span><br></pre></td></tr></table></figure><h1 id="四、jedis中连接池：jedisPool的使用"><a href="#四、jedis中连接池：jedisPool的使用" class="headerlink" title="四、jedis中连接池：jedisPool的使用"></a>四、jedis中连接池：jedisPool的使用</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><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. Java客户端 Jedis</span><br><span class="line">* Jedis: 一款java操作redis数据库的工具.</span><br><span class="line">* 使用步骤：</span><br><span class="line">1. 下载jedis的jar包，并导入工程中</span><br><span class="line">2. 使用</span><br><span class="line">//1. 获取连接</span><br><span class="line">    Jedis jedis = new Jedis(&quot;localhost&quot;,6379);</span><br><span class="line">   //2. 操作</span><br><span class="line">   jedis.set(&quot;username&quot;,&quot;zhangsan&quot;);</span><br><span class="line">    //3. 关闭连接</span><br><span class="line">    jedis.close();</span><br><span class="line">2. 创建JedisPool连接池对象</span><br><span class="line">    2. 调用方法 getResource()方法获取Jedis连接</span><br><span class="line">    //0.创建一个配置对象</span><br><span class="line">    JedisPoolConfig config = new JedisPoolConfig();</span><br><span class="line">    config.setMaxTotal(50);</span><br><span class="line">    config.setMaxIdle(10);</span><br><span class="line"></span><br><span class="line">    //1.创建Jedis连接池对象</span><br><span class="line">    JedisPool jedisPool = new JedisPool(config,&quot;localhost&quot;,6379);</span><br><span class="line"></span><br><span class="line">    //2.获取连接</span><br><span class="line">    Jedis jedis = jedisPool.getResource();</span><br><span class="line">    //3. 使用</span><br><span class="line">    jedis.set(&quot;hehe&quot;,&quot;heihei&quot;);</span><br><span class="line">    //4. 关闭 归还到连接池中</span><br><span class="line">    jedis.close();</span><br></pre></td></tr></table></figure><h1 id="五、注意"><a href="#五、注意" class="headerlink" title="五、注意"></a>五、注意</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">* 注意：使用redis，缓存一些不经常发生变化的数据。</span><br><span class="line">* 数据库的数据一旦发生改变，则需要更新缓存。</span><br><span class="line">* 数据库的表执行 增删改的相关操作，需要将redis缓存数据情况，再次存入</span><br><span class="line">* 在service对应的增删改方法中，将redis数据删除。</span><br></pre></td></tr></table></figure><h1 id="六、面试中的Redis相关知识"><a href="#六、面试中的Redis相关知识" class="headerlink" title="六、面试中的Redis相关知识"></a>六、面试中的Redis相关知识</h1><h2 id="6-1-redis-和-memcached-的区别"><a href="#6-1-redis-和-memcached-的区别" class="headerlink" title="6.1 redis 和 memcached 的区别"></a>6.1 redis 和 memcached 的区别</h2><ol><li>redis支持<strong>更丰富的数据类型</strong>（支持更复杂的应用场景）：Redis不仅仅支持简单的k/v类型的数据，同时还提供list，set，zset，hash等数据结构的存储。memcache支持<strong>简单的数据类型</strong>，String。</li><li>Redis支持数据的<strong>持久化</strong>，可以将内存中的数据保持在磁盘中，重启的时候可以再次加载进行使用,而<br>Memecache把数据<strong>全部存在内存之中</strong>。</li><li><strong>集群模式</strong>：memcached没有原生的集群模式，需要依靠客户端来实现往集群中分片写入数据；但是 redis 目前是原生支持 cluster 模式的.</li><li>Memcached是多线程，非阻塞IO复用的网络模型；Redis使用<strong>单线程的多路 IO 复用模型</strong>。</li></ol><h2 id="6-2-redis-设置过期时间"><a href="#6-2-redis-设置过期时间" class="headerlink" title="6.2 redis 设置过期时间"></a>6.2 redis 设置过期时间</h2><p><strong>定期删除</strong>：redis默认是每隔 100ms 就随机抽取一些设置了过期时间的key，检查其是否过期，如果过期就删<br>除。注意这里是随机抽取的。为什么要随机呢？你想一想假如 redis 存了几十万个 key ，每隔100ms就遍历所<br>有的设置过期时间的 key 的话，就会给 CPU 带来很大的负载！</p><p><strong>惰性删除</strong> ：定期删除可能会导致很多过期 key 到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期<br>key，靠定期删除没有被删除掉，还停留在内存里，除非你的系统去查一下那个 key，才会被redis给删除掉。这<br>就是所谓的惰性删除，也是够懒的哈！</p><p>但是仅仅通过设置过期时间还是有问题的。我们想一下：如果定期删除漏掉了很多过期 key，然后你也没及时去查，也就没走惰性删除，此时会怎么样？如果大量过期key堆积在内存里，导致redis内存块耗尽了。怎么解决这个问题呢？<br><strong>redis 内存淘汰机制。</strong></p><h2 id="6-3-redis-内存淘汰机制（MySQL里有2000w数据，Redis中只存20w的数据，如何保证Redis中的数据都是热点数据？）"><a href="#6-3-redis-内存淘汰机制（MySQL里有2000w数据，Redis中只存20w的数据，如何保证Redis中的数据都是热点数据？）" class="headerlink" title="6.3 redis 内存淘汰机制（MySQL里有2000w数据，Redis中只存20w的数据，如何保证Redis中的数据都是热点数据？）"></a>6.3 redis 内存淘汰机制（MySQL里有2000w数据，Redis中只存20w的数据，如何保证Redis中的数据都是热点数据？）</h2><p>redis 提供 6种数据淘汰策略：</p><ol><li>volatile-lru：从已设置过期时间的数据集（server.db[i].expires）中挑选最近最少使用的数据淘汰</li><li>volatile-ttl：从已设置过期时间的数据集（server.db[i].expires）中挑选将要过期的数据淘汰</li><li>volatile-random：从已设置过期时间的数据集（server.db[i].expires）中任意选择数据淘汰</li><li>allkeys-lru：当内存不足以容纳新写入数据时，在键空间中，移除最近最少使用的key（这个是最常用的）.</li><li>allkeys-random：从数据集（server.db[i].dict）中任意选择数据淘汰</li><li>no-eviction：禁止驱逐数据，也就是说当内存不足以容纳新写入数据时，新写入操作会报错。这个应该没人使用吧！</li></ol><h2 id="6-4-redis-持久化机制（怎么保证-redis-挂掉之后再重启数据可以进行恢复？）"><a href="#6-4-redis-持久化机制（怎么保证-redis-挂掉之后再重启数据可以进行恢复？）" class="headerlink" title="6.4  redis 持久化机制（怎么保证 redis 挂掉之后再重启数据可以进行恢复？）"></a>6.4  redis 持久化机制（怎么保证 redis 挂掉之后再重启数据可以进行恢复？）</h2><p>Redis的一种持久化方式叫<strong>快照（snapshotting，RDB）</strong>,另一种方式是只<strong>追加文件（append-only file,AOF）</strong></p><p>① 快照（snapshotting）持久化（RDB）：</p><p>​    Redis可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。Redis创建快照之后，可以对快照进行备份，可以将快照复制到其他服务器从而创建具有相同数据的服务器副本（Redis主从结构，主要用来提高Redis性能），还可以将快照留在原地以便重启服务器的时候使用。<br>​    <strong>快照持久化是Redis默认采用的持久化方式</strong></p><p>② AOF（append-only file）持久化：<br>    与快照持久化相比，AOF持久化 的实时性更好，因此已成为主流的持久化方案。默认情况下Redis没有开启<br>AOF（append only file）方式的持久化，可以通过appendonly参数开启：</p><blockquote><p>appendonly yes</p></blockquote><p>​    开启AOF持久化后每执行一条会更改Redis中的数据的命令，Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同，都是通过dir参数设置的，默认的文件名是appendonly.aof。<br>在Redis的配置文件中存在三种不同的 AOF 持久化方式，它们分别是：</p><blockquote><p>appendfsync always         #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度<br>appendfsync everysec     #每秒钟同步一次，显示地将多个写命令同步到硬盘<br>appendfsync no                #让操作系统决定何时进行同步</p></blockquote><p>为了兼顾数据和写入性能，用户可以考虑 appendfsync everysec选项 ，让Redis每秒同步一次AOF文件，Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃，用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候，Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。</p><p><strong>Redis 4.0 对于持久化机制的优化</strong><br>    Redis 4.0 开始支持 RDB 和 AOF 的混合持久化（默认关闭，可以通过配置项 aof-use-rdb-preamble 开启）。<br>如果把混合持久化打开，AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的， AOF 里面的 RDB 部分是压缩格式不再是AOF 格式，可读性较差。</p><h2 id="6-5-缓存雪崩和缓存穿透问题解决方案"><a href="#6-5-缓存雪崩和缓存穿透问题解决方案" class="headerlink" title="6.5 缓存雪崩和缓存穿透问题解决方案"></a>6.5 缓存雪崩和缓存穿透问题解决方案</h2><p><strong>缓存雪崩</strong><br>简介：缓存同一时间大面积的失效，所以，后面的请求都会落到数据库上，造成数据库短时间内承受大量请求而崩<br>掉。<br>解决办法：<br>    事前：尽量保证整个 redis 集群的高可用性，发现机器宕机尽快补上。选择合适的内存淘汰策略。<br>    事中：本地ehcache缓存 + hystrix限流&amp;降级，避免MySQL崩掉<br>    事后：利用 redis 持久化机制保存的数据尽快恢复缓存</p><p><strong>缓存穿透</strong><br>简介：一般是黑客故意去请求缓存中不存在的数据，导致所有的请求都落到数据库上，造成数据库短时间内承受大量请求而崩掉。</p><p>解决办法： </p><p>​    有很多种方法可以有效地解决缓存穿透问题，最常见的则是采用布隆过滤器，将所有可能存在的数据哈希到一个足够大的bitmap中，一个一定不存在的数据会被 这个bitmap拦截掉，从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法（我们采用的就是这种），如果一个查询返回的数据为空（不管是数 据不存在，还是系统故障），我们仍然把这个空结果进行缓存，但它的过期时间会很短，最长不超过五分钟。</p><h2 id="6-6-如何保证缓存与数据库双写时的数据一致性？"><a href="#6-6-如何保证缓存与数据库双写时的数据一致性？" class="headerlink" title="6.6 如何保证缓存与数据库双写时的数据一致性？"></a>6.6 如何保证缓存与数据库双写时的数据一致性？</h2><p>你只要用缓存，就可能会涉及到缓存与数据库双存储双写，你只要是双写，就一定会有数据一致性的问题，那么你如何解决一致性问题？<br>一般来说，就是如果你的系统不是严格要求缓存+数据库必须一致性的话，缓存可以稍微的跟数据库偶尔有不一致的情况，最好不要做这个方案，读请求和写请求串行化，串到一个内存队列里去，这样就可以保证一定不会出现不一致的情况。<br>串行化之后，就会导致系统的吞吐量会大幅度的降低，用比正常情况下多几倍的机器去支撑线上的一个请求。</p><h2 id="6-7-Redis的主从复制如何实现？"><a href="#6-7-Redis的主从复制如何实现？" class="headerlink" title="6.7 Redis的主从复制如何实现？"></a>6.7 Redis的主从复制如何实现？</h2><p>主节点将自己内存中的数据做一份快照，将快照发给从节点，从节点将数据恢复到内存中</p><p>在每次增加新数据的时候，主节点以类似于MySQL的二进制日志方式将语句发送给从节点，从节点拿到主节点发送过来的语句进行重放</p><h2 id="6-8-Redis的单线程模型-为什么redis单线程还能支撑高并发"><a href="#6-8-Redis的单线程模型-为什么redis单线程还能支撑高并发" class="headerlink" title="6.8 Redis的单线程模型? 为什么redis单线程还能支撑高并发?"></a>6.8 Redis的单线程模型? 为什么redis单线程还能支撑高并发?</h2><p>客户端发出 socket 请求—–&gt;连接到 redis 的 server socket —–&gt;通过 AE_READABLE 发送到IO多路复用器—–&gt;将请求压入任务队列中—–&gt;通过文件事件分派器分配到相应的事件处理器</p><p>核心是基于非阻塞的IO多路复用模型</p><p>纯内存操作，处理请求非常快</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;一、概念：redis是一款高性能的NoSQL系列的非关系型数据库&quot;&gt;&lt;a href=&quot;#一、概念：redis是一款高性能的NoSQL系列的非关系型数据库&quot; class=&quot;headerlink&quot; title=&quot;一、概念：redis是一款高性能的NoSQL系列的非关系
      
    
    </summary>
    
      <category term="redis" scheme="http://yoursite.com/categories/redis/"/>
    
    
      <category term="redis, jedis" scheme="http://yoursite.com/tags/redis-jedis/"/>
    
  </entry>
  
  <entry>
    <title>Mybatis的相关知识</title>
    <link href="http://yoursite.com/2019/07/26/Mybatis/"/>
    <id>http://yoursite.com/2019/07/26/Mybatis/</id>
    <published>2019-07-26T15:29:35.797Z</published>
    <updated>2019-07-26T15:37:04.748Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Mybatis"><a href="#Mybatis" class="headerlink" title="Mybatis"></a>Mybatis</h1><h2 id="1-Mybatis概述"><a href="#1-Mybatis概述" class="headerlink" title="1.Mybatis概述"></a>1.Mybatis概述</h2><figure class="highlight plain"><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">Mybatis是一个优秀的基于java的持久层框架，它内部封装了jdbc，使开发者只需要关注sql语句本身，而不需要花精力去处理加载驱动，创建连接，创建statement等繁杂的过程</span><br><span class="line">Mybatis通过xml或注解的方式将要执行的各种statement配置起来，并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句，最后由Mybatis框架执行sql并将结果映射为java对象并返回。</span><br><span class="line">采用ORM思想解决了实体和数据库映射的问题，对jdbc进行了封装，屏蔽jdbc api 底层访问细节，使我们不用与 jdbc api 打交道，就可以完成对数据库的持久化操作。</span><br></pre></td></tr></table></figure><h2 id="2-搭建Mybatis开发环境"><a href="#2-搭建Mybatis开发环境" class="headerlink" title="2.搭建Mybatis开发环境"></a>2.搭建Mybatis开发环境</h2><h3 id="2-1创建Maven工程"><a href="#2-1创建Maven工程" class="headerlink" title="2.1创建Maven工程"></a>2.1创建Maven工程</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">创建 mybatis01 的工程，工程信息如下：</span><br><span class="line">Groupid:com.holicCode</span><br><span class="line">ArtifactId:mybatis01</span><br><span class="line">Packing:jar</span><br></pre></td></tr></table></figure><h3 id="2-2添加Mybatis3-4-5的坐标"><a href="#2-2添加Mybatis3-4-5的坐标" class="headerlink" title="2.2添加Mybatis3.4.5的坐标"></a>2.2添加Mybatis3.4.5的坐标</h3><p>在pom.xml文件中添加Mybatis3.4.5的坐标，如下：</p><figure class="highlight"><table><tr><td class="gutter"><pre><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">&lt;dependencies&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">&lt;groupId&gt;org.mybatis&lt;/groupId&gt;</span><br><span class="line">&lt;artifactId&gt;mybatis&lt;/artifactId&gt;</span><br><span class="line">&lt;version&gt;3.4.5&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">&lt;groupId&gt;junit&lt;/groupId&gt;</span><br><span class="line">&lt;artifactId&gt;junit&lt;/artifactId&gt;</span><br><span class="line">&lt;version&gt;4.10&lt;/version&gt;</span><br><span class="line">&lt;scope&gt;test&lt;/scope&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">&lt;groupId&gt;mysql&lt;/groupId&gt;</span><br><span class="line">&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;</span><br><span class="line">&lt;version&gt;5.1.6&lt;/version&gt;</span><br><span class="line"> &lt;scope&gt;runtime&lt;/scope&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">&lt;groupId&gt;log4j&lt;/groupId&gt;</span><br><span class="line">&lt;artifactId&gt;log4j&lt;/artifactId&gt;</span><br><span class="line">&lt;version&gt;1.2.12&lt;/version&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br><span class="line">&lt;/dependencies&gt;</span><br></pre></td></tr></table></figure><h3 id="2-3编写必要代码-实体类和持久层接口"><a href="#2-3编写必要代码-实体类和持久层接口" class="headerlink" title="2.3编写必要代码(实体类和持久层接口)"></a>2.3编写必要代码(实体类和持久层接口)</h3><h3 id="2-4编写SqlMapConfig-xml配置文件"><a href="#2-4编写SqlMapConfig-xml配置文件" class="headerlink" title="2.4编写SqlMapConfig.xml配置文件"></a>2.4编写SqlMapConfig.xml配置文件</h3><figure class="highlight"><table><tr><td class="gutter"><pre><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">&lt;?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"UTF-8"</span>?&gt;</span><br><span class="line">&lt;!DOCTYPE configuration</span><br><span class="line"> PUBLIC <span class="string">"-//mybatis.org//DTD Config 3.0//EN"</span></span><br><span class="line"> <span class="string">"http://mybatis.org/dtd/mybatis-3-config.dtd"</span>&gt;</span><br><span class="line">&lt;configuration&gt;</span><br><span class="line">&lt;!-- 配置 mybatis 的环境 --&gt;</span><br><span class="line">&lt;environments <span class="keyword">default</span>=<span class="string">"mysql"</span>&gt;</span><br><span class="line">&lt;!-- 配置 mysql 的环境 --&gt;</span><br><span class="line">&lt;environment id=<span class="string">"mysql"</span>&gt;</span><br><span class="line">&lt;!-- 配置事务的类型 --&gt;</span><br><span class="line">&lt;transactionManager type="JDBC"&gt;&lt;/transactionManager&gt;</span><br><span class="line">&lt;!-- 配置连接数据库的信息：用的是数据源(连接池) --&gt;</span><br><span class="line">&lt;dataSource type=<span class="string">"POOLED"</span>&gt;</span><br><span class="line">&lt;property name=<span class="string">"driver"</span> value=<span class="string">"com.mysql.jdbc.Driver"</span>/&gt;</span><br><span class="line">&lt;property name=<span class="string">"url"</span> value=<span class="string">"jdbc:mysql://localhost:3306/student"</span>/&gt;</span><br><span class="line">&lt;property name=<span class="string">"username"</span> value=<span class="string">"root"</span>/&gt;</span><br><span class="line">&lt;property name=<span class="string">"password"</span> value=<span class="string">"root"</span>/&gt;</span><br><span class="line">&lt;/dataSource&gt;</span><br><span class="line">&lt;/environment&gt;</span><br><span class="line">&lt;/environments&gt;</span><br><span class="line">&lt;!-- 告知 mybatis 映射配置的位置 --&gt;</span><br><span class="line">&lt;mappers&gt;</span><br><span class="line">&lt;mapper resource=<span class="string">"com/holicCode/dao/IUserDao.xml"</span>/&gt;</span><br><span class="line">&lt;/mappers&gt;</span><br><span class="line">&lt;/configuration&gt;</span><br></pre></td></tr></table></figure><h3 id="2-5编写映射配置文件"><a href="#2-5编写映射配置文件" class="headerlink" title="2.5编写映射配置文件"></a>2.5编写映射配置文件</h3><h3 id="2-6编写测试类"><a href="#2-6编写测试类" class="headerlink" title="2.6编写测试类"></a>2.6编写测试类</h3><h2 id="3-Mybatis中用到的设计模式"><a href="#3-Mybatis中用到的设计模式" class="headerlink" title="3.Mybatis中用到的设计模式"></a>3.Mybatis中用到的设计模式</h2><figure class="highlight plain"><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">工厂模式（SqlSessionFactory）</span><br><span class="line">代理模式(MapperProxyFactory)</span><br><span class="line">构建者模式(SqlSessionFactoryBuilder)</span><br></pre></td></tr></table></figure><h2 id="4-Mybatis与JDBC编程的比较"><a href="#4-Mybatis与JDBC编程的比较" class="headerlink" title="4.Mybatis与JDBC编程的比较"></a>4.Mybatis与JDBC编程的比较</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1.数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能，如果使用数据库链接池可解决此问题。</span><br><span class="line">解决：</span><br><span class="line">在 SqlMapConfig.xml 中配置数据链接池，使用连接池管理数据库链接。</span><br><span class="line">2.Sql 语句写在代码中造成代码不易维护，实际应用 sql 变化的可能较大，sql 变动需要改变 java 代码。</span><br><span class="line">解决：</span><br><span class="line">将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。</span><br><span class="line">3.向 sql 语句传参数麻烦，因为 sql 语句的 where 条件不一定，可能多也可能少，占位符需要和参数对应。</span><br><span class="line">解决：</span><br><span class="line">Mybatis 自动将 java 对象映射至 sql 语句，通过 statement 中的 parameterType 定义输入参数的类型。</span><br><span class="line">4.对结果集解析麻烦，sql 变化导致解析代码变化，且解析前需要遍历，如果能将数据库记录封装成 pojo 对象解析比较方便。</span><br><span class="line">解决：</span><br><span class="line">Mybatis 自动将 sql 执行结果映射至 java 对象，通过 statement 中的resultType 定义输出结果的类型。</span><br></pre></td></tr></table></figure><h2 id="5-当编写的实体类属性名和数据库表的列名不一致时"><a href="#5-当编写的实体类属性名和数据库表的列名不一致时" class="headerlink" title="5.当编写的实体类属性名和数据库表的列名不一致时"></a>5.当编写的实体类属性名和数据库表的列名不一致时</h2><h3 id="5-1出现的问题"><a href="#5-1出现的问题" class="headerlink" title="5.1出现的问题"></a>5.1出现的问题</h3><figure class="highlight plain"><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">查询出来的结果会都为null</span><br><span class="line">有时有可能会出现某一列有值的情况,这是因为MySQL在Windows系统中不区分大小写!</span><br></pre></td></tr></table></figure><h3 id="5-2解决方案一"><a href="#5-2解决方案一" class="headerlink" title="5.2解决方案一"></a>5.2解决方案一</h3><figure class="highlight plain"><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">给映射配置文件的SQL语句中的列名起别名(该方法当我们查询很多事,都使用的话写起来很麻烦)</span><br></pre></td></tr></table></figure><h3 id="5-3解决方案二"><a href="#5-3解决方案二" class="headerlink" title="5.3解决方案二"></a>5.3解决方案二</h3><p>​    resultMap结果类型</p><figure class="highlight plain"><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">resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。</span><br><span class="line">在 select 标签中使用 resultMap 属性指定引用即可。同时 resultMap 可以实现将查询结果映射为复杂类型的 pojo，比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询。</span><br></pre></td></tr></table></figure><h2 id="6-Mybatis连接池"><a href="#6-Mybatis连接池" class="headerlink" title="6.Mybatis连接池"></a>6.Mybatis连接池</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Mybatis连接池与web中的连接池不同,Mybatis中的连接池使用的自己的连接池技术,在Mybatis的SqlMapConfig.xml配置文件中,通过&lt;dataSource type=&quot;pooled&quot;&gt;来实现Mybatis中连接池的配置。</span><br></pre></td></tr></table></figure><h3 id="6-1Mybatis连接池的分类"><a href="#6-1Mybatis连接池的分类" class="headerlink" title="6.1Mybatis连接池的分类"></a>6.1Mybatis连接池的分类</h3><figure class="highlight plain"><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">UNPOOLED不使用连接池的数据源</span><br><span class="line">POOLED使用连接池的数据源（我们一般使用的数据源）</span><br><span class="line">JNDI使用JNDI实现的数据源</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">相应地，MyBatis 内部分别定义了实现了 java.sql.DataSource 接口的 UnpooledDataSource，PooledDataSource 类来表示 UNPOOLED、POOLED 类型的数据源。</span><br></pre></td></tr></table></figure><h3 id="6-2Mybatis中数据源的配置"><a href="#6-2Mybatis中数据源的配置" class="headerlink" title="6.2Mybatis中数据源的配置"></a>6.2Mybatis中数据源的配置</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></pre></td><td class="code"><pre><span class="line">数据源配置就是在 SqlMapConfig.xml 文件中，具体配置如下：</span><br><span class="line">&lt;!-- 配置数据源（连接池）信息 --&gt;</span><br><span class="line">&lt;dataSource type=<span class="string">"POOLED"</span>&gt;</span><br><span class="line">&lt;property name=<span class="string">"driver"</span> value=<span class="string">"$&#123;jdbc.driver&#125;"</span>/&gt;</span><br><span class="line">&lt;property name=<span class="string">"url"</span> value=<span class="string">"$&#123;jdbc.url&#125;"</span>/&gt;</span><br><span class="line">&lt;property name=<span class="string">"username"</span> value=<span class="string">"$&#123;jdbc.username&#125;"</span>/&gt;</span><br><span class="line">&lt;property name=<span class="string">"password"</span> value=<span class="string">"$&#123;jdbc.password&#125;"</span>/&gt;</span><br><span class="line">&lt;/dataSource&gt;</span><br><span class="line">MyBatis 在初始化时，根据&lt;dataSource&gt;的 type 属性来创建相应类型的的数据源 DataSource，即：</span><br><span class="line">type=”POOLED”：MyBatis 会创建 PooledDataSource 实例</span><br><span class="line">type=”UNPOOLED” ： MyBatis 会创建 UnpooledDataSource 实例</span><br><span class="line">type=”JNDI”：MyBatis 会从 JNDI 服务上查找 DataSource 实例，然后返回使用</span><br></pre></td></tr></table></figure><h2 id="7-Mybatis中事务控制"><a href="#7-Mybatis中事务控制" class="headerlink" title="7.Mybatis中事务控制"></a>7.Mybatis中事务控制</h2><h3 id="7-3Mybatis中事务提交方式"><a href="#7-3Mybatis中事务提交方式" class="headerlink" title="7.3Mybatis中事务提交方式"></a>7.3Mybatis中事务提交方式</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Mybatis中事务的提交方式，本质上就是调用JDBC的setAutoComment（）来实现事务控制，默认情况下setAutoComment（）的参数为false，所以我们要手动使用SqlSession.commit（）来提交事务</span><br></pre></td></tr></table></figure><h3 id="7-4Mybatis自动提交事务的设置"><a href="#7-4Mybatis自动提交事务的设置" class="headerlink" title="7.4Mybatis自动提交事务的设置"></a>7.4Mybatis自动提交事务的设置</h3><figure class="highlight plain"><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">在创建SqlSession工厂对象时，传入true</span><br><span class="line">SqlSession session = factory.openSession（true）;</span><br></pre></td></tr></table></figure><h2 id="8-Mybatis中的动态SQL语句"><a href="#8-Mybatis中的动态SQL语句" class="headerlink" title="8.Mybatis中的动态SQL语句"></a>8.Mybatis中的动态SQL语句</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">主要就是使用Mybatis中提供的动态SQL语句标签</span><br><span class="line">&lt;if&gt;</span><br><span class="line">&lt;where&gt;</span><br><span class="line">&lt;foreach&gt;</span><br></pre></td></tr></table></figure><h2 id="9-Mybatis延迟加载策略"><a href="#9-Mybatis延迟加载策略" class="headerlink" title="9.Mybatis延迟加载策略"></a>9.Mybatis延迟加载策略</h2><h3 id="9-1何为延迟加载"><a href="#9-1何为延迟加载" class="headerlink" title="9.1何为延迟加载"></a>9.1何为延迟加载</h3><figure class="highlight plain"><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><h3 id="9-2开启Mybatis的延迟加载策略"><a href="#9-2开启Mybatis的延迟加载策略" class="headerlink" title="9.2开启Mybatis的延迟加载策略"></a>9.2开启Mybatis的延迟加载策略</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></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>.需要再Mybatis的配置文件SqlMapConfig.xml文件中添加延迟加载的配置</span><br><span class="line"></span><br><span class="line">&lt;settings&gt;</span><br><span class="line">&lt;setting name=<span class="string">"lazyLoadingEnabled"</span> value=<span class="string">"true"</span>/&gt;</span><br><span class="line">&lt;setting name=<span class="string">"aggressiveLazyLoading"</span> value=<span class="string">"false"</span>/&gt;</span><br><span class="line">&lt;/settings&gt;</span><br><span class="line"></span><br><span class="line"><span class="number">2</span>.使用Collection实现延迟加载</span><br><span class="line"></span><br><span class="line">&lt;!-- collection 是用于建立一对多中集合属性的对应关系</span><br><span class="line">ofType 用于指定集合元素的数据类型</span><br><span class="line">select 是用于指定查询账户的唯一标识（账户的 dao 全限定类名加上方法名称）</span><br><span class="line">column 是用于指定使用哪个字段的值作为条件查询</span><br><span class="line">--&gt;</span><br><span class="line">&lt;collection property=<span class="string">"accounts"</span> </span><br><span class="line">    ofType=<span class="string">"account"</span></span><br><span class="line">select=<span class="string">""</span></span><br><span class="line">column=<span class="string">""</span>&gt;</span><br><span class="line">&lt;/collection&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;collection&gt;标签：</span><br><span class="line">主要用于加载关联的集合对象</span><br><span class="line">select 属性：</span><br><span class="line">用于指定查询 account 列表的 sql 语句，所以填写的是该 sql 映射的 id</span><br><span class="line">column 属性：</span><br><span class="line">用于指定 select 属性的 sql 语句的参数来源，上面的参数来自于 user 的 id 列，所以就写成 id 这一个字段名了</span><br></pre></td></tr></table></figure><h2 id="10-Mybatis缓存"><a href="#10-Mybatis缓存" class="headerlink" title="10.Mybatis缓存"></a>10.Mybatis缓存</h2><p>Mybatis通过缓存策略来减少数据库的查询次数，从而提高性能</p><h3 id="10-1Mybatis一级缓存"><a href="#10-1Mybatis一级缓存" class="headerlink" title="10.1Mybatis一级缓存"></a>10.1Mybatis一级缓存</h3><figure class="highlight plain"><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">一级缓存是 SqlSession 级别的缓存，只要 SqlSession 没有 flush 或 close，它就存在。</span><br><span class="line">一级缓存是 SqlSession 范围的缓存，当调用 SqlSession 的修改，添加，删除，commit()，close()等方法时，就会清空一级缓存。</span><br></pre></td></tr></table></figure><h3 id="10-2Mybatis二级缓存"><a href="#10-2Mybatis二级缓存" class="headerlink" title="10.2Mybatis二级缓存"></a>10.2Mybatis二级缓存</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">二级缓存是 mapper 映射级别的缓存，多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句，多个SqlSession 可以共用二级缓存，二级缓存是跨 SqlSession 的。</span><br></pre></td></tr></table></figure><h4 id="10-2-1二级缓存的开启与关闭"><a href="#10-2-1二级缓存的开启与关闭" class="headerlink" title="10.2.1二级缓存的开启与关闭"></a>10.2.1二级缓存的开启与关闭</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">第一步：在SqlMapConfig.xml文件开启二级缓存</span><br><span class="line">&lt;settings&gt;</span><br><span class="line">&lt;!-- 开启二级缓存的支持 --&gt;</span><br><span class="line">&lt;setting name=&quot;cacheEnabled&quot; value=&quot;true&quot;/&gt;</span><br><span class="line">&lt;/settings&gt;</span><br><span class="line">因为 cacheEnabled 的取值默认就为 true，所以这一步可以省略不配置。为 true 代表开启二级缓存；为false 代表不开启二级缓存。</span><br><span class="line"></span><br><span class="line">第二步：配置相关的Mapper映射文件</span><br><span class="line">&lt;cache&gt;标签表示当前这个 mapper 映射将使用二级缓存，区分的标准就看 mapper 的 namespace 值。</span><br><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="line">&lt;!DOCTYPE mapper</span><br><span class="line"> PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;</span><br><span class="line"> &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&gt;</span><br><span class="line">&lt;mapper namespace=&quot;com.holicCode.dao.IUserDao&quot;&gt;</span><br><span class="line">&lt;!-- 开启二级缓存的支持 --&gt;</span><br><span class="line">&lt;cache&gt;&lt;/cache&gt;</span><br><span class="line">&lt;/mapper&gt;</span><br><span class="line"></span><br><span class="line">第三部：配置statement上面的useCache属性</span><br><span class="line">&lt;!-- 根据 id 查询 --&gt;</span><br><span class="line">&lt;select id=&quot;findById&quot; resultType=&quot;user&quot; parameterType=&quot;int&quot; useCache=&quot;true&quot;&gt;</span><br><span class="line">select * from user where id = #&#123;uid&#125;</span><br><span class="line">&lt;/select&gt;</span><br><span class="line">将 UserDao.xml 映射文件中的&lt;select&gt;标签中设置 useCache=”true”代表当前这个 statement 要使用二级缓存，如果不使用二级缓存可以设置为 false。</span><br><span class="line">注意：针对每次查询都需要最新的数据 sql，要设置成 useCache=false，禁用二级缓存</span><br></pre></td></tr></table></figure><h4 id="10-2-2基于注解的二级缓存"><a href="#10-2-2基于注解的二级缓存" class="headerlink" title="10.2.2基于注解的二级缓存"></a>10.2.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></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>.在SqlMapConfig中开启二级缓存支持</span><br><span class="line">&lt;!-- 配置二级缓存 --&gt;</span><br><span class="line">&lt;settings&gt;</span><br><span class="line">&lt;!-- 开启二级缓存的支持 --&gt;</span><br><span class="line">&lt;setting name=<span class="string">"cacheEnabled"</span> value=<span class="string">"true"</span>/&gt;</span><br><span class="line">&lt;/settings&gt;</span><br><span class="line"></span><br><span class="line"><span class="number">2</span>.在持久层接口中使用注解配置二级缓存</span><br><span class="line"><span class="meta">@CacheNamespace</span>(blocking=<span class="keyword">true</span>)<span class="comment">//mybatis 基于注解方式实现配置二级缓存</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">IUserDao</span> </span>&#123;&#125;</span><br></pre></td></tr></table></figure><h4 id="10-2-3二级缓存的注意事项"><a href="#10-2-3二级缓存的注意事项" class="headerlink" title="10.2.3二级缓存的注意事项"></a>10.2.3二级缓存的注意事项</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">当我们在使用二级缓存时，所缓存的类一定要实现 java.io.Serializable 接口，这种就可以使用序列化方式来保存对象。</span><br></pre></td></tr></table></figure><h2 id="11-Mybatis的注解开发"><a href="#11-Mybatis的注解开发" class="headerlink" title="11.Mybatis的注解开发"></a>11.Mybatis的注解开发</h2><h3 id="11-1Mybatis常用注解说明"><a href="#11-1Mybatis常用注解说明" class="headerlink" title="11.1Mybatis常用注解说明"></a>11.1Mybatis常用注解说明</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">@Insert:实现新增</span><br><span class="line">@Update:实现更新</span><br><span class="line">@Delete:实现删除</span><br><span class="line">@Select:实现查询</span><br><span class="line">@Result:实现结果集封装</span><br><span class="line">@Results:可以与@Result 一起使用，封装多个结果集</span><br><span class="line">@ResultMap:实现引用@Results 定义的封装</span><br><span class="line">@One:实现一对一结果集封装</span><br><span class="line">@Many:实现一对多结果集封装</span><br><span class="line">@SelectProvider: 实现动态 SQL 映射</span><br><span class="line">@CacheNamespace:实现注解二级缓存的使用</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-Mybatis概述&quot;&gt;&lt;a href=&quot;#1-Mybatis概述&quot; class=&quot;he
      
    
    </summary>
    
      <category term="Mybatis" scheme="http://yoursite.com/categories/Mybatis/"/>
    
    
      <category term="Mybatis" scheme="http://yoursite.com/tags/Mybatis/"/>
    
  </entry>
  
  <entry>
    <title>MySQL初级</title>
    <link href="http://yoursite.com/2019/07/24/MySQL%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/"/>
    <id>http://yoursite.com/2019/07/24/MySQL基础知识/</id>
    <published>2019-07-24T11:09:20.220Z</published>
    <updated>2019-07-26T15:48:42.956Z</updated>
    
    <content type="html"><![CDATA[<h1 id="MySQL基础知识汇总"><a href="#MySQL基础知识汇总" class="headerlink" title="MySQL基础知识汇总"></a>MySQL基础知识汇总</h1><h2 id="数据库的基本概念"><a href="#数据库的基本概念" class="headerlink" title="数据库的基本概念"></a>数据库的基本概念</h2><pre><code>1. 数据库的英文单词： DataBase 简称 ： DB2. 什么数据库？    * 用于存储和管理数据的仓库。3. 数据库的特点：    1. 持久化存储数据的。其实数据库就是一个文件系统    2. 方便存储和管理数据    3. 使用了统一的方式操作数据库 -- SQL</code></pre><h2 id="MySQL数据库软件"><a href="#MySQL数据库软件" class="headerlink" title="MySQL数据库软件"></a>MySQL数据库软件</h2><pre><code>1. 安装2. 卸载    1. 去mysql的安装目录找到my.ini文件        * 复制 datadir=&quot;C:/ProgramData/MySQL/MySQL Server 5.5/Data/&quot;    2. 卸载MySQL    3. 删除C:/ProgramData目录下的MySQL文件夹。3. 配置    * MySQL服务启动        1. 手动。        2. cmd--&gt; services.msc 打开服务的窗口        3. 使用管理员打开cmd            * net start mysql : 启动mysql的服务            * net stop mysql:关闭mysql服务    * MySQL登录        1. mysql -uroot -p密码        2. mysql -hip -uroot -p连接目标的密码        3. mysql --host=ip --user=root --password=连接目标的密码    * MySQL退出        1. exit        2. quit    * MySQL目录结构        1. MySQL安装目录：basedir=&quot;D:/develop/MySQL/&quot;            * 配置文件 my.ini        2. MySQL数据目录：datadir=&quot;C:/ProgramData/MySQL/MySQL Server 5.5/Data/&quot;            * 几个概念                * 数据库：文件夹                * 表：文件                * 数据：数据</code></pre><h1 id="SQL"><a href="#SQL" class="headerlink" title="SQL"></a>SQL</h1><pre><code>1.什么是SQL？    Structured Query Language：结构化查询语言    其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方，称为“方言”。2.SQL通用语法    1. SQL 语句可以单行或多行书写，以分号结尾。    2. 可使用空格和缩进来增强语句的可读性。    3. MySQL 数据库的 SQL 语句不区分大小写，关键字建议使用大写。    4. 3 种注释        * 单行注释: -- 注释内容 或 # 注释内容(mysql 特有)         * 多行注释: /* 注释 */3. SQL分类    1) DDL(Data Definition Language)数据定义语言        用来定义数据库对象：数据库，表，列等。关键字：create, drop,alter 等    2) DML(Data Manipulation Language)数据操作语言        用来对数据库中表的数据进行增删改。关键字：insert, delete, update 等    3) DQL(Data Query Language)数据查询语言        用来查询数据库中表的记录(数据)。关键字：select, where 等    4) DCL(Data Control Language)数据控制语言(了解)        用来定义数据库的访问权限和安全级别，及创建用户。关键字：GRANT， REVOKE 等</code></pre><p><img src="G:%5C%E9%BB%91%E9%A9%AC%E5%BF%85%E7%9C%8B%E8%A7%86%E9%A2%91%5C%E8%AE%B2%E4%B9%89+%E7%AC%94%E8%AE%B0+%E8%B5%84%E6%96%99%5CJavaWeb%5C12.%E4%BC%9A%E5%91%98%E7%89%88(2.0)-%E5%B0%B1%E4%B8%9A%E8%AF%BE(2.0)-MySQL%5C26.MySQL%E5%9F%BA%E7%A1%80%5Cday22_MySQL%E5%9F%BA%E7%A1%80%5C01_%E8%AE%B2%E4%B9%89%5CSQL%E5%88%86%E7%B1%BB.bmp" alt="SQL分类"></p><h2 id="DDL-操作数据库、表"><a href="#DDL-操作数据库、表" class="headerlink" title="DDL:操作数据库、表"></a>DDL:操作数据库、表</h2><pre><code>1. 操作数据库：CRUD    1. C(Create):创建        * 创建数据库：            * create database 数据库名称;        * 创建数据库，判断不存在，再创建：            * create database if not exists 数据库名称;        * 创建数据库，并指定字符集            * create database 数据库名称 character set 字符集名;        * 练习： 创建db4数据库，判断是否存在，并制定字符集为gbk            * create database if not exists db4 character set gbk;    2. R(Retrieve)：查询        * 查询所有数据库的名称:            * show databases;        * 查询某个数据库的字符集:查询某个数据库的创建语句            * show create database 数据库名称;    3. U(Update):修改        * 修改数据库的字符集            * alter database 数据库名称 character set 字符集名称;    4. D(Delete):删除        * 删除数据库            * drop database 数据库名称;        * 判断数据库存在，存在再删除            * drop database if exists 数据库名称;    5. 使用数据库        * 查询当前正在使用的数据库名称            * select database();        * 使用数据库            * use 数据库名称;2. 操作表    1. C(Create):创建        1. 语法：            create table 表名(                列名1 数据类型1,                列名2 数据类型2,                ....                列名n 数据类型n            );            * 注意：最后一列，不需要加逗号（,）            * 数据库类型：                1. int：整数类型                    * age int,                2. double:小数类型                    * score double(5,2)                3. date:日期，只包含年月日，yyyy-MM-dd                4. datetime:日期，包含年月日时分秒     yyyy-MM-dd HH:mm:ss                5. timestamp:时间错类型    包含年月日时分秒     yyyy-MM-dd HH:mm:ss                        * 如果将来不给这个字段赋值，或赋值为null，则默认使用当前的系统时间，来自动赋值                6. varchar：字符串                    * name varchar(20):姓名最大20个字符                    * zhangsan 8个字符  张三 2个字符</code></pre><figure class="highlight"><table><tr><td class="gutter"><pre><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><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> student(</span><br><span class="line"><span class="keyword">id</span> <span class="built_in">int</span>,</span><br><span class="line"><span class="keyword">name</span> <span class="built_in">varchar</span>(<span class="number">32</span>),</span><br><span class="line">age <span class="built_in">int</span> ,</span><br><span class="line">score <span class="keyword">double</span>(<span class="number">4</span>,<span class="number">1</span>),</span><br><span class="line">birthday <span class="built_in">date</span>,</span><br><span class="line">insert_time <span class="built_in">timestamp</span></span><br><span class="line">);</span><br><span class="line">* 复制表：</span><br><span class="line">* create table 表名 like 被复制的表名;  </span><br><span class="line">2. R(Retrieve)：查询</span><br><span class="line">* 查询某个数据库中所有的表名称</span><br><span class="line">* show tables;</span><br><span class="line">* 查询表结构</span><br><span class="line">* desc 表名;</span><br><span class="line">3. U(<span class="keyword">Update</span>):修改</span><br><span class="line"><span class="number">1.</span> 修改表名</span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 <span class="keyword">rename</span> <span class="keyword">to</span> 新的表名;</span><br><span class="line">2. 修改表的字符集</span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 <span class="built_in">character</span> <span class="keyword">set</span> 字符集名称;</span><br><span class="line">3. 添加一列</span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 <span class="keyword">add</span> 列名 数据类型;</span><br><span class="line">4. 修改列名称 类型</span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 <span class="keyword">change</span> 列名 新列别 新数据类型;</span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 <span class="keyword">modify</span> 列名 新数据类型;</span><br><span class="line">5. 删除列</span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 <span class="keyword">drop</span> 列名;</span><br><span class="line">4. D(<span class="keyword">Delete</span>):删除</span><br><span class="line">* <span class="keyword">drop</span> <span class="keyword">table</span> 表名;</span><br><span class="line">* drop table  if exists 表名 ;</span><br></pre></td></tr></table></figure><h2 id="DML：增删改表中数据"><a href="#DML：增删改表中数据" class="headerlink" title="DML：增删改表中数据"></a>DML：增删改表中数据</h2><pre><code>1. 添加数据：    * 语法：        * insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);    * 注意：        1. 列名和值要一一对应。        2. 如果表名后，不定义列名，则默认给所有列添加值            insert into 表名 values(值1,值2,...值n);        3. 除了数字类型，其他类型需要使用引号(单双都可以)引起来2. 删除数据：    * 语法：        * delete from 表名 [where 条件]    * 注意：        1. 如果不加条件，则删除表中所有记录。        2. 如果要删除所有记录            1. delete from 表名; -- 不推荐使用。有多少条记录就会执行多少次删除操作            2. TRUNCATE TABLE 表名; -- 推荐使用，效率更高 先删除表，然后再创建一张一样的表。3. 修改数据：    * 语法：        * update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 条件];    * 注意：        1. 如果不加任何条件，则会将表中所有记录全部修改。</code></pre><h2 id="DQL：查询表中的记录"><a href="#DQL：查询表中的记录" class="headerlink" title="DQL：查询表中的记录"></a>DQL：查询表中的记录</h2><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><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">* select * from 表名;</span><br><span class="line"></span><br><span class="line">1. 语法：</span><br><span class="line"><span class="keyword">select</span></span><br><span class="line">字段列表</span><br><span class="line"><span class="keyword">from</span></span><br><span class="line">表名列表</span><br><span class="line"><span class="keyword">where</span></span><br><span class="line">条件列表</span><br><span class="line"><span class="keyword">group</span> <span class="keyword">by</span></span><br><span class="line">分组字段</span><br><span class="line"><span class="keyword">having</span></span><br><span class="line">分组之后的条件</span><br><span class="line"><span class="keyword">order</span> <span class="keyword">by</span></span><br><span class="line">排序</span><br><span class="line"><span class="keyword">limit</span></span><br><span class="line">分页限定</span><br></pre></td></tr></table></figure><pre><code>2. 基础查询    1. 多个字段的查询        select 字段名1，字段名2... from 表名；        * 注意：            * 如果查询所有字段，则可以使用*来替代字段列表。    2. 去除重复：        * distinct    3. 计算列        * 一般可以使用四则运算计算一些列的值。（一般只会进行数值型的计算）        * ifnull(表达式1,表达式2)：null参与的运算，计算结果都为null            * 表达式1：哪个字段需要判断是否为null            * 如果该字段为null后的替换值。    4. 起别名：        * as：as也可以省略</code></pre><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><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">3. 条件查询</span><br><span class="line">1. where子句后跟条件</span><br><span class="line">2. 运算符</span><br><span class="line">* &gt; 、&lt; 、&lt;= 、&gt;= 、= 、&lt;&gt;</span><br><span class="line">* BETWEEN...AND  </span><br><span class="line">* IN( 集合) </span><br><span class="line">* LIKE：模糊查询</span><br><span class="line">* 占位符：</span><br><span class="line">* _:单个任意字符</span><br><span class="line">* %：多个任意字符</span><br><span class="line">* IS NULL  </span><br><span class="line">* and  或 &amp;&amp;</span><br><span class="line">* or  或 || </span><br><span class="line">* not  或 !</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询年龄大于20岁</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age &gt; <span class="number">20</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age &gt;= <span class="number">20</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询年龄等于20岁</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age = <span class="number">20</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询年龄不等于20岁</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age != <span class="number">20</span>;</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age &lt;&gt; <span class="number">20</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询年龄大于等于20 小于等于30</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age &gt;= <span class="number">20</span> &amp;&amp;  age &lt;=<span class="number">30</span>;</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age &gt;= <span class="number">20</span> <span class="keyword">AND</span>  age &lt;=<span class="number">30</span>;</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age <span class="keyword">BETWEEN</span> <span class="number">20</span> <span class="keyword">AND</span> <span class="number">30</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询年龄22岁，18岁，25岁的信息</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age = <span class="number">22</span> <span class="keyword">OR</span> age = <span class="number">18</span> <span class="keyword">OR</span> age = <span class="number">25</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> age <span class="keyword">IN</span> (<span class="number">22</span>,<span class="number">18</span>,<span class="number">25</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询英语成绩为null</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> english = <span class="literal">NULL</span>; <span class="comment">-- 不对的。null值不能使用 = （!=） 判断</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> english <span class="keyword">IS</span> <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询英语成绩不为null</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> english  <span class="keyword">IS</span> <span class="keyword">NOT</span> <span class="literal">NULL</span>;</span><br></pre></td></tr></table></figure><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><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">-- 查询姓马的有哪些？ like</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> <span class="keyword">NAME</span> <span class="keyword">LIKE</span> <span class="string">'马%'</span>;</span><br><span class="line"><span class="comment">-- 查询姓名第二个字是化的人</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> <span class="keyword">NAME</span> <span class="keyword">LIKE</span> <span class="string">"_化%"</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询姓名是3个字的人</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> <span class="keyword">NAME</span> <span class="keyword">LIKE</span> <span class="string">'___'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询姓名中包含德的人</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> <span class="keyword">NAME</span> <span class="keyword">LIKE</span> <span class="string">'%德%'</span>;</span><br></pre></td></tr></table></figure><figure class="highlight"><table><tr><td class="gutter"><pre><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">4. 排序查询</span><br><span class="line">* 语法：order by 子句</span><br><span class="line">* order by 排序字段1 排序方式1 ，  排序字段2 排序方式2...</span><br><span class="line"></span><br><span class="line">* 排序方式：</span><br><span class="line">* ASC：升序，默认的。</span><br><span class="line">* DESC：降序。</span><br><span class="line"></span><br><span class="line">* 注意：</span><br><span class="line">* 如果有多个排序条件，则当前边的条件值一样时，才会判断第二条件。</span><br></pre></td></tr></table></figure><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><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">2. 聚合函数：将一列数据作为一个整体，进行纵向的计算。</span><br><span class="line">1. count：计算个数</span><br><span class="line">1. 一般选择非空的列：主键</span><br><span class="line">2. count(*)</span><br><span class="line">2. max：计算最大值</span><br><span class="line">3. min：计算最小值</span><br><span class="line">4. sum：计算和</span><br><span class="line">5. avg：计算平均值</span><br><span class="line">* 注意：聚合函数的计算，排除null值。</span><br><span class="line">解决方案：</span><br><span class="line">1. 选择不包含非空的列进行计算</span><br><span class="line">2. IFNULL函数</span><br></pre></td></tr></table></figure><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><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">3. 分组查询:</span><br><span class="line">1. 语法：group by 分组字段；</span><br><span class="line">2. 注意：</span><br><span class="line">1. 分组之后查询的字段：分组字段、聚合函数</span><br><span class="line">2. where 和 having 的区别？</span><br><span class="line">1. where 在分组之前进行限定，如果不满足条件，则不参与分组。having在分组之后进行限定，如果不满足结果，则不会被查询出来</span><br><span class="line">2. where 后不可以跟聚合函数，having可以进行聚合函数的判断。</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 按照性别分组。分别查询男、女同学的平均分</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> sex , <span class="keyword">AVG</span>(math) <span class="keyword">FROM</span> student <span class="keyword">GROUP</span> <span class="keyword">BY</span> sex;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 按照性别分组。分别查询男、女同学的平均分,人数</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> sex , <span class="keyword">AVG</span>(math),<span class="keyword">COUNT</span>(<span class="keyword">id</span>) <span class="keyword">FROM</span> student <span class="keyword">GROUP</span> <span class="keyword">BY</span> sex;</span><br><span class="line"></span><br><span class="line"><span class="comment">--  按照性别分组。分别查询男、女同学的平均分,人数 要求：分数低于70分的人，不参与分组</span></span><br><span class="line"><span class="keyword">SELECT</span> sex , <span class="keyword">AVG</span>(math),<span class="keyword">COUNT</span>(<span class="keyword">id</span>) <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> math &gt; <span class="number">70</span> <span class="keyword">GROUP</span> <span class="keyword">BY</span> sex;</span><br><span class="line"></span><br><span class="line"><span class="comment">--  按照性别分组。分别查询男、女同学的平均分,人数 要求：分数低于70分的人，不参与分组,分组之后。人数要大于2个人</span></span><br><span class="line"><span class="keyword">SELECT</span> sex , <span class="keyword">AVG</span>(math),<span class="keyword">COUNT</span>(<span class="keyword">id</span>) <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> math &gt; <span class="number">70</span> <span class="keyword">GROUP</span> <span class="keyword">BY</span> sex <span class="keyword">HAVING</span> <span class="keyword">COUNT</span>(<span class="keyword">id</span>) &gt; <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> sex , <span class="keyword">AVG</span>(math),<span class="keyword">COUNT</span>(<span class="keyword">id</span>) 人数 <span class="keyword">FROM</span> student <span class="keyword">WHERE</span> math &gt; <span class="number">70</span> <span class="keyword">GROUP</span> <span class="keyword">BY</span> sex <span class="keyword">HAVING</span> 人数 &gt; <span class="number">2</span>;</span><br></pre></td></tr></table></figure><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><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">4. 分页查询</span><br><span class="line">1. 语法：limit 开始的索引,每页查询的条数;</span><br><span class="line">2. 公式：开始的索引 = （当前的页码 - 1） * 每页显示的条数</span><br><span class="line"><span class="comment">-- 每页显示3条记录 </span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">LIMIT</span> <span class="number">0</span>,<span class="number">3</span>; <span class="comment">-- 第1页</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">LIMIT</span> <span class="number">3</span>,<span class="number">3</span>; <span class="comment">-- 第2页</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> student <span class="keyword">LIMIT</span> <span class="number">6</span>,<span class="number">3</span>; <span class="comment">-- 第3页</span></span><br><span class="line"></span><br><span class="line">3. limit 是一个MySQL"方言"</span><br></pre></td></tr></table></figure><h2 id="约束"><a href="#约束" class="headerlink" title="约束"></a>约束</h2><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><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><br><span class="line">* 分类：</span><br><span class="line">1. 主键约束：primary key</span><br><span class="line">2. 非空约束：not null</span><br><span class="line">3. 唯一约束：unique</span><br><span class="line">4. 外键约束：foreign key</span><br><span class="line"></span><br><span class="line">* 非空约束：not null，值不能为null</span><br><span class="line">1. 创建表时添加约束</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> stu(</span><br><span class="line"><span class="keyword">id</span> <span class="built_in">INT</span>,</span><br><span class="line"><span class="keyword">NAME</span> <span class="built_in">VARCHAR</span>(<span class="number">20</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="comment">-- name为非空</span></span><br><span class="line">);</span><br><span class="line">2. 创建表完后，添加非空约束</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> stu <span class="keyword">MODIFY</span> <span class="keyword">NAME</span> <span class="built_in">VARCHAR</span>(<span class="number">20</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line">3. 删除name的非空约束</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> stu <span class="keyword">MODIFY</span> <span class="keyword">NAME</span> <span class="built_in">VARCHAR</span>(<span class="number">20</span>);</span><br></pre></td></tr></table></figure><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><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">* 唯一约束：unique，值不能重复</span><br><span class="line">1. 创建表时，添加唯一约束</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> stu(</span><br><span class="line"><span class="keyword">id</span> <span class="built_in">INT</span>,</span><br><span class="line">phone_number <span class="built_in">VARCHAR</span>(<span class="number">20</span>) <span class="keyword">UNIQUE</span> <span class="comment">-- 添加了唯一约束</span></span><br><span class="line"></span><br><span class="line">);</span><br><span class="line">* 注意mysql中，唯一约束限定的列的值可以有多个null</span><br><span class="line">2. 删除唯一约束</span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> stu <span class="keyword">DROP</span> <span class="keyword">INDEX</span> phone_number;</span><br><span class="line"></span><br><span class="line">3. 在创建表后，添加唯一约束</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> stu <span class="keyword">MODIFY</span> phone_number <span class="built_in">VARCHAR</span>(<span class="number">20</span>) <span class="keyword">UNIQUE</span>;</span><br><span class="line"></span><br><span class="line">* 主键约束：primary key。</span><br><span class="line">1. 注意：</span><br><span class="line">1. 含义：非空且唯一</span><br><span class="line">2. 一张表只能有一个字段为主键</span><br><span class="line">3. 主键就是表中记录的唯一标识</span><br><span class="line"></span><br><span class="line">2. 在创建表时，添加主键约束</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> stu(</span><br><span class="line"><span class="keyword">id</span> <span class="built_in">int</span> primary <span class="keyword">key</span>,<span class="comment">-- 给id添加主键约束</span></span><br><span class="line"><span class="keyword">name</span> <span class="built_in">varchar</span>(<span class="number">20</span>)</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line">3. 删除主键</span><br><span class="line"><span class="comment">-- 错误 alter table stu modify id int ;</span></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> stu <span class="keyword">DROP</span> PRIMARY <span class="keyword">KEY</span>;</span><br><span class="line"></span><br><span class="line">4. 创建完表后，添加主键</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> stu <span class="keyword">MODIFY</span> <span class="keyword">id</span> <span class="built_in">INT</span> PRIMARY <span class="keyword">KEY</span>;</span><br><span class="line"></span><br><span class="line">5. 自动增长：</span><br><span class="line">1.  概念：如果某一列是数值类型的，使用 auto_increment 可以来完成值得自动增长</span><br><span class="line"></span><br><span class="line">2. 在创建表时，添加主键约束，并且完成主键自增长</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> stu(</span><br><span class="line"><span class="keyword">id</span> <span class="built_in">int</span> primary <span class="keyword">key</span> auto_increment,<span class="comment">-- 给id添加主键约束</span></span><br><span class="line"><span class="keyword">name</span> <span class="built_in">varchar</span>(<span class="number">20</span>)</span><br><span class="line">);</span><br><span class="line">3. 删除自动增长</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> stu <span class="keyword">MODIFY</span> <span class="keyword">id</span> <span class="built_in">INT</span>;</span><br><span class="line">4. 添加自动增长</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> stu <span class="keyword">MODIFY</span> <span class="keyword">id</span> <span class="built_in">INT</span> AUTO_INCREMENT;</span><br></pre></td></tr></table></figure><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><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">* 外键约束：foreign key,让表于表产生关系，从而保证数据的正确性。</span><br><span class="line">1. 在创建表时，可以添加外键</span><br><span class="line">* 语法：</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> 表名(</span><br><span class="line">....</span><br><span class="line">外键列</span><br><span class="line"><span class="keyword">constraint</span> 外键名称 <span class="keyword">foreign</span> <span class="keyword">key</span> (外键列名称) <span class="keyword">references</span> 主表名称(主表列名称)</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line">2. 删除外键</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> 表名 <span class="keyword">DROP</span> <span class="keyword">FOREIGN</span> <span class="keyword">KEY</span> 外键名称;</span><br><span class="line"></span><br><span class="line">3. 创建表之后，添加外键</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> 表名 <span class="keyword">ADD</span> <span class="keyword">CONSTRAINT</span> 外键名称 <span class="keyword">FOREIGN</span> <span class="keyword">KEY</span> (外键字段名称) <span class="keyword">REFERENCES</span> 主表名称(主表列名称);</span><br><span class="line"></span><br><span class="line">4. 级联操作</span><br><span class="line">1. 添加级联操作</span><br><span class="line">语法：<span class="keyword">ALTER</span> <span class="keyword">TABLE</span> 表名 <span class="keyword">ADD</span> <span class="keyword">CONSTRAINT</span> 外键名称 </span><br><span class="line"><span class="keyword">FOREIGN</span> <span class="keyword">KEY</span> (外键字段名称) <span class="keyword">REFERENCES</span> 主表名称(主表列名称) <span class="keyword">ON</span> <span class="keyword">UPDATE</span> <span class="keyword">CASCADE</span> <span class="keyword">ON</span> <span class="keyword">DELETE</span> <span class="keyword">CASCADE</span>  ;</span><br><span class="line">2. 分类：</span><br><span class="line">1. 级联更新：ON <span class="keyword">UPDATE</span> <span class="keyword">CASCADE</span> </span><br><span class="line"><span class="number">2.</span> 级联删除：<span class="keyword">ON</span> <span class="keyword">DELETE</span> <span class="keyword">CASCADE</span></span><br></pre></td></tr></table></figure><h1 id="数据库的设计"><a href="#数据库的设计" class="headerlink" title="数据库的设计"></a>数据库的设计</h1><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><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></pre></td><td class="code"><pre><span class="line">1. 多表之间的关系</span><br><span class="line">1. 分类：</span><br><span class="line">1. 一对一(了解)：</span><br><span class="line">* 如：人和身份证</span><br><span class="line">* 分析：一个人只有一个身份证，一个身份证只能对应一个人</span><br><span class="line">2. 一对多(多对一)：</span><br><span class="line">* 如：部门和员工</span><br><span class="line">* 分析：一个部门有多个员工，一个员工只能对应一个部门</span><br><span class="line">3. 多对多：</span><br><span class="line">* 如：学生和课程</span><br><span class="line">* 分析：一个学生可以选择很多门课程，一个课程也可以被很多学生选择</span><br><span class="line">2. 实现关系：</span><br><span class="line">1. 一对多(多对一)：</span><br><span class="line">* 如：部门和员工</span><br><span class="line">* 实现方式：在多的一方建立外键，指向一的一方的主键。</span><br><span class="line">2. 多对多：</span><br><span class="line">* 如：学生和课程</span><br><span class="line">* 实现方式：多对多关系实现需要借助第三张中间表。中间表至少包含两个字段，这两个字段作为第三张表的外键，分别指向两张表的主键</span><br><span class="line">3. 一对一(了解)：</span><br><span class="line">* 如：人和身份证</span><br><span class="line">* 实现方式：一对一关系实现，可以在任意一方添加唯一外键指向另一方的主键。</span><br><span class="line"></span><br><span class="line">3. 案例</span><br><span class="line"><span class="comment">/*创建用户表 tab_user</span></span><br><span class="line"><span class="comment">uid 用户主键，自增长</span></span><br><span class="line"><span class="comment">username 用户名长度 100，唯一，非空</span></span><br><span class="line"><span class="comment">password 密码长度 30，非空</span></span><br><span class="line"><span class="comment">name 真实姓名长度 100</span></span><br><span class="line"><span class="comment">birthday 生日</span></span><br><span class="line"><span class="comment">sex 性别，定长字符串 1</span></span><br><span class="line"><span class="comment">telephone 手机号，字符串 11</span></span><br><span class="line"><span class="comment">email 邮箱，字符串长度 100</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> tab_user (</span><br><span class="line">uid <span class="built_in">INT</span> PRIMARY <span class="keyword">KEY</span> AUTO_INCREMENT,</span><br><span class="line">username <span class="built_in">VARCHAR</span>(<span class="number">100</span>) <span class="keyword">UNIQUE</span> <span class="keyword">NOT</span> <span class="literal">NULL</span>,</span><br><span class="line"><span class="keyword">PASSWORD</span> <span class="built_in">VARCHAR</span>(<span class="number">30</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span>,</span><br><span class="line"><span class="keyword">NAME</span> <span class="built_in">VARCHAR</span>(<span class="number">100</span>),</span><br><span class="line">birthday <span class="built_in">DATE</span>,</span><br><span class="line">sex <span class="built_in">CHAR</span>(<span class="number">1</span>) <span class="keyword">DEFAULT</span> <span class="string">'男'</span>,</span><br><span class="line">telephone <span class="built_in">VARCHAR</span>(<span class="number">11</span>),</span><br><span class="line">email <span class="built_in">VARCHAR</span>(<span class="number">100</span>)</span><br><span class="line">);</span><br></pre></td></tr></table></figure><h2 id="数据库设计的范式"><a href="#数据库设计的范式" class="headerlink" title="数据库设计的范式"></a>数据库设计的范式</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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">1. 第一范式（1NF）：每一列都是不可分割的原子数据项</span><br><span class="line">2. 第二范式（2NF）：在1NF的基础上，非码属性必须完全依赖于码（在1NF基础上消除非主属性对主码的部分函数依赖）</span><br><span class="line">* 几个概念：</span><br><span class="line">1. 函数依赖：A--&gt;B,如果通过A属性(属性组)的值，可以确定唯一B属性的值。则称B依赖于A</span><br><span class="line">例如：学号--&gt;姓名。  （学号，课程名称） --&gt; 分数</span><br><span class="line">2. 完全函数依赖：A--&gt;B， 如果A是一个属性组，则B属性值得确定需要依赖于A属性组中所有的属性值。</span><br><span class="line">例如：（学号，课程名称） --&gt; 分数</span><br><span class="line">3. 部分函数依赖：A--&gt;B， 如果A是一个属性组，则B属性值得确定只需要依赖于A属性组中某一些值即可。</span><br><span class="line">例如：（学号，课程名称） -- &gt; 姓名</span><br><span class="line">4. 传递函数依赖：A--&gt;B, B -- &gt;C . 如果通过A属性(属性组)的值，可以确定唯一B属性的值，在通过B属性（属性组）的值可以确定唯一C属性的值，则称 C 传递函数依赖于A</span><br><span class="line">例如：学号--&gt;系名，系名--&gt;系主任</span><br><span class="line">5. 码：如果在一张表中，一个属性或属性组，被其他所有属性所完全依赖，则称这个属性(属性组)为该表的码</span><br><span class="line">例如：该表中码为：（学号，课程名称）</span><br><span class="line">* 主属性：码属性组中的所有属性</span><br><span class="line">* 非主属性：除过码属性组的属性</span><br><span class="line">3. 第三范式（3NF）：在2NF基础上，任何非主属性不依赖于其它非主属性（在2NF基础上消除传递依赖）</span><br></pre></td></tr></table></figure><h2 id="数据库的备份和还原"><a href="#数据库的备份和还原" class="headerlink" title="数据库的备份和还原"></a>数据库的备份和还原</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><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. 命令行：</span><br><span class="line">* 语法：</span><br><span class="line">* 备份： mysqldump -u用户名 -p密码 数据库名称 &gt; 保存的路径</span><br><span class="line">* 还原：</span><br><span class="line">1. 登录数据库</span><br><span class="line">2. 创建数据库</span><br><span class="line">3. 使用数据库</span><br><span class="line">4. 执行文件。source 文件路径</span><br><span class="line">2. 也可以使用图形化工具, 更加方便</span><br><span class="line">推荐 Navicat for MySQL, 个人觉得比较好用</span><br></pre></td></tr></table></figure><h1 id="MySQL的多表查询-amp-事务"><a href="#MySQL的多表查询-amp-事务" class="headerlink" title="MySQL的多表查询&amp;事务"></a>MySQL的多表查询&amp;事务</h1><h2 id="多表查询"><a href="#多表查询" class="headerlink" title="多表查询"></a>多表查询</h2><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><br><span class="line"><span class="keyword">select</span></span><br><span class="line">列名列表</span><br><span class="line"><span class="keyword">from</span></span><br><span class="line">表名列表</span><br><span class="line">where....</span><br></pre></td></tr></table></figure><figure class="highlight plain"><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">* 有两个集合A,B .取这两个集合的所有组成情况。</span><br><span class="line">* 要完成多表查询，需要消除无用的数据</span><br></pre></td></tr></table></figure><figure class="highlight"><table><tr><td class="gutter"><pre><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><br><span class="line">1. 内连接查询：</span><br><span class="line">1. 隐式内连接：使用where条件消除无用数据</span><br><span class="line">* 语法： SELECT * FROM 表1,表2 WHERE 表名1.`表1的外键` = 表2的主键;</span><br><span class="line">其中表1的外键是表二的主键</span><br><span class="line">2. 显式内连接：</span><br><span class="line">* 语法： select 字段列表 from 表1 [inner] join 表2 on 条件</span><br></pre></td></tr></table></figure><h2 id="事务"><a href="#事务" class="headerlink" title="事务"></a>事务</h2><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><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. 事务的基本介绍</span><br><span class="line">1. 概念:</span><br><span class="line">如果一个包含多个步骤的业务操作, 被事务管理, 那么这些操作要么都成功, 要们都失败</span><br><span class="line">2.操作:</span><br><span class="line">1.开启事务: <span class="keyword">start</span> <span class="keyword">transaction</span>;</span><br><span class="line">2.回滚: <span class="keyword">rollback</span>;</span><br><span class="line">3.提交: <span class="keyword">commit</span>;</span><br><span class="line">2. 事务的四大特征(ACID):</span><br><span class="line">1. 原子性(Atomicity): 是不可分割的最小操作单位, 要么都成功, 要么都失败</span><br><span class="line">2. 一致性(Consistency): 事务操作前后, 数据总量不变</span><br><span class="line">3. 隔离性(Isolation): 多个事务之间, 相互独立</span><br><span class="line">4. 持久性(Durability): 当事务提交或回滚后, 数据库会持久化的保存数据</span><br><span class="line">3. 事务的隔离级别</span><br><span class="line">1. 概念: 多个事务之间是隔离的,相互独立的, 但是如果多个事务操作同一批数据, 则会引发一些问题,设置不同的隔离级别就可以解决这些问题</span><br><span class="line">2. 存在的问题:</span><br><span class="line">1.脏读: 一个事务,读取到另一个事务中没有提交的数据</span><br><span class="line">2.不可重复读(虚读): 在同一个事务中,两次读取到的数据不一样</span><br><span class="line">2.幻读: 一个事务操作(DML)数据表中的所有记录, 另一个事务添加了一条数据,则第一个事务查询不到自己的修改</span><br><span class="line">3. 隔离级别:</span><br><span class="line">1.read uncommitted: 读未提交</span><br><span class="line">产生的问题: 脏读, 不可重复读, 幻读</span><br><span class="line">2. read committed: 读已提交(Oracle)</span><br><span class="line">        产生的问题: 不可重复读, 幻读</span><br><span class="line">        3. repeatable read: 可重复读(MySQL默认)</span><br><span class="line">        产生的问题: 幻读</span><br><span class="line">        4. serializable: 串行化</span><br><span class="line">        可以解决所有问题</span><br><span class="line">注意: 隔离级别从小到大安全性越来越高, 但是效率越来越低</span><br><span class="line"> 数据库查询隔离级别: <span class="keyword">select</span> @@tx_isolation;</span><br><span class="line"> 数据库设置隔离级别: <span class="keyword">set</span> <span class="keyword">global</span> <span class="keyword">transaction</span> <span class="keyword">isolation</span> <span class="keyword">level</span> 级别字符串;</span><br></pre></td></tr></table></figure><h2 id="DCL"><a href="#DCL" class="headerlink" title="DCL"></a>DCL</h2><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><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></pre></td><td class="code"><pre><span class="line">DCL：管理用户，授权</span><br><span class="line">1. 管理用户</span><br><span class="line">1. 添加用户：</span><br><span class="line">* 语法：CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';</span><br><span class="line">2. 删除用户：</span><br><span class="line">* 语法：DROP USER '用户名'@'主机名';</span><br><span class="line">3. 修改用户密码：</span><br><span class="line"></span><br><span class="line"><span class="keyword">UPDATE</span> <span class="keyword">USER</span> <span class="keyword">SET</span> <span class="keyword">PASSWORD</span> = <span class="keyword">PASSWORD</span>(<span class="string">'新密码'</span>) <span class="keyword">WHERE</span> <span class="keyword">USER</span> = <span class="string">'用户名'</span>;</span><br><span class="line"><span class="keyword">UPDATE</span> <span class="keyword">USER</span> <span class="keyword">SET</span> <span class="keyword">PASSWORD</span> = <span class="keyword">PASSWORD</span>(<span class="string">'abc'</span>) <span class="keyword">WHERE</span> <span class="keyword">USER</span> = <span class="string">'lisi'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">SET</span> <span class="keyword">PASSWORD</span> <span class="keyword">FOR</span> <span class="string">'用户名'</span>@<span class="string">'主机名'</span> = <span class="keyword">PASSWORD</span>(<span class="string">'新密码'</span>);</span><br><span class="line"><span class="keyword">SET</span> <span class="keyword">PASSWORD</span> <span class="keyword">FOR</span> <span class="string">'root'</span>@<span class="string">'localhost'</span> = <span class="keyword">PASSWORD</span>(<span class="string">'123'</span>);</span><br><span class="line"></span><br><span class="line">* mysql中忘记了root用户的密码？</span><br><span class="line">1. cmd <span class="comment">-- &gt; net stop mysql 停止mysql服务</span></span><br><span class="line">* 需要管理员运行该cmd</span><br><span class="line"></span><br><span class="line">2. 使用无验证方式启动mysql服务： mysqld <span class="comment">--skip-grant-tables</span></span><br><span class="line">3. 打开新的cmd窗口,直接输入mysql命令，敲回车。就可以登录成功</span><br><span class="line">4. <span class="keyword">use</span> mysql;</span><br><span class="line">5. <span class="keyword">update</span> <span class="keyword">user</span> <span class="keyword">set</span> <span class="keyword">password</span> = <span class="keyword">password</span>(<span class="string">'你的新密码'</span>) <span class="keyword">where</span> <span class="keyword">user</span> = <span class="string">'root'</span>;</span><br><span class="line">6. 关闭两个窗口</span><br><span class="line">7. 打开任务管理器，手动结束mysqld.exe 的进程</span><br><span class="line">8. 启动mysql服务</span><br><span class="line">9. 使用新密码登录。</span><br><span class="line">4. 查询用户：</span><br><span class="line"><span class="comment">-- 1. 切换到mysql数据库</span></span><br><span class="line"><span class="keyword">USE</span> myql;</span><br><span class="line"><span class="comment">-- 2. 查询user表</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> <span class="keyword">USER</span>;</span><br><span class="line"></span><br><span class="line">* 通配符： % 表示可以在任意主机使用用户登录数据库</span><br><span class="line"></span><br><span class="line">2. 权限管理：</span><br><span class="line">1. 查询权限：</span><br><span class="line"><span class="comment">-- 查询权限</span></span><br><span class="line"><span class="keyword">SHOW</span> <span class="keyword">GRANTS</span> <span class="keyword">FOR</span> <span class="string">'用户名'</span>@<span class="string">'主机名'</span>;</span><br><span class="line"><span class="keyword">SHOW</span> <span class="keyword">GRANTS</span> <span class="keyword">FOR</span> <span class="string">'lisi'</span>@<span class="string">'%'</span>;</span><br><span class="line"></span><br><span class="line">2. 授予权限：</span><br><span class="line"><span class="comment">-- 授予权限</span></span><br><span class="line"><span class="keyword">grant</span> 权限列表 <span class="keyword">on</span> 数据库名.表名 <span class="keyword">to</span> <span class="string">'用户名'</span>@<span class="string">'主机名'</span>;</span><br><span class="line"><span class="comment">-- 给张三用户授予所有权限，在任意数据库任意表上</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">GRANT</span> <span class="keyword">ALL</span> <span class="keyword">ON</span> *.* <span class="keyword">TO</span> <span class="string">'zhangsan'</span>@<span class="string">'localhost'</span>;</span><br><span class="line">3. 撤销权限：</span><br><span class="line"><span class="comment">-- 撤销权限：</span></span><br><span class="line"><span class="keyword">revoke</span> 权限列表 <span class="keyword">on</span> 数据库名.表名 <span class="keyword">from</span> <span class="string">'用户名'</span>@<span class="string">'主机名'</span>;</span><br><span class="line"><span class="keyword">REVOKE</span> <span class="keyword">UPDATE</span> <span class="keyword">ON</span> db3.<span class="string">`account`</span> <span class="keyword">FROM</span> <span class="string">'lisi'</span>@<span class="string">'%'</span>;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;MySQL基础知识汇总&quot;&gt;&lt;a href=&quot;#MySQL基础知识汇总&quot; class=&quot;headerlink&quot; title=&quot;MySQL基础知识汇总&quot;&gt;&lt;/a&gt;MySQL基础知识汇总&lt;/h1&gt;&lt;h2 id=&quot;数据库的基本概念&quot;&gt;&lt;a href=&quot;#数据库的基本概念&quot;
      
    
    </summary>
    
      <category term="SQL" scheme="http://yoursite.com/categories/SQL/"/>
    
    
      <category term="MySQL, sql语句, MySQL概念" scheme="http://yoursite.com/tags/MySQL-sql%E8%AF%AD%E5%8F%A5-MySQL%E6%A6%82%E5%BF%B5/"/>
    
  </entry>
  
  <entry>
    <title>剑指offer题库以及详解</title>
    <link href="http://yoursite.com/2019/07/24/%E5%89%91%E6%8C%87offer/"/>
    <id>http://yoursite.com/2019/07/24/剑指offer/</id>
    <published>2019-07-24T03:53:54.081Z</published>
    <updated>2019-08-20T14:44:32.282Z</updated>
    
    <content type="html"><![CDATA[<h1 id="剑指offer"><a href="#剑指offer" class="headerlink" title="剑指offer"></a><strong>剑指offer</strong></h1><h2 id="第一题"><a href="#第一题" class="headerlink" title="第一题"></a>第一题</h2><p><strong>题目</strong>:在一个二维数组中（每个一维数组的长度相同），每一行都按照从左到右递增的顺序排序，每一列都按照从上到下递增的顺序排序。请完成一个函数，输入这样的一个二维数组和一个整数，判断数组中是否含有该整数。</p><p><strong>思路</strong>:因为这个二维数组是有序的, 可以先定位到左下角, 判断要找的数,  如果target &gt; 左下角 就往右找, 然后target &lt; 左下角 就往上找</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">Find</span><span class="params">(<span class="keyword">int</span> target, <span class="keyword">int</span> [][] array)</span> </span>&#123;</span><br><span class="line"><span class="comment">//得到二维数组的行和列</span></span><br><span class="line"><span class="keyword">int</span> rows = array.length;</span><br><span class="line"><span class="keyword">int</span> cols = array[<span class="number">0</span>].length;</span><br><span class="line"><span class="comment">//定位到左下角</span></span><br><span class="line"><span class="keyword">int</span> i = rows - <span class="number">1</span>;</span><br><span class="line"><span class="keyword">int</span> j = <span class="number">0</span>;</span><br><span class="line"><span class="comment">//循环查找, 不知道循环次数, 用while</span></span><br><span class="line"><span class="keyword">while</span>(i &gt;= <span class="number">0</span> &amp;&amp; j &lt; cols)&#123;</span><br><span class="line"><span class="keyword">if</span>(target &gt; array[i][j])</span><br><span class="line">j++;</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">if</span>(target &lt; array[i][j])</span><br><span class="line">i--;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第二题"><a href="#第二题" class="headerlink" title="第二题"></a>第二题</h2><p><strong>题目</strong>: 请实现一个函数，将一个字符串中的每个空格替换成“%20”。例如，当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。</p><p><strong>思路</strong>:首先不能使用String提供的replace()方法</p><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><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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">replaceSpace</span><span class="params">(StringBuffer str)</span> </span>&#123;</span><br><span class="line"><span class="comment">//计算空格数</span></span><br><span class="line"><span class="keyword">int</span> spacenum = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; str.length(); i++)&#123;</span><br><span class="line"><span class="keyword">if</span>(str.charAt(i) == <span class="string">' '</span>)</span><br><span class="line">spacenum++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//扩容</span></span><br><span class="line"><span class="keyword">int</span> indexOld = str.length() - <span class="number">1</span>;</span><br><span class="line"><span class="keyword">int</span> newLength = str.length() + spacenum * <span class="number">2</span>;</span><br><span class="line"><span class="keyword">int</span> indexNew = newLength - <span class="number">1</span>;</span><br><span class="line">str.setLength(indexNew);</span><br><span class="line"><span class="comment">//替换</span></span><br><span class="line"><span class="keyword">for</span>(;indexOld &gt;= <span class="number">0</span> &amp;&amp; newLength &gt; indexOld; --indexOld)&#123;</span><br><span class="line"><span class="keyword">if</span>(str.charAt(indexOld) == <span class="string">' '</span>)&#123;</span><br><span class="line">str.setCharAt(indexNew--, <span class="string">'0'</span>);</span><br><span class="line">str.setCharAt(indexNew--, <span class="string">'2'</span>);</span><br><span class="line">str.setCharAt(indexNew--, <span class="string">'%'</span>);</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">str.setCharAt(indexNew--, str.charAt(indexOld));</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> str.toString();</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第三题"><a href="#第三题" class="headerlink" title="第三题"></a>第三题</h2><p><strong>题目</strong>: 输入一个链表，按链表值从尾到头的顺序返回一个ArrayList。</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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ListNode</span> </span>&#123;</span><br><span class="line">       <span class="keyword">int</span> val;</span><br><span class="line">       ListNode next = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">       ListNode(<span class="keyword">int</span> val) &#123;</span><br><span class="line">           <span class="keyword">this</span>.val = val;</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure><p><strong>代码实现:</strong> </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><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"><span class="comment">//先创建一个 ArrayList 集合</span></span><br><span class="line">ArrayList&lt;Integer&gt; arrayList = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ArrayList&lt;Integer&gt; <span class="title">printListFromTailToHead</span><span class="params">(ListNode listNode)</span> </span>&#123;</span><br><span class="line"><span class="comment">//判断传入的链表是否不为空</span></span><br><span class="line"><span class="keyword">if</span>(listNode != <span class="keyword">null</span>)&#123;</span><br><span class="line"><span class="comment">//递归调用 printListFromTailToHead()方法, 传入链表的元素</span></span><br><span class="line"><span class="keyword">this</span>.printListFromTailToHead(listNode.next);</span><br><span class="line"><span class="comment">//将遍历出来的链表的元素的值添加入 arrayList 中</span></span><br><span class="line">arrayList.add(listNode.val);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> arrayList;</span><br><span class="line">    &#125;</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><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">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.Stack;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ArrayList&lt;Integer&gt; <span class="title">printListFromTailToHead</span><span class="params">(ListNode listNode)</span> </span>&#123;</span><br><span class="line">        Stack&lt;Integer&gt; temp = <span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">        ArrayList&lt;Integer&gt; newList = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        ListNode t = listNode;</span><br><span class="line">        <span class="keyword">while</span>( t != <span class="keyword">null</span> )&#123;</span><br><span class="line">temp.push(t.val);</span><br><span class="line">t = t.next;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">while</span>( !temp.empty() )&#123;</span><br><span class="line">newList.add(temp.pop());</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> newList;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第四题"><a href="#第四题" class="headerlink" title="第四题"></a>第四题</h2><p><strong>题目</strong>: 输入某二叉树的前序遍历和中序遍历的结果，请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}，则重建二叉树并返回。</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">Definition <span class="keyword">for</span> binary tree</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TreeNode</span> </span>&#123;</span><br><span class="line">       <span class="keyword">int</span> val;</span><br><span class="line">       TreeNode left;</span><br><span class="line">       TreeNode right;</span><br><span class="line">       TreeNode(<span class="keyword">int</span> x) &#123; val = x;&#125;</span><br><span class="line">   &#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><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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> TreeNode <span class="title">reConstructBinaryTree</span><span class="params">(<span class="keyword">int</span> [] pre,<span class="keyword">int</span> [] in)</span> </span>&#123;</span><br><span class="line">        TreeNode root=reConstructBinaryTree(pre,<span class="number">0</span>,pre.length-<span class="number">1</span>,in,<span class="number">0</span>,in.length-<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//前序遍历&#123;1,2,4,7,3,5,6,8&#125;和中序遍历序列&#123;4,7,2,1,5,3,8,6&#125;</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> TreeNode <span class="title">reConstructBinaryTree</span><span class="params">(<span class="keyword">int</span> [] pre,<span class="keyword">int</span> startPre,<span class="keyword">int</span> endPre,<span class="keyword">int</span> [] in,<span class="keyword">int</span> startIn,<span class="keyword">int</span> endIn)</span> </span>&#123;</span><br><span class="line">         </span><br><span class="line">        <span class="keyword">if</span>(startPre&gt;endPre||startIn&gt;endIn)</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">        TreeNode root= <span class="keyword">new</span> TreeNode(pre[startPre]); <span class="comment">//前序遍历结果的 第一个元素就是根节点</span></span><br><span class="line">         </span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=startIn;i&lt;=endIn;i++)</span><br><span class="line">            <span class="keyword">if</span>(in[i]==pre[startPre])&#123;</span><br><span class="line">                root.left=reConstructBinaryTree(pre,startPre+<span class="number">1</span>,startPre+i-startIn,in,startIn,i-<span class="number">1</span>);</span><br><span class="line">                root.right=reConstructBinaryTree(pre,i-startIn+startPre+<span class="number">1</span>,endPre,in,i+<span class="number">1</span>,endIn);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">                 </span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第五题"><a href="#第五题" class="headerlink" title="第五题"></a>第五题</h2><p><strong>题目</strong>: 用两个栈来实现一个队列,完成队列的Push和Pop操作, 队列中的元素为 int 类型</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><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="keyword">import</span> java.util.Stack;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    Stack&lt;Integer&gt; stack1 = <span class="keyword">new</span> Stack&lt;Integer&gt;();</span><br><span class="line">    Stack&lt;Integer&gt; stack2 = <span class="keyword">new</span> Stack&lt;Integer&gt;();</span><br><span class="line">    </span><br><span class="line"><span class="comment">//队列的 push 操作和 栈的 push 是相同的</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">push</span><span class="params">(<span class="keyword">int</span> node)</span> </span>&#123;</span><br><span class="line">        stack1.push(node);</span><br><span class="line">    &#125;</span><br><span class="line">     </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">pop</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="comment">//判断 stack1 和 stack2 是否为空</span></span><br><span class="line">        <span class="keyword">if</span>(stack1.empty()&amp;&amp;stack2.empty())&#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(<span class="string">"Queue is empty!"</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span>(stack2.empty())&#123;</span><br><span class="line">            <span class="keyword">while</span>(!stack1.empty())&#123;</span><br><span class="line">                stack2.push(stack1.pop());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> stack2.pop();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第六题"><a href="#第六题" class="headerlink" title="第六题"></a>第六题</h2><p><strong>题目</strong>:把一个数组最开始的若干元素搬到数组的末尾, 我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转, 输出旋转数组的最小元素.例如数组{3,4,5,1,2} 为 {1,2,3,4,5}, 该数组的最小值为1, NOTE: 给出的所有元素都大于0, 若数组大小为0 ,请返回0</p><p><strong>思路</strong>:(1)array[mid] &gt; array[high]:<br>            出现这种情况的array类似[3,4,5,6,0,1,2]，此时最小数字一定在mid的右边。<br>            low = mid + 1<br>         (2)array[mid] == array[high]:<br>            出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1]，此时最小数字不好判断在mid左边<br>            还是右边,这时只好一个一个试 ，<br>            high = high - 1<br>         (3)array[mid] &lt; array[high]:<br>            出现这种情况的array类似[2,2,3,4,5,6,6],此时最小数字一定就是array[mid]或者在mid的左<br>            边。因为右边必然都是递增的。<br>            high = mid</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">minNumberInRotateArray</span><span class="params">(<span class="keyword">int</span> [] array)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> low = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> hight = array.length - <span class="number">1</span>;</span><br><span class="line"><span class="keyword">while</span>(low &lt; hight)&#123;</span><br><span class="line"><span class="comment">//中间的位置</span></span><br><span class="line"><span class="keyword">int</span> mid = low + (hight - low)/<span class="number">2</span>;</span><br><span class="line"><span class="comment">//若中间的数 &gt; 最后一个数, 最小的数就是中间数的下一个</span></span><br><span class="line"><span class="keyword">if</span>(array[mid] &gt; array[hight])&#123;</span><br><span class="line">low = mid + <span class="number">1</span>;</span><br><span class="line"><span class="comment">//若中间的数 = 最后一个数, 最小的数左右都有可能, 所有要缩小,继续找</span></span><br><span class="line">&#125;<span class="keyword">else</span> <span class="keyword">if</span>(array[mid] == array[hight])&#123;</span><br><span class="line">hight -= <span class="number">1</span>;</span><br><span class="line"><span class="comment">//若中间的数 &lt; 最后一个数, 最小的数只能是中间的数,或,中间数的左边的数中的某一个</span></span><br><span class="line">&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">hight = mid;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> array[low];</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第七题"><a href="#第七题" class="headerlink" title="第七题"></a>第七题</h2><p><strong>题目</strong>: 输入一个整数n, 请你输出斐波那契列的第n项(从0开始,第0项为0)</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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">Fibonacci</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(n &lt; <span class="number">2</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> n;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> Fibonacci(n - <span class="number">1</span>) + Fibonacci(n - <span class="number">2</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><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><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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">Fibonacci</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(n &lt; <span class="number">0</span>) <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"输入的数不能小于0"</span>);</span><br><span class="line">        <span class="keyword">if</span>(n == <span class="number">0</span> || n == <span class="number">1</span>) <span class="keyword">return</span> n;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">1</span>, b = <span class="number">0</span>, sum = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">2</span>;i &lt;= n;i++)&#123;</span><br><span class="line">            sum = a + b;</span><br><span class="line">            b = a;</span><br><span class="line">            a = sum;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sum;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第八题"><a href="#第八题" class="headerlink" title="第八题"></a>第八题</h2><p><strong>题目</strong>: 一只青蛙一次可以跳上1级台阶，也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法（先后次序不同算不同的结果）。</p><p><strong>思路</strong>: 这还是一个斐波那契列, 唯一不同的是从1开始</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">JumpFloor</span><span class="params">(<span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(target &lt; <span class="number">1</span>) <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"台阶数不能小于1"</span>);;</span><br><span class="line">        <span class="keyword">if</span>(target &lt; <span class="number">3</span>) <span class="keyword">return</span> target;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">1</span>, b = <span class="number">2</span>, sum = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">3</span>;i &lt;= target;i++)&#123;</span><br><span class="line">            sum = a + b;</span><br><span class="line">            a = b;</span><br><span class="line">            b = sum;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sum;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第九题"><a href="#第九题" class="headerlink" title="第九题"></a>第九题</h2><p><strong>题目</strong>: 一只青蛙一次可以跳上1级台阶，也可以跳上2级……它也可以跳上n级。<br>            求该青蛙跳上一个n级的台阶总共有多少种跳法。<br><strong>分析</strong>:    f(1) = 1<br>            f(2) = f(2-1) + f(2-2)         //f(2-2) 表示2阶一次跳2阶的次数。<br>            f(3) = f(3-1) + f(3-2) + f(3-3)<br>            …<br>            f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n) </p><pre><code>说明：     1）这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。    2）n = 1时，只有1种跳法，f(1) = 1    3) n = 2时，会有两个跳得方式，一次1阶或者2阶，这回归到了问题（1） ，f(2) = f(2-1) + f(2-2)     4) n = 3时，会有三种跳得方式，1阶、2阶、3阶，那么就是第一次跳出1阶后面剩下：f(3-1);第一次跳出2阶，剩下f(3-2)；第一次3阶，那么剩下f(3-3)因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)    5) n = n时，会有n中跳的方式，1阶、2阶...n阶，得出结论：f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) =&gt; f(0) + f(1) + f(2) + f(3) + ... + f(n-1)    6) 由以上已经是一种结论，但是为了简单，我们可以继续简化：f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)可以得出：f(n) = 2*f(n-1)    7) 得出最终结论,在n阶台阶，一次有1、2、...n阶的跳的方式时，总得跳法为：               | 1       ,(n=0 )     f(n) =     | 1       ,(n=1 )               | 2*f(n-1),(n&gt;=2)</code></pre><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><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">JumpFloorII</span><span class="params">(<span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(target &lt; <span class="number">0</span>) <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"台阶数不能小于0"</span>);</span><br><span class="line">        <span class="keyword">if</span>(target == <span class="number">1</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">2</span> * JumpFloorII(target - <span class="number">1</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="第十题"><a href="#第十题" class="headerlink" title="第十题"></a>第十题</h2><p><strong>题目</strong>: 我们可以用2×1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2×n的大矩形，总共有多少种方法？</p><p><strong>分析</strong>: 还是一个斐波那契</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">RectCover</span><span class="params">(<span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(target &lt; <span class="number">0</span>) <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"输入的n不能小于0的整数"</span>);</span><br><span class="line">        <span class="keyword">if</span>(target == <span class="number">0</span> || target == <span class="number">1</span> || target == <span class="number">2</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> target;</span><br><span class="line">        &#125; <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> RectCover(target - <span class="number">1</span>) + RectCover(target - <span class="number">2</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">RectCover</span><span class="params">(<span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(target &lt; <span class="number">0</span>) <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"输入的数不能小于0"</span>);</span><br><span class="line">        <span class="keyword">if</span>(target == <span class="number">0</span> || target == <span class="number">1</span>) <span class="keyword">return</span> target;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">1</span>, b = <span class="number">1</span>, sum = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">2</span>;i &lt;= target;i++)&#123;</span><br><span class="line">            sum = a + b;</span><br><span class="line">            b = a;</span><br><span class="line">            a = sum;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sum;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第十一题"><a href="#第十一题" class="headerlink" title="第十一题"></a>第十一题</h2><p><strong>题目</strong>: 输入一个整数, 输出该数二进制表示中1的个数, 其中负数用补码表示</p><p><strong>思路</strong>:如果一个整数不为0，那么这个整数至少有一位是1。如果我们把这个整数减1，那么原来处在整数最右边的1就会变为0，原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。</p><p><strong>举个例子</strong>：一个二进制数1100，从右边数起第三位是处于最右边的一个1。减去1后，第三位变成0，它后面的两位0变成了1，而前面的1保持不变，因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算，从原来整数最右边一个1那一位开始所有位都会变成0。如1100&amp;1011=1000.也就是说，把一个整数减去1，再和原整数做与运算，会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1，就可以进行多少次这样的操作。</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="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">NumberOf1</span><span class="params">(<span class="keyword">int</span> n)</span></span>&#123;</span><br><span class="line"><span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span>(n != <span class="number">0</span>)&#123;</span><br><span class="line">count++;</span><br><span class="line">n = n &amp; (n - <span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第十二题"><a href="#第十二题" class="headerlink" title="第十二题"></a>第十二题</h2><p>题目: 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。</p><p>解法一: 常规解法, 时间复杂度为O(n)</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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">Power</span><span class="params">(<span class="keyword">double</span> base, <span class="keyword">int</span> exponent)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">double</span> result = <span class="number">1</span>;</span><br><span class="line">        <span class="comment">//abs() : 返回这个数的绝对值</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i &lt; Math.abs(exponent);i++)&#123;</span><br><span class="line">            result *= base;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(exponent &lt; <span class="number">0</span>)&#123;</span><br><span class="line">            result = <span class="number">1</span>/result;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>解法二: 递归: </p><blockquote><p>​        n为偶数时, a^n = a^(n/2) * a^(n/2)</p><p>​        n为奇数时, a^n=（a^（n-1）/2）×（a^（n-1/2））×a</p><p>时间复杂度为 O(logn)</p></blockquote><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="function"><span class="keyword">public</span> class <span class="title">Solution</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">Power</span><span class="params">(<span class="keyword">double</span> base, <span class="keyword">int</span> exponent)</span></span>&#123;</span><br><span class="line">        <span class="keyword">int</span> n = Math.abs(exponent);</span><br><span class="line">        <span class="keyword">if</span>(n == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">if</span>(n == <span class="number">1</span>) <span class="keyword">return</span> base;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">double</span> result = Power(base, n&gt;&gt;<span class="number">1</span>);</span><br><span class="line">        result *= result;</span><br><span class="line">        <span class="keyword">if</span>((n&amp;<span class="number">1</span>) == <span class="number">1</span>) result *= base;</span><br><span class="line">        <span class="keyword">if</span>(exponent &lt; <span class="number">0</span>) result = <span class="number">1</span>/result;</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第十三题"><a href="#第十三题" class="headerlink" title="第十三题"></a>第十三题</h2><p>题目: 输入一个整数数组,实现一个函数来调整该数组中的数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变.</p><p>思路: </p><figure class="highlight plain"><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">然后新建一个等长数组，设置两个指针，奇数指针从0开始，偶数指针从奇数个数的末尾开始 遍历，填数</span><br><span class="line">此方法的时间复杂度为O(n)</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><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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">reOrderArray</span><span class="params">(<span class="keyword">int</span> [] array)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(array.length == <span class="number">0</span> ||array.length == <span class="number">1</span>) <span class="keyword">return</span>;</span><br><span class="line">        <span class="keyword">int</span> oddCount = <span class="number">0</span>,oddBegin = <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//创建一个和原数组等长的新数组</span></span><br><span class="line">        <span class="keyword">int</span>[] newArray = <span class="keyword">new</span> <span class="keyword">int</span>[array.length];</span><br><span class="line">        <span class="comment">//遍历数组</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i &lt; array.length;i++)&#123;</span><br><span class="line">            <span class="comment">//判断数组元素为奇数时,将oddCount向后移一位,</span></span><br><span class="line">            <span class="comment">//最终oddCount的位置就是第一个偶数的位置</span></span><br><span class="line">            <span class="keyword">if</span>((array[i]&amp;<span class="number">1</span>) == <span class="number">1</span>) oddCount++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i &lt; array.length;i++)&#123;</span><br><span class="line">            <span class="comment">//判断元素为奇数就从新数组的开头位置开始放</span></span><br><span class="line">            <span class="keyword">if</span>((array[i]&amp;<span class="number">1</span>) == <span class="number">1</span>)&#123;</span><br><span class="line">                newArray[oddBegin++] = array[i];</span><br><span class="line">            &#125; <span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="comment">//如果元素为偶数就从新数组的偶数第一个位置开始放</span></span><br><span class="line">                newArray[oddCount++] = array[i];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//最后用新数组排好序的元素替换原数组的元素</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i &lt; array.length;i++)&#123;</span><br><span class="line">            array[i] = newArray[i];</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="第十四题"><a href="#第十四题" class="headerlink" title="第十四题"></a>第十四题</h2><p>题目: 输入一个链表,输出该链表中倒数第K个节点</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="comment">/*</span></span><br><span class="line"><span class="comment">public class ListNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    ListNode next = null;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    ListNode(int val) &#123;</span></span><br><span class="line"><span class="comment">        this.val = val;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;*/</span></span><br></pre></td></tr></table></figure><p>思路: 定义两个指针, 先让着两个指针都指向链表的头结点, 然后让其中一个指针往后移(k - 1)位, 再让另一个指针开始跑(此时两个指针在相对静止的跑), 当先跑的那个指针到达链表末尾时, 后跑的那个指针到达的位置就是倒数第k的位置</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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ListNode <span class="title">FindKthToTail</span><span class="params">(ListNode head,<span class="keyword">int</span> k)</span></span>&#123;</span><br><span class="line">        <span class="comment">//定义两个指针都指向头结点</span></span><br><span class="line">        ListNode p, q;</span><br><span class="line">        p = q = head;</span><br><span class="line">        <span class="comment">//记录k值</span></span><br><span class="line">        <span class="keyword">int</span> a = k;</span><br><span class="line">        <span class="comment">//记录节点个数</span></span><br><span class="line">        <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(p != <span class="keyword">null</span>)&#123;</span><br><span class="line">            p = p.next;</span><br><span class="line">            count++;</span><br><span class="line">            <span class="keyword">if</span>(k &lt; <span class="number">1</span>) q = q.next;</span><br><span class="line">            k--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(count &lt; a) <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">return</span> q;</span><br><span class="line">    &#125;</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><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"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ListNode <span class="title">FindKthToTail</span><span class="params">(ListNode head,<span class="keyword">int</span> k)</span></span>&#123;</span><br><span class="line">    ListNode p, q;</span><br><span class="line">    p = q = head;</span><br><span class="line">    <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>( ; p != <span class="keyword">null</span>; i++)&#123;</span><br><span class="line">    <span class="keyword">if</span>(i &gt;= k) q = q.next;</span><br><span class="line">    p = p.next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> i &lt; k ? <span class="keyword">null</span> : q;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第十五题"><a href="#第十五题" class="headerlink" title="第十五题"></a>第十五题</h2><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="comment">/*</span></span><br><span class="line"><span class="comment">public class ListNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    ListNode next = null;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    ListNode(int val) &#123;</span></span><br><span class="line"><span class="comment">        this.val = val;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;*/</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><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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ListNode <span class="title">ReverseList</span><span class="params">(ListNode head)</span> </span>&#123;</span><br><span class="line">       </span><br><span class="line">        <span class="keyword">if</span>(head==<span class="keyword">null</span>)</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">        <span class="comment">//head为当前节点，如果当前节点为空的话，那就什么也不做，直接返回null；</span></span><br><span class="line">        ListNode pre = <span class="keyword">null</span>;</span><br><span class="line">        ListNode next = <span class="keyword">null</span>;</span><br><span class="line">        <span class="comment">//当前节点是head，pre为当前节点的前一节点，next为当前节点的下一节点</span></span><br><span class="line">        <span class="comment">//需要pre和next的目的是让当前节点从pre-&gt;head-&gt;next1-&gt;next2变成pre&lt;-head next1-&gt;next2</span></span><br><span class="line">        <span class="comment">//即pre让节点可以反转所指方向，但反转之后如果不用next节点保存next1节点的话，此单链表就此断开了</span></span><br><span class="line">        <span class="comment">//所以需要用到pre和next两个节点</span></span><br><span class="line">        <span class="comment">//1-&gt;2-&gt;3-&gt;4-&gt;5</span></span><br><span class="line">        <span class="comment">//1&lt;-2&lt;-3 4-&gt;5</span></span><br><span class="line">        <span class="keyword">while</span>(head!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            <span class="comment">//做循环，如果当前节点不为空的话，始终执行此循环，此循环的目的就是让当前节点从指向next到指向pre</span></span><br><span class="line">            <span class="comment">//如此就可以做到反转链表的效果</span></span><br><span class="line">            <span class="comment">//先用next保存head的下一个节点的信息，保证单链表不会因为失去head节点的原next节点而就此断裂</span></span><br><span class="line">            next = head.next;</span><br><span class="line">            <span class="comment">//保存完next，就可以让head从指向next变成指向pre了，代码如下</span></span><br><span class="line">            head.next = pre;</span><br><span class="line">            <span class="comment">//head指向pre后，就继续依次反转下一个节点</span></span><br><span class="line">            <span class="comment">//让pre，head，next依次向后移动一个节点，继续下一次的指针反转</span></span><br><span class="line">            pre = head;</span><br><span class="line">            head = next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//如果head为null的时候，pre就为最后一个节点了，但是链表已经反转完毕，pre就是反转后链表的第一个节点</span></span><br><span class="line">        <span class="comment">//直接输出pre就是我们想要得到的反转后的链表</span></span><br><span class="line">        <span class="keyword">return</span> pre;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第十六题"><a href="#第十六题" class="headerlink" title="第十六题"></a>第十六题</h2><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">public class ListNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    ListNode next = null;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    ListNode(int val) &#123;</span></span><br><span class="line"><span class="comment">        this.val = val;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//采用递归的方法</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ListNode <span class="title">Merge</span><span class="params">(ListNode list1,ListNode list2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(list1 == <span class="keyword">null</span>) <span class="keyword">return</span> list2;</span><br><span class="line">        <span class="keyword">if</span>(list2 == <span class="keyword">null</span>) <span class="keyword">return</span> list1;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span>(list1.val &lt;= list2.val)&#123;</span><br><span class="line">            list1.next = Merge(list1.next, list2);</span><br><span class="line">            <span class="keyword">return</span> list1;</span><br><span class="line">        &#125; <span class="keyword">else</span>&#123;</span><br><span class="line">            list2.next = Merge(list1, list2.next);</span><br><span class="line">            <span class="keyword">return</span> list2;</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><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="comment">//非递归版</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ListNode <span class="title">Merge</span><span class="params">(ListNode list1,ListNode list2)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//新建一个头节点，用来存合并的链表。</span></span><br><span class="line">        ListNode head=<span class="keyword">new</span> ListNode(-<span class="number">1</span>);</span><br><span class="line">        head.next=<span class="keyword">null</span>;</span><br><span class="line">        ListNode root=head;</span><br><span class="line">        <span class="keyword">while</span>(list1!=<span class="keyword">null</span>&amp;&amp;list2!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(list1.val&lt;list2.val)&#123;</span><br><span class="line">                head.next=list1;</span><br><span class="line">                head=list1;</span><br><span class="line">                list1=list1.next;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                head.next=list2;</span><br><span class="line">                head=list2;</span><br><span class="line">                list2=list2.next;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//把未结束的链表连接到合并后的链表尾部</span></span><br><span class="line">        <span class="keyword">if</span>(list1!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            head.next=list1;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(list2!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            head.next=list2;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> root.next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第十七题"><a href="#第十七题" class="headerlink" title="第十七题"></a>第十七题</h2><p>题目：输入两棵二叉树A，B，判断B是不是A的子结构。（ps：我们约定空树不是任意一个树的子结构）</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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">public class TreeNode &#123;</span></span><br><span class="line"><span class="comment">    int val = 0;</span></span><br><span class="line"><span class="comment">    TreeNode left = null;</span></span><br><span class="line"><span class="comment">    TreeNode right = null;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    public TreeNode(int val) &#123;</span></span><br><span class="line"><span class="comment">        this.val = val;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">HasSubtree</span><span class="params">(TreeNode root1, TreeNode root2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">boolean</span> result = <span class="keyword">false</span>;</span><br><span class="line">        <span class="comment">//当Tree1和Tree2都不为零的时候，才进行比较。否则直接返回false</span></span><br><span class="line">        <span class="keyword">if</span> (root2 != <span class="keyword">null</span> &amp;&amp; root1 != <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="comment">//如果找到了对应Tree2的根节点的点</span></span><br><span class="line">            <span class="keyword">if</span>(root1.val == root2.val)&#123;</span><br><span class="line">                <span class="comment">//以这个根节点为为起点判断是否包含Tree2</span></span><br><span class="line">                result = doesTree1HaveTree2(root1,root2);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//如果找不到，那么就再去root的左儿子当作起点，去判断时候包含Tree2</span></span><br><span class="line">            <span class="keyword">if</span> (!result) &#123;</span><br><span class="line">                result = HasSubtree(root1.left,root2);</span><br><span class="line">            &#125;</span><br><span class="line">             </span><br><span class="line">            <span class="comment">//如果还找不到，那么就再去root的右儿子当作起点，去判断时候包含Tree2</span></span><br><span class="line">            <span class="keyword">if</span> (!result) &#123;</span><br><span class="line">                result = HasSubtree(root1.right,root2);</span><br><span class="line">               &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//返回结果</span></span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">doesTree1HaveTree2</span><span class="params">(TreeNode node1, TreeNode node2)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//如果Tree2已经遍历完了都能对应的上，返回true</span></span><br><span class="line">        <span class="keyword">if</span> (node2 == <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//如果Tree2还没有遍历完，Tree1却遍历完了。返回false</span></span><br><span class="line">        <span class="keyword">if</span> (node1 == <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//如果其中有一个点没有对应上，返回false</span></span><br><span class="line">        <span class="keyword">if</span> (node1.val != node2.val) &#123;  </span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">         </span><br><span class="line">        <span class="comment">//如果根节点对应的上，那么就分别去子节点里面匹配</span></span><br><span class="line">        <span class="keyword">return</span> doesTree1HaveTree2(node1.left,node2.left) &amp;&amp; doesTree1HaveTree2(node1.right,node2.right);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><h2 id="第十八题"><a href="#第十八题" class="headerlink" title="第十八题"></a>第十八题</h2><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">public class TreeNode &#123;</span></span><br><span class="line"><span class="comment">    int val = 0;</span></span><br><span class="line"><span class="comment">    TreeNode left = null;</span></span><br><span class="line"><span class="comment">    TreeNode right = null;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    public TreeNode(int val) &#123;</span></span><br><span class="line"><span class="comment">        this.val = val;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">Mirror</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(root == <span class="keyword">null</span>) <span class="keyword">return</span>;</span><br><span class="line">        <span class="keyword">if</span>(root.left == <span class="keyword">null</span> &amp;&amp; root.right == <span class="keyword">null</span>) <span class="keyword">return</span>;</span><br><span class="line">        </span><br><span class="line">        TreeNode temp = root.left;</span><br><span class="line">        root.left = root.right;</span><br><span class="line">        root.right = temp;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span>(root.left != <span class="keyword">null</span>) Mirror(root.left);</span><br><span class="line">        <span class="keyword">if</span>(root.right != <span class="keyword">null</span>) Mirror(root.right);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第十九题"><a href="#第十九题" class="headerlink" title="第十九题"></a>第十九题</h2><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">public class ListNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    ListNode next = null;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    ListNode(int val) &#123;</span></span><br><span class="line"><span class="comment">        this.val = val;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//定义两个起始位置为头结点的指针,p1指在较短链表上,p2指在较长链表上</span></span><br><span class="line"><span class="comment">//让这p1,p2同时next,当p1到达链表尾部时,让p1指向较长链表的头部</span></span><br><span class="line"><span class="comment">//当p2到达链表尾部时,让p2指向较短链表头部</span></span><br><span class="line"><span class="comment">//当它们指向同一个节点时,该节点就是两个链表的第一个公共节点</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ListNode <span class="title">FindFirstCommonNode</span><span class="params">(ListNode pHead1, ListNode pHead2)</span> </span>&#123;</span><br><span class="line"> ListNode p1 = pHead1;</span><br><span class="line">        ListNode p2 = pHead2;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">while</span>(p1 != p2)&#123;</span><br><span class="line">            <span class="keyword">if</span>(p1 != <span class="keyword">null</span>) p1 = p1.next;</span><br><span class="line">            <span class="keyword">if</span>(p2 != <span class="keyword">null</span>) p2 = p2.next;</span><br><span class="line">            </span><br><span class="line">            <span class="keyword">if</span>(p1 != p2)&#123;</span><br><span class="line">                <span class="keyword">if</span>(p1 == <span class="keyword">null</span>) p1 = pHead2;</span><br><span class="line">                <span class="keyword">if</span>(p2 == <span class="keyword">null</span>) p2 = pHead1;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> p1;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第二十题"><a href="#第二十题" class="headerlink" title="第二十题"></a>第二十题</h2><p>题目：给一个链表，若其中包含环，请找出该链表的环的入口结点，否则，输出null。</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><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 class="comment">/*</span></span><br><span class="line"><span class="comment"> public class ListNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    ListNode next = null;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    ListNode(int val) &#123;</span></span><br><span class="line"><span class="comment">        this.val = val;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">    <span class="function">ListNode <span class="title">EntryNodeOfLoop</span><span class="params">(ListNode pHead)</span></span>&#123;</span><br><span class="line"><span class="comment">//判断是否为链表,不是直接返回null</span></span><br><span class="line">        <span class="keyword">if</span>(pHead == <span class="keyword">null</span> || pHead.next == <span class="keyword">null</span>) <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">        <span class="comment">//定意两个快慢指针</span></span><br><span class="line">        ListNode m = pHead.next;</span><br><span class="line">        ListNode k = pHead.next.next;</span><br><span class="line">        <span class="comment">//进行指针前进</span></span><br><span class="line">        <span class="keyword">while</span>(m != k)&#123;</span><br><span class="line">            <span class="keyword">if</span>(k != <span class="keyword">null</span> &amp;&amp; k.next != <span class="keyword">null</span>)&#123;</span><br><span class="line">             m = m.next;</span><br><span class="line">             k = k.next.next;</span><br><span class="line">     &#125; <span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">null</span>;</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">//当快慢指针指向同一个节点时,跳出while循环</span></span><br><span class="line">        k = pHead;</span><br><span class="line">        <span class="keyword">while</span>(m != k)&#123;</span><br><span class="line">            m = m.next;</span><br><span class="line">            k = k.next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> m;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="第二十一题"><a href="#第二十一题" class="headerlink" title="第二十一题"></a>第二十一题</h2><p>题目: 输入一个矩阵，按照从外向里以顺时针的顺序依次打印出每一个数字，例如，如果输入如下4 X 4矩阵： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.holicCode;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> ArrayList&lt;Integer&gt; <span class="title">printMatrix</span><span class="params">(<span class="keyword">int</span> [][] matrix)</span> </span>&#123;</span><br><span class="line">        ArrayList&lt;Integer&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (matrix == <span class="keyword">null</span> || matrix.length == <span class="number">0</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 class="keyword">int</span> up = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> down = matrix.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> left = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> right = matrix[<span class="number">0</span>].length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line">            <span class="comment">// 向右</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i = left; i &lt;= right; i++) &#123;</span><br><span class="line">                list.add(matrix[up][i]);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (++up &gt; down) &#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 向下</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i = up; i &lt;= down; i++) &#123;</span><br><span class="line">                list.add(matrix[i][right]);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (--right &lt; left) &#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 向左</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i = right; i &gt;= left; i--) &#123;</span><br><span class="line">                list.add(matrix[down][i]);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (--down &lt; up) &#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 向上</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i = down; i &gt;= up; i--) &#123;</span><br><span class="line">                list.add(matrix[i][left]);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (++left &gt; right) &#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</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><br><span class="line">    <span class="comment">//测试</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span>[][] matrix = &#123;&#123;<span class="number">1</span>&#125;,&#123;<span class="number">2</span>&#125;,&#123;<span class="number">3</span>&#125;,&#123;<span class="number">4</span>&#125;,&#123;<span class="number">5</span>&#125;&#125;;</span><br><span class="line">System.out.println(printMatrix(matrix));</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="未完-待续………"><a href="#未完-待续………" class="headerlink" title="未完,待续………."></a>未完,待续……….</h2>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;剑指offer&quot;&gt;&lt;a href=&quot;#剑指offer&quot; class=&quot;headerlink&quot; title=&quot;剑指offer&quot;&gt;&lt;/a&gt;&lt;strong&gt;剑指offer&lt;/strong&gt;&lt;/h1&gt;&lt;h2 id=&quot;第一题&quot;&gt;&lt;a href=&quot;#第一题&quot; class=&quot;h
      
    
    </summary>
    
      <category term="算法" scheme="http://yoursite.com/categories/%E7%AE%97%E6%B3%95/"/>
    
    
      <category term="剑指offer, 算法, 详解" scheme="http://yoursite.com/tags/%E5%89%91%E6%8C%87offer-%E7%AE%97%E6%B3%95-%E8%AF%A6%E8%A7%A3/"/>
    
  </entry>
  
</feed>
