<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>李子菜Lizicai</title>
    <link>https://lizicai.com/</link>
      <atom:link href="https://lizicai.com/index.xml" rel="self" type="application/rss+xml" />
    <description>李子菜Lizicai</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>en</language><lastBuildDate>Wed, 06 Jul 2022 17:25:57 +0800</lastBuildDate>
    <item>
      <title>Maven Li.074</title>
      <link>https://lizicai.com/p/maven-li.074/</link>
      <pubDate>Wed, 06 Jul 2022 17:25:57 +0800</pubDate>
      <guid>https://lizicai.com/p/maven-li.074/</guid>
      <description>&lt;h2 id=&#34;maven-坐标&#34;&gt;Maven 坐标&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Maven坐标主要组成
&lt;ul&gt;
&lt;li&gt;groupld：定义当前Maven项目隶属组织名称（通常是域名反写，例如：org.mybatis)&lt;/li&gt;
&lt;li&gt;artifactld：定义当前Maven项目名称（通常是模块名称，例如CRM、SMS)&lt;/li&gt;
&lt;li&gt;version：定义当前项目版本号&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;maven-指定本地仓库位置&#34;&gt;Maven 指定本地仓库位置&lt;/h2&gt;
&lt;h3 id=&#34;maven-软件和指定仓库位置的settingxml都需要更改&#34;&gt;Maven 软件和指定仓库位置的setting.xml都需要更改&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;localRepository&amp;gt;D:\maven\repository&amp;lt;/localRepository&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;maven-镜像&#34;&gt;Maven 镜像&lt;/h2&gt;
&lt;h4 id=&#34;maven-软件和指定仓库位置的settingxml都需要更改-1&#34;&gt;Maven 软件和指定仓库位置的setting.xml都需要更改&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;mirror&amp;gt;
    &amp;lt;id&amp;gt;&amp;lt;/id&amp;gt;
    &amp;lt;mirrorOf&amp;gt;central&amp;lt;/mirrorOf&amp;gt;
    &amp;lt;name&amp;gt;&amp;lt;/name&amp;gt;
    &amp;lt;url&amp;gt;&amp;lt;/url&amp;gt;
&amp;lt;/mirror&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;maven-项目构建命令&#34;&gt;Maven 项目构建命令&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 编译
mvn compile

# 清理
mvn clean

# 测试
mvn test

# 打包
mvn package

# 安装到本地仓库
mvn install
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;maven-插件创建工程&#34;&gt;Maven 插件创建工程&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mvn archetype:generate
    -DgroupId={project-packaging}
    -DartifactId={project-name}
    -DarchetypeArtifactId=maven-archetype-quickstart
    -Dversion={project-version}
    -DinteractiveMode=false

mvn archetype:generate &amp;#34;-DgroupId=com.companyname.bank&amp;#34; &amp;#34;-DartifactId=consumerBanking&amp;#34;
&amp;#34;-DarchetypeArtifactId=maven-archetype-quickstart&amp;#34; &amp;#34;-DinteractiveMode=false&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;idea-创建空项目&#34;&gt;Idea 创建空项目&lt;/h2&gt;
&lt;h3 id=&#34;再创建modules-即可-可创建多个maven工程&#34;&gt;再创建Modules 即可, 可创建多个maven工程&lt;/h3&gt;
&lt;h2 id=&#34;maven中依赖传递&#34;&gt;Maven中依赖传递&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;依赖具有传递性&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直接依赖: 在当前项目中通过依赖配置建立的依赖关系&lt;/li&gt;
&lt;li&gt;间接依赖: 被依赖的资源如果依赖其他资源, 当前项目间接依赖其他资源&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;依赖传递冲突问题&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;路径优先: 当依赖中出现相同的资源时, 层级越深, 优先级越低, 层级越浅, 优先级越高&lt;/li&gt;
&lt;li&gt;声明优先: 当资源在相同层级被依赖时, 配置顺序先前的覆盖配置顺序我才看到的&lt;/li&gt;
&lt;li&gt;特殊优先: 当同级配置了相同资源的不同版本, 后配置的覆盖先配置的.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;maven-依赖资源可见和排除&#34;&gt;Maven 依赖资源可见和排除&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 被依赖时, 其他人看到不到
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;4.13.1&amp;lt;/version&amp;gt;
    &amp;lt;option&amp;gt;true&amp;lt;/option&amp;gt;
&amp;lt;/dependency&amp;gt;

# 排除依赖的某个资源
&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;org.example&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;web02&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
  &amp;lt;exclusions&amp;gt;
    &amp;lt;exclusion&amp;gt;
      &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;
    &amp;lt;/exclusion&amp;gt;
  &amp;lt;/exclusions&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;依赖范围&#34;&gt;依赖范围&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;scope&lt;/th&gt;
          &lt;th&gt;主代码&lt;/th&gt;
          &lt;th&gt;测试代码&lt;/th&gt;
          &lt;th&gt;打包&lt;/th&gt;
          &lt;th&gt;范例&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;compile(默认)&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;log4j&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;test&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;junit&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;provided&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;servlet-api&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;runtime&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;jdbc&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;compile&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;test&lt;/th&gt;
          &lt;th&gt;provided&lt;/th&gt;
          &lt;th&gt;runtime&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;complile&lt;/td&gt;
          &lt;td&gt;compile&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;test&lt;/td&gt;
          &lt;td&gt;provided&lt;/td&gt;
          &lt;td&gt;runtime&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;test&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;provided&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;runtime&lt;/td&gt;
          &lt;td&gt;runtime&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;test&lt;/td&gt;
          &lt;td&gt;provided&lt;/td&gt;
          &lt;td&gt;runtime&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;maven-构建生命周期&#34;&gt;Maven 构建生命周期&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;default构建生命周期&lt;/th&gt;
          &lt;th&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;validate（校验）&lt;/td&gt;
          &lt;td&gt;校验项目是否正确并且所有必要的信息可以完成项目的构建过程。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;initialize（初始化）&lt;/td&gt;
          &lt;td&gt;初始化构建状态，比如设置属性值。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;generate-sources（生成源代码）&lt;/td&gt;
          &lt;td&gt;生成包含在编译阶段中的任何源代码。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;process-sources（处理源代码）&lt;/td&gt;
          &lt;td&gt;处理源代码，比如说，过滤任意值。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;generate-resources（生成资源文件）&lt;/td&gt;
          &lt;td&gt;生成将会包含在项目包中的资源文件。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;process-resources （处理资源文件）&lt;/td&gt;
          &lt;td&gt;复制和处理资源到目标目录，为打包阶段最好准备。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;compile（编译）&lt;/td&gt;
          &lt;td&gt;编译项目的源代码。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;process-classes（处理类文件）&lt;/td&gt;
          &lt;td&gt;处理编译生成的文件，比如说对Java class文件做字节码改善优化。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;generate-test-sources（生成测试源代码）&lt;/td&gt;
          &lt;td&gt;生成包含在编译阶段中的任何测试源代码。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;process-test-sources（处理测试源代码）&lt;/td&gt;
          &lt;td&gt;处理测试源代码，比如说，过滤任意值。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;generate-test-resources（生成测试资源文件）&lt;/td&gt;
          &lt;td&gt;为测试创建资源文件。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;process-test-resources（处理测试资源文件）&lt;/td&gt;
          &lt;td&gt;复制和处理测试资源到目标目录。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;test-compile（编译测试源码）&lt;/td&gt;
          &lt;td&gt;编译测试源代码到测试目标目录.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;process-test-classes（处理测试类文件）&lt;/td&gt;
          &lt;td&gt;处理测试源码编译生成的文件。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;test（测试）&lt;/td&gt;
          &lt;td&gt;使用合适的单元测试框架运行测试（Juint是其中之一）。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;prepare-package（准备打包）&lt;/td&gt;
          &lt;td&gt;在实际打包之前，执行任何的必要的操作为打包做准备。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;package（打包）&lt;/td&gt;
          &lt;td&gt;将编译后的代码打包成可分发格式的文件，比如JAR、WAR或者EAR文件。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;pre-integration-test（集成测试前）&lt;/td&gt;
          &lt;td&gt;在执行集成测试前进行必要的动作。比如说，搭建需要的环境。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;integration-test（集成测试）&lt;/td&gt;
          &lt;td&gt;处理和部署项目到可以运行集成测试环境中。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;post-integration-test（集成测试后）&lt;/td&gt;
          &lt;td&gt;在执行集成测试完成后进行必要的动作。比如说，清理集成测试环境。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;verify （验证）&lt;/td&gt;
          &lt;td&gt;运行任意的检查来验证项目包有效且达到质量标准。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;install（安装）&lt;/td&gt;
          &lt;td&gt;安装项目包到本地仓库，这样项目包可以用作其他本地项目的依赖。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;deploy（部署）&lt;/td&gt;
          &lt;td&gt;将最终的项目包复制到远程仓库中与其他开发者和项目共享。&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;插件&#34;&gt;插件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;build&amp;gt;
&amp;lt;plugins&amp;gt;
&amp;lt;plugin&amp;gt;
&amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;maven-source-plugin&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;3.2.1&amp;lt;/version&amp;gt;
&amp;lt;executions&amp;gt;
  &amp;lt;execution&amp;gt;
    &amp;lt;goals&amp;gt;
      &amp;lt;goal&amp;gt;jar&amp;lt;/goal&amp;gt;
      &amp;lt;/goals&amp;gt;
    &amp;lt;phase&amp;gt;generate-test-resources&amp;lt;/phase&amp;gt;
  &amp;lt;/execution&amp;gt;
&amp;lt;/executions&amp;gt;
&amp;lt;/plugin&amp;gt;
&amp;lt;/plugins&amp;gt;
&amp;lt;/build&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Redis Li.073</title>
      <link>https://lizicai.com/p/redis-li.073/</link>
      <pubDate>Tue, 10 May 2022 16:26:20 +0800</pubDate>
      <guid>https://lizicai.com/p/redis-li.073/</guid>
      <description>&lt;h2 id=&#34;redis-简介&#34;&gt;Redis 简介&lt;/h2&gt;
&lt;h3 id=&#34;nosql&#34;&gt;NoSQL&lt;/h3&gt;
&lt;p&gt;NoSQL: 即Not-Only SQL(泛指非关系型的数据库), 作为关系型数据库的补充.&lt;/p&gt;
&lt;p&gt;作用: 应对基于海量用户和海量数据前提下的数据处理问题.&lt;/p&gt;
&lt;h3 id=&#34;特征&#34;&gt;特征&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;可扩容, 可伸缩&lt;/li&gt;
&lt;li&gt;大数据量下高性能&lt;/li&gt;
&lt;li&gt;灵活的数据模型&lt;/li&gt;
&lt;li&gt;高可用&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;类nosql数据库&#34;&gt;类NoSQL数据库:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;memcache&lt;/li&gt;
&lt;li&gt;HBase&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;redis安装与配置&#34;&gt;Redis安装与配置&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;wget https://github.com/redis/redis/archive/7.0.0.tar.gz
mkdir -p /opt
mv 7.0.0.tar.gz /opt/redis.tar.gz
cd /opt
tar -xzvf redis.tar.gz
cd redis
make
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;redisconf&#34;&gt;redis.conf&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 需要创建data
dir /opt/redis/data
#默认端口6379
port 6379
#绑定ip，如果是内网可以直接绑定 127.0.0.1, 或者忽略, 0.0.0.0是外网
bind 0.0.0.0
#守护进程启动
daemonize yes
#超时
timeout 300
loglevel notice
#分区
databases 16
save 900 1
save 300 10
save 60 10000
rdbcompression yes
#存储文件
dbfilename dump.rdb
#密码 abcd123
requirepass abcd123
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;etcsystemdsystemredisservice-execstart与安装目录保持一致&#34;&gt;/etc/systemd/system/redis.service, ExecStart与安装目录保持一致&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[Unit]
Description=Redis7
After=redis7.service

[Service]
Type=forking
ExecStart=/opt/redis/src/redis-server /opt/redis/redis.conf 
ExecStop=/opt/redis/src/redis-cli shutdown
ExecReload=/bin/kill -s HUP $MAINPID
PrivateTmp=true
RestartSec=10
# The UNIX user and group to execute PostgreSQL as

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;启动&#34;&gt;启动&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;systemctl daemon-reload
systemctl start redis
systemctl stop redis
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;redis的数据类型&#34;&gt;Redis的数据类型&lt;/h2&gt;
&lt;h3 id=&#34;string&#34;&gt;String&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;存储的数据: 单个数据,最简单的数据存储类型, 也是最常用的数据存储类型&lt;/li&gt;
&lt;li&gt;存储数据的格式: 一个存储空间保存一个数据&lt;/li&gt;
&lt;li&gt;存储内容: 通常使用字符串, 如果字符串以整数的形式展示, 可以作为数字操作使用&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;基本操作&#34;&gt;基本操作&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 添加/修改数据
set key value
# 获取数据
get key
# 删除数据
del key
# 判定性添加数据
setnx key value

# 添加/修改多个数据
mset key1 value1 key2 value2 ...
# 获取多个数据
mget key1 key2 ...
获取数据字符个数
strlen key
追加信息到原始信息后部(如果原始信息存在就追加, 否则新建)
append key value
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;string-类型数据的扩展操作&#34;&gt;String 类型数据的扩展操作&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 设置数值数据增加指定范围的值
incr key
incrby key increment
incrbyfloat key increment

# 设置数值数据减少指定小范围的值
decr key
decrby key increment

# 设置数据具有指定的生命周期
setex key seconds value
psetex key milliseconds value
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;hash类型&#34;&gt;hash类型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;新的存储需求: 对一系列存储的数据进行编组, 方便管理, 典型应用存储对象信息&lt;/li&gt;
&lt;li&gt;需要的存储结构: 一个存储空间保存多个键值对数据&lt;/li&gt;
&lt;li&gt;hash类型: 底层使用哈希表学习方式去实现数据存储&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 添加/修改数据
hset key field value

# 获取数据
hget key field
hgetall key

# 删除数据
hdel key field1 [field2]

# 设置field值, 如果该field存在则不做任何操作
hsetnx key field value

# 添加/修改多个数据
hmset key field1 value1 field2 value2 ...

# 获取多个数据
hmget key field1 field2 ...

# 获取哈希表中字段的数量
hlen key

# 获取哈希表中是否存在指定的字段
hexists key field
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;hash类型数据扩展操作&#34;&gt;hash类型数据扩展操作&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 获取哈希表中所有的字段名或字段值
hkeys key
hvals key

# 设置指定字段的数值数据增加指定范围的值
hincrby key field increment
hincrbyfloat key field increment
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;list-双链结构&#34;&gt;List 双链结构&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 从左存入
lpush list1 zs ls ww zl

# 查询从start到end索引的数据
lrange list1 0 3
lrange list1 0 -1

# 从左移除一个
lpop list1

# 长度
llen list1

# 索引获取
lindex list1 1
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;list-扩展操作&#34;&gt;list 扩展操作&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 先锋队指定数据
lrem key count value

# 规定时间内获取并移除数据, 过了拿不以则返回null
blpop key1 [key2] timeout
brpop key1 [key2] timeout
brpoplpush source destination timeout
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;set&#34;&gt;set&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 添加数据
sadd key member1 [member2]

# 获取全部数据
smembers key

# 删除数据
srem key member1 [member2]

# 获取集合数据数量
scard key

# 判断集合中是否包含指定数据
sismember key member

# 随机获取集合中指定数量的数据
srandmember key [count]

# 随机获取集合中某个数据并将该数据移出集合
spop key [count]
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;set类型数据的扩展操作&#34;&gt;Set类型数据的扩展操作&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 求两个集合的交, 并, 差集
sinter key1 [key2 ...]
sunion key1 [key2 ...]
sdiff key1 [key2 ...]

# 求两个集合的交,并,差集并存储到指定集合中
sinterstore destination key1 [key2 ...]
sunionstore destination key1 [key2 ...]
sdiffstore destination key1 [key2 ...]

# 将指定数据从原始集合中移动到目标集合中
smove source destination member
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;key-基本操作&#34;&gt;key 基本操作&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 删除指定key
del key

# 获取key是否存在
exists key

# 获取key的类型
type key

# 排序
sort

# 改名
rename key newkey
renamenx key newkey

# 为指定key设置有效期
expire key seconds
pexpire key milliseconds
expireat key timestamp
pexpireat key milliseconds-timestamp

# 获取key的有效时间
ttl key
pttl key

# 切换key从时效性黑的为永久性
persist key

# 查询scan, keys会阻塞不再推荐
SCAN cursor [MATCH pattern] [COUNT count]

scan 0 MATCH list* COUNT 5
keys pattern

# MATCH模式规则
# * 匹配什么问题数量的什么任意符号 ? 配合一个任意符号  []匹配一个指定符号

*         查询所有
hh*       查询所有以hh开头
*hh       查询所有以hh结尾
??hh      查询所有前面两个字符什么任意, 后面以hh结尾
user:?    查询所有以user:开头,最后一个字符任意
u[st]er:1 查询以u开头,以er:1结尾,中间饮食一个字母,s或t
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;db-基本操作&#34;&gt;db 基本操作&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 切换数据库
select index

# 其他操作, 测试连通
ping

# 清空当前库
flushdb

# 清空所有库
flushall

# 选择库
select

# 移动
move

# 查询库内存储个数
dbsize
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;jedis&#34;&gt;Jedis&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package util;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ResourceBundle;

public class JedisUtils {

    private static int maxTotal;
    private static int maxIdle;
    private static String HOST;
    private static int PORT;
    private static JedisPoolConfig jedisPoolConfig;
    private static  JedisPool jedisPool;
    static {
        ResourceBundle bundle = ResourceBundle.getBundle(&amp;#34;redis&amp;#34;);
        maxTotal = Integer.parseInt( bundle.getString(&amp;#34;redis.maxTotal&amp;#34;));
        maxIdle = Integer.parseInt( bundle.getString(&amp;#34;redis.maxIdel&amp;#34;));
        HOST = bundle.getString(&amp;#34;redis.host&amp;#34;);
        PORT = Integer.parseInt( bundle.getString(&amp;#34;redis.port&amp;#34;));

        jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(maxTotal);
        jedisPoolConfig.setMaxIdle(maxIdle);

        jedisPool = new JedisPool(jedisPoolConfig,HOST,PORT);
    }
    public static Jedis getJedis(){

        return jedisPool.getResource();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import redis.clients.jedis.Jedis;
import util.JedisUtils;

import java.util.List;

public class Test {
    public static void main(String[] args) {

        Jedis jedis = JedisUtils.getJedis();

        jedis.auth(&amp;#34;password&amp;#34;);

        jedis.set(&amp;#34;str2&amp;#34;,&amp;#34;Mark&amp;#34;);

        jedis.sadd(&amp;#34;set1&amp;#34;,&amp;#34;a&amp;#34;,&amp;#34;B&amp;#34;,&amp;#34;CC&amp;#34;);
        long longst1 = jedis.scard(&amp;#34;set1&amp;#34;);
        System.out.println(longst1);

        jedis.lpush(&amp;#34;list1&amp;#34;,&amp;#34;ab&amp;#34;,&amp;#34;bc&amp;#34;,&amp;#34;cd&amp;#34;,&amp;#34;aa&amp;#34;);
        List&amp;lt;String&amp;gt; list1 = jedis.lrange(&amp;#34;list1&amp;#34;, 0, -1);
        System.out.println(list1.toString());

        String str1 = jedis.get(&amp;#34;str1&amp;#34;);

        System.out.println(str1);

        jedis.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;redisproperties&#34;&gt;redis.properties&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;redis.maxTotal=50
redis.maxIdel=10
redis.host=127.0.0.1
redis.port=6379 ```
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;rdb&#34;&gt;RDB&lt;/h3&gt;
&lt;h4 id=&#34;bgsave-启动子进程进行保存-优于save的阻塞保存方式&#34;&gt;bgsave 启动子进程进行保存, 优于save的阻塞保存方式&lt;/h4&gt;
&lt;h4 id=&#34;sava-2-10-10秒内2次数据变化保存-sava配置在后台执行的bgsave操作&#34;&gt;sava 2 10, 10秒内2次数据变化保存, sava配置在后台执行的bgsave操作&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;会对数据产生影响&lt;/li&gt;
&lt;li&gt;真正产生了影响, delete不算&lt;/li&gt;
&lt;li&gt;不进行数据比对, set s1 2, set s1 3算2次&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;aof-记录操作内容&#34;&gt;AOF 记录操作内容&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;appendonly yes
appendfilename &amp;#34;appendonly.aof&amp;#34;
appenddirname &amp;#34;appendonlydir&amp;#34;
appendfsync everysec
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Vue和Element二 Li.072</title>
      <link>https://lizicai.com/p/vue%E5%92%8Celement%E4%BA%8C-li.072/</link>
      <pubDate>Mon, 14 Feb 2022 15:37:02 +0800</pubDate>
      <guid>https://lizicai.com/p/vue%E5%92%8Celement%E4%BA%8C-li.072/</guid>
      <description>&lt;h2 id=&#34;vue的自定义组件&#34;&gt;Vue的自定义组件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宣言组件: 本质上, 组件是带有一个名称且可复用的Vue实例&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Vue.component(组件名称,{
        props:组件的属性,
        data:组件的数据函数,
        template:组件解析的标签模板
    }
)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;自定义组件&amp;lt;/title&amp;gt;
    &amp;lt;script src=&amp;#34;../js2/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;my-button&amp;gt;我的按钮&amp;lt;/my-button&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;
    Vue.component(&amp;#34;my-button&amp;#34;,{
        // 属性
        props:[&amp;#34;style&amp;#34;] ,
        // 数据函数
        data: function (){
            return{
                msg:&amp;#34;我的按钮&amp;#34;
            }
        },
        // 解析标签模板
        template:&amp;#34;&amp;lt;button style=&amp;#39;color:red&amp;#39;&amp;gt;{{msg}}&amp;lt;/button&amp;gt;&amp;#34;
    });
    new Vue({
        el:&amp;#34;#div&amp;#34;
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;vue的生命周期&#34;&gt;Vue的生命周期&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;生命周期的八个阶段&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;状态          阶段周期
beforeCreate  创建前
created       创建后
beforeMount   载入前
mounted       载入后
beforeUpdate  更新前
updated       更新后
beforeDestroy 销毁前
destroyed     销毁后
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;vue-异步操作&#34;&gt;Vue 异步操作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在Vue中发送异步请求, 本质上还是AJAX. 我们可以使用axios这个插件来简化操作&lt;/li&gt;
&lt;li&gt;使用步骤
&lt;ul&gt;
&lt;li&gt;引入axios核心js文件&lt;/li&gt;
&lt;li&gt;调用axios对象的方法来发起异步请求&lt;/li&gt;
&lt;li&gt;调用axios对象的方法来处理响应的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;axios常用方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法名                          作用
get(请求的资源路径与请求的参数) 发起GET方式请求
post(请求的资源路径,请求的参数) 发起POST方式请求
then(reponse)                   请求成功后的回调函数,通过resposnse获取响应的数据
catch(error)                    请求失败后的回调函数,通过error获取错误信息
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;异步操作&amp;lt;/title&amp;gt;
    &amp;lt;script src=&amp;#34;js/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;#34;https://unpkg.com/axios/dist/axios.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    {{name}}
    &amp;lt;button @click=&amp;#34;send()&amp;#34;&amp;gt;发起请求&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        data:{
            name:&amp;#34;张三&amp;#34;
        },
        methods:{
            send(){
                // // Get方式请求
                // axios.get(&amp;#34;testServlet?name=&amp;#34;+this.name)
                // .then(resp =&amp;gt; {
                //     alert(resp.data);
                // })
                // .catch(error =&amp;gt;{
                //     alert(error)
                // })

                axios.post(&amp;#34;testServlet&amp;#34;,&amp;#34;name=&amp;#34;+this.name)
                .then( resp =&amp;gt;{
                    alert(resp.data);
                })
                .catch( error =&amp;gt;{
                    alert(error)
                })
            }
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Vue和Element一 Li.071</title>
      <link>https://lizicai.com/p/vue%E5%92%8Celement%E4%B8%80-li.071/</link>
      <pubDate>Thu, 30 Dec 2021 23:14:34 +0800</pubDate>
      <guid>https://lizicai.com/p/vue%E5%92%8Celement%E4%B8%80-li.071/</guid>
      <description>&lt;h2 id=&#34;vue-简介&#34;&gt;Vue 简介&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Vue 是一套构建用户界面的渐进式前端框架。&lt;/li&gt;
&lt;li&gt;只关注视图层，并且非常容易学习，还可以很方便的与其它库或已有项目整合。&lt;/li&gt;
&lt;li&gt;通过尽可能简单的 API来实现响应数据的绑定和组合的视图组件。&lt;/li&gt;
&lt;li&gt;特点
&lt;ul&gt;
&lt;li&gt;易用：在有HTML CSS JavaScript 的基础上，快速上手。&lt;/li&gt;
&lt;li&gt;灵活：简单小巧的核心，渐进式技术栈，足以应付任何规模的应用。&lt;/li&gt;
&lt;li&gt;性能：20kb min+gzip运行大小、超快虛拟DOM、最省心的优化。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;vue-入门&#34;&gt;Vue 入门&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;快速入门&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    {{msg}}
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;js/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 脚本
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        data:{
            msg:&amp;#34;Hello Vue&amp;#34;
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Vue 核心对象: 每一个Vue程序都是从一个Vue核心对象开始的&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;let vm = new Vue({
    选项列表;
})
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Vue的程序包含视图和脚本两个核心部分&lt;/li&gt;
&lt;li&gt;选项列表
&lt;ul&gt;
&lt;li&gt;el选项: 用于接收获取到页面中的元素.(根据常用选择器获取)&lt;/li&gt;
&lt;li&gt;data选项: 用于保存当前Vue对象中的数据. 在视图中声明的变量需要在此处赋值&lt;/li&gt;
&lt;li&gt;methods选项: 用于定义方法. 方法可以直接通过对象名调用, this代表当前Vue对象&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;数据绑定
&lt;ul&gt;
&lt;li&gt;在视图部分获取脚本部分的数据&lt;/li&gt;
&lt;li&gt;{{变量名}}&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;快速入门升级&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;!--    视图--&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;div&amp;gt;姓名:{{name}}&amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;班级:{{classRoom}}&amp;lt;/div&amp;gt;
    &amp;lt;button onclick=&amp;#34;hi()&amp;#34;&amp;gt;打招呼&amp;lt;/button&amp;gt;
    &amp;lt;button onclick=&amp;#34;update()&amp;#34;&amp;gt;修改班级&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;js/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 脚本
    let vm = new Vue({
        el:&amp;#34;#div&amp;#34;,
        data:{
            name:&amp;#34;张三&amp;#34;,
            classRoom:&amp;#34;不一班&amp;#34;
        },
        methods:{
            study(){
                alert(this.name + &amp;#34;正在&amp;#34; + this.classRoom+&amp;#34;好好学习&amp;#34;)
            }
        }
    })
    // 定义打招呼的方法
    function hi(){
        vm.study();
    }
    function update(){
        vm.classRoom = &amp;#34;地球人&amp;#34;
    }
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;vue-常用指令&#34;&gt;Vue 常用指令&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;指令: 是带有v-前缀的我死属性, 不同指令具有不同含义. 例如v-html, v-if, v-for&lt;/li&gt;
&lt;li&gt;使用指令时，通常编与在标签的属性上，值可以使用JS的表达式。&lt;/li&gt;
&lt;li&gt;常用指令&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;指令      作用
v-html    把文本解析为HTML代码
v-bind    为HTML标签绑定属性值
v-if      条件性的渲染某元素,判定为true时渲染,否则不渲染
v-else    条件性的渲染某元素,判定为true时渲染,否则不渲染
v-else-if 条件性的渲染某元素,判定为true时渲染,否则不渲染
v-show    根据条件展示某元素, 区别在于切换的是display属性的值
y-for     列表渲染,           遍历容器的元素或者对象的厲性
v-on      为HTML标签绑定事件
v-model   在表单元素上创建双向数据绑定
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;文本插值
&lt;ul&gt;
&lt;li&gt;v-html: 把文本解析为HTML代码&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;文本插值&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;div&amp;gt;{{msg}}&amp;lt;/div&amp;gt;
    &amp;lt;div v-html=&amp;#34;msg&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../js/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    let vm = new Vue({
        el:&amp;#34;#div&amp;#34;,
        data:{
            msg:&amp;#34;&amp;lt;b&amp;gt;Hello Vue&amp;lt;/b&amp;gt;&amp;#34;
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;绑定属性
&lt;ul&gt;
&lt;li&gt;v-bind:为HTML标签绑定属性值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;绑定属性&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        .my{
            border: 1px solid red;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;a v-bind:href=&amp;#34;url&amp;#34;&amp;gt;百度一下&amp;lt;/a&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;a :href=&amp;#34;url&amp;#34;&amp;gt;百度一下&amp;lt;/a&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;div :class=&amp;#34;cls&amp;#34;&amp;gt;我是div&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../js/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        data:{
            url:&amp;#34;http://www.baidu.com&amp;#34;,
            cls: &amp;#34;my&amp;#34;
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;条件渲染
&lt;ul&gt;
&lt;li&gt;v-if: 条件性的渲染某元素, 判定为真时渲染,否则不渲染&lt;/li&gt;
&lt;li&gt;v-else:条件性的渲染&lt;/li&gt;
&lt;li&gt;v-else-if:条件性的渲染&lt;/li&gt;
&lt;li&gt;v-show:根据条件展示某元素,区别在于切换的是display属性的值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;条件渲染&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
&amp;lt;!--    判断num的值, 对3取余, 余数为0显示div1 余数为1显示div2 余数为2显示div3--&amp;gt;
    &amp;lt;div v-if=&amp;#34;num % 3 == 0&amp;#34;&amp;gt;div1&amp;lt;/div&amp;gt;
    &amp;lt;div v-else-if=&amp;#34;num % 3 == 1&amp;#34;&amp;gt;div2&amp;lt;/div&amp;gt;
    &amp;lt;div v-else&amp;gt;div3&amp;lt;/div&amp;gt;

    &amp;lt;div v-show=&amp;#34;flag&amp;#34;&amp;gt;div4&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../js/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        data:{
            num:2,
            flag:false
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;列表渲染
&lt;ul&gt;
&lt;li&gt;v-for:列表渲染,遍历窗口的元素或者对象的属性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;列表渲染&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;ul&amp;gt;
        &amp;lt;li v-for=&amp;#34;name in names&amp;#34;&amp;gt;
            {{name}}
        &amp;lt;/li&amp;gt;
        &amp;lt;li v-for=&amp;#34;value in student&amp;#34;&amp;gt;
            {{value}}
        &amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../js/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el: &amp;#34;#div&amp;#34;,
        data:{
            names:[&amp;#34;张三&amp;#34;,&amp;#34;李四&amp;#34;,&amp;#34;王五&amp;#34;],
            student:{
                name:&amp;#34;张三&amp;#34;,
                age:23
            }
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;事件绑定
&lt;ul&gt;
&lt;li&gt;v-on: 为HTML标签绑定事件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;事件绑定&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;div&amp;gt;{{name}}&amp;lt;/div&amp;gt;
    &amp;lt;button v-on:click=&amp;#34;change&amp;#34;&amp;gt;改变div的内容&amp;lt;/button&amp;gt;
    &amp;lt;button v-on:dblclick=&amp;#34;change&amp;#34;&amp;gt;改变div的内容&amp;lt;/button&amp;gt;
    &amp;lt;button @click=&amp;#34;change&amp;#34;&amp;gt;改变div的内容&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../js/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        data:{
            name:&amp;#34;来了呀, 老弟!&amp;#34;
        },
        methods:{
            change(){
                this.name = &amp;#34;来了&amp;#34;
            }
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;表单绑定, 只能表单使用
&lt;ul&gt;
&lt;li&gt;v-model:在表单元素上创建双向数据绑定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;双向数据绑定
&lt;ul&gt;
&lt;li&gt;更新data数据, 页面中的数据也会更新&lt;/li&gt;
&lt;li&gt;更新页面数据, data数据也会更新&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MVVM模型(Model View ViewModel)：是MVC模式的改进版
&lt;ul&gt;
&lt;li&gt;在前端页面中，JS对象表示 Model，页面表示View，两者做到了最大限度的分离。&lt;/li&gt;
&lt;li&gt;将Model和View 关联起来的就是ViewModel，它是桥梁。&lt;/li&gt;
&lt;li&gt;ViewModel 负责把 Model 的数据同步到 View 显示出来，还负责把 View 修改的数据同步回 Model.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;表单绑定&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;form  autocomplete=&amp;#34;off&amp;#34;&amp;gt;
        姓名: &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;username&amp;#34; v-model=&amp;#34;username&amp;#34;&amp;gt;
        &amp;lt;br&amp;gt;
        年龄: &amp;lt;input type=&amp;#34;number&amp;#34; name=&amp;#34;age&amp;#34; v-model=&amp;#34;age&amp;#34;&amp;gt;
    &amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../js/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        data:{
            username:&amp;#34;张三&amp;#34;,
            age:23
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;element-组件库&#34;&gt;Element 组件库&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;快速入门&amp;lt;/title&amp;gt;
    &amp;lt;link  rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;../element-ui/lib/theme-chalk/index.css&amp;#34;&amp;gt;
    &amp;lt;script src=&amp;#34;../js2/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;#34;../element-ui/lib/index.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;button&amp;gt;我是按钮&amp;lt;/button&amp;gt;
&amp;lt;br&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;template&amp;gt;
        &amp;lt;el-row class=&amp;#34;mb-4&amp;#34;&amp;gt;
            &amp;lt;el-button&amp;gt;Default&amp;lt;/el-button&amp;gt;
            &amp;lt;el-button type=&amp;#34;primary&amp;#34;&amp;gt;Primary&amp;lt;/el-button&amp;gt;
            &amp;lt;el-button type=&amp;#34;success&amp;#34;&amp;gt;Success&amp;lt;/el-button&amp;gt;
            &amp;lt;el-button type=&amp;#34;info&amp;#34;&amp;gt;Info&amp;lt;/el-button&amp;gt;
            &amp;lt;el-button type=&amp;#34;warning&amp;#34;&amp;gt;Warning&amp;lt;/el-button&amp;gt;
            &amp;lt;el-button type=&amp;#34;danger&amp;#34;&amp;gt;Danger&amp;lt;/el-button&amp;gt;
            &amp;lt;el-button&amp;gt;中文&amp;lt;/el-button&amp;gt;
        &amp;lt;/el-row&amp;gt;
        &amp;lt;br&amp;gt;

    &amp;lt;/template&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;基础布局&amp;lt;/title&amp;gt;
    &amp;lt;link  rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;../element-ui/lib/theme-chalk/index.css&amp;#34;&amp;gt;
    &amp;lt;script src=&amp;#34;../js2/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;#34;../element-ui/lib/index.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;style&amp;gt;
    .bg-purple-dark {
            background: #99a9bf;
        }
        .bg-purple {
            background: #d3dce6;
        }
        .bg-purple-light {
            background: #e5e9f2;
        }
        .grid-content {
            border-radius: 4px;
            min-height: 36px;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;template&amp;gt;
        &amp;lt;el-row&amp;gt;
            &amp;lt;el-col :span=&amp;#34;24&amp;#34;&amp;gt;&amp;lt;div class=&amp;#34;grid-content bg-purple-dark&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/el-col&amp;gt;
        &amp;lt;/el-row&amp;gt;
        &amp;lt;el-row&amp;gt;
            &amp;lt;el-col :span=&amp;#34;12&amp;#34;&amp;gt;&amp;lt;div class=&amp;#34;grid-content bg-purple&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/el-col&amp;gt;
            &amp;lt;el-col :span=&amp;#34;12&amp;#34;&amp;gt;&amp;lt;div class=&amp;#34;grid-content bg-purple-light&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/el-col&amp;gt;
        &amp;lt;/el-row&amp;gt;
        &amp;lt;el-row&amp;gt;
            &amp;lt;el-col :span=&amp;#34;8&amp;#34;&amp;gt;&amp;lt;div class=&amp;#34;grid-content bg-purple&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/el-col&amp;gt;
            &amp;lt;el-col :span=&amp;#34;8&amp;#34;&amp;gt;&amp;lt;div class=&amp;#34;grid-content bg-purple-light&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/el-col&amp;gt;
            &amp;lt;el-col :span=&amp;#34;8&amp;#34;&amp;gt;&amp;lt;div class=&amp;#34;grid-content bg-purple&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/el-col&amp;gt;
        &amp;lt;/el-row&amp;gt;
        &amp;lt;/template&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;布局方式&#34;&gt;布局方式&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;容器布局&amp;lt;/title&amp;gt;
    &amp;lt;link  rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;../element-ui/lib/theme-chalk/index.css&amp;#34;&amp;gt;
    &amp;lt;script src=&amp;#34;../js2/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;#34;../element-ui/lib/index.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;style&amp;gt;
        .el-header, .el-footer {
            background-color: #B3C0D1;
            color: #333;
            text-align: center;
            line-height: 60px;
        }

        .el-aside {
            background-color: #D3DCE6;
            color: #333;
            text-align: center;
            line-height: 300px;
        }

        .el-main {
            background-color: #E9EEF3;
            color: #333;
            text-align: center;
            line-height: 600px;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;el-container&amp;gt;
        &amp;lt;el-header&amp;gt;Header&amp;lt;/el-header&amp;gt;
        &amp;lt;el-container&amp;gt;
            &amp;lt;el-aside width=&amp;#34;300px&amp;#34;&amp;gt;Aside&amp;lt;/el-aside&amp;gt;
            &amp;lt;el-container&amp;gt;
                &amp;lt;el-main&amp;gt;Main&amp;lt;/el-main&amp;gt;
                &amp;lt;el-footer&amp;gt;Footer&amp;lt;/el-footer&amp;gt;
            &amp;lt;/el-container&amp;gt;
        &amp;lt;/el-container&amp;gt;
    &amp;lt;/el-container&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;表单组件&#34;&gt;表单组件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;容器布局&amp;lt;/title&amp;gt;
    &amp;lt;link  rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;../element-ui/lib/theme-chalk/index.css&amp;#34;&amp;gt;
    &amp;lt;script src=&amp;#34;../js2/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;#34;../element-ui/lib/index.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;style&amp;gt;

    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;el-form ref=&amp;#34;form&amp;#34; :model=&amp;#34;form&amp;#34; label-width=&amp;#34;80px&amp;#34;&amp;gt;
        &amp;lt;el-form-item label=&amp;#34;活动名称&amp;#34;&amp;gt;
            &amp;lt;el-input v-model=&amp;#34;form.name&amp;#34;&amp;gt;&amp;lt;/el-input&amp;gt;
        &amp;lt;/el-form-item&amp;gt;
        &amp;lt;el-form-item label=&amp;#34;活动区域&amp;#34;&amp;gt;
            &amp;lt;el-select v-model=&amp;#34;form.region&amp;#34; placeholder=&amp;#34;请选择活动区域&amp;#34;&amp;gt;
                &amp;lt;el-option label=&amp;#34;区域一&amp;#34; value=&amp;#34;shanghai&amp;#34;&amp;gt;&amp;lt;/el-option&amp;gt;
                &amp;lt;el-option label=&amp;#34;区域二&amp;#34; value=&amp;#34;beijing&amp;#34;&amp;gt;&amp;lt;/el-option&amp;gt;
            &amp;lt;/el-select&amp;gt;
        &amp;lt;/el-form-item&amp;gt;
        &amp;lt;el-form-item label=&amp;#34;活动时间&amp;#34;&amp;gt;
            &amp;lt;el-col :span=&amp;#34;11&amp;#34;&amp;gt;
                &amp;lt;el-date-picker type=&amp;#34;date&amp;#34; placeholder=&amp;#34;选择日期&amp;#34; v-model=&amp;#34;form.date1&amp;#34; style=&amp;#34;width: 100%;&amp;#34;&amp;gt;&amp;lt;/el-date-picker&amp;gt;
            &amp;lt;/el-col&amp;gt;
            &amp;lt;el-col class=&amp;#34;line&amp;#34; :span=&amp;#34;2&amp;#34;&amp;gt;-&amp;lt;/el-col&amp;gt;
            &amp;lt;el-col :span=&amp;#34;11&amp;#34;&amp;gt;
                &amp;lt;el-time-picker placeholder=&amp;#34;选择时间&amp;#34; v-model=&amp;#34;form.date2&amp;#34; style=&amp;#34;width: 100%;&amp;#34;&amp;gt;&amp;lt;/el-time-picker&amp;gt;
            &amp;lt;/el-col&amp;gt;
        &amp;lt;/el-form-item&amp;gt;
        &amp;lt;el-form-item label=&amp;#34;即时配送&amp;#34;&amp;gt;
            &amp;lt;el-switch v-model=&amp;#34;form.delivery&amp;#34;&amp;gt;&amp;lt;/el-switch&amp;gt;
        &amp;lt;/el-form-item&amp;gt;
        &amp;lt;el-form-item label=&amp;#34;活动性质&amp;#34;&amp;gt;
            &amp;lt;el-checkbox-group v-model=&amp;#34;form.type&amp;#34;&amp;gt;
                &amp;lt;el-checkbox label=&amp;#34;美食/餐厅线上活动&amp;#34; name=&amp;#34;type&amp;#34;&amp;gt;&amp;lt;/el-checkbox&amp;gt;
                &amp;lt;el-checkbox label=&amp;#34;地推活动&amp;#34; name=&amp;#34;type&amp;#34;&amp;gt;&amp;lt;/el-checkbox&amp;gt;
                &amp;lt;el-checkbox label=&amp;#34;线下主题活动&amp;#34; name=&amp;#34;type&amp;#34;&amp;gt;&amp;lt;/el-checkbox&amp;gt;
                &amp;lt;el-checkbox label=&amp;#34;单纯品牌曝光&amp;#34; name=&amp;#34;type&amp;#34;&amp;gt;&amp;lt;/el-checkbox&amp;gt;
            &amp;lt;/el-checkbox-group&amp;gt;
        &amp;lt;/el-form-item&amp;gt;
        &amp;lt;el-form-item label=&amp;#34;特殊资源&amp;#34;&amp;gt;
            &amp;lt;el-radio-group v-model=&amp;#34;form.resource&amp;#34;&amp;gt;
                &amp;lt;el-radio label=&amp;#34;线上品牌商赞助&amp;#34;&amp;gt;&amp;lt;/el-radio&amp;gt;
                &amp;lt;el-radio label=&amp;#34;线下场地免费&amp;#34;&amp;gt;&amp;lt;/el-radio&amp;gt;
            &amp;lt;/el-radio-group&amp;gt;
        &amp;lt;/el-form-item&amp;gt;
        &amp;lt;el-form-item label=&amp;#34;活动形式&amp;#34;&amp;gt;
            &amp;lt;el-input type=&amp;#34;textarea&amp;#34; v-model=&amp;#34;form.desc&amp;#34;&amp;gt;&amp;lt;/el-input&amp;gt;
        &amp;lt;/el-form-item&amp;gt;
        &amp;lt;el-form-item&amp;gt;
            &amp;lt;el-button type=&amp;#34;primary&amp;#34; @click=&amp;#34;onSubmit&amp;#34;&amp;gt;立即创建&amp;lt;/el-button&amp;gt;
            &amp;lt;el-button&amp;gt;取消&amp;lt;/el-button&amp;gt;
        &amp;lt;/el-form-item&amp;gt;
    &amp;lt;/el-form&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        data() {
            return {
                form: {
                    name: &amp;#39;&amp;#39;,
                    region: &amp;#39;&amp;#39;,
                    date1: &amp;#39;&amp;#39;,
                    date2: &amp;#39;&amp;#39;,
                    delivery: false,
                    type: [],
                    resource: &amp;#39;&amp;#39;,
                    desc: &amp;#39;&amp;#39;
                }
            }
        },
        methods: {
            onSubmit() {
                console.log(&amp;#39;submit!&amp;#39;);
            }
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;表格组件&#34;&gt;表格组件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;表格组件&amp;lt;/title&amp;gt;
    &amp;lt;link  rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;../element-ui/lib/theme-chalk/index.css&amp;#34;&amp;gt;
    &amp;lt;script src=&amp;#34;../js2/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;#34;../element-ui/lib/index.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;template&amp;gt;
        &amp;lt;el-table
                :data=&amp;#34;tableData&amp;#34;
                stripe
                style=&amp;#34;width: 100%&amp;#34;&amp;gt;
            &amp;lt;el-table-column
                    prop=&amp;#34;date&amp;#34;
                    label=&amp;#34;日期&amp;#34;
                    width=&amp;#34;180&amp;#34;&amp;gt;
            &amp;lt;/el-table-column&amp;gt;
            &amp;lt;el-table-column
                    prop=&amp;#34;name&amp;#34;
                    label=&amp;#34;姓名&amp;#34;
                    width=&amp;#34;180&amp;#34;&amp;gt;
            &amp;lt;/el-table-column&amp;gt;
            &amp;lt;el-table-column
                    prop=&amp;#34;address&amp;#34;
                    label=&amp;#34;地址&amp;#34;&amp;gt;
            &amp;lt;/el-table-column&amp;gt;

            &amp;lt;el-table-column
                    label=&amp;#34;操作&amp;#34;
                    width=&amp;#34;100&amp;#34;&amp;gt;
                &amp;lt;el-button size=&amp;#34;mini&amp;#34; type=&amp;#34;warning&amp;#34;&amp;gt;编辑&amp;lt;/el-button&amp;gt;
                &amp;lt;el-button size=&amp;#34;mini&amp;#34; type=&amp;#34;danger&amp;#34;&amp;gt;编辑&amp;lt;/el-button&amp;gt;
            &amp;lt;/el-table-column&amp;gt;
        &amp;lt;/el-table&amp;gt;
    &amp;lt;/template&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        data() {
            return {
                tableData: [{
                    date: &amp;#39;2016-05-02&amp;#39;,
                    name: &amp;#39;王小虎&amp;#39;,
                    address: &amp;#39;上海市普陀区金沙江路 1518 弄&amp;#39;
                }, {
                    date: &amp;#39;2016-05-04&amp;#39;,
                    name: &amp;#39;王小虎&amp;#39;,
                    address: &amp;#39;上海市普陀区金沙江路 1517 弄&amp;#39;
                }, {
                    date: &amp;#39;2016-05-01&amp;#39;,
                    name: &amp;#39;王小虎&amp;#39;,
                    address: &amp;#39;上海市普陀区金沙江路 1519 弄&amp;#39;
                }, {
                    date: &amp;#39;2016-05-03&amp;#39;,
                    name: &amp;#39;王小虎&amp;#39;,
                    address: &amp;#39;上海市普陀区金沙江路 1516 弄&amp;#39;
                }]
            }
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;顶部导航栏组件&#34;&gt;顶部导航栏组件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;顶部导航栏组件&amp;lt;/title&amp;gt;
    &amp;lt;link  rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;../element-ui/lib/theme-chalk/index.css&amp;#34;&amp;gt;
    &amp;lt;script src=&amp;#34;../js2/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;#34;../element-ui/lib/index.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;el-menu :default-active=&amp;#34;activeIndex&amp;#34; class=&amp;#34;el-menu-demo&amp;#34; mode=&amp;#34;horizontal&amp;#34; @select=&amp;#34;handleSelect&amp;#34;&amp;gt;
        &amp;lt;el-menu-item index=&amp;#34;1&amp;#34;&amp;gt;处理中心&amp;lt;/el-menu-item&amp;gt;
        &amp;lt;el-submenu index=&amp;#34;2&amp;#34;&amp;gt;
            &amp;lt;template slot=&amp;#34;title&amp;#34;&amp;gt;我的工作台&amp;lt;/template&amp;gt;
            &amp;lt;el-menu-item index=&amp;#34;2-1&amp;#34;&amp;gt;选项1&amp;lt;/el-menu-item&amp;gt;
            &amp;lt;el-menu-item index=&amp;#34;2-2&amp;#34;&amp;gt;选项2&amp;lt;/el-menu-item&amp;gt;
            &amp;lt;el-menu-item index=&amp;#34;2-3&amp;#34;&amp;gt;选项3&amp;lt;/el-menu-item&amp;gt;
            &amp;lt;el-submenu index=&amp;#34;2-4&amp;#34;&amp;gt;
                &amp;lt;template slot=&amp;#34;title&amp;#34;&amp;gt;选项4&amp;lt;/template&amp;gt;
                &amp;lt;el-menu-item index=&amp;#34;2-4-1&amp;#34;&amp;gt;选项1&amp;lt;/el-menu-item&amp;gt;
                &amp;lt;el-menu-item index=&amp;#34;2-4-2&amp;#34;&amp;gt;选项2&amp;lt;/el-menu-item&amp;gt;
                &amp;lt;el-menu-item index=&amp;#34;2-4-3&amp;#34;&amp;gt;选项3&amp;lt;/el-menu-item&amp;gt;
            &amp;lt;/el-submenu&amp;gt;
        &amp;lt;/el-submenu&amp;gt;
        &amp;lt;el-menu-item index=&amp;#34;3&amp;#34; disabled&amp;gt;消息中心&amp;lt;/el-menu-item&amp;gt;
        &amp;lt;el-menu-item index=&amp;#34;4&amp;#34;&amp;gt;&amp;lt;a href=&amp;#34;https://www.ele.me&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;订单管理&amp;lt;/a&amp;gt;&amp;lt;/el-menu-item&amp;gt;
    &amp;lt;/el-menu&amp;gt;
    &amp;lt;div class=&amp;#34;line&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;el-menu
            :default-active=&amp;#34;activeIndex2&amp;#34;
            class=&amp;#34;el-menu-demo&amp;#34;
            mode=&amp;#34;horizontal&amp;#34;
            @select=&amp;#34;handleSelect&amp;#34;
            background-color=&amp;#34;#545c64&amp;#34;
            text-color=&amp;#34;#fff&amp;#34;
            active-text-color=&amp;#34;#ffd04b&amp;#34;&amp;gt;
        &amp;lt;el-menu-item index=&amp;#34;1&amp;#34;&amp;gt;处理中心&amp;lt;/el-menu-item&amp;gt;
        &amp;lt;el-submenu index=&amp;#34;2&amp;#34;&amp;gt;
            &amp;lt;template slot=&amp;#34;title&amp;#34;&amp;gt;我的工作台&amp;lt;/template&amp;gt;
            &amp;lt;el-menu-item index=&amp;#34;2-1&amp;#34;&amp;gt;选项1&amp;lt;/el-menu-item&amp;gt;
            &amp;lt;el-menu-item index=&amp;#34;2-2&amp;#34;&amp;gt;选项2&amp;lt;/el-menu-item&amp;gt;
            &amp;lt;el-menu-item index=&amp;#34;2-3&amp;#34;&amp;gt;选项3&amp;lt;/el-menu-item&amp;gt;
            &amp;lt;el-submenu index=&amp;#34;2-4&amp;#34;&amp;gt;
                &amp;lt;template slot=&amp;#34;title&amp;#34;&amp;gt;选项4&amp;lt;/template&amp;gt;
                &amp;lt;el-menu-item index=&amp;#34;2-4-1&amp;#34;&amp;gt;选项1&amp;lt;/el-menu-item&amp;gt;
                &amp;lt;el-menu-item index=&amp;#34;2-4-2&amp;#34;&amp;gt;选项2&amp;lt;/el-menu-item&amp;gt;
                &amp;lt;el-menu-item index=&amp;#34;2-4-3&amp;#34;&amp;gt;选项3&amp;lt;/el-menu-item&amp;gt;
            &amp;lt;/el-submenu&amp;gt;
        &amp;lt;/el-submenu&amp;gt;
        &amp;lt;el-menu-item index=&amp;#34;3&amp;#34; disabled&amp;gt;消息中心&amp;lt;/el-menu-item&amp;gt;
        &amp;lt;el-menu-item index=&amp;#34;4&amp;#34;&amp;gt;&amp;lt;a href=&amp;#34;https://www.ele.me&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;订单管理&amp;lt;/a&amp;gt;&amp;lt;/el-menu-item&amp;gt;
    &amp;lt;/el-menu&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        data() {
            return {
                activeIndex: &amp;#39;1&amp;#39;,
                activeIndex2: &amp;#39;1&amp;#39;
            };
        },
        methods: {
            handleSelect(key, keyPath) {
                console.log(key, keyPath);
            }
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;侧边导航栏&#34;&gt;侧边导航栏&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;侧边导航栏&amp;lt;/title&amp;gt;
    &amp;lt;link  rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;../element-ui/lib/theme-chalk/index.css&amp;#34;&amp;gt;
    &amp;lt;script src=&amp;#34;../js2/vue.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;#34;../element-ui/lib/index.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;
    &amp;lt;el-row class=&amp;#34;tac&amp;#34;&amp;gt;
    &amp;lt;el-col :span=&amp;#34;3&amp;#34;&amp;gt;
        &amp;lt;h5&amp;gt;自定义颜色&amp;lt;/h5&amp;gt;
        &amp;lt;el-menu
                default-active=&amp;#34;2&amp;#34;
                class=&amp;#34;el-menu-vertical-demo&amp;#34;
                @open=&amp;#34;handleOpen&amp;#34;
                @close=&amp;#34;handleClose&amp;#34;
                background-color=&amp;#34;#545c64&amp;#34;
                text-color=&amp;#34;#fff&amp;#34;
                active-text-color=&amp;#34;#ffd04b&amp;#34;&amp;gt;
            &amp;lt;el-submenu index=&amp;#34;1&amp;#34;&amp;gt;
                &amp;lt;template slot=&amp;#34;title&amp;#34;&amp;gt;
                    &amp;lt;i class=&amp;#34;el-icon-location&amp;#34;&amp;gt;&amp;lt;/i&amp;gt;
                    &amp;lt;span&amp;gt;导航一&amp;lt;/span&amp;gt;
                &amp;lt;/template&amp;gt;
                &amp;lt;el-menu-item-group&amp;gt;
                    &amp;lt;template slot=&amp;#34;title&amp;#34;&amp;gt;分组一&amp;lt;/template&amp;gt;
                    &amp;lt;el-menu-item index=&amp;#34;1-1&amp;#34;&amp;gt;选项1&amp;lt;/el-menu-item&amp;gt;
                    &amp;lt;el-menu-item index=&amp;#34;1-2&amp;#34;&amp;gt;选项2&amp;lt;/el-menu-item&amp;gt;
                &amp;lt;/el-menu-item-group&amp;gt;
                &amp;lt;el-menu-item-group title=&amp;#34;分组2&amp;#34;&amp;gt;
                    &amp;lt;el-menu-item index=&amp;#34;1-3&amp;#34;&amp;gt;选项3&amp;lt;/el-menu-item&amp;gt;
                &amp;lt;/el-menu-item-group&amp;gt;
                &amp;lt;el-submenu index=&amp;#34;1-4&amp;#34;&amp;gt;
                    &amp;lt;template slot=&amp;#34;title&amp;#34;&amp;gt;选项4&amp;lt;/template&amp;gt;
                    &amp;lt;el-menu-item index=&amp;#34;1-4-1&amp;#34;&amp;gt;选项1&amp;lt;/el-menu-item&amp;gt;
                &amp;lt;/el-submenu&amp;gt;
            &amp;lt;/el-submenu&amp;gt;
            &amp;lt;el-menu-item index=&amp;#34;2&amp;#34;&amp;gt;
                &amp;lt;i class=&amp;#34;el-icon-menu&amp;#34;&amp;gt;&amp;lt;/i&amp;gt;
                &amp;lt;span slot=&amp;#34;title&amp;#34;&amp;gt;导航二&amp;lt;/span&amp;gt;
            &amp;lt;/el-menu-item&amp;gt;
            &amp;lt;el-menu-item index=&amp;#34;3&amp;#34; disabled&amp;gt;
                &amp;lt;i class=&amp;#34;el-icon-document&amp;#34;&amp;gt;&amp;lt;/i&amp;gt;
                &amp;lt;span slot=&amp;#34;title&amp;#34;&amp;gt;导航三&amp;lt;/span&amp;gt;
            &amp;lt;/el-menu-item&amp;gt;
            &amp;lt;el-menu-item index=&amp;#34;4&amp;#34;&amp;gt;
                &amp;lt;i class=&amp;#34;el-icon-setting&amp;#34;&amp;gt;&amp;lt;/i&amp;gt;
                &amp;lt;span slot=&amp;#34;title&amp;#34;&amp;gt;导航四&amp;lt;/span&amp;gt;
            &amp;lt;/el-menu-item&amp;gt;
        &amp;lt;/el-menu&amp;gt;
    &amp;lt;/el-col&amp;gt;
    &amp;lt;/el-row&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;
    new Vue({
        el:&amp;#34;#div&amp;#34;,
        methods: {
            handleOpen(key, keyPath) {
                console.log(key, keyPath);
            },
            handleClose(key, keyPath) {
                console.log(key, keyPath);
            }
        }
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>AJAX Li.070</title>
      <link>https://lizicai.com/p/ajax-li.070/</link>
      <pubDate>Fri, 10 Dec 2021 11:14:44 +0800</pubDate>
      <guid>https://lizicai.com/p/ajax-li.070/</guid>
      <description>&lt;h2 id=&#34;ajax-介绍&#34;&gt;AJAX 介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AJAX(Asynchronous JavaScript And XML): 异步的JavaScript和XML&lt;/li&gt;
&lt;li&gt;本身不是新技术, 而是多个技术的综合. 用于快速创建动态网页的技术.&lt;/li&gt;
&lt;li&gt;一般的负面如果需要更新内容, 必需重新加载整个页面&lt;/li&gt;
&lt;li&gt;而AJAX通过浏览器与服务器进行少量数据交换, 不可以使网页异步更新. 不重新加载整个页面, 对网页部分内容局部更新&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;原生javascript-实现ajax&#34;&gt;原生JavaScript 实现AJAX&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;核心对象：xMLHttpRequest
&lt;ul&gt;
&lt;li&gt;用于在后台与服务器交换数据。可以在不重新加载整个网页的情况下，对网页的某部分进行更新。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;打开链接：open(method,url,async)
&lt;ul&gt;
&lt;li&gt;method ：请求的类型 GET 或 POST.&lt;/li&gt;
&lt;li&gt;url：请求资源的路径,&lt;/li&gt;
&lt;li&gt;async：true(异步) 或false(同步）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;发送请求：send(String params)
&lt;ul&gt;
&lt;li&gt;params：请求的参数(POST 专用）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;处理响应：onreadystatechange
&lt;ul&gt;
&lt;li&gt;readyState ：0-请求末初始化，1-服务器连接已建立，2-请求已接收 ，3-请求处理中，4-请求已完成，且响应已就绪。&lt;/li&gt;
&lt;li&gt;status：200-响应已全部OK。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获得响应数据形式
&lt;ul&gt;
&lt;li&gt;response Text ：获得字符串形式的响应数据。&lt;/li&gt;
&lt;li&gt;responseXML：获得XML形式的响应&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;jquery的get方式实现ajax&#34;&gt;jQuery的Get方式实现AJAX&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;核心语法：$.get(url,[data],[callback],[type]);
&lt;ul&gt;
&lt;li&gt;url：请求的资源路径&lt;/li&gt;
&lt;li&gt;data：发送给服务器端的请求参数，格式可以是key=value，也可以是js对象&lt;/li&gt;
&lt;li&gt;callback ：当请求成功后的回调函数，可以在函数中编写我们的逻辑代码&lt;/li&gt;
&lt;li&gt;type : 预期的返回数据的类型, 取值可以是xml, html, js, ison, text等&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@WebServlet(&amp;#34;/userServlet&amp;#34;)
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding(&amp;#34;UTF-8&amp;#34;);
        resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);

        // 1. 获取请求参数
        String username = req.getParameter(&amp;#34;username&amp;#34;);

        // 2. 判断姓名是否注册
        if(&amp;#34;zhangsan&amp;#34;.equals(username)){
            resp.getWriter().write((&amp;#34;&amp;lt;font color=&amp;#39;red&amp;#39;&amp;gt;用户名已注册&amp;lt;/font&amp;gt;&amp;#34;));
        }else{
            resp.getWriter().write((&amp;#34;&amp;lt;font color=&amp;#39;green&amp;#39;&amp;gt;用户名可用&amp;lt;/font&amp;gt;&amp;#34;));
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;用户注册&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form autocomplete=&amp;#34;off&amp;#34; &amp;gt;
    姓名: &amp;lt;input type=&amp;#34;text&amp;#34; id=&amp;#34;username&amp;#34;&amp;gt;
    &amp;lt;span id=&amp;#34;uSpan&amp;#34;&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;br&amp;gt;
    密码: &amp;lt;input type=&amp;#34;password&amp;#34; id=&amp;#34;password&amp;#34;&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;input type=&amp;#34;submit&amp;#34; value=&amp;#34;注册&amp;#34;&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;js/jquery-3.6.0.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
// 1. 为姓名绑定推动焦点事件
    $(&amp;#34;#username&amp;#34;).blur(function(){
        let username = $(&amp;#34;#username&amp;#34;).val();
        // 2. jQuery的get方式实现AJAX
        $.get(
        &amp;#34;userServlet&amp;#34;,
        &amp;#34;username=&amp;#34;+username,
        // 3. 回调函数
        function(data){
            // 将响应的数据显示到span标签
            $(&amp;#34;#uSpan&amp;#34;).html(data)
        },
        &amp;#34;text&amp;#34;
        );
    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery的post方式实现ajax&#34;&gt;jQuery的POST方式实现AJAX&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;核心语法：$.post(url,[data],[callback],[type])
&lt;ul&gt;
&lt;li&gt;url：请求的资源路径&lt;/li&gt;
&lt;li&gt;data：发送给服务器端的请求参数，格式可以是key=value，也可以是js对象&lt;/li&gt;
&lt;li&gt;callback ：当请求成功后的回调函数，可以在函数中编写我们的逻辑代码&lt;/li&gt;
&lt;li&gt;type : 预期的返回数据的类型, 取值可以是xml, html, js, ison, text等&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script src=&amp;#34;js/jquery-3.6.0.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
// 1. 为姓名绑定推动焦点事件
    $(&amp;#34;#username&amp;#34;).blur(function(){
        let username = $(&amp;#34;#username&amp;#34;).val();
        // 2. jQuery的POST方式实现AJAX
        $.post(
        &amp;#34;userServlet&amp;#34;,
        &amp;#34;username=&amp;#34;+username,
        // 3. 回调函数
        function(data){
            // 将响应的数据显示到span标签
            $(&amp;#34;#uSpan&amp;#34;).html(data)
        },
        &amp;#34;text&amp;#34;
        );
    })
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery的通用方式实现ajax&#34;&gt;jQuery的通用方式实现AJAX&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;核心语法: $.ajax({name:value,name:value,&amp;hellip;});
&lt;ul&gt;
&lt;li&gt;url ：请求的资源路径.&lt;/li&gt;
&lt;li&gt;async ：是否异步请求，true-是，false-否（默认是true)。&lt;/li&gt;
&lt;li&gt;data：发送到服务器的数据，可以是键值对形式，也可以是js对象形式。&lt;/li&gt;
&lt;li&gt;type：请求方式，POST或GET （默认是GET)。&lt;/li&gt;
&lt;li&gt;dataType：预期的返回数据的券型，取值可以是xml,html,js, json, text等。&lt;/li&gt;
&lt;li&gt;success ：请求成功时调用的回调函数。&lt;/li&gt;
&lt;li&gt;error ：请求失败时调用的回调函数。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script src=&amp;#34;js/jquery-3.6.0.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
// 1. 为姓名绑定推动焦点事件
    $(&amp;#34;#username&amp;#34;).blur(function(){
        let username = $(&amp;#34;#username&amp;#34;).val();

        $.ajax({
            url: &amp;#34;userServlet&amp;#34;,
            async: true,
            data: &amp;#34;username=&amp;#34; + username,
            type: &amp;#34;GET&amp;#34;,
            success: function (data) {
                $(&amp;#34;#uSpan&amp;#34;).html(data)
            },
            dataType: &amp;#34;text&amp;#34;,
            error: function () {
                $(&amp;#34;#uSpan&amp;#34;).html(&amp;#34;&amp;lt;font color=&amp;#39;red&amp;#39;&amp;gt;出错了, 请稍后重试&amp;lt;/font&amp;gt;&amp;#34;)
            }
        });
    })
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;json-格式&#34;&gt;JSON 格式&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;类型&lt;/th&gt;
          &lt;th&gt;语法&lt;/th&gt;
          &lt;th&gt;说明&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;对象类型&lt;/td&gt;
          &lt;td&gt;{name:value,name:value,&amp;hellip;}&lt;/td&gt;
          &lt;td&gt;name是字符串类型,&lt;br&gt;value可以是任意类型&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;数组/集合类型&lt;/td&gt;
          &lt;td&gt;[{name:value,&amp;hellip;},{name:value,&amp;hellip;}]&lt;/td&gt;
          &lt;td&gt;name是字符串类型,&lt;br&gt;value可以是任意类型&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;混合类型&lt;/td&gt;
          &lt;td&gt;{name:&lt;br&gt; [{name:value,&amp;hellip;},{name:value,&amp;hellip;}]&lt;br&gt;}&lt;/td&gt;
          &lt;td&gt;name是字符串类型,&lt;br&gt;value可以是任意类型&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;常用方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;成员方法        说明
stringify(对象) 将指定对象转换为json格式字符串
parse(字符串)   将指定json格式字符串解析成对象
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;JSON Java 转换工具 jackson&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;类名          说明
ObjectMapper  Jackson工具包的核心类,它提供一些方法来实现JSON字符串和对象之间的转换
TypeReference 对集合泛型的反序列化,使用TypeReference可以明确的指定反序列化的对象类型
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;ObjectMappper 常用方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法名                                                 说明
String.writeValueAsString(Object.obj)                  将Java对象转换成JSON字符串
&amp;lt;T&amp;gt;T.readValue(String.json,Class&amp;lt;T&amp;gt;.valueType)         将JSON字符串转换成Java对象
&amp;lt;T&amp;gt;T.readValue(String.json,TypeReference.valueTypeRef) 将JSON字符串转换成Java对象
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class User {
    private String name;
    private Integer age;

    public User(){}
    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.example.ajax2;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import com.example.ajax2.User;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ObjectMapperTest {

    private ObjectMapper mapper = new ObjectMapper();
    // 1. User对象转换json, json转User对象
    @Test
    public void test01() throws JsonProcessingException {
        User user1 = new User(&amp;#34;张三&amp;#34;, 23);
        String json = mapper.writeValueAsString(user1);
        System.out.println(&amp;#34;json字符串&amp;#34;+json);

        User user2 = mapper.readValue(json, User.class);
        System.out.println(&amp;#34;Java对象&amp;#34;+user2);
    }

    // 2.map&amp;lt;String,String&amp;gt;转json json转map&amp;lt;String,String&amp;gt;

    @Test
    public void test02() throws IOException {
        Map&amp;lt;String,String&amp;gt; map = new HashMap&amp;lt;&amp;gt;();
        map.put(&amp;#34;姓名&amp;#34;,&amp;#34;张三&amp;#34;);
        map.put(&amp;#34;性别&amp;#34;,&amp;#34;男&amp;#34;);
        String json = mapper.writeValueAsString(map);
        System.out.println(&amp;#34;json字符串&amp;#34;+json);

        HashMap map2 = mapper.readValue(json, HashMap.class);
        System.out.println(&amp;#34;Map对象&amp;#34;+map2);

    }

    // 3. map&amp;lt;String,User&amp;gt;转json json转map&amp;lt;String,User&amp;gt;
    @Test
    public void test03() throws Exception{
        Map&amp;lt;String, User&amp;gt; map1 = new HashMap&amp;lt;&amp;gt;();
        map1.put(&amp;#34;1&amp;#34;, new User(&amp;#34;张三&amp;#34;,23));
        map1.put(&amp;#34;2&amp;#34;, new User(&amp;#34;李四&amp;#34;,24));

        String json = mapper.writeValueAsString(map1);
        System.out.println(&amp;#34;json字符串&amp;#34;+json);

        HashMap map2 = mapper.readValue(json, new TypeReference&amp;lt;HashMap&amp;lt;String, User&amp;gt;&amp;gt;() {} );
        System.out.println(&amp;#34;Map对象&amp;#34;+map2);
    }

    // 4.List&amp;lt;String&amp;gt;转json, json转List&amp;lt;String&amp;gt;
    @Test
    public void test04() throws Exception{
        ArrayList&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        list.add(&amp;#34;张三&amp;#34;);
        list.add(&amp;#34;李四&amp;#34;);
        String json = mapper.writeValueAsString(list);
        System.out.println(&amp;#34;json字符串&amp;#34;+json);

//        ArrayList&amp;lt;String&amp;gt; list2 = mapper.readVal ue(json, new TypeReference&amp;lt;ArrayList&amp;lt;String&amp;gt;&amp;gt;() { });
        ArrayList&amp;lt;String&amp;gt; list2 = mapper.readValue(json, ArrayList.class);
        System.out.println(&amp;#34;List&amp;lt;string&amp;gt;集合&amp;#34;+list2);
     }

    // 5. List&amp;lt;User&amp;gt;转json, json转List&amp;lt;User&amp;gt;
    @Test
    public void test05() throws Exception {
        ArrayList&amp;lt;User&amp;gt; list1 = new ArrayList&amp;lt;&amp;gt;();
        list1.add(new User(&amp;#34;张三&amp;#34;,23));
        list1.add(new User(&amp;#34;李四&amp;#34;,24));
        String json = mapper.writeValueAsString(list1);
        System.out.println(&amp;#34;json字符串&amp;#34;+json);

        ArrayList&amp;lt;User&amp;gt; list2 = mapper.readValue(json, new TypeReference&amp;lt;ArrayList&amp;lt;User&amp;gt;&amp;gt;() {
        });
        System.out.println(&amp;#34;List对象&amp;#34;+list2);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;搜索联想&#34;&gt;搜索联想&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.bean;

public class Student {
    private Integer id;
    private String name;
    private Integer age;

    private Integer score;

    public Student(){}

    public Student(Integer id, String name, Integer age, Integer score) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.score = score;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;搜索&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form autocomplete=&amp;#34;off&amp;#34; &amp;gt;
    姓名: &amp;lt;input type=&amp;#34;text&amp;#34; id=&amp;#34;username&amp;#34; list=&amp;#34;userlist&amp;#34; placeholder=&amp;#34;输入名称搜索&amp;#34;&amp;gt;
    &amp;lt;datalist id=&amp;#34;userlist&amp;#34;&amp;gt;
    &amp;lt;/datalist&amp;gt;
&amp;lt;/form&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;js/jquery-3.6.0.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 1. 为用户名输入框绑定鼠标点击事件
    $(&amp;#34;#username&amp;#34;).mousedown(function(){
        // 2. 获取用户名是否为空
        let username = $(&amp;#34;#username&amp;#34;).val();

        if( username == null || username == &amp;#34;&amp;#34;){
            return;
        }else{
            $.ajax({
                url: &amp;#34;userServlet&amp;#34;,
                async: true,
                data: {&amp;#34;username&amp;#34;:username},
                type: &amp;#34;POST&amp;#34;,
                success: function (data) {
                    let names = &amp;#34;&amp;#34;;
                    console.log(data)
                    for(let i=0;i&amp;lt;data.length;i++){
                        names +=&amp;#34;&amp;lt;option&amp;gt;&amp;#34;+data[i].name+&amp;#34;&amp;lt;/option&amp;gt;&amp;#34;;
                        console.log(data[i])
                    }
                    $(&amp;#34;#userlist&amp;#34;).html(names)
                },
                dataType: &amp;#34;json&amp;#34;
            });
        }

    })
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.sql;

import org.apache.ibatis.jdbc.SQL;

public class ReturnSql {
    public String getSelectLikeName(){
        return new SQL(){
            {
                SELECT(&amp;#34;*&amp;#34;);
                FROM(&amp;#34;student&amp;#34;);
                WHERE(&amp;#34;name like CONCAT(&amp;#39;%&amp;#39;,#{name},&amp;#39;%&amp;#39;)&amp;#34;);
                ORDER_BY(&amp;#34;score DESC&amp;#34;);
                LIMIT(&amp;#34;0,4&amp;#34;);
            }
        }.toString();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.mapper;

import com.lizicai.bean.Student;
import com.lizicai.sql.ReturnSql;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface StudentMapper {
    @SelectProvider(type = ReturnSql.class, method = &amp;#34;getSelectAll&amp;#34;)
    public abstract List&amp;lt;Student&amp;gt; selectAll();

    @SelectProvider(type = ReturnSql.class, method = &amp;#34;getSelectLikeName&amp;#34;)
    public abstract List&amp;lt;Student&amp;gt; selectLikeName(String name);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.service;

import com.lizicai.bean.Student;
import com.lizicai.mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class Test001 {
    @Test
    public  List&amp;lt;Student&amp;gt; selectLikeName(String name) throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        List&amp;lt;Student&amp;gt; students = mapper.selectLikeName(name);

        for (Student stu : students) {
            System.out.println(stu);
        }

        sqlSession.close();

        is.close();
        return students;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.controller;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.lizicai.bean.Student;
import com.lizicai.service.Test001;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet(&amp;#34;/userServlet&amp;#34;)
public class UserServlet extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {


        req.setCharacterEncoding(&amp;#34;UTF-8&amp;#34;);
        String username = req.getParameter(&amp;#34;username&amp;#34;);
        ObjectMapper mapper = new ObjectMapper();
        Test001 t = new Test001();
        List&amp;lt;Student&amp;gt; list =  t.selectLikeName(username);
        String json = mapper.writeValueAsString(list);

        resp.setContentType(&amp;#34;application/json; charset=utf-8&amp;#34;);
        PrintWriter pw = resp.getWriter();
        pw.write(json);
        pw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;瀑布流分页&#34;&gt;瀑布流分页&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create database db11;
use db11;
CREATE TABLE news(
  id INT PRIMARY KEY AUTO_INCREMENT,
  title VARCHAR(999)
);

DELIMITER $$
CREATE PROCEDURE create_date()
BEGIN
    DECLARE i INT;
    SET i=1;
    WHILE i&amp;lt;=100 do
        INSERT INTO news VALUES (NULL,CONCAT(&amp;#39;今天吃瓜啦,瓜&amp;#39;,i));
        SET i=i+1;
        end WHILE;
end $$

CALL create_date();
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;如何确定当前显示的数据已经浏览完毕
&lt;ul&gt;
&lt;li&gt;公式: 滚动条距询问的距离+滚去条上下滚动的距离+当前窗口的高度&amp;gt;=100&lt;/li&gt;
&lt;li&gt;当前文档高度: 存储10条数据,100px&lt;/li&gt;
&lt;li&gt;滚去条距询问的距离: 1px&lt;/li&gt;
&lt;li&gt;当前窗口的高度: 80px&lt;/li&gt;
&lt;li&gt;滚去条上下滚去的距离: &amp;gt;=19px&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;前置知识&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;功能                  说明
$(function(){})       页面加载事件
$(window)             获取当前窗口对象
scroll()              鼠标滚去事件
$(window).height()    当前窗口的高度
$(window).scrollTop() 滚去条上下滚去的距离
$(document).height()  当前文档的高度
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.lizicai.bean.News;
import com.lizicai.service.NewsService;
import com.lizicai.service.impl.NewsServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet(&amp;#34;/newsList&amp;#34;)
public class NewsServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding(&amp;#34;UTF-8&amp;#34;);
        String pageNum = req.getParameter(&amp;#34;pageNum&amp;#34;);
        String pageSize = req.getParameter(&amp;#34;pageSize&amp;#34;);

        System.out.println(pageNum+&amp;#34; &amp;#34;+pageSize+&amp;#34;----&amp;#34;);

        Integer intPageNum = Integer.parseInt(pageNum) ;
        Integer intPageSize = Integer.parseInt(pageSize) ;

        ObjectMapper mapper = new ObjectMapper();
        NewsService newsService = new NewsServiceImpl();
        Page&amp;lt;News&amp;gt; page = newsService.pageQuery(intPageNum,intPageSize);

        String json = mapper.writeValueAsString(page);

        resp.setContentType(&amp;#34;application/json; charset=utf-8&amp;#34;);
        PrintWriter pw = resp.getWriter();
        pw.write(json);
        pw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.lizicai.bean.News;
import com.lizicai.service.NewsService;
import com.lizicai.service.impl.NewsServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet(&amp;#34;/newsList2&amp;#34;)
public class NewsServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding(&amp;#34;UTF-8&amp;#34;);
        String pageNum = req.getParameter(&amp;#34;pageNum&amp;#34;);
        String pageSize = req.getParameter(&amp;#34;pageSize&amp;#34;);

        System.out.println(pageNum+&amp;#34; &amp;#34;+pageSize+&amp;#34;----&amp;#34;);

        Integer intPageNum = Integer.parseInt(pageNum) ;
        Integer intPageSize = Integer.parseInt(pageSize) ;

        ObjectMapper mapper = new ObjectMapper();
        NewsService newsService = new NewsServiceImpl();
        Page page = newsService.pageQuery(intPageNum,intPageSize);

        PageInfo&amp;lt;List&amp;lt;News&amp;gt;&amp;gt; pageInfo = new PageInfo&amp;lt;&amp;gt;(page);

        String json = mapper.writeValueAsString(pageInfo);

        resp.setContentType(&amp;#34;application/json; charset=utf-8&amp;#34;);
        PrintWriter pw = resp.getWriter();
        pw.write(json);
        pw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    //1.定义发送请求标记
    let send = true;

    //2.定义当前页码和每页显示的条数
    let pageNum = 1;
    let pageSize = 10;

    //3.定义滚动条距底部的距离
    let bottom = 1

    //4.设置页面加载事件
    $(function (){
        //5.为当前窗口绑定滚动条滚动事件
        $(window).scroll(function (){
            //6.获取必要信息，用于计算当前展示数据是否浏览完毕

            //当前窗口的高度
            let windowHeight = $(window).height() ;
            //当前滚动条从上往下滚动的距离
            let scrollTop = $(window).scrollTop();
            //当前文档的高度
            let docHeight = $(document).height() ;

            //7.计算当前展示数据什么时候浏览完毕
            //当 滚动条距底部的距离 + 当前滚动条滚动的距离 + 当前窗口的高度 &amp;gt;= 当前文档的高度
            if((bottom + scrollTop + windowHeight) &amp;gt;= docHeight) {
                //8.判断请求标记是否为true
                if(send == true){
                    // 如果当前页大于10，则将加载动图隐藏并结束方法

                    //9.将请求标记置为false，当前异步操作完成前，不能重新发起请求
                    send = false;
                    //10.根据当前页和每页显示的条数来 请求查询分页数据
                    queryByPage(pageNum, pageSize);
                    //11.当前页码+1
                    pageNum++;
                }
            }
        });
    })

    //请求查询分页数据的函数
    function queryByPage(pageNum, pageSize){
        //将加载动图显示
        $(&amp;#34;.loading&amp;#34;).show();

        //发起AJAX异步请求
        $.ajax({
            url:&amp;#34;newsList&amp;#34;,
            data:{&amp;#34;pageNum&amp;#34;:pageNum,&amp;#34;pageSize&amp;#34;:pageSize},
            type:&amp;#34;POST&amp;#34;,
            dataType:&amp;#34;json&amp;#34;,
            success:function (data){
                if(data.length == 0){
                    // 加载动图隐藏
                    $(&amp;#34;.loading&amp;#34;).hide();
                    $(&amp;#34;#no&amp;#34;).html(&amp;#34;我也是有底线的&amp;#34;)
                    return;
                }

                // 将数据进行显示
                let titles = &amp;#34;&amp;#34;;
                for(let i=0;i&amp;lt;data.length;i++){
                     titles += &amp;#34;&amp;lt;li&amp;gt;\n&amp;#34; +
                         &amp;#34;                &amp;lt;div class=\&amp;#34;title-box\&amp;#34;&amp;gt;\n&amp;#34; +
                         &amp;#34;                    &amp;lt;a href=\&amp;#34;#\&amp;#34; class=\&amp;#34;link\&amp;#34;&amp;gt;\n&amp;#34; +
                                            data[i].title+
                         &amp;#34;                        &amp;lt;hr&amp;gt;\n&amp;#34; +
                         &amp;#34;                    &amp;lt;/a&amp;gt;\n&amp;#34; +
                         &amp;#34;                &amp;lt;/div&amp;gt;\n&amp;#34; +
                         &amp;#34;            &amp;lt;/li&amp;gt;&amp;#34;;
                }
                //追加到页面
                $(&amp;#34;.news_list&amp;#34;).append(titles);

                //将请求标记置为true
                send = true;
            }
        })
    }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // 1. 定义当前页码和每页显示的条数
    let pageNum = 1;
    let pageSize = 10;

    // 2. 调用查询数据的方法
    queryByPage(pageNum, pageSize)

    // 3. 定义请求查询分布数据的函数, 发起AJAX异步请求, 将数据显示到页面
    function queryByPage(pageNum, pageSize){
         $.ajax({
            url:&amp;#34;newsList2&amp;#34;,
            data:{&amp;#34;pageNum&amp;#34;:pageNum,&amp;#34;pageSize&amp;#34;:pageSize},
            type:&amp;#34;POST&amp;#34;,
            dataType:&amp;#34;json&amp;#34;,
            success:function (pageInfo){
                let titles = &amp;#34;&amp;#34;;
                for( let i=0;i&amp;lt;pageInfo.list.length;i++){
                    titles +=  &amp;#34;&amp;lt;li&amp;gt;\n&amp;#34; +
                         &amp;#34;                &amp;lt;div class=\&amp;#34;title-box\&amp;#34;&amp;gt;\n&amp;#34; +
                         &amp;#34;                    &amp;lt;a href=\&amp;#34;#\&amp;#34; class=\&amp;#34;link\&amp;#34;&amp;gt;\n&amp;#34; +
                                            pageInfo.list[i].title+
                         &amp;#34;                        &amp;lt;hr&amp;gt;\n&amp;#34; +
                         &amp;#34;                    &amp;lt;/a&amp;gt;\n&amp;#34; +
                         &amp;#34;                &amp;lt;/div&amp;gt;\n&amp;#34; +
                         &amp;#34;            &amp;lt;/li&amp;gt;&amp;#34;;
                }
                // 将数据显示到页面上
                $(&amp;#34;.news_list&amp;#34;).html(titles);

                 // 4. 为分布按钮区域设置页数参数(总页数和当前页)
                 $(&amp;#34;#light-pagination&amp;#34;).pagination({
                     pages:pageInfo.pages,
                     currentPage: pageInfo.pageNum
                 });

                 // 5. 为分布按钮绑定单击事件, 完成上一页下一页
                $(&amp;#34;.page-link&amp;#34;).click(function(){
                    // 获取点击按钮的文本内容
                     let page = $(this).html()
                    console.log(page)
                    // 如果点击的是Prev, 调用查询方法, 查询当前页的上一页数据
                    if( page == &amp;#34;Prev&amp;#34;){
                        queryByPage(pageInfo.pageNum-1, pageSize)
                    } else if(page == &amp;#34;Next&amp;#34;){
                       queryByPage(pageInfo.pageNum+1, pageSize)
                    } else{
                       queryByPage(page, pageSize)
                    }
                })
            }
         })
    }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>jQuery二 Li.069</title>
      <link>https://lizicai.com/p/jquery%E4%BA%8C-li.069/</link>
      <pubDate>Tue, 30 Nov 2021 16:54:11 +0800</pubDate>
      <guid>https://lizicai.com/p/jquery%E4%BA%8C-li.069/</guid>
      <description>&lt;h2 id=&#34;jquery-dom&#34;&gt;jQuery DOM&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;常用方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法        作用
html()      获取标签的文本
html(value) 设置标签的文本内容,解析标签
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;操作文本&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;我是div&amp;lt;/div&amp;gt;
    &amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn1&amp;#34; value=&amp;#34;获取div的文本&amp;#34;&amp;gt;
    &amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn2&amp;#34; value=&amp;#34;获取div的文本&amp;#34;&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // html()      获取标签的文本
    let div = $(&amp;#34;div&amp;#34;);

    // html(value) 设置标签的文本内容,解析标签
    let btn1 = $(&amp;#34;#btn1&amp;#34;)
    btn1.click(cc1)

    function cc1() {
        alert(div.html())
    }

    let btn2 = $(&amp;#34;#btn2&amp;#34;)
    btn2.click(cc2)
    function cc2(){
        div.html(&amp;#34;&amp;lt;b&amp;gt;小明&amp;lt;/b&amp;gt;&amp;#34;)
    }

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery-操作对象&#34;&gt;jQuery 操作对象&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法               作用
$(&amp;#34;元素&amp;#34;)          创建指定元素
append(element)    添加成最后一个子元素,由添加者对象调用
appendTo(element)  添加成最后一个子元素,由被添加者对象调用
prepend(element)   添加成第一个子元素,由添加者对象调用
prependTo(element) 添加成第一个子元素,由被添加者对象调用
before(element)    添加到当前元素的前面,两者是兄弟关系,由添加者对象调用
after(element)     添加到当前元素的后面,两者之间是兄弟关系,由添加者对象调用
remove()           删除指定元素(自己移除自己)
empty()            清空指定元素的所有子元素
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;操作对象&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn1&amp;#34; value=&amp;#34;添加一个span到div&amp;#34;&amp;gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;

&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn2&amp;#34; value=&amp;#34;将加油添加到城市列表最下方&amp;#34;&amp;gt;&amp;lt;br/&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn3&amp;#34; value=&amp;#34;将加油添加到城市列表最上方&amp;#34;&amp;gt;&amp;lt;br/&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn4&amp;#34; value=&amp;#34;将加油添加到上海下方&amp;#34;&amp;gt;&amp;lt;br/&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn5&amp;#34; value=&amp;#34;将加油添加到上海上方&amp;#34;&amp;gt;&amp;lt;br/&amp;gt;

&amp;lt;ul id=&amp;#34;city&amp;#34;&amp;gt;
    &amp;lt;li id=&amp;#34;bj&amp;#34;&amp;gt;北京&amp;lt;/li&amp;gt;
    &amp;lt;li id=&amp;#34;sh&amp;#34;&amp;gt;上海&amp;lt;/li&amp;gt;
    &amp;lt;li id=&amp;#34;gz&amp;#34;&amp;gt;广州&amp;lt;/li&amp;gt;
    &amp;lt;li id=&amp;#34;sz&amp;#34;&amp;gt;深圳&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;br&amp;gt;

&amp;lt;ul id=&amp;#34;desc&amp;#34;&amp;gt;
    &amp;lt;li id=&amp;#34;xg&amp;#34;&amp;gt;新冠&amp;lt;/li&amp;gt;
    &amp;lt;li id=&amp;#34;xq&amp;#34;&amp;gt;雄起&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn6&amp;#34; value=&amp;#34;清除新冠&amp;#34;&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn7&amp;#34; value=&amp;#34;描述列表删除&amp;#34;&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;br&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;

    let div = $(&amp;#34;#div&amp;#34;);

    // $(&amp;#34;元素&amp;#34;)           创建指定元素
    // append(element)    添加成最后一个子元素,由添加者对象调用
    // 添加一个span到div
    let btn1 = $(&amp;#34;#btn1&amp;#34;);
    btn1.click(cc1)
    function cc1(){
        let span = $(&amp;#34;&amp;lt;span&amp;gt;span&amp;lt;/span&amp;gt;&amp;#34;)
        div.append(span)
    }

    // appendTo(element)  添加成最后一个子元素,由被添加者对象调用
    // 将加油添加到城市列表最下方
    let city = $(&amp;#34;#city&amp;#34;)
    let btn2 = $(&amp;#34;#btn2&amp;#34;)
    btn2.click(cc2)
    function cc2(){
        let jy = $(&amp;#34;&amp;lt;li id=\&amp;#34;jy\&amp;#34;&amp;gt;加油&amp;lt;/li&amp;gt;&amp;#34;)
        jy.appendTo(city)

    }

    // prepend(element)   添加成第一个子元素,由添加者对象调用
    // 加油添加到城市列表最上方
    let btn3 = $(&amp;#34;#btn3&amp;#34;)
    btn3.click(cc3)
    function cc3(){
        let jy = $(&amp;#34;&amp;lt;li id=\&amp;#34;jy\&amp;#34;&amp;gt;加油&amp;lt;/li&amp;gt;&amp;#34;)
        city.prepend(jy)
    }

    // prependTo(element) 添加成第一个子元素,由被添加者对象调用


    // before(element)    添加到当前元素的前面,两者是兄弟关系,由添加者对象调用
    // 将加油添加到上海下方
    let btn5 = $(&amp;#34;#btn5&amp;#34;)
    btn5.click(cc5)
    function cc5(){
        let jy = $(&amp;#34;&amp;lt;li id=\&amp;#34;jy\&amp;#34;&amp;gt;加油&amp;lt;/li&amp;gt;&amp;#34;)
        let sh = $(&amp;#34;#sh&amp;#34;)
        sh.before(jy)
    }


    // after(element)     添加到当前元素的后面,两者之间是兄弟关系,由添加者对象调用
    let btn4 = $(&amp;#34;#btn4&amp;#34;)
    btn4.click(cc4)
    function cc4(){
        let jy = $(&amp;#34;&amp;lt;li id=\&amp;#34;jy\&amp;#34;&amp;gt;加油&amp;lt;/li&amp;gt;&amp;#34;)
        let sh = $(&amp;#34;#sh&amp;#34;)
        sh.after(jy)
    }

    // remove()           删除指定元素(自己移除自己)
    let btn6 = $(&amp;#34;#btn6&amp;#34;)
    btn6.click(cc5)
    function cc5(){
        let xg = $(&amp;#34;#xg&amp;#34;)
        xg.remove()
    }

    // empty()            清空指定元素的所有子元素
    let btn7 = $(&amp;#34;#btn7&amp;#34;)
    btn7.click(cc6)
    function cc6(){
        let desc = $(&amp;#34;#desc&amp;#34;)
        desc.empty()
    }

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;iquery-dom&#34;&gt;iQuery DOM&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;常用方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法               作用
css(name)          根据样式名称获取css样式
css(name,value)    设置CSS样式
addClass(value)    给指定的对象添加样式类名
removeClass(value) 给指定的对象删除样式类名
toggleClass(value) 如果没有样式类名,则添加,如果有,则删除
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;操作样式&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        .cls1{
            background: pink;
            height: 30px;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;div style=&amp;#34;border: 1px solid red;&amp;#34; id=&amp;#34;div&amp;#34;&amp;gt;我是div&amp;lt;/div&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn1&amp;#34; value=&amp;#34;获取div样式&amp;#34;&amp;gt;&amp;lt;br/&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn2&amp;#34; value=&amp;#34;设置div的背景色为蓝色&amp;#34;&amp;gt;&amp;lt;br/&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn3&amp;#34; value=&amp;#34;给div设置cls1样式&amp;#34;&amp;gt;&amp;lt;br/&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn4&amp;#34; value=&amp;#34;给div删除cls1样式&amp;#34;&amp;gt;&amp;lt;br/&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn5&amp;#34; value=&amp;#34;给div设置或删除cls1样式&amp;#34;&amp;gt;&amp;lt;br/&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;

    let div = $(&amp;#34;#div&amp;#34;)
    // css(name)          根据样式名称获取css样式
    let btn1 = $(&amp;#34;#btn1&amp;#34;)
    btn1.click(get1)
    function get1(){
        alert(div.css(&amp;#34;border&amp;#34;))
    }

    // css(name,value)    设置CSS样式
    // div背景色为蓝色
    let btn2 = $(&amp;#34;#btn2&amp;#34;)
    btn2.click(get2)
    function get2(){
        div.css(&amp;#34;background&amp;#34;,&amp;#34;blue&amp;#34;)
    }

    // addClass(value)    给指定的对象添加样式类名
    let btn3 = $(&amp;#34;#btn3&amp;#34;)
    btn3.click(get3)
    function get3(){
        div.addClass(&amp;#34;cls1&amp;#34;);
    }

    // removeClass(value) 给指定的对象删除样式类名
    let btn4 = $(&amp;#34;#btn4&amp;#34;)
    btn4.click(get4)
    function get4(){
        div.removeClass(&amp;#34;cls1&amp;#34;);
    }

    // toggleClass(value) 如果没有样式类名,则添加,如果有,则删除
    let btn5 = $(&amp;#34;#btn5&amp;#34;)
    btn5.click(get5)
    function get5(){
        div.toggleClass(&amp;#34;cls1&amp;#34;);
    }

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery-dom-操作属性&#34;&gt;jQuery DOM 操作属性&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法               作用
attr(name,[value]) 获得/设置属性的值
prop(name,[value]) 获得/设置属性的值(checked,selected)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;操作属性&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;input type=&amp;#34;text&amp;#34; id=&amp;#34;username&amp;#34;&amp;gt;
&amp;lt;br&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn1&amp;#34; value=&amp;#34;获取输入框的id属性&amp;#34;&amp;gt;
&amp;lt;br/&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn2&amp;#34; value=&amp;#34;给输入框设置value属性&amp;#34;&amp;gt;
&amp;lt;br/&amp;gt;

&amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; id=&amp;#34;gender1&amp;#34;&amp;gt;男
&amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; id=&amp;#34;gender2&amp;#34;&amp;gt;女
&amp;lt;br/&amp;gt;

&amp;lt;input type=&amp;#34;button&amp;#34; value=&amp;#34;选中女&amp;#34; id=&amp;#34;btn3&amp;#34;&amp;gt;
&amp;lt;br/&amp;gt;


&amp;lt;select&amp;gt;
    &amp;lt;option&amp;gt;---请选择---&amp;lt;/option&amp;gt;
    &amp;lt;option id=&amp;#34;bk&amp;#34;&amp;gt;本科&amp;lt;/option&amp;gt;
    &amp;lt;option id=&amp;#34;zk&amp;#34;&amp;gt;专科&amp;lt;/option&amp;gt;
&amp;lt;/select&amp;gt;
&amp;lt;br/&amp;gt;

&amp;lt;input type=&amp;#34;button&amp;#34; value=&amp;#34;选中本科&amp;#34; id=&amp;#34;btn4&amp;#34;&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 获取输入框的id属性
    let username = $(&amp;#34;#username&amp;#34;)
    let btn1 = $(&amp;#34;#btn1&amp;#34;)
    btn1.click(test1)
    function test1(){
        alert(username.attr(&amp;#34;id&amp;#34;))
    }

    // 给输入框设置value属性
    let btn2 = $(&amp;#34;#btn2&amp;#34;)
    btn2.click(test2)
    function test2(){
        username.attr(&amp;#34;value&amp;#34;,&amp;#34;哈哈&amp;#34;)
    }

    // 选中女
    $(&amp;#34;#btn3&amp;#34;).click(function (){
        $(&amp;#34;#gender2&amp;#34;).prop(&amp;#34;checked&amp;#34;,true)
    })

    // 选中本科
    let bk = $(&amp;#34;#bk&amp;#34;)
    let btn4 = $(&amp;#34;#btn4&amp;#34;)
    btn4.click(test4)
    function test4(){
        bk.prop(&amp;#34;selected&amp;#34;,true)
    }
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;操作复选框&#34;&gt;操作复选框&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;meta name=&amp;#34;viewport&amp;#34; content=&amp;#34;width=device-width, initial-scale=1.0&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;复选框&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;table id=&amp;#34;tab1&amp;#34; border=&amp;#34;1&amp;#34; width=&amp;#34;800&amp;#34; align=&amp;#34;center&amp;#34;&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;th style=&amp;#34;text-align: left&amp;#34;&amp;gt;
                &amp;lt;input style=&amp;#34;background:lightgreen&amp;#34; id=&amp;#34;selectAll&amp;#34; type=&amp;#34;button&amp;#34; value=&amp;#34;全选&amp;#34;&amp;gt;
                &amp;lt;input style=&amp;#34;background:lightgreen&amp;#34; id=&amp;#34;selectNone&amp;#34; type=&amp;#34;button&amp;#34; value=&amp;#34;全不选&amp;#34;&amp;gt;
                &amp;lt;input style=&amp;#34;background:lightgreen&amp;#34; id=&amp;#34;reverse&amp;#34; type=&amp;#34;button&amp;#34; value=&amp;#34;反选&amp;#34;&amp;gt;
            &amp;lt;/th&amp;gt;

            &amp;lt;th&amp;gt;分类ID&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;分类名称&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;分类描述&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;操作&amp;lt;/th&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;&amp;lt;input type=&amp;#34;checkbox&amp;#34; class=&amp;#34;item&amp;#34;&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;手机数码&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;手机数码类商品&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;&amp;lt;a href=&amp;#34;&amp;#34;&amp;gt;修改&amp;lt;/a&amp;gt;|&amp;lt;a href=&amp;#34;&amp;#34;&amp;gt;删除&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;&amp;lt;input type=&amp;#34;checkbox&amp;#34; class=&amp;#34;item&amp;#34;&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;电脑办公&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;电脑办公类商品&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;&amp;lt;a href=&amp;#34;&amp;#34;&amp;gt;修改&amp;lt;/a&amp;gt;|&amp;lt;a href=&amp;#34;&amp;#34;&amp;gt;删除&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;&amp;lt;input type=&amp;#34;checkbox&amp;#34; class=&amp;#34;item&amp;#34;&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;鞋靴箱包&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;鞋靴箱包类商品&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;&amp;lt;a href=&amp;#34;&amp;#34;&amp;gt;修改&amp;lt;/a&amp;gt;|&amp;lt;a href=&amp;#34;&amp;#34;&amp;gt;删除&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;&amp;lt;input type=&amp;#34;checkbox&amp;#34; class=&amp;#34;item&amp;#34;&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;4&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;家居饰品&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;家居饰品类商品&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;&amp;lt;a href=&amp;#34;&amp;#34;&amp;gt;修改&amp;lt;/a&amp;gt;|&amp;lt;a href=&amp;#34;&amp;#34;&amp;gt;删除&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
    &amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    //全选
    //1.为全选按钮添加单击事件
    $(&amp;#34;#selectAll&amp;#34;).click(function(){
        //2.获取所有的商品复选框元素，为其添加checked属性，属性值true
        $(&amp;#34;.item&amp;#34;).prop(&amp;#34;checked&amp;#34;,true);
    });


    //全不选
    //1.为全不选按钮添加单击事件
    $(&amp;#34;#selectNone&amp;#34;).click(function(){
        //2.获取所有的商品复选框元素，为其添加checked属性，属性值false
        $(&amp;#34;.item&amp;#34;).prop(&amp;#34;checked&amp;#34;,false);
    });


    //反选
    //1.为反选按钮添加单击事件
    $(&amp;#34;#reverse&amp;#34;).click(function(){
        //2.获取所有的商品复选框元素，为其添加checked属性，属性值是目前相反的状态
        let items = $(&amp;#34;.item&amp;#34;);
        items.each(function(){
            $(this).prop(&amp;#34;checked&amp;#34;,!$(this).prop(&amp;#34;checked&amp;#34;));
        });
    });
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;随机图片&#34;&gt;随机图片&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;meta name=&amp;#34;viewport&amp;#34; content=&amp;#34;width=device-width, initial-scale=1.0&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;随机图片&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;!-- 小图 --&amp;gt;
&amp;lt;div style=&amp;#34;background-color:red;border: dotted; height: 50px; width: 50px&amp;#34;&amp;gt;
    &amp;lt;img src=&amp;#34;img/01.jpg&amp;#34; id=&amp;#34;small&amp;#34; style=&amp;#34;width: 50px; height: 50px;&amp;#34;&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;!-- 大图 --&amp;gt;
&amp;lt;div style=&amp;#34;border: double ;width: 400px; height: 400px; position: absolute; left: 500px; top:10px&amp;#34;&amp;gt;
    &amp;lt;img src=&amp;#34;&amp;#34; id=&amp;#34;big&amp;#34; style=&amp;#34;width: 400px; height: 400px; display:none;&amp;#34;&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;!-- 开始和结束按钮 --&amp;gt;
&amp;lt;input id=&amp;#34;startBtn&amp;#34; type=&amp;#34;button&amp;#34; style=&amp;#34;width: 150px;height: 150px; font-size: 20px&amp;#34; value=&amp;#34;开始&amp;#34;&amp;gt;
&amp;lt;input id=&amp;#34;stopBtn&amp;#34; type=&amp;#34;button&amp;#34; style=&amp;#34;width: 150px;height: 150px; font-size: 20px&amp;#34; value=&amp;#34;停止&amp;#34;&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;js/jquery-3.3.1.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    //1.准备一个数组
    let imgs = [
        &amp;#34;img/01.jpg&amp;#34;,
        &amp;#34;img/02.jpg&amp;#34;,
        &amp;#34;img/03.jpg&amp;#34;,
        &amp;#34;img/04.jpg&amp;#34;,
        &amp;#34;img/05.jpg&amp;#34;,
        &amp;#34;img/06.jpg&amp;#34;,
        &amp;#34;img/07.jpg&amp;#34;,
        &amp;#34;img/08.jpg&amp;#34;,
        &amp;#34;img/09.jpg&amp;#34;,
        &amp;#34;img/10.jpg&amp;#34;];

    //2.定义计数器变量
    let count = 0;

    //3.声明定时器对象
    let time = null;

    //4.声明图片路径变量
    let imgSrc = &amp;#34;&amp;#34;;

    //5.为开始按钮绑定单击事件
    $(&amp;#34;#startBtn&amp;#34;).click(function(){
        //6.设置按钮状态
        //禁用开始按钮
        $(&amp;#34;#startBtn&amp;#34;).prop(&amp;#34;disabled&amp;#34;,true);
        //启用停止按钮
        $(&amp;#34;#stopBtn&amp;#34;).prop(&amp;#34;disabled&amp;#34;,false);

        //7.设置定时器，循环显示图片
        time = setInterval(function(){
            //8.循环获取图片路径
            let index = count % imgs.length; // 0%10=0  1%10=1  2%10=2 .. 9%10=9  10%10=0

            //9.将当前图片显示到小图片上
            imgSrc = imgs[index];
            $(&amp;#34;#small&amp;#34;).prop(&amp;#34;src&amp;#34;,imgSrc);

            //10.计数器自增
            count++;
        },10);
    });


    //11.为停止按钮绑定单击事件
    $(&amp;#34;#stopBtn&amp;#34;).click(function(){
        //12.取消定时器
        clearInterval(time);

        //13.设置按钮状态
        //启用开始按钮
        $(&amp;#34;#startBtn&amp;#34;).prop(&amp;#34;disabled&amp;#34;,false);
        //禁用停止按钮
        $(&amp;#34;#stopBtn&amp;#34;).prop(&amp;#34;disabled&amp;#34;,true);

        //14.将图片显示到大图片上
        $(&amp;#34;#big&amp;#34;).prop(&amp;#34;src&amp;#34;,imgSrc);
        $(&amp;#34;#big&amp;#34;).prop(&amp;#34;style&amp;#34;,&amp;#34;width: 400px; height: 400px;&amp;#34;);
    });

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>jQuery一 Li.068</title>
      <link>https://lizicai.com/p/jquery%E4%B8%80-li.068/</link>
      <pubDate>Wed, 24 Nov 2021 10:52:40 +0800</pubDate>
      <guid>https://lizicai.com/p/jquery%E4%B8%80-li.068/</guid>
      <description>&lt;h2 id=&#34;jquery-介绍&#34;&gt;jQuery 介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;jQuery是一个JavaScript库&lt;/li&gt;
&lt;li&gt;封装了很多预定义的函数, 获取元素, 执行隐藏移动等&lt;/li&gt;
&lt;li&gt;目的就是在使用时直接调用, 不需要再重复定义, 这样就可以极大地简化了JavaScript编程&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;jquery-快速入门&#34;&gt;jQuery 快速入门&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;快速入门jQuery&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;我是div&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // let div = document.getElementById(&amp;#34;div&amp;#34;);
    // alert(div.innerText)


    // jQuery 方式

    let jqDiv = $(&amp;#34;#div&amp;#34;);
    alert(jqDiv)
    alert(jqDiv.html())
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;js对象和jquery对象黑的&#34;&gt;JS对象和jQuery对象黑的&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;jQuery本质上虽然也是JS, 但如果想使用jQuery的属性和方法那么必须保证对象是jQuery对象, 而不是JS方式获得的DOM对象&lt;/li&gt;
&lt;li&gt;二者的API方法不能混合使用, 若想使用对方的API, 需要进行对象转换&lt;/li&gt;
&lt;li&gt;JS的DOM对象黑的成jQuery对象
&lt;ul&gt;
&lt;li&gt;$(JS的DOM对象);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;jQuery对象转换成jQuery对象
&lt;ul&gt;
&lt;li&gt;jQuery对象[索引];&lt;/li&gt;
&lt;li&gt;jQuery对象.get(索引);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;我是div&amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // js 方式, 通过id获取div元素
    // JS对象  转换    jQuery对象
    let div1 = document.getElementById(&amp;#34;div&amp;#34;);
    jsDiv1 = $(div1)
    alert(jsDiv1.html())


    // jQuery对象  转换  DOM对象

    let jqDiv2 = $(&amp;#34;#div&amp;#34;);
    let div2 = jqDiv2[0]
    alert(div2.innerText)

    let div3 = jqDiv2.get(0)
    alert(div3.innerText)

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery事件的使用&#34;&gt;jQuery事件的使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;常用事件&lt;/li&gt;
&lt;li&gt;jQuery中将事件封装成了对应的方法. 去年了JS中的.on语法.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;事件名 说明
onload 某个页面或图像被完成加载
onsubmit 当表单提交时触发该事件
onclick 鼠标单击事件
ondblclick 鼠标双击事件
onblur 元素失去焦点
onfocus 元素获得焦点
onchange 用户改变真苦域的内容
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;事件的使用&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn&amp;#34; value=&amp;#34;点我&amp;#34;&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; id=&amp;#34;input&amp;#34;&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    let btn = $(&amp;#34;#btn&amp;#34;)
    btn.click(check)
    function check(){
        alert(&amp;#34;点我干嘛&amp;#34;)
    }

    $(&amp;#34;#btn&amp;#34;).click(function () {
        alert(&amp;#34;匿名函数&amp;#34;)
    })


    // 获取焦点事件
    let input = $(&amp;#34;#input&amp;#34;)
    input.focus(getFocus)
    function getFocus(){
        // alert(&amp;#34;你要输入数据了&amp;#34;)
    }

    input.blur(loseFocus)
    function loseFocus(){
        alert(&amp;#34;你输入完成了&amp;#34;)
    }

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;事件的绑定和解绑&#34;&gt;事件的绑定和解绑&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;绑定事件
&lt;ul&gt;
&lt;li&gt;jQuery对象.on(事件名称,执行的功能);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;解绑事件
&lt;ul&gt;
&lt;li&gt;jQuery对象.off(事件名称)
&lt;strong&gt;如果不指定事件名称,则会把该对象绑定的所有事件都解绑&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;事件的绑定和解绑&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn1&amp;#34; value=&amp;#34;点我&amp;#34;&amp;gt;
    &amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn2&amp;#34; value=&amp;#34;解绑&amp;#34;&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 1. 给btn1 绑定一个单击的事件
    let btn1 = $(&amp;#34;#btn1&amp;#34;);
    btn1.on(&amp;#34;click&amp;#34;, cc)
    function cc(){
        alert(&amp;#34;点我干嘛&amp;#34;)
    }

    let btn2 = $(&amp;#34;#btn2&amp;#34;)
    btn2.on(&amp;#34;click&amp;#34;, jiebang)
    function jiebang(){
        btn1.off(&amp;#34;click&amp;#34;)
    }
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;事件的切换&#34;&gt;事件的切换&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;事件的切换: 需要给同一个对象绑定多个事件, 而且多个事件还有先后顺序关系&lt;/li&gt;
&lt;li&gt;方式一: 单独定义
&lt;ul&gt;
&lt;li&gt;$(元素).事件方法名(要执行的功能);&lt;/li&gt;
&lt;li&gt;$(元素).事件方法名(要执行的功能);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;方式二: 链式定义
&lt;ul&gt;
&lt;li&gt;$(元素).事件方法名1(要执行的功能).事件方法名2(要执行的功能)
&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;事件的切换&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        #div{
            border: 1px solid black;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;dvi&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 方式一, this的使用

    // $(&amp;#34;#div&amp;#34;).mouseover(function () {
    //     $(this).css(&amp;#34;background&amp;#34;,&amp;#34;red&amp;#34;);
    // })

    // 方式一, 单独定义
    let div = $(&amp;#34;#div&amp;#34;);
    // div.on(&amp;#34;mouseover&amp;#34;, changeRed)
    // div.on(&amp;#34;mouseout&amp;#34;,changeBlue)
    function changeRed(){
        div.css(&amp;#34;background-color&amp;#34;,&amp;#34;red&amp;#34;)
    }
    function changeBlue(){
        div.css(&amp;#34;background-color&amp;#34;,&amp;#34;blue&amp;#34;)
    }

    // 方式二, 链式定义
    div.on(&amp;#34;mouseover&amp;#34;, changeRed).on(&amp;#34;mouseout&amp;#34;,changeBlue)

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;遍历&#34;&gt;遍历&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;方式一: 传统方式&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;for (let i=0;i&amp;lt;窗口对象长度;i++){
    执行功能;
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;方式二:对象.each()方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;容器对象.each(function(index,ele){
    执行功能;
})
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;方式三:$.each()方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$.each(容器对象,function(index.ele){
    执行功能;
});
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;方式四: for of 语句&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;for(ele of 容器对象){
    执行功能;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;遍历&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;btn&amp;#34; value=&amp;#34;遍历列表项&amp;#34;&amp;gt;
    &amp;lt;ul&amp;gt;
        &amp;lt;li&amp;gt;前端&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;后端&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;全占工程师&amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;

    $(&amp;#34;#btn&amp;#34;).on(&amp;#34;click&amp;#34;, showCicle4);

    // 方式一: 传统方式
    let lis = document.getElementsByTagName(&amp;#34;li&amp;#34;);

    function showCicle1(){
        for(let i=0; i&amp;lt; lis.length; i++){
            console.log(lis[i].innerHTML+&amp;#34; &amp;#34;)
        }
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }


    // 方式二: 对象.each()方法
    let lis2 = $(&amp;#34;li&amp;#34;)
    function showCicle2(){
        lis2.each(function(index,ele){
            console.log(ele.innerHTML+&amp;#34; &amp;#34;)
        });
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }


    // 方式三: $.each()方法
    let lis3 = $(&amp;#34;li&amp;#34;)
    function showCicle3(){
        $.each(lis3,function(index,ele){
            console.log(ele.innerHTML+&amp;#34; &amp;#34;)
        });
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }

    // 方式四: ele of 容器
    let lis4 = $(&amp;#34;li&amp;#34;)
    function showCicle4(){
        for(ele of lis4){
            console.log(ele.innerHTML+&amp;#34; &amp;#34;)
        }
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery-基本选择器&#34;&gt;jQuery 基本选择器&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;id选择器, 类选择器, 元素选择器, 属性选择器等等&lt;/li&gt;
&lt;li&gt;jQuery中选择器的语法:$()&lt;/li&gt;
&lt;li&gt;基本选择器&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;选择器     语法              作用
元素选择器 $(&amp;#34;元素名称&amp;#34;);    根据元素名称获取元素对象们
id选择器   $(&amp;#34;#id属性值&amp;#34;)    根据id属性值获取元素对象
类选择器   $(&amp;#34;.class属性值&amp;#34;) 根据class属性值获取元素对象位
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;基本选择器&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;div id=&amp;#34;#div1&amp;#34;&amp;gt;div1&amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;#34;div2&amp;#34;&amp;gt;div2&amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;#34;div2&amp;#34;&amp;gt;div3&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    let divs = $(&amp;#34;div&amp;#34;)
    alert(divs.length)

    let div1 = $(&amp;#34;#div1&amp;#34;);
    alert(div1)

    let div2 = $(&amp;#34;.div2&amp;#34;)
    alert(div2.length)
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery-层级选择器&#34;&gt;jQuery 层级选择器&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;选择器     语法       作用
后代选择器 $(&amp;#34;A B&amp;#34;)   A下的所有B(包括B的子级)
子选择器   $(&amp;#34;A &amp;gt; B&amp;#34;) A下的所有B(不包括B的子级)
兄弟选择器 $(&amp;#34;A + B&amp;#34;) A相邻的下一个B
兄弟选择器 $(&amp;#34;A ~ B&amp;#34;) A相邻的所有B
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;层级选择器&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

    &amp;lt;div&amp;gt;
        &amp;lt;span&amp;gt;s1
            &amp;lt;span&amp;gt;s1-1&amp;lt;/span&amp;gt;
            &amp;lt;span&amp;gt;s1-2&amp;lt;/span&amp;gt;
        &amp;lt;/span&amp;gt;
        &amp;lt;span&amp;gt;s2&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;p&amp;gt;p1&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;p2&amp;lt;/p&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js &amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 1. 后代选择器 $(&amp;#34;A B&amp;#34;) A下的所有B(包括B的子级)
    let spans = $(&amp;#34;div span&amp;#34;);
    // alert(spans.length)

    // 子选择器   $(&amp;#34;A &amp;gt; B&amp;#34;) A下的所有B(不包括B的子级)
    let spans2 = $(&amp;#34;div &amp;gt; span&amp;#34;)
    // alert(spans2.length)

    // 兄弟选择器 $(&amp;#34;A + B&amp;#34;) A相邻的下一个B
    let p1 = $(&amp;#34;div+p&amp;#34;)
    alert(p1.html())

    // 兄弟选择器 $(&amp;#34;A ~ B&amp;#34;) A相邻的所有B
    let p2 = $(&amp;#34;div ~ p&amp;#34;)
    alert(p2.length+&amp;#34; &amp;#34;+p2[0].innerHTML)

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery-属性选择器&#34;&gt;jQuery 属性选择器&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;选择器       语法                   作用
属性名选择器 $(&amp;#34;A[属性名]&amp;#34;);        根据指定属性名获取元素对象们
属性值选择器 $(&amp;#34;A[属性名=属性值]&amp;#34;); 根据指定属性名和属性值获取元素对象们
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;属性选择器&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;input type=&amp;#34;text&amp;#34;&amp;gt;
&amp;lt;input type=&amp;#34;password&amp;#34;&amp;gt;
&amp;lt;input type=&amp;#34;password&amp;#34;&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 属性名选择器 $(&amp;#34;A[属性名]&amp;#34;);        根据指定属性名获取元素对象们
    let inputs = $(&amp;#34;input[type]&amp;#34;);
    // alert(inputs.length)

    // 属性值选择器 $(&amp;#34;A[属性名=属性值]&amp;#34;); 根据指定属性名和属性值获取元素对象们
    let inputs2 = $(&amp;#34;input[type=&amp;#39;password&amp;#39;]&amp;#34;)
    alert(inputs2.length)

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery-过滤器选择器&#34;&gt;jQuery 过滤器选择器&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;选择器         语法             作用
首元素选择器   $(&amp;#34;A:first&amp;#34;);    获得选择的元素中的第一个元素
尾元素选择器   $(&amp;#34;A:last&amp;#34;);     获得选择的元素中的最后一个元素
非元素选择器   $(&amp;#34;A:not(B)&amp;#34;);   不包括指定内容的元素
偶数选择器     $(&amp;#34;A:even&amp;#34;);     偶数,从0开始计数
奇数选择器     $(&amp;#34;A:odd&amp;#34;);      奇数,从0开始计数
等于索引选择器 $(&amp;#34;A:eq(index)&amp;#34;) 指定索引元素,和数组索引一致
大于索引选择器 $(&amp;#34;A:gt(index)&amp;#34;) 大于指定索引元素
小于索引选择器 $(&amp;#34;A:lt(index)&amp;#34;) 小玩指定索引元素
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;过滤器选择器&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div&amp;gt;div1&amp;lt;/div&amp;gt;
&amp;lt;div id=&amp;#34;div2&amp;#34;&amp;gt;div2&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;div3&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;div4&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 首元素选择器   $(&amp;#34;A:first&amp;#34;);    获得选择的元素中的第一个元素
    let divFirst = $(&amp;#34;div:first&amp;#34;);
    // alert(divFirst.html())

    // 尾元素选择器   $(&amp;#34;A:last&amp;#34;);     获得选择的元素中的最后一个元素
    let divLast = $(&amp;#34;div:last&amp;#34;);
    // alert(divLast.html())

    // 非元素选择器   $(&amp;#34;A:not(B)&amp;#34;);   不包括指定内容的元素
    let divs3 = $(&amp;#34;div:not(#div2)&amp;#34;)
    // alert(divs3.length)

    // 偶数选择器     $(&amp;#34;A:even&amp;#34;);     偶数,从0开始计数
    let divs4 = $(&amp;#34;div:even&amp;#34;)
    // alert(divs4.length)
    // alert(divs4[0].innerHTML)
    // alert(divs4[1].innerHTML)

    // 奇数选择器     $(&amp;#34;A:odd&amp;#34;);      奇数,从0开始计数
    let divs5 = $(&amp;#34;div:odd&amp;#34;)
    // alert(divs5.length)
    alert(divs5[0].innerHTML)
    alert(divs5[1].innerHTML)

    // 等于索引选择器 $(&amp;#34;A:eq(index)&amp;#34;) 指定索引元素,和数组索引一致
    let divs6 = $(&amp;#34;div:eq(2)&amp;#34;)
    // alert(divs6.html())

    // 大于索引选择器 $(&amp;#34;A:gt(index)&amp;#34;) 大于指定索引元素
    let divs7 = $(&amp;#34;div:gt(0)&amp;#34;)
    // alert(divs7.length)

    // 小于索引选择器 $(&amp;#34;A:lt(index)&amp;#34;) 小玩指定索引元素
    let divs8 = $(&amp;#34;div:lt(4)&amp;#34;)
    // alert(divs8.length)

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jquery-表单属性选择器&#34;&gt;jQuery 表单属性选择器&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;选择器                  语法             作用
可用元素选择器          $(&amp;#34;A:enabled&amp;#34;);  获得可用元素
不可用元素选择器        $(&amp;#34;A:disabled&amp;#34;); 获得不可用元素
单选/复选框被选中的元素 $(&amp;#34;A:checked&amp;#34;);  获得单选/复选框被选中的元素
下拉框被选中的元素      $(&amp;#34;A:selected&amp;#34;); 获得下拉框选中的元素
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;表单选择器&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;input type=&amp;#34;text&amp;#34; disabled&amp;gt;
&amp;lt;input type=&amp;#34;text&amp;#34;&amp;gt;
&amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; value=&amp;#34;men&amp;#34; checked&amp;gt;男
&amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; value=&amp;#34;women&amp;#34;&amp;gt;女
&amp;lt;input type=&amp;#34;checkbox&amp;#34; name=&amp;#34;hobby&amp;#34; value=&amp;#34;study&amp;#34; checked&amp;gt;
&amp;lt;input type=&amp;#34;checkbox&amp;#34; name=&amp;#34;hobby&amp;#34; value=&amp;#34;sleep&amp;#34; checked&amp;gt;

&amp;lt;select&amp;gt;
    &amp;lt;option&amp;gt;---请选择---&amp;lt;/option&amp;gt;
    &amp;lt;option selected&amp;gt;本科&amp;lt;/option&amp;gt;
    &amp;lt;option&amp;gt;专科&amp;lt;/option&amp;gt;
&amp;lt;/select&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;#34;../jQuery/jquery-3.6.0.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
    // 可用元素选择器          $(&amp;#34;A:enabled&amp;#34;);  获得可用元素
    let inputs1 = $(&amp;#34;input:enabled&amp;#34;);
    // alert(inputs1.length)

    // 不可用元素选择器        $(&amp;#34;A:disabled&amp;#34;); 获得不可用元素
    let inputs2 = $(&amp;#34;input:disabled&amp;#34;);
    // alert(inputs2.length)

    // 单选/复选框被选中的元素 $(&amp;#34;A:checked&amp;#34;);  获得单选/复选框被选中的元素
    let inputs3 = $(&amp;#34;input:checked&amp;#34;);
    // alert(inputs3.length)

    // 下拉框被选中的元素      $(&amp;#34;A:selected&amp;#34;); 获得下拉框选中的元素
    let selects1 = $(&amp;#34;option:selected&amp;#34;)
    alert(selects1.get(0).innerHTML)

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>JavaScript二 Li.067</title>
      <link>https://lizicai.com/p/javascript%E4%BA%8C-li.067/</link>
      <pubDate>Fri, 19 Nov 2021 23:12:49 +0800</pubDate>
      <guid>https://lizicai.com/p/javascript%E4%BA%8C-li.067/</guid>
      <description>&lt;h2 id=&#34;javascript-面向对象-类的定义和使用&#34;&gt;JavaScript 面向对象, 类的定义和使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;定义格式&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class 类名{
    constructor(变量列表){
        变量赋值;
    }
    方法名(参数列表){
        方法体;
        return 返回值;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;类的定义和使用&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;/body&amp;gt;

&amp;lt;script&amp;gt;
    class Person{
        constructor(name,age) {
            this.name = name
            this.age = age
        }

        // show method
        show(){
            document.write(this.name+&amp;#34; &amp;#34;+this.age+&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;);
        }

        eat(){
            document.write(&amp;#34;吃饭&amp;lt;br&amp;gt;&amp;#34;);
        }
    }

    let p = new Person(&amp;#34;张三&amp;#34;,23)
    p.show()
    p.eat()
&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;字面量定义类和使用&#34;&gt;字面量定义类和使用&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;let 对象名 = {
    变量名 : 变量值,
    变量名 : 变量值,
    ...

    方法名 : function(参数列表){
        方法体;
        return 返回值;
    }
    ...
};
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;使用格式
&lt;ul&gt;
&lt;li&gt;对象名.变量名&lt;/li&gt;
&lt;li&gt;对象名.方法名();&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    let person = {
        name : &amp;#34;张三&amp;#34;,
        age : 23,
        hobby : [&amp;#34;听课&amp;#34;,&amp;#34;学习&amp;#34;],
        show : function (){
            document.write(this.name+&amp;#34; &amp;#34;+this.age+&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)
        },

        eat : function (){
            document.write(&amp;#34;吃饭&amp;#34;)
        }
    }
    document.write(person.name+person.age+person.hobby[0]+&amp;#34;,&amp;#34;+person.hobby[1]+&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    person.eat()
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;继承&#34;&gt;继承&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;继承: 让类与类产生子父类的关系,子类可以使用父类有权限的成员&lt;/li&gt;
&lt;li&gt;继承关键字: extends&lt;/li&gt;
&lt;li&gt;顶级父类: Object&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    class Person{
        constructor(name,age) {
            this.name = name
            this.age = age
        }

        // show method
        show(){
            document.write(this.name+&amp;#34; &amp;#34;+this.age+&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;);
        }
    }

    class Worker extends Person{
        constructor(name,age,salary) {
            super(name, age);
            this.salary = salary
        }
        show(){
            document.write(this.name+this.age+this.salary)
        }
    }

    var w = new Worker(&amp;#34;张三&amp;#34;,23,10000)
    w.show()
&amp;lt;/script
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;javascript-内置对象&#34;&gt;JavaScript 内置对象&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Number&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法名       说明
parseFloat() 将传入的字符串浮点数转为浮点数
parseInt()   将传入的字符串整数转为整数
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // 1. parseFloat() 将传入的字符串浮点数转为浮点数
    document.write(Number.parseFloat(&amp;#34;2.333&amp;#34;))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)
    document.write(Number.parseFloat(&amp;#34;2.333&amp;#34;)+2)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // 2. parseInt() 将传入的字符串整数转为整数
    document.write(Number.parseInt(&amp;#34;100&amp;#34;))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)
    document.write(Number.parseInt(&amp;#34;100&amp;#34;)+20)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)
    document.write(Number.parseInt(&amp;#34;1100ab&amp;#34;))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Math&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法名 说明
ceil(x) 向上取整
floor(x) 向下取整
round(x) 把数四舍五入为最接近的整数
random() 随机数,返回的是0.0-1.0之间范围(含头不含尾)
pow(x,y) 幂运算的x的y次方
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // ceil(x) 向上取整
    document.write(Math.ceil(4.4))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // floor(x) 向下取整
    document.write(Math.floor(4.4))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // round(x) 把数四舍五入为最接近的整数
    document.write(Math.round(4.1))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)
    document.write(Math.round(4.6))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // random() 随机数,返回的是0.0-1.0之间范围(含头不含尾)
    document.write(Math.random())
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // pow(x,y) 幂运算的x的y次方
    document.write(Math.pow(2,3))
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Date&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;构造方法                                                  说明
Date()                                                    根据当前时间创建对象
Date(value)                                               根据指定毫秒值创建对象
Date(year,month,[day,hours,minutes,seconds,milliseconds]) 根据指定字段你出去对象(月份是0-11)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;成员方法         说明
getFullYear()    获取年份
getMonth()       获取月份
getDate()        获取天数
getHours()       获取小时
getMinutes()     获取分钟
getSeconds()     获取秒数
getTime()        返回距1970年1月1日至今的毫秒数
toLocaleString() 返回本地日期格式的字符串
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // Date()                                                    根据当前时间创建对象
    let d1 = new Date()
    document.write(d1)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // Date(value)                                               根据指定毫秒值创建对象
    let d2 = new Date(20000)
    document.write(d2)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // Date(year,month,[day,hours,minutes,seconds,milliseconds]) 根据指定字段你出去对象(月份是0-11)
    let d3 = new Date(2022,9,3,4,5,6)
    document.write(d3)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)


    // getFullYear()    获取年份
    document.write(d3.getFullYear())
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // getMonth()       获取月份
    document.write(d3.getMonth())
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // getDate()        获取天数
    document.write(d3.getDate())
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // getHours()       获取小时
    document.write(d3.getHours())
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // getMinutes()     获取分钟
    document.write(d3.getMinutes())
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // getSeconds()     获取秒数
    document.write(d3.getSeconds())
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // getTime()        返回距1970年1月1日至今的毫秒数
    document.write(d3.getTime())
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // toLocaleString() 返回本地日期格式的字符串
    document.write(d3.toLocaleString())
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

&amp;lt;/script
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;String 内置对象&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;构造方法 说明
String(value) 根据指定字符串创建对象
let s=&amp;#34;字符串&amp;#34; 直接赋值
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;成员方法 说明
length属性           获取字符串长度
charAt(index)        获取指定索引处的字符
indexOf(value)       获取指定字符串出现的索引位置,换不到为-1
substring(start,end) 根据指定索引范围截取字符串(含头不含尾)
split(value)         根据指定规则切割字符串,返回数组
replace(old,new)     使用新字符串替换老字符串
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    //     String(value) 根据指定字符串创建对象
    let s1 = new String(&amp;#34;Hello&amp;#34;)
    document.write(s1)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    //     let s=&amp;#34;字符串&amp;#34; 直接赋值
    let s2 = &amp;#34;World&amp;#34;
    document.write(s2)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    //     成员方法 说明
    //     length属性           获取字符串长度
    let s3 = &amp;#34;What is you name!&amp;#34;
    document.write(s3.length)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    //     charAt(index)        获取指定索引处的字符
    document.write(s3.charAt(10))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    //     indexOf(value)       获取指定字符串出现的索引位置,换不到为-1
    document.write(s3.indexOf(&amp;#34;a&amp;#34;))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    //     substring(start,end) 根据指定索引范围截取字符串(含头不含尾)
    document.write(s3.substring(0,4))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    //     split(value)         根据指定规则切割字符串,返回数组
    let s5arr = s3.split(&amp;#34;\\s&amp;#34;)
    for(ss of s5arr){
        document.write(ss)
    }
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    //     replace(old,new)     使用新字符串替换老字符串
    let s6 = &amp;#34;What is youuuu name!&amp;#34;
    document.write(s6.replace(&amp;#34;uu&amp;#34;,&amp;#34;s&amp;#34;))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;RegExp&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;正则表达: 是一种对字符串进行匹配的规则&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;构造方法         说明
RegExp(规则)     根据指定规则创建对象
let reg=/^规则$/ 直接赋值
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;成员方法           说明
test(匹配的字符串) 根据指定规则验证字符串是否符合
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;规则&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;表达式 说明
[a]    只能是a
[abc]  只能是abc中的某一个
[1]    只能是1
[123]  只能是123中的某一个
[a-z]  只能a到z中某一个
[A-Z]  只能A到Z中某一个
[0-9]  只能0到9中某一个
{5}    只能出现5次
{4,6}  只能出现4到6次
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // RegExp(规则)     根据指定规则创建对象
    let regx1 = new RegExp(&amp;#34;[1][358][0-9]{9}&amp;#34;)
    document.write(regx1.test(13510002000))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)
    document.write(regx1.test(12510002000))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // let reg=/^规则$/ 直接赋值
    let regx2 =/^[\\_0-9a-zA-Z]{4,16}$/
    document.write(regx2.test(&amp;#34;_sdkfj.&amp;#34;))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)
    document.write(regx2.test(&amp;#34;_dkjf23&amp;#34;))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Array&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;成员方法       说明
push(元素)     添加元素到数组的末尾
pop()          删除数组末尾的元素
shift()        删除数组最前面的元素
includes(元素) 判断数组是否包含给定的值
reverse()      反转数组中的元素
sort()         对数组元素进行排序
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // push(元素)     添加元素到数组的末尾
    let arr = [4,2,3,5,1]
    arr.push(8)
    for(let a of arr){
        document.write(a+&amp;#34; &amp;#34;)
    }
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // pop()          删除数组末尾的元素
    arr.pop()
    for(let a of arr){
        document.write(a+&amp;#34; &amp;#34;)
    }
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // shift()        删除数组最前面的元素
    arr.shift()
    for(let a of arr){
        document.write(a+&amp;#34; &amp;#34;)
    }
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // includes(元素) 判断数组是否包含给定的值
    document.write(arr.includes(5))
    document.write(arr.includes(10))
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // reverse()      反转数组中的元素
    arr.reverse()
    for(let a of arr){
        document.write(a+&amp;#34; &amp;#34;)
    }
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // sort()         对数组元素进行排序
    arr.sort()
    for(let a of arr){
        document.write(a+&amp;#34; &amp;#34;)
    }
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Set&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;JavaScript中的Set集合, 元素唯一, 存取顺序一致&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;构造方法 说明
Set()    创建Set集合对象
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;成员方法     说明
add(元素)    向集合中添加元素
size属性     获取集合长度
keys()       获取迭代器对象
delete(元素) 删除指定元素
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // Set()    创建Set集合对象
    let s = new Set();

    // add(元素)    向集合中添加元素
    s.add(&amp;#34;a&amp;#34;)
    s.add(&amp;#34;b&amp;#34;)
    s.add(&amp;#34;c&amp;#34;)
    s.add(&amp;#34;c&amp;#34;)

    // size属性     获取集合长度
    document.write(s.size)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // keys()       获取迭代器对象
    var st = s.keys();
    for(let i=0; i&amp;lt;s.size ; i++){
        document.write(st.next().value + &amp;#34; &amp;#34;)
    }
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // delete(元素) 删除指定元素
    s.delete(&amp;#34;a&amp;#34;)
    for(let sa of s){
        document.write(sa+&amp;#34; &amp;#34;)
    }
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Map
&lt;ul&gt;
&lt;li&gt;JavaScript的Map集合, key唯一, 存取顺序一致&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;构造方法 说明
Map()    创建Map集合对象
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;成员方法       说明
set(key,value) 向集合中添加元素
size属性       获取集合长度
get(key)       根据key获取value
entries()      获取迭代器对象
delete(key)    根据key删除键值对
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // Map()    创建Map集合对象
    let map = new Map()

    // set(key,value) 向集合中添加元素
    map.set(&amp;#34;张三&amp;#34;,23)
    map.set(&amp;#34;王五&amp;#34;,25)
    map.set(&amp;#34;王五&amp;#34;,26)

    // size属性       获取集合长度
    document.write(map.size)
    document.write(&amp;#34;&amp;lt;br&amp;gt;&amp;#34;)

    // get(key)       根据key获取value
    document.write(map.get(&amp;#34;张三&amp;#34;))
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    // entries()      获取迭代器对象
    let st = map.entries()
    for(let i = 0; i&amp;lt; map.size ; i++){
        document.write(st.next().value+&amp;#34; &amp;#34;)
    }
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)



    // delete(key)    根据key删除键值对
    document.write(map.delete(&amp;#34;张三&amp;#34;))
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    st = map.entries()
    for(let i = 0; i&amp;lt; map.size ; i++){
        document.write(st.next().value+&amp;#34; &amp;#34;)
    }
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;JSON
&lt;ul&gt;
&lt;li&gt;JSON(JavaScript Obect Notation): 是一种轻量级的数据交换格式&lt;/li&gt;
&lt;li&gt;基于ECMAScript 规范的一个子集, 采用完全独立于编程语言的文本格式来存储和表示数据&lt;/li&gt;
&lt;li&gt;乘法和清晰的层次结构舍不得JSON成为理想的数据交换语言. 易于人阅读和编写, 同时也晚于计算机解析和生成, 并有效提升网络传输效率.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;成员方法       说明
stringfy(对象) 将指定对象黑的为json格式字符串
parse(字符串)  将指定json格式字符串解析成对象
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // 定义天气
    let weather = {
        city : &amp;#34;北京&amp;#34;,
        date : &amp;#34;2088-08-08&amp;#34;,
        wendu : &amp;#34;10~23&amp;#34;,
        shidu : &amp;#34;22%&amp;#34;
    };

    // 1. 天气转换成JSON格式的字符串
    let str = JSON.stringify(weather)
    document.write(str)
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    // 2. 将JSON格式字符串解析成JS对象
    let weather2 = JSON.parse(str)
    document.write(weather2.city+&amp;#34; &amp;#34;+weather2.date+&amp;#34; &amp;#34;+weather2.wendu+&amp;#34; &amp;#34;+weather2.shidu)
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;表单校验&#34;&gt;表单校验&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;

    let dd = document.getElementById(&amp;#34;regist&amp;#34;)
    dd.onsubmit = check

    function check(){
        let username = document.getElementById(&amp;#34;username&amp;#34;).value

        let password = document.getElementById(&amp;#34;password&amp;#34;).value

        let nameRegx = /^[a-zA-Z]{4,16}$/
        let passwordRegx = /^[\d]{6}$/

        if( !nameRegx.test(username)){
            alert(&amp;#34;用户名4-16位字母&amp;#34;)
            return false
        }

        if(! passwordRegx.test(password)){
            alert(&amp;#34;密码6位数字&amp;#34;)
            return false
        }

        return true;
    }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;bom&#34;&gt;BOM&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;BOM(Browser Object Model) 浏览器对象模型&lt;/li&gt;
&lt;li&gt;将浏览器的各个组成部分封装成不同的对象, 方便我们进行操作&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;window-窗口对象&#34;&gt;Window 窗口对象&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;定时器
&lt;ul&gt;
&lt;li&gt;唯一标识setTimeout(功能,毫秒值):设置一次性定时器.&lt;/li&gt;
&lt;li&gt;clearTimeout(标识):取消一次性定时器&lt;/li&gt;
&lt;li&gt;唯一标识setInterval(功能,毫秒值):设置循环定时器&lt;/li&gt;
&lt;li&gt;clearInterval(标识):取消循环定时器&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;加载事件
&lt;ul&gt;
&lt;li&gt;window.onload:在页面加载完毕后触发此事件的功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // 定时器
    function fun(){
        alert(&amp;#34;该起床了&amp;#34;)
    }


    // 设置一次性定时器
    let d1 = window.setTimeout(&amp;#34;fun()&amp;#34;,2000)
    window.clearTimeout(d1)

    // 设置循环定时器
    let d2 = window.setInterval(&amp;#34;fun()&amp;#34;, 3000)
    window.clearInterval(d2)


    // 加载事件
    window.onload = function (){
        let div = document.getElementById(&amp;#34;div&amp;#34;)
        alert(div)
    }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;location-地址栏对象&#34;&gt;Location 地址栏对象&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;href 属性
&lt;ul&gt;
&lt;li&gt;就是浏览器的地址栏, 我们可以通过为该属性设置的新的URL, 使浏览器读取并显示新的URL的内容&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;location地址栏对象&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        p{
            text-align: center;
        }
        span{
            color: red;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;p&amp;gt;
        注册成功!&amp;lt;span id=&amp;#34;time&amp;#34;&amp;gt;5&amp;lt;/span&amp;gt;秒之后自动跳转到首页...
    &amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;

    let num = 5;
    function show(){
        num--;
        if(num&amp;lt;=0){
            location.href = &amp;#34;01-windows窗口对象.html&amp;#34;
        }

        let span = document.getElementById(&amp;#34;time&amp;#34;);
        span.innerHTML = num
    }

    window.setInterval(&amp;#34;show()&amp;#34;,1000)

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;图片显示&#34;&gt;图片显示&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;body&amp;gt;

    &amp;lt;img src=&amp;#34;dayanmiao3.png&amp;#34; id=&amp;#34;img&amp;#34; alt=&amp;#34;da&amp;#34; height=&amp;#34;400px&amp;#34; style=&amp;#34;display: none&amp;#34;&amp;gt;
    &amp;lt;div class=&amp;#34;login-form-wrap&amp;#34;&amp;gt;
        &amp;lt;h1&amp;gt;黑马程序员&amp;lt;/h1&amp;gt;
        &amp;lt;form class=&amp;#34;login-form&amp;#34; action=&amp;#34;#&amp;#34; id=&amp;#34;regist&amp;#34; method=&amp;#34;get&amp;#34; autocomplete=&amp;#34;off&amp;#34;&amp;gt;
            &amp;lt;label&amp;gt;
                &amp;lt;input type=&amp;#34;text&amp;#34; id=&amp;#34;username&amp;#34; name=&amp;#34;username&amp;#34; placeholder=&amp;#34;Username...&amp;#34; value=&amp;#34;&amp;#34;&amp;gt;
            &amp;lt;/label&amp;gt;
            &amp;lt;label&amp;gt;
                &amp;lt;input type=&amp;#34;password&amp;#34; id=&amp;#34;password&amp;#34; name=&amp;#34;password&amp;#34; placeholder=&amp;#34;Password...&amp;#34; value=&amp;#34;&amp;#34;&amp;gt;
            &amp;lt;/label&amp;gt;
            &amp;lt;input type=&amp;#34;submit&amp;#34; value=&amp;#34;注册&amp;#34;&amp;gt;
        &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;

    function hideImg(){
        let imgId = document.getElementById(&amp;#34;img&amp;#34;);
        imgId.setAttribute(&amp;#34;style&amp;#34;,&amp;#34;display:none&amp;#34;)
    }
    let sd1 = window.setTimeout(function(){
        let imgId = document.getElementById(&amp;#34;img&amp;#34;);
        imgId.setAttribute(&amp;#34;style&amp;#34;,&amp;#34;display:block&amp;#34;)
    },3000)
    let sd2 = window.setTimeout(&amp;#34;hideImg()&amp;#34;,6000)
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;封装&#34;&gt;封装&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;my.js&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function getById(id){
    return document.getElementById(id);
}

function getByName(name){
    return document.getElementsByName(name);
}

function getByTag(tag){
    return document.getElementsByTagName(tag)
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    // 效果是一样的
    let div2 = getById(&amp;#34;div1&amp;#34;)
    alert(div2)

    let arr2 = getByName(&amp;#34;div2&amp;#34;)
    alert(arr2.length)


    // let div1 = document.getElementById(&amp;#34;div1&amp;#34;)
    // alert(div1)
    //
    // let arr = document.getElementsByName(&amp;#34;div2&amp;#34;)
    // alert(arr.length)
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>JavaScript一 Li.066</title>
      <link>https://lizicai.com/p/javascript%E4%B8%80-li.066/</link>
      <pubDate>Sun, 14 Nov 2021 15:51:02 +0800</pubDate>
      <guid>https://lizicai.com/p/javascript%E4%B8%80-li.066/</guid>
      <description>&lt;h2 id=&#34;javascript&#34;&gt;JavaScript&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JS的2种引入方式
&lt;ul&gt;
&lt;li&gt;直接在页面写&lt;/li&gt;
&lt;li&gt;在页面引入&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;快速入门&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;button id=&amp;#34;btn&amp;#34;&amp;gt;点我呀&amp;lt;/button&amp;gt;

&amp;lt;!--引入js的方式一: 内部方式--&amp;gt;
&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
    document.getElementById(&amp;#34;btn&amp;#34;).onclick = function (){
        alert(&amp;#34;点我干嘛&amp;#34;)
    }
&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;#34;js/my.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;输入输出语句&#34;&gt;输入输出语句&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;输入框
&lt;ul&gt;
&lt;li&gt;prompt(&amp;ldquo;提示内容&amp;rdquo;);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;弹出警告框
&lt;ul&gt;
&lt;li&gt;alert(&amp;ldquo;提示内容&amp;rdquo;);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;控制台输出
&lt;ul&gt;
&lt;li&gt;console.log(&amp;ldquo;显示内容&amp;rdquo;);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;页面内容输出
&lt;ul&gt;
&lt;li&gt;document.write(&amp;ldquo;显示内容&amp;rdquo;);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;输入输出语句&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;script&amp;gt;
    /*
    * 输入框
    * prompt(&amp;#34;提示内容&amp;#34;);
    * 弹出警告框
    * alert(&amp;#34;提示内容&amp;#34;);
    * 控制台输出
    * console.log(&amp;#34;显示内容&amp;#34;);
    * 页面内容输出
    * document.write(&amp;#34;显示内容&amp;#34;);
    */
    prompt(&amp;#34;请输入数据&amp;#34;)

    alert(&amp;#34;hello&amp;#34;)

    console.log(&amp;#34;打印logo&amp;#34;)

    document.write(&amp;#34;DaDaDa...&amp;#34;)
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    document.write(&amp;#34;DaDa&amp;#34;)
    document.write(&amp;#34;&amp;lt;h1&amp;gt;Hello&amp;lt;/h1&amp;gt;&amp;#34;)
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;变量和常量&#34;&gt;变量和常量&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JavaScrip属于弱类型语言, 定义变量时不区分具体的数据类型&lt;/li&gt;
&lt;li&gt;定义局部变量
&lt;ul&gt;
&lt;li&gt;let 变量名 = 值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;定义全局变量
&lt;ul&gt;
&lt;li&gt;变量名 = 值;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;定义常量
&lt;ul&gt;
&lt;li&gt;const 常量名= 值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;变量和常量&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;script&amp;gt;
  // 1. 定义局部变量

  let name = &amp;#34;张三&amp;#34;;
  let age = 23;
  document.write(name+&amp;#34;, &amp;#34;+ age)
  document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

  // 2. 定义全局变量
  {
      let l1 = &amp;#34;aa&amp;#34;;
      l2 = &amp;#34;bb&amp;#34;;
  }
  // document.writeln(l1)
  document.writeln(l2)
  document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

  // 3. 定义常量
  const PI = 3.1415926
  // PI = 3.15
  document.write(PI)
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;原始数据类型&#34;&gt;原始数据类型&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;数据类型  说明
boolean   布尔类型,true或false
null      声明null值的声明关键字
undefined 代表变量未定义
number    整数或浮点数
string    字符串
bigint    大整数,例如let num=10n;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;typeof用于判断变量的数据类型
&lt;ul&gt;
&lt;li&gt;let age=18;&lt;/li&gt;
&lt;li&gt;document.write(typeof(age)); //number&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;typeof方法&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;script&amp;gt;
    let l1 = true
    document.write(typeof (l1))
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    let l2 = null
    document.write(typeof (l2))
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    let l3
    document.write(typeof (l3))
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    let l4 = 10
    document.write(typeof (l4))
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    let l5 = &amp;#34;hello&amp;#34;
    document.write(typeof (l5))
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    let l6 = 100n
    document.write(typeof (l6))
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;算数运算符&#34;&gt;算数运算符&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;算术运算符&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;运算符 说明
+      加法运算
-      减法运算
*      乘法运算
/      除法运算
%      取余数
++     自增
--     自减
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;赋值运算符&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;运算符 说明
=      将箱封号右边的值赋值给箱封号左边的变量
+=     想回后赋值
-=     相减后赋值
*=     相乘后赋值
/=     相除后赋值
%=     取余数后赋值
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;比较运算符&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;运算符 说明
== 判断值是否相等
=== 判断数据类型和值是否相等
&amp;gt; 大于
&amp;gt;= 大于等于
&amp;lt; 小于
&amp;lt;= 小于等于
!= 不等于
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;逻辑运算符&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;运算符 说明
&amp;amp;&amp;amp;     逻辑与,并且
||     逻辑或,或者
!      取反
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;三元运算符
&lt;ul&gt;
&lt;li&gt;三元运算符格式
&lt;ul&gt;
&lt;li&gt;(比较表达式)?表达式1:表达式2;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;执行流程
&lt;ul&gt;
&lt;li&gt;如果比较表达为true, 则取表达式1&lt;/li&gt;
&lt;li&gt;如果比较表达为false, 则取表达式2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;运算符&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;script&amp;gt;
    let num = &amp;#34;10&amp;#34;
    // 和字符之间的+号, 拼接, 其他符号则把字符转成number运算
    document.write(num + 5)
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    document.write(num + &amp;#34;5&amp;#34;)
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    document.write(num - 5)
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    document.write(num * 5)
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    let num2 = 10
    document.write(num == num2)
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    document.write(num === num2)
    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;javascrip的-流程控制和循环语句&#34;&gt;JavaScrip的 流程控制和循环语句&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;if&lt;/li&gt;
&lt;li&gt;switch&lt;/li&gt;
&lt;li&gt;for&lt;/li&gt;
&lt;li&gt;while&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;流程控制和循环语句&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;script&amp;gt;
    // if 语句
    let month = 10
    if(month &amp;gt;= 3 &amp;amp;&amp;amp; month &amp;lt;= 5){
        document.write(&amp;#34;春季&amp;#34;)
    } else if( month &amp;gt;= 6 &amp;amp;&amp;amp; month &amp;lt;= 6){
        document.write(&amp;#34;夏季&amp;#34;)
    } else if( month &amp;gt;= 9 &amp;amp;&amp;amp; month &amp;lt;= 11) {
        document.write(&amp;#34;秋季&amp;#34;)
    } else if( month == 12 || month == 1 || month == 2) {
        document.write(&amp;#34;冬季&amp;#34;)
    } else  {
        document.write(&amp;#34;月份有误&amp;#34;)
    }

    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    // switch 语句
    switch (month){
        case 3:
        case 4:
        case 5:
            document.write(&amp;#34;春季&amp;#34;)
            break
        case 6:
        case 7:
        case 8:
            document.write(&amp;#34;夏季&amp;#34;)
            break
        case 9:
        case 10:
        case 11:
            document.write(&amp;#34;秋季&amp;#34;)
            break
        case 12:
        case 1:
        case 2:
            document.write(&amp;#34;冬季&amp;#34;)
            break
        default:
            document.write(&amp;#34;月份有误&amp;#34;)
    }

    document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    // for
    for(let i=1;i&amp;lt;=5;i++){
        document.write(i+&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }

    // while
    let n =6
    while (n &amp;lt;= 10){
        document.write(n+&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
        n++
    }
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;数组&#34;&gt;数组&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;数组的使用Java中的数据基本一致, 但是在JavaScript中的数据更加灵活, 数据类型和长度都没有限制&lt;/li&gt;
&lt;li&gt;定义格式
&lt;ul&gt;
&lt;li&gt;let 数组名 = [元素1,元素2,&amp;hellip;];&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;索引范围
&lt;ul&gt;
&lt;li&gt;从0开始, 最大到数组长度-1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;数组长度
&lt;ul&gt;
&lt;li&gt;数组名.length&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;数组高级运算符&amp;hellip;
&lt;ul&gt;
&lt;li&gt;数组复制&lt;/li&gt;
&lt;li&gt;合并数组&lt;/li&gt;
&lt;li&gt;字符串转数组&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;数组&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
    // 定义数组
    let arr = [10,20,30]

    for(let i=0; i &amp;lt; arr.length; i++){
        document.write(arr[i])
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }
    document.write(&amp;#34;=======================&amp;lt;br/&amp;gt;&amp;#34;)


    arr[3] = 40
    for(let i=0; i &amp;lt; arr.length; i++){
        document.write(arr[i])
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }
    document.write(&amp;#34;=======================&amp;lt;br/&amp;gt;&amp;#34;)

    // 数组高级运算符: ...
    // 复制数组
    let arr2 = [...arr]

    for(let i=0; i &amp;lt; arr2.length; i++){
        document.write(arr2[i])
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }
    document.write(&amp;#34;=======================&amp;lt;br/&amp;gt;&amp;#34;)

    // 合并数据
    let arr3 = [40,50,60];
    let arr4 = [...arr2,...arr3]
    for(let i=0; i &amp;lt; arr4.length; i++){
        document.write(arr4[i])
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }

    for(var i of arr4){
        document.write(i)
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }

    document.write(&amp;#34;=======================&amp;lt;br/&amp;gt;&amp;#34;)
    // 字符串转成数组
    let arr5 = [...&amp;#34;heima&amp;#34;]
    for(var i of arr5){
        document.write(i)
        document.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }

&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;函数&#34;&gt;函数&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;函数类似于java中的方法, 可以将一些代码进行抽取, 达到复用的效果&lt;/li&gt;
&lt;li&gt;定义格式
&lt;ul&gt;
&lt;li&gt;function 方法名(参数列表){方法体 return 返回值}&lt;/li&gt;
&lt;li&gt;有返回值, 可以写&lt;/li&gt;
&lt;li&gt;无返回值, 则不需要写&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;可变参数
&lt;ul&gt;
&lt;li&gt;function 方法名(&amp;hellip;参数名){ 方法体; return 返回值 }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;匿名函数
&lt;ul&gt;
&lt;li&gt;function(参数列表){ 方法体; }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;函数&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;script &amp;gt;
    // 无参无返回值的函数
    function println(){
        document.write(&amp;#34;Hello JS&amp;#34;+&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)
    }
    println()

    // 有参 有返回值方法
    function getSum(num1,num2){
        return num1 + num2;
    }
    let sum = getSum(10,20);
    document.write(sum+&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;)

    // 可变参数, 对n个数字进行求和
    function getSum(...params){
        let ss = 0
        for(let i=0; i &amp;lt;params.length; i++){
            ss+=params[i]
        }
        return ss;
    }
    let sum2 = getSum(10,20, 20)
    document.write(sum2)


    // 匿名函数
    let fun = function(){
        document.write(&amp;#34;hello&amp;#34;)
    }
    fun()
&amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dom&#34;&gt;DOM&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DOM(Document Object Model):文档对象模型&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将HTML文档的各个组成部分, 封装为对象. 借助这些对象可以对HTML文档进行增删改查的动态操作&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Document: 文档对象&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Element: 元素对象
&lt;ul&gt;
&lt;li&gt;Attribute: 属性对象
&lt;ul&gt;
&lt;li&gt;Text: 文本对象&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法名                              说明
getElementById(id属性值)            根据id获得一个元素
getElementsByTagName(标签名称)      根据标签名称获得多个元素
getElementsByName(name属性值)       根据name属性获得多个元素
getElementsByClassName(class属性值) 根据class属性获得多个元素
子元素对象.parentElement属性        获取当前元素的父元素
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;元素的操作&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        .cls{
            border: 1px solid red;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;#34;div1&amp;#34;&amp;gt;div1&amp;lt;/div&amp;gt;
&amp;lt;div id=&amp;#34;div2&amp;#34;&amp;gt;div2&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;cls&amp;#34;&amp;gt;div3&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;cls&amp;#34;&amp;gt;div4&amp;lt;/div&amp;gt;
&amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;username&amp;#34;/&amp;gt;

&amp;lt;script&amp;gt;
    // 1. getElementById(id属性值)            根据id获得一个元素
    var div1 = document.getElementById(&amp;#34;div1&amp;#34;);
    // alert(div1)
    console.log(div1.innerHTML)

    // 2. getElementsByTagName(标签名称)      根据标签名称获得多个元素
    var divs = document.getElementsByTagName(&amp;#34;div&amp;#34;);
    // alert(divs.length)
    for(var i of divs){
        console.log(i.innerHTML)
    }

    // 3. getElementsByName(name属性值)       根据name属性获得多个元素
    var nameEs = document.getElementsByName(&amp;#34;username&amp;#34;);
    alert(nameEs.length)
    for(let e of nameEs){
        console.log(e.getAttribute(&amp;#34;type&amp;#34;))
    }

    // 4. getElementsByClassName(class属性值) 根据class属性获得多个元素
    var clsE = document.getElementsByClassName(&amp;#34;cls&amp;#34;);
    // alert(clsE.length)
    for(let e of clsE){
        console.log(e.innerHTML)
    }

    // 5. 子元素对象.parentElement属性        获取当前元素的父元素
    var parentElement = div1.parentElement;
    console.log(parentElement.tagName)

&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;element-元素的操作&#34;&gt;Element 元素的操作&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法名                      说明
createElement(标签名)       创建一个新元素
appendChild(子元素)         将指定子元素添加到父元素中
removeChild(子元素)         父元素删除指定子元素
replaceChild(新元素,旧元素) 用新元素替换子元素
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;元素的操作&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;select id=&amp;#34;s&amp;#34;&amp;gt;
    &amp;lt;option&amp;gt;---请选择---&amp;lt;/option&amp;gt;
    &amp;lt;option&amp;gt;北京&amp;lt;/option&amp;gt;
    &amp;lt;option&amp;gt;上海&amp;lt;/option&amp;gt;
    &amp;lt;option&amp;gt;广州&amp;lt;/option&amp;gt;
&amp;lt;/select&amp;gt;

&amp;lt;script&amp;gt;
    // 1. createElement() 创建元素
    var sz = document.createElement(&amp;#34;option&amp;#34;);
    // 为option添加文本内容
    sz.innerHTML = &amp;#34;深圳&amp;#34;

    // 2. appendChild(子元素)         将指定子元素添加到父元素中
    var select = document.getElementById(&amp;#34;s&amp;#34;);
    select.appendChild(sz)

    // 3. removeChild(子元素)         父元素删除指定子元素
    // select.removeChild(sz)

    // 4. replaceChild(新元素,旧元素) 用新元素替换子元素
    var hz = document.createElement(&amp;#34;option&amp;#34;);
    hz.innerHTML = &amp;#34;杭州&amp;#34;
    select.replaceChild(cq,sz)

&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;attribute-属性的操作&#34;&gt;Attribute 属性的操作&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法名                      说明
setAtrribute(属性名,属性值) 设置属性
getAtrribute(属性名)        根据属性名获取属性值
removeAtrribute             根据属性名先锋队指定的属性
style属性                   为元素添加样式
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;属性的操作&amp;lt;/title&amp;gt;
  &amp;lt;style&amp;gt;
    .acolor{
      color: #1c1ccb;
    }
  &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;a&amp;gt;点我呀&amp;lt;/a&amp;gt;
&amp;lt;script&amp;gt;
    // 1. setAtrribute(属性名,属性值) 设置属性
    var a = document.getElementsByTagName(&amp;#34;a&amp;#34;)[0];
    a.setAttribute(&amp;#34;href&amp;#34;,&amp;#34;https://baidu.com&amp;#34;)

    // 2. getAtrribute(属性名)        根据属性名获取属性值
    var value = a.getAttribute(&amp;#34;href&amp;#34;);
    // alert(value)

    // 3. removeAtrribute             根据属性名先锋队指定的属性
    a.removeAttribute(&amp;#34;href&amp;#34;)

    // 4. style属性                   为元素添加样式
    // a.style.color = &amp;#34;red&amp;#34;

    // 5. className 属性 添加指定样式
    a.className = &amp;#34;acolor&amp;#34;

&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;text-文本的操作&#34;&gt;Text 文本的操作&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;属性名    说明
innerText 添加文本内容,不解析标签
innerHTML 添加文本内容,解析标签
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;文本的操作&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;div id=&amp;#34;div&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;script&amp;gt;
    // 1. innerText 添加文本内容, 不解析标签
    var div = document.getElementById(&amp;#34;div&amp;#34;);
    div.innerText = &amp;#34;&amp;lt;h1&amp;gt;这是div&amp;lt;/h1&amp;gt;&amp;#34;

    // 2. innerHTML 添加文本内容, 解析标签
    div.innerHTML = &amp;#34;&amp;lt;h1&amp;gt;这也是DIV&amp;lt;/h1&amp;gt;&amp;#34;
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;事件&#34;&gt;事件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;事件指的就是当某些组件执行了某些操作后, 会触发某些代码的执行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;事件名     说明
onload     某个页面或图像被完成加载
onsubmit   当表单提交时触发该事件
onclick    鼠标赣南事件
ondblclick 鼠标双击事件
onblur     元素失去售点
onfocus    元素获得售点
onchange   用户改变域的内容
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;了解的事件&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;事件名      说明
onkeydown   某个键盘的键被按下
onkeypress  某个键盘的键被按下或按住
onkeyup     某个键盘的键被松开
onmousedown 某个鼠标按钮被按下
onmouseup   某个鼠标按钮被李嘉琪
onmouseover 鼠标被移到某元素之上
onmouseout  鼠标从某元素移开
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;绑定事件&#34;&gt;绑定事件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;方式一
&lt;ul&gt;
&lt;li&gt;通过标签中的事件属性进行绑定&lt;/li&gt;
&lt;li&gt;button id=&amp;ldquo;btn&amp;rdquo; onclick=&amp;ldquo;执行的功能&amp;rdquo;&amp;gt;&lt;/button&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;方式二
&lt;ul&gt;
&lt;li&gt;通过DOM元素属性绑定&lt;/li&gt;
&lt;li&gt;document.getElementById(&amp;ldquo;btn&amp;rdquo;).onclick=执行的功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;事件&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div align=&amp;#34;center&amp;#34;&amp;gt;
&amp;lt;img id=&amp;#34;img&amp;#34; width=&amp;#34;80%&amp;#34; height=&amp;#34;800px&amp;#34; src=&amp;#34;img/p1.jpg&amp;#34; /&amp;gt;
&amp;lt;br/&amp;gt;
&amp;lt;button id=&amp;#34;up&amp;#34; onclick=&amp;#34;up()&amp;#34;&amp;gt;上一张&amp;lt;/button&amp;gt;
&amp;lt;button id=&amp;#34;down&amp;#34;&amp;gt;下一张&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;

    // var btnup = document.getElementById(&amp;#34;up&amp;#34;);

    var btndown = document.getElementById(&amp;#34;down&amp;#34;);

    function up(){
        let img = document.getElementById(&amp;#34;img&amp;#34;)
        img.setAttribute(&amp;#34;src&amp;#34;,&amp;#34;img/p1.jpg&amp;#34;)
    }

    function down(){
        let img = document.getElementById(&amp;#34;img&amp;#34;)
        img.setAttribute(&amp;#34;src&amp;#34;,&amp;#34;img/p2.jpg&amp;#34;)
    }

    btndown.onclick = down()

&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;综合案例&#34;&gt;综合案例&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;appendChild&lt;/li&gt;
&lt;li&gt;append支持添加多个Child了&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;综合案例&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;

        a{
            color: blue;
        }
        table,table tr th, table tr td {
            border:1px solid black;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div align=&amp;#34;center&amp;#34;&amp;gt;
    &amp;lt;div id=&amp;#34;divinput&amp;#34; &amp;gt;
        &amp;lt;input type=&amp;#34;text&amp;#34; id=&amp;#34;name&amp;#34; placeholder=&amp;#34;请输入姓名&amp;#34; autocomplete=&amp;#34;off&amp;#34;&amp;gt;
        &amp;lt;input type=&amp;#34;text&amp;#34; id=&amp;#34;age&amp;#34; placeholder=&amp;#34;请输入年龄&amp;#34; autocomplete=&amp;#34;off&amp;#34;&amp;gt;
        &amp;lt;input type=&amp;#34;text&amp;#34; id=&amp;#34;gender&amp;#34; placeholder=&amp;#34;请输入姓名&amp;#34; autocomplete=&amp;#34;off&amp;#34; &amp;gt;
        &amp;lt;input type=&amp;#34;button&amp;#34; id=&amp;#34;add&amp;#34; value=&amp;#34;添加&amp;#34; onclick=&amp;#34;add()&amp;#34; &amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;div &amp;gt;
        &amp;lt;a style=&amp;#34;color: black;&amp;#34;&amp;gt;学生信息表&amp;lt;/a&amp;gt;
        &amp;lt;table style=&amp;#34;width: 300px; border: 1px solid black&amp;#34; &amp;gt;
            &amp;lt;thead&amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;th&amp;gt;姓名&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;年龄&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;性别&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;操作&amp;lt;/th&amp;gt;
            &amp;lt;/tr&amp;gt;
            &amp;lt;/thead&amp;gt;
            &amp;lt;tbody id=&amp;#34;tbody&amp;#34; &amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;td&amp;gt;张三&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;23&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;男&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;&amp;lt;a href=&amp;#34;JavaScript:void(0);&amp;#34; onclick=&amp;#34;deleteTr(this)&amp;#34;&amp;gt;删除&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;td&amp;gt;王五&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;25&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;女&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;&amp;lt;a href=&amp;#34;JavaScript:void(0);&amp;#34;  onclick=&amp;#34;deleteTr(this)&amp;#34;&amp;gt;删除&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
            &amp;lt;/tbody&amp;gt;
        &amp;lt;/table&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;script&amp;gt;

    function deleteTr(obj){
        let tbody = obj.parentElement.parentElement.parentElement
        let tr = obj.parentElement.parentElement;
        tbody.removeChild(tr)
    }
    function add(){
        let tr = document.createElement(&amp;#34;tr&amp;#34;);

        let tdName = document.createElement(&amp;#34;td&amp;#34;);
        let tdAge = document.createElement(&amp;#34;td&amp;#34;);
        let tdGender = document.createElement(&amp;#34;td&amp;#34;);
        let tdDel = document.createElement(&amp;#34;td&amp;#34;);

        tr.appendChild(tdName)
        tr.appendChild(tdAge)
        tr.appendChild(tdGender)
        tr.appendChild(tdDel)

        let nameText = document.getElementById(&amp;#34;name&amp;#34;).value
        let ageText = document.getElementById(&amp;#34;age&amp;#34;).value
        let genderText = document.getElementById(&amp;#34;gender&amp;#34;).value

        tdName.innerText = nameText
        tdAge.innerText = ageText
        tdGender.innerText = genderText

        let a = document.createElement(&amp;#34;a&amp;#34;)
        let aText = document.createTextNode(&amp;#34;删除&amp;#34;)
        a.setAttribute(&amp;#34;href&amp;#34;,&amp;#34;JavaScript:void (0);&amp;#34;)
        a.setAttribute(&amp;#34;onclick&amp;#34;, &amp;#34;deleteTr(this)&amp;#34;)
        a.appendChild(aText)
        tdDel.appendChild(a)

        let tbody = document.getElementById(&amp;#34;tbody&amp;#34;);

        tbody.appendChild(tr);

        // append 支持多参数了

        // let name = document.getElementById(&amp;#34;name&amp;#34;);
        // let age = document.getElementById(&amp;#34;age&amp;#34;);
        // let gender = document.getElementById(&amp;#34;gender&amp;#34;);
        //
        // let tr = document.createElement(&amp;#34;tr&amp;#34;);
        // let tdname = document.createElement(&amp;#34;td&amp;#34;);
        // tdname.innerText = name.value
        // let tdage = document.createElement(&amp;#34;td&amp;#34;);
        // tdage.innerText = age.value
        // let tdgender = document.createElement(&amp;#34;td&amp;#34;);
        // tdgender.innerText = gender.value
        //
        // let tddel = document.createElement(&amp;#34;td&amp;#34;);
        // tddel.innerHTML = &amp;#34;&amp;lt;a href=\&amp;#34;JavaScript:void(0);\&amp;#34; onclick=\&amp;#34;deleteTr()\&amp;#34;&amp;gt;删除&amp;lt;/a&amp;gt;&amp;#34;
        //
        // tr.append(tdname,tdage,tdgender,tddel);
        //
        // let tbody = document.getElementById(&amp;#34;tbody&amp;#34;);
        //
        // tbody.append(tr);
    }

&amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>MyBatis框架三 Li.065</title>
      <link>https://lizicai.com/p/mybatis%E6%A1%86%E6%9E%B6%E4%B8%89-li.065/</link>
      <pubDate>Thu, 04 Nov 2021 21:59:16 +0800</pubDate>
      <guid>https://lizicai.com/p/mybatis%E6%A1%86%E6%9E%B6%E4%B8%89-li.065/</guid>
      <description>&lt;h2 id=&#34;注解开发mybatis&#34;&gt;注解开发MyBatis&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;操作
&lt;ul&gt;
&lt;li&gt;创建接口和查询方法&lt;/li&gt;
&lt;li&gt;在核心配置文件中配置映射关系&lt;/li&gt;
&lt;li&gt;编写测试类&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.mapper;

import com.lizicai.bean.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface StudentMapper {

    // 查询
    @Select( &amp;#34;SELECT * FROM student&amp;#34;)
    public abstract List&amp;lt;Student&amp;gt; selectAll();

    // 插入数据
    @Insert(&amp;#34;INSERT INTO student VALUES (#{id},#{name},#{age})&amp;#34;)
    public abstract Integer insert(Student stu);

    // 修改数据
    @Update(&amp;#34;UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}&amp;#34; )
    public abstract Integer update(Student stu);

    // 删除数据
    @Delete(&amp;#34;DELETE FROM student WHERE id=#{id}&amp;#34;)
    public abstract Integer delete(Integer id);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&amp;lt;!DOCTYPE configuration
        PUBLIC &amp;#34;-//mybatis.org//DTA Mapper 3.0//EN&amp;#34;
        &amp;#34;http://mybatis.org/dtd/mybatis-3-config.dtd&amp;#34;&amp;gt;
&amp;lt;configuration&amp;gt;
&amp;lt;!--    数据库账号配置--&amp;gt;
    &amp;lt;properties resource=&amp;#34;jdbc.properties&amp;#34;&amp;gt;&amp;lt;/properties&amp;gt;

&amp;lt;!--    配置log4j--&amp;gt;
    &amp;lt;settings&amp;gt;
        &amp;lt;setting name=&amp;#34;logImpl&amp;#34; value=&amp;#34;log4j&amp;#34;/&amp;gt;
    &amp;lt;/settings&amp;gt;


    &amp;lt;!-- 起别名 --&amp;gt;
    &amp;lt;typeAliases&amp;gt;
        &amp;lt;package name=&amp;#34;com.lizicai.bean&amp;#34;/&amp;gt;
    &amp;lt;/typeAliases&amp;gt;

    &amp;lt;!-- 集成分页助手插件 --&amp;gt;
    &amp;lt;plugins&amp;gt;
        &amp;lt;plugin interceptor=&amp;#34;com.github.pagehelper.PageInterceptor&amp;#34;&amp;gt;&amp;lt;/plugin&amp;gt;
    &amp;lt;/plugins&amp;gt;

    &amp;lt;environments default=&amp;#34;mariadb&amp;#34;&amp;gt;
        &amp;lt;environment id=&amp;#34;mariadb&amp;#34;&amp;gt;
            &amp;lt;!-- 事务管理, 默认采用JDBC默认的事务--&amp;gt;
            &amp;lt;transactionManager type=&amp;#34;JDBC&amp;#34;&amp;gt;&amp;lt;/transactionManager&amp;gt;
&amp;lt;!--            dataSource数据源信息 type属性 连接池--&amp;gt;
            &amp;lt;dataSource type=&amp;#34;POOLED&amp;#34;&amp;gt;
                &amp;lt;property name=&amp;#34;driver&amp;#34; value=&amp;#34;${driver}&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;url&amp;#34; value=&amp;#34;${url}&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;username&amp;#34; value=&amp;#34;${username}&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;password&amp;#34; value=&amp;#34;${password}&amp;#34;/&amp;gt;
            &amp;lt;/dataSource&amp;gt;
        &amp;lt;/environment&amp;gt;
        &amp;lt;environment id=&amp;#34;mariadb2&amp;#34;&amp;gt;
            &amp;lt;transactionManager type=&amp;#34;JDBC&amp;#34;&amp;gt;&amp;lt;/transactionManager&amp;gt;
            &amp;lt;dataSource type=&amp;#34;POOLED&amp;#34;&amp;gt;
                &amp;lt;property name=&amp;#34;driver&amp;#34; value=&amp;#34;org.mariadb.jdbc.Driver&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;url&amp;#34; value=&amp;#34;jdbc:mariadb://192.168.0.100:3306/db2&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;username&amp;#34; value=&amp;#34;root&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;password&amp;#34; value=&amp;#34;rootPassword&amp;#34;/&amp;gt;
            &amp;lt;/dataSource&amp;gt;
        &amp;lt;/environment&amp;gt;
    &amp;lt;/environments&amp;gt;
    &amp;lt;mappers&amp;gt;
&amp;lt;!--        配置映射关系--&amp;gt;
        &amp;lt;package name=&amp;#34;com.lizicai.mapper&amp;#34;/&amp;gt;
    &amp;lt;/mappers&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.test;

import com.lizicai.bean.Student;
import com.lizicai.mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class Test01 {
    @Test
    public void selectAll() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        List&amp;lt;Student&amp;gt; list = mapper.selectAll();

        for(Student c : list){
            System.out.println(c);
        }
        sqlSession.close();

        is.close();
    }

    @Test
    public void insert() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        Student stu = new Student(9,&amp;#34;李大刀&amp;#34;,20);

        Integer result = mapper.insert(stu);

        System.out.println(result);

        sqlSession.close();

        is.close();
    }

    @Test
    public void update() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        Student stu = new Student(9,&amp;#34;李大刀&amp;#34;,22);

        Integer result = mapper.update(stu);

        System.out.println(result);

        sqlSession.close();

        is.close();
    }
    @Test
    public void delete() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        Integer result = mapper.delete(9);

        System.out.println(result);

        sqlSession.close();

        is.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;一对一&#34;&gt;一对一&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;环境准备&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@Results: 封装&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;环境准备&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@Results：封装映射关系的父注解。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Result[] value() ：定义了Result 数组&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@Result：封装映射关系的子注解。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;column 属性：查询出的表中字段名称&lt;/li&gt;
&lt;li&gt;property 属性：实体对象中的属性名称&lt;/li&gt;
&lt;li&gt;javalype 厲性：被包含对象的数据类型&lt;/li&gt;
&lt;li&gt;one 属性：一对—查询固定属性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@One：一对一查询的注解。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;select 属性：指定调用某个接口中的方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Person {
    private Integer id;
    private String name;
    private Integer age;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Card {
    private Integer id;
    private String number;
    private Person p;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.one_to_one;

import com.lizicai.bean.Card;
import com.lizicai.bean.Person;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface CardMapper {
    // 查询全部
    @Select(&amp;#34;SELECT * FROM card&amp;#34;)
    @Results({
            @Result(column = &amp;#34;id&amp;#34;, property = &amp;#34;id&amp;#34;),
            @Result(column = &amp;#34;number&amp;#34;,property = &amp;#34;number&amp;#34;),
            @Result(
                    property = &amp;#34;p&amp;#34;,
                    javaType = Person.class,
                    column = &amp;#34;pid&amp;#34;,
                    /**
                     * one @One 一对一固定写法
                     * select属性: 指定调用哪个接口中的哪个方法
                    */
                    one = @One(select = &amp;#34;com.lizicai.one_to_one.PersonMapper.selectById&amp;#34;)
            )
    })
    public abstract List&amp;lt;Card&amp;gt; selectAll();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.one_to_one;

import com.lizicai.bean.Person;
import org.apache.ibatis.annotations.Select;

public interface PersonMapper {

    // 根据id查询
    @Select(&amp;#34;SELECT * FROM person WHERE id=#{id}&amp;#34;)
    public abstract Person selectById(Integer id);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void selectAll() throws IOException {
    InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    CardMapper mapper = sqlSession.getMapper(CardMapper.class);
    List&amp;lt;Card&amp;gt; list = mapper.selectAll();

    for (Card card : list) {
        System.out.println(card);
    }
    sqlSession.close();

    is.close();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;MyBatisConfig.xml仍然要配置对应的mapper&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    &amp;lt;mappers&amp;gt;
&amp;lt;!--        配置映射关系--&amp;gt;
        &amp;lt;package name=&amp;#34;com.lizicai.one_to_one&amp;#34;/&amp;gt;
    &amp;lt;/mappers&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;一对多&#34;&gt;一对多&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;环境准备&lt;/li&gt;
&lt;li&gt;@Results：封装映射关系的父注解。
Result[] value() ：定义了 Result 数组&lt;/li&gt;
&lt;li&gt;@Result ：封装映射关系的子注解。
&lt;ul&gt;
&lt;li&gt;column 属性：查询出的表中字段名称&lt;/li&gt;
&lt;li&gt;property 厲性：实体对象中的属性名称&lt;/li&gt;
&lt;li&gt;javaType厲快：被包含对象的数据类型&lt;/li&gt;
&lt;li&gt;many 属性：一对多查询固定属性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Classes {
    private Integer id;
    private String name;

    private List&amp;lt;Student&amp;gt; students;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Student {
    private Integer id;
    private String name;
    private Integer age;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE classes(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20)
);
INSERT INTO classes VALUES (NULL, &amp;#39;一班&amp;#39;);
INSERT INTO classes VALUES (NULL, &amp;#39;二班&amp;#39;);

CREATE TABLE student(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(30),
    age INT,
    cid INT,
    CONSTRAINT cs_fk FOREIGN KEY (cid) REFERENCES classes(id)
);

INSERT INTO student VALUES (NULL,&amp;#39;张三&amp;#39;,23,1);
INSERT INTO student VALUES (NULL,&amp;#39;李四&amp;#39;,24,1);
INSERT INTO student VALUES (NULL,&amp;#39;王五&amp;#39;,25,2);
INSERT INTO student VALUES (NULL,&amp;#39;赵六&amp;#39;,26,2);

SELECT * FROM student;
SELECT * FROM classes;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.one_to_many;

import com.lizicai.bean.Classes;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface ClassesMapper {

    @Select(&amp;#34;SELECT * FROM classes&amp;#34;)
    @Results({
            @Result(column = &amp;#34;id&amp;#34;, property = &amp;#34;id&amp;#34;),
            @Result(column = &amp;#34;name&amp;#34;,property = &amp;#34;name&amp;#34;),
            @Result(
                    property = &amp;#34;students&amp;#34;,
                    javaType = List.class,
                    column = &amp;#34;id&amp;#34;,
                    /**
                     * many @Many 一对一固定写法
                     * select属性: 指定调用哪个接口中的哪个方法
                    */
                    many = @Many(select = &amp;#34;com.lizicai.one_to_many.StudentMapper.selectByCid&amp;#34;)
            )
    })
    public abstract List&amp;lt;Classes&amp;gt; selectAll();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.one_to_many;

import com.lizicai.bean.Student;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface StudentMapper {

    @Select(&amp;#34;SELECT * FROM student WHERE cid=#{cid}&amp;#34;)
    public abstract List&amp;lt;Student&amp;gt; selectByCid(Integer cid);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void selectAll() throws IOException {
    InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    ClassesMapper mapper = sqlSession.getMapper(ClassesMapper.class);

    List&amp;lt;Classes&amp;gt; list = mapper.selectAll();

    for (Classes c : list) {
        System.out.println(c.getId()+c.getName());
        List&amp;lt;Student&amp;gt; students = c.getStudents();
        if(students !=null){
            for (Student student : students) {
                System.out.println(student);
            }
        }
    }
    sqlSession.close();

    is.close();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;mappers&amp;gt;
    &amp;lt;!-- 配置映射关系--&amp;gt;
    &amp;lt;package name=&amp;#34;com.lizicai.one_to_one&amp;#34;/&amp;gt;
    &amp;lt;package name=&amp;#34;com.lizicai.one_to_many&amp;#34;/&amp;gt;
    &amp;lt;!-- &amp;lt;package name=&amp;#34;com.lizicai&amp;#34;/&amp;gt; 也可--&amp;gt;
&amp;lt;/mappers&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多对多&#34;&gt;多对多&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;环境准备&lt;/li&gt;
&lt;li&gt;@Results：封装映射关系的父注解。
Result[] value() ：定义了 Result 数组&lt;/li&gt;
&lt;li&gt;@Result ：封装映射关系的子注解。
&lt;ul&gt;
&lt;li&gt;column 属性：查询出的表中字段名称&lt;/li&gt;
&lt;li&gt;property 厲性：实体对象中的属性名称&lt;/li&gt;
&lt;li&gt;javaType厲快：被包含对象的数据类型&lt;/li&gt;
&lt;li&gt;many 属性：一对多查询固定属性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;@Many: 一对多查询的注解
&lt;ul&gt;
&lt;li&gt;select属性: 指定调用某个接口中的方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE course(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20)
);
INSERT INTO course VALUES (NULL,&amp;#39;语文&amp;#39;);
INSERT INTO course VALUES (NULL,&amp;#39;数学&amp;#39;);

CREATE TABLE stu_cr(
    id INT PRIMARY KEY AUTO_INCREMENT,
    sid INT,
    cid INT,
    CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id),
    CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id)
);
INSERT INTO stu_cr VALUES (NULL,1,1);
INSERT INTO stu_cr VALUES (NULL,1,2);
INSERT INTO stu_cr VALUES (NULL,2,1);
INSERT INTO stu_cr VALUES (NULL,2,2);

SELECT * FROM course;
SELECT * FROM stu_cr;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;mappers&amp;gt;
        &amp;lt;!--  配置映射关系--&amp;gt;
        &amp;lt;package name=&amp;#34;com.lizicai.one_to_one&amp;#34;/&amp;gt;
        &amp;lt;package name=&amp;#34;com.lizicai.one_to_many&amp;#34;/&amp;gt;
        &amp;lt;package name=&amp;#34;com.lizicai.many_to_many&amp;#34;/&amp;gt;
        &amp;lt;!-- &amp;lt;package name=&amp;#34;com.lizicai&amp;#34;/&amp;gt; 也可--&amp;gt;
    &amp;lt;/mappers&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.many_to_many;

import com.lizicai.bean.Course;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface CourseMapper {

    @Select(&amp;#34;SELECT c.id,c.name FROM stu_cr sc, course c WHERE  sc.cid = c.id AND sc.sid=#{id}&amp;#34;)
    public abstract List&amp;lt;Course&amp;gt; selectBySid(Integer id);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.many_to_many;

import com.lizicai.bean.Student;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface StudentCourseMapper {
    @Select(&amp;#34;SELECT DISTINCT s.id,s.name,s.age FROM stu_cr sc, student s WHERE  sc.sid=s.id ;&amp;#34;)
    @Results({
            @Result(column = &amp;#34;id&amp;#34;,property = &amp;#34;id&amp;#34;),
            @Result(column = &amp;#34;name&amp;#34;,property = &amp;#34;name&amp;#34;),
            @Result(column = &amp;#34;age&amp;#34;,property = &amp;#34;age&amp;#34;),
            @Result(
                    property = &amp;#34;courses&amp;#34;,
                    javaType = List.class,
                    column = &amp;#34;id&amp;#34;,
                    many = @Many(select = &amp;#34;com.lizicai.many_to_many.CourseMapper.selectBySid&amp;#34;)
            )
    })
    public abstract List&amp;lt;Student&amp;gt; selectAll();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void selectAll() throws IOException {
    InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    StudentCourseMapper mapper = sqlSession.getMapper(StudentCourseMapper.class);

    List&amp;lt;Student&amp;gt; list = mapper.selectAll();

    for (Student stu : list) {
        System.out.println(stu.getId()+stu.getName());
        List&amp;lt;Course&amp;gt; courses = stu.getCourses();
        if(courses !=null){
            for (Course c : courses) {
                System.out.println(c);
            }
        }
    }
    sqlSession.close();

    is.close();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;构建sql语句&#34;&gt;构建SQL语句&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;org.apache.ibatis.idbcSQL：构建SQL 语句的功能类。通过一些方法来代替SQL 语句的关键字。
&lt;ul&gt;
&lt;li&gt;SELECTO&lt;/li&gt;
&lt;li&gt;FROMO&lt;/li&gt;
&lt;li&gt;WHEREO&lt;/li&gt;
&lt;li&gt;INSERT INTOO&lt;/li&gt;
&lt;li&gt;VALUESO&lt;/li&gt;
&lt;li&gt;UPDATEO&lt;/li&gt;
&lt;li&gt;DELETE FROMO&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;@SelectProvider : 生成查询用的SQL语句注解。&lt;/li&gt;
&lt;li&gt;@InsertProvider : 生成新增用的SQL语句注解&lt;/li&gt;
&lt;li&gt;@UpdateProvider : 生成修改用的SQL语句注解，&lt;/li&gt;
&lt;li&gt;@DeleteProvider : 生成洲除用的SQL语句注解。
&lt;ul&gt;
&lt;li&gt;type属性: 生成SQL语句功能类对象&lt;/li&gt;
&lt;li&gt;method属性: 指定调用方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Student {
    private Integer id;
    private String name;
    private Integer age;

    private Integer cid;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.sql;

import org.apache.ibatis.jdbc.SQL;

public class ReturnSql {

    public String getSelectAll(){
        return new SQL() {
            {
                SELECT(&amp;#34;*&amp;#34;);
                FROM(&amp;#34;student&amp;#34;);
            }
        }.toString();
    }

    public String getInsert(){
        return new SQL(){
            {
                INSERT_INTO(&amp;#34;student&amp;#34;);
//                VALUES(&amp;#34;id,name,age,cid&amp;#34;,&amp;#34; #{id},#{name},#{age},#{cid}&amp;#34;);
                INTO_VALUES(&amp;#34;#{id},#{name},#{age},#{cid}&amp;#34;);
            }
        }.toString();
    }

    public String getUpdate(){
        return new SQL(){
            {
                UPDATE(&amp;#34;student&amp;#34;);
                SET(&amp;#34;name=#{name}&amp;#34;,&amp;#34;age=#{age}&amp;#34;);
                WHERE(&amp;#34;id=#{id}&amp;#34;);
            }
        }.toString();
    }

    public String getDelete(){
        return new SQL(){
            {
                DELETE_FROM(&amp;#34;student&amp;#34;);
                WHERE(&amp;#34;id=#{id}&amp;#34;);
            }
        }.toString();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    &amp;lt;mappers&amp;gt;
        &amp;lt;!--  配置映射关系--&amp;gt;
         &amp;lt;package name=&amp;#34;com.lizicai&amp;#34;/&amp;gt;
    &amp;lt;/mappers&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.mapper;

import com.lizicai.bean.Student;
import com.lizicai.sql.ReturnSql;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface StudentMapper {
//    @Select(&amp;#34;SELECT * FROM student&amp;#34;)
//    public abstract List&amp;lt;Student&amp;gt; selectAll();

    @SelectProvider(type = ReturnSql.class, method = &amp;#34;getSelectAll&amp;#34;)
    public abstract List&amp;lt;Student&amp;gt; selectAll();

    @InsertProvider(type = ReturnSql.class, method = &amp;#34;getInsert&amp;#34;)
    public abstract Integer insert(Student stu);

    @UpdateProvider(type = ReturnSql.class, method = &amp;#34;getUpdate&amp;#34;)
    public abstract Integer update(Student stu);

    @DeleteProvider(type = ReturnSql.class, method = &amp;#34;getDelete&amp;#34;)
    public abstract Integer delete(Integer id);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.test;

import com.lizicai.bean.Student;
import com.lizicai.mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class Test001 {
    @Test
    public void selectAll() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        List&amp;lt;Student&amp;gt; students = mapper.selectAll();

        for (Student stu : students) {
            System.out.println(stu);
        }

        sqlSession.close();

        is.close();
    }

    @Test
    public void insert() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        Student stu = new Student(5,&amp;#34;赵七&amp;#34;,27,1);


        Integer result = mapper.insert(stu);

        System.out.println(result);
        sqlSession.close();

        is.close();
    }


    @Test
    public void update() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        Student stu = new Student(5,&amp;#34;赵七&amp;#34;,17,1);


        Integer result = mapper.update(stu);

        System.out.println(result);
        sqlSession.close();

        is.close();
    }

    @Test
    public void delete() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        Integer result = mapper.delete(5);

        System.out.println(result);
        sqlSession.close();

        is.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>MyBatis框架二 Li.064</title>
      <link>https://lizicai.com/p/mybatis%E6%A1%86%E6%9E%B6%E4%BA%8C-li.064/</link>
      <pubDate>Wed, 03 Nov 2021 10:30:07 +0800</pubDate>
      <guid>https://lizicai.com/p/mybatis%E6%A1%86%E6%9E%B6%E4%BA%8C-li.064/</guid>
      <description>&lt;h2 id=&#34;接口代理方式实现dao层&#34;&gt;接口代理方式实现Dao层&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;接口代理方式-实现规则
&lt;ul&gt;
&lt;li&gt;传统方式实现Dao 层，我们既要写接口，还要与实现类。而MyBatis框架可以帮助我们省略编写 Dao 层接口实现类的步骤&lt;/li&gt;
&lt;li&gt;程序员只需要编写接口，由MyBatis 框架根据接口的定义来创建该接口的动态代理对象。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;实现规则
&lt;ul&gt;
&lt;li&gt;映射配置文件中的名称空间必须和 Dao 层接口的全类名相同。&lt;/li&gt;
&lt;li&gt;映射配置文件中的增删改查标签的 id 属性必须和 Dao 层接口的方法名相同。&lt;/li&gt;
&lt;li&gt;映射配置文件中的增删改查标签的 parameterType 属性必须和 Dao 层接口方法的参数相同。&lt;/li&gt;
&lt;li&gt;映射配置文件中的增删改查标签的 resultType 属性必须和 Dao 层接口方法的返回值相同。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获取动态代理对象
&lt;ul&gt;
&lt;li&gt;SqlSession功能类中的getMapper()方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&amp;lt;!DOCTYPE mapper
        PUBLIC &amp;#34;-//mybatis.org//DTA Mapper 3.0//EN&amp;#34;
        &amp;#34;http://mybatis.org/dtd/mybatis-3-mapper.dtd&amp;#34;&amp;gt;
&amp;lt;!--
mapper: 核心根标签
namespace属性: 名称空间
--&amp;gt;
&amp;lt;mapper namespace=&amp;#34;com.lizicai.mapper.StudentMapper&amp;#34;&amp;gt;
&amp;lt;!--
    select: 查询功能的标签
    id属性: 唯一标识
    resultType属性: 指定结果映射对象类型
    parameterType属性: 指定参数映射对象类型
--&amp;gt;
    &amp;lt;select id=&amp;#34;selectAll&amp;#34; resultType=&amp;#34;student&amp;#34;&amp;gt;
        SELECT * FROM student
    &amp;lt;/select&amp;gt;

    &amp;lt;select id=&amp;#34;selectById&amp;#34; resultType=&amp;#34;student&amp;#34; parameterType=&amp;#34;int&amp;#34;&amp;gt;
        SELECT * FROM student WHERE id = #{id}
    &amp;lt;/select&amp;gt;

    &amp;lt;insert id=&amp;#34;insert&amp;#34; parameterType=&amp;#34;student&amp;#34;&amp;gt;
        INSERT INTO student VALUES (#{id},#{name},#{age})
    &amp;lt;/insert&amp;gt;

    &amp;lt;update id=&amp;#34;update&amp;#34; parameterType=&amp;#34;student&amp;#34;&amp;gt;
        UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}
    &amp;lt;/update&amp;gt;

    &amp;lt;delete id=&amp;#34;delete&amp;#34; parameterType=&amp;#34;int&amp;#34;&amp;gt;
        DELETE FROM student WHERE id=#{id};
    &amp;lt;/delete&amp;gt;
&amp;lt;/mapper
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.service.impl;

import com.lizicai.bean.Student;
import com.lizicai.mapper.StudentMapper;
import com.lizicai.service.StudentService;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class StudentServiceImpl implements StudentService {

    // 查询全部
    @Override
    public List&amp;lt;Student&amp;gt; selectAll() {
        List&amp;lt;Student&amp;gt; list = null;
        InputStream is = null;
        SqlSession sqlSession = null;

        try{
            // 1. 加载核心配置文件
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            // 2. 获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            // 3. 通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            // 4. 获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

            // 5. 通过实现类对象调用方法, 接收结果
            list = mapper.selectAll();

        }catch (IOException e){
            e.printStackTrace();
        } finally {
            // 6. 释放资源
            if( sqlSession != null){
                sqlSession.close();
            }
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        // 7. 返回结果
        return list;
    }

    // 根据id查询
    @Override
    public Student selectById(Integer id) {
        Student stu = null;
        InputStream is = null;
        SqlSession sqlSession = null;

        try{
            // 1. 加载核心配置文件
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            // 2. 获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            // 3. 通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            // 4. 获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

            // 5. 通过实现类对象调用方法, 接收结果
            stu = mapper.selectById(id);

        }catch (IOException e){
            e.printStackTrace();
        } finally {
            // 6. 释放资源
            if( sqlSession != null){
                sqlSession.close();
            }
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        // 7. 返回结果
        return stu;
    }

    @Override
    public Integer insert(Student stu) {
        Integer result = null;
        InputStream is = null;
        SqlSession sqlSession = null;

        try{
            // 1. 加载核心配置文件
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            // 2. 获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            // 3. 通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            // 4. 获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

            // 5. 通过实现类对象调用方法, 接收结果
            result = mapper.insert(stu);

        }catch (IOException e){
            e.printStackTrace();
        } finally {
            // 6. 释放资源
            if( sqlSession != null){
                sqlSession.close();
            }
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        // 7. 返回结果
        return result;
    }

    @Override
    public Integer update(Student stu) {
        Integer result = null;
        InputStream is = null;
        SqlSession sqlSession = null;

        try{
            // 1. 加载核心配置文件
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            // 2. 获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            // 3. 通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            // 4. 获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

            // 5. 通过实现类对象调用方法, 接收结果
            result = mapper.update(stu);

        }catch (IOException e){
            e.printStackTrace();
        } finally {
            // 6. 释放资源
            if( sqlSession != null){
                sqlSession.close();
            }
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        // 7. 返回结果
        return result;
    }

    @Override
    public Integer delete(Integer id) {
        Integer result = null;
        InputStream is = null;
        SqlSession sqlSession = null;

        try{
            // 1. 加载核心配置文件
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            // 2. 获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            // 3. 通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            // 4. 获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

            // 5. 通过实现类对象调用方法, 接收结果
            result = mapper.delete(id);

        }catch (IOException e){
            e.printStackTrace();
        } finally {
            // 6. 释放资源
            if( sqlSession != null){
                sqlSession.close();
            }
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        // 7. 返回结果
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;动态sql&#34;&gt;动态SQL&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;动态SQL介绍
&lt;ul&gt;
&lt;li&gt;MyBatis映射配置文件中, 前面SQL都是简单的, 有些业务逻辑复杂时, SQL是动态变化, 此时前面学习的SQL就不能满足要求了&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;多条件查询
&lt;ul&gt;
&lt;li&gt;SELECT * FORM student WHERE id=? AND name=? AND age=?;&lt;/li&gt;
&lt;li&gt;SELECT * FORM student WHERE id=? AND name=?;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;动态SQL标签
&lt;ul&gt;
&lt;li&gt;&lt;if&gt;: 条件判断标签&lt;/li&gt;
&lt;li&gt;&lt;foreach&gt;: 循环遍历标签&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;标签&#34;&gt;&lt;if&gt; 标签&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;where&gt; : 条件标签. 如果有动态条件, 则使用访标签代替where关键字&lt;/li&gt;
&lt;li&gt;&lt;if&gt;: 条件判断标签&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;if test=&amp;#34;条件判断&amp;#34;&amp;gt;
    查询条件拼接
&amp;lt;/if&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    &amp;lt;select id=&amp;#34;selectCondition&amp;#34; resultType=&amp;#34;student&amp;#34; parameterType=&amp;#34;student&amp;#34;&amp;gt;
        SELECT * FROM student
        &amp;lt;where&amp;gt;
            &amp;lt;if test=&amp;#34;id != null&amp;#34;&amp;gt;
                id=#{id}
            &amp;lt;/if&amp;gt;
            &amp;lt;if test=&amp;#34;name != null&amp;#34;&amp;gt;
                AND name=#{name}
            &amp;lt;/if&amp;gt;
            &amp;lt;if test=&amp;#34;age != null&amp;#34;&amp;gt;
                AND age=#{age}
            &amp;lt;/if&amp;gt;
        &amp;lt;/where&amp;gt;
    &amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; @Test
    public void selectCondition() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        Student stu = new Student();
//        stu.setId(2);
        stu.setName(&amp;#34;李四&amp;#34;);
        stu.setAge(24);

        List&amp;lt;Student&amp;gt; list = mapper.selectCondition(stu);

        for(Student student : list){
            System.out.println(student);
        }

        sqlSession.close();

        is.close();
    }
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;标签-1&#34;&gt;&lt;Foreach&gt; 标签&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;foreach : 循环遍历标签, 适用于多个参数或者的关系&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;froeach colloction=&amp;#34;&amp;#34; open=&amp;#34;&amp;#34; close=&amp;#34;&amp;#34; item=&amp;#34;&amp;#34; separator=&amp;#34;&amp;#34;&amp;gt;
    获取参数
&amp;lt;/froeach&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;属性
&lt;ul&gt;
&lt;li&gt;colloction: 参数容器,(list 集合, array 数组)&lt;/li&gt;
&lt;li&gt;open: 开始的SQL语句&lt;/li&gt;
&lt;li&gt;close: 结束的SQL语句&lt;/li&gt;
&lt;li&gt;item: 参数变量名&lt;/li&gt;
&lt;li&gt;separator: 分隔符&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    &amp;lt;select id=&amp;#34;selectByIds&amp;#34; resultType=&amp;#34;student&amp;#34; parameterType=&amp;#34;list&amp;#34;&amp;gt;
        SELECT * FROM student
        &amp;lt;where&amp;gt;
            &amp;lt;foreach collection=&amp;#34;list&amp;#34; open=&amp;#34;id IN (&amp;#34; close=&amp;#34;)&amp;#34;  item=&amp;#34;id&amp;#34; separator=&amp;#34;,&amp;#34;&amp;gt;
                #{id}
            &amp;lt;/foreach&amp;gt;
        &amp;lt;/where&amp;gt;
    &amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;StudentMapper&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; // 多个id查询学生数据
    public abstract List&amp;lt;Student&amp;gt; selectByIds(List&amp;lt;Integer&amp;gt; ids);
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void selectByIds() throws IOException{
    InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    List&amp;lt;Integer&amp;gt; ids = new ArrayList&amp;lt;&amp;gt;();
    ids.add(1);
    ids.add(2);

    List&amp;lt;Student&amp;gt; list = mapper.selectByIds(ids);

    for(Student student : list){
        System.out.println(student);
    }

    sqlSession.close();

    is.close();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;sql-片段抽取&#34;&gt;SQL 片段抽取&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;我们可以将一些重复的SQL语句进行抽取, 以达到复用的效果&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;sql id=&amp;#34;select&amp;#34;&amp;gt;SELECT * FROM student&amp;lt;/sql&amp;gt;

&amp;lt;select id=&amp;#34;selectAll&amp;#34; resultType=&amp;#34;student&amp;#34;&amp;gt;
    &amp;lt;include refid=&amp;#34;select&amp;#34;&amp;gt;&amp;lt;/include&amp;gt;
&amp;lt;/select&amp;gt;

&amp;lt;select id=&amp;#34;selectById&amp;#34; resultType=&amp;#34;student&amp;#34; parameterType=&amp;#34;int&amp;#34;&amp;gt;
    &amp;lt;include refid=&amp;#34;select&amp;#34;&amp;gt;&amp;lt;/include&amp;gt; WHERE id = #{id}
&amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;分页插件&#34;&gt;分页插件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;企业开发中, 分页是常见技术. MyBatis是不带分页功能的, 如果想实现分页功能, 需要手动编写LIMIT语句.不同数据库实现分页SQL语句也是不同, 手写成本高.&lt;/li&gt;
&lt;li&gt;PageHelper: 第三方分页助手, 将复杂的分页操作进行封装, 从而让分页功能变得非常简单.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;分页插件实现步骤&#34;&gt;分页插件实现步骤&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;导入 包&lt;/li&gt;
&lt;li&gt;在核心配置文件中集成分页助手插件&lt;/li&gt;
&lt;li&gt;在测试类中使用分页助手相关API实现分页功能&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;分页插件实现步骤-1&#34;&gt;分页插件实现步骤&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;导入pagehelper-5.1.10.jar, jsqlparser-3.1.jar包
&lt;ul&gt;
&lt;li&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://repo1.maven.org/maven2/com/github/pagehelper/pagehelper/&#34; target=&#34;_blank&#34;&gt;PageHelper下载&lt;/a&gt; 

&lt;/li&gt;
&lt;li&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://repo1.maven.org/maven2/com/github/jsqlparser/jsqlparser/&#34; target=&#34;_blank&#34;&gt;jsqlparser下载&lt;/a&gt; 

&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;在核心配置文件中集成分页助手插件&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
    &amp;lt;!-- 集成分页助手插件 --&amp;gt;
    &amp;lt;plugins&amp;gt;
        &amp;lt;plugin interceptor=&amp;#34;com.github.pagehelper.PageInterceptor&amp;#34;&amp;gt;&amp;lt;/plugin&amp;gt;
    &amp;lt;/plugins&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;在测试类中使用分页助手相关API实现分页功能&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; @Test
    public void selectCondition() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        // 通过分页助手来实现分页功能
        // 第1页3条数据
//        PageHelper.startPage(1,3);

        // 第2页3条数据
//        PageHelper.startPage(2,3);

        // 第3页3条数据
        PageHelper.startPage(3,3);
        List&amp;lt;Student&amp;gt; list = mapper.selectAll();

        for(Student student : list){
            System.out.println(student);
        }

        sqlSession.close();

        is.close();
    }
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;分页插件相关参数&#34;&gt;分页插件相关参数&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PageInfo: 封装分页相关参数的功能类&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值  方法名          说明
long    getTotal()      获取总条数
int     getPages()      获取总页数
int     getPageNum()    获取当前页
int     getPageSize()   获取每页显示条数
int     getPrePage()    获取上一页
int     getNextPage()   获取下一页
boolean isIsFirstPage() 获取是否是第一页
boolean isIsLastPage()  获取是否是最后一页
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void selectCondition() throws IOException {
    InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    // 通过分页助手来实现分页功能
    // 第1页3条数据
//        PageHelper.startPage(1,3);

    // 第2页3条数据
//        PageHelper.startPage(2,3);

    // 第3页3条数据
    PageHelper.startPage(3,3);
    List&amp;lt;Student&amp;gt; list = mapper.selectAll();

    for(Student student : list){
        System.out.println(student);
    }

    // 获取页相关参数
    PageInfo&amp;lt;Student&amp;gt; info = new PageInfo&amp;lt;&amp;gt;(list);

    System.out.println(&amp;#34;总条数&amp;#34;+info.getTotal());
    System.out.println(&amp;#34;总页数&amp;#34;+info.getPages());
    System.out.println(&amp;#34;当前页&amp;#34;+info.getPageNum());
    System.out.println(&amp;#34;每页显示条数&amp;#34;+info.getPageSize());
    System.out.println(&amp;#34;上一页&amp;#34;+info.getPrePage());
    System.out.println(&amp;#34;下一页&amp;#34;+info.getNextPage());
    System.out.println(&amp;#34;是否第1页&amp;#34;+info.isIsFirstPage());
    System.out.println(&amp;#34;是否最后1页&amp;#34;+info.isIsLastPage());

    sqlSession.close();

    is.close();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;一对一&#34;&gt;一对一&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;resultMap: 配置字段和对象属性的映射关系标签&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;id属性: 唯一标识&lt;/li&gt;
&lt;li&gt;type属性: 实体对象类型&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;id: 配置主键映射关系标签&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;result: 配置非主键映射关系标签&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;column属性: 表中字段名称&lt;/li&gt;
&lt;li&gt;property属性: 实体对象变量名称&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;association: 配置被包含对象的映射关系标签&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;property属性: 被包含对象的变量名&lt;/li&gt;
&lt;li&gt;javaType属性: 被包含对象的数据类型&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一对一模型: 人和身份证, 一个人只有一个身份证&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;数据准备&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE DATABASE db2;
USE db2;
CREATE TABLE person(
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20),
    age INT
);
INSERT INTO person VALUES (NULL,&amp;#34;张三&amp;#34;,23);
INSERT INTO person VALUES (NULL,&amp;#34;李四&amp;#34;,24);
INSERT INTO person VALUES (NULL,&amp;#34;王五&amp;#34;,25);

SELECT * FROM person;

CREATE TABLE card(
    id INT PRIMARY KEY  AUTO_INCREMENT,
    number VARCHAR(30),
    pid INT,
    CONSTRAINT cp_fk FOREIGN KEY (pid) REFERENCES person(id)
);

INSERT INTO card VALUES (NULL,&amp;#39;12345&amp;#39;,1);
INSERT INTO card VALUES (NULL,&amp;#39;22345&amp;#39;,2);
INSERT INTO card VALUES (NULL,&amp;#39;32345&amp;#39;,3);
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Person {
    private Integer id;
    private String name;
    private Integer age;
    ...略
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Card {
    private Integer id;
    private String number;
    private Person p;
    ...略
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;mapper namespace=&amp;#34;com.lizicai.table01.OneToOneMapper&amp;#34;&amp;gt;
    &amp;lt;!-- 配置字段和实体对象属性的映射关系 --&amp;gt;
    &amp;lt;resultMap id=&amp;#34;oneToOne&amp;#34; type=&amp;#34;card&amp;#34;&amp;gt;
        &amp;lt;id column=&amp;#34;cid&amp;#34; property=&amp;#34;id&amp;#34; /&amp;gt;
        &amp;lt;result column=&amp;#34;number&amp;#34; property=&amp;#34;number&amp;#34; /&amp;gt;

        &amp;lt;!-- 配置被包含对象的映射关系
           property 被包含的变量名
           javaType 被包含对象的数据类型
        --&amp;gt;
        &amp;lt;association property=&amp;#34;p&amp;#34; javaType=&amp;#34;person&amp;#34;&amp;gt;
            &amp;lt;id column=&amp;#34;pid&amp;#34; property=&amp;#34;id&amp;#34; /&amp;gt;
            &amp;lt;result column=&amp;#34;name&amp;#34; property=&amp;#34;name&amp;#34; /&amp;gt;
            &amp;lt;result column=&amp;#34;age&amp;#34; property=&amp;#34;age&amp;#34; /&amp;gt;
        &amp;lt;/association&amp;gt;
    &amp;lt;/resultMap&amp;gt;
    &amp;lt;select id=&amp;#34;selectAll&amp;#34; resultMap=&amp;#34;oneToOne&amp;#34;&amp;gt;
        SELECT c.id cid,number,pid,NAME,age FROM card c, person p WHERE c.pid = p.id
    &amp;lt;/select&amp;gt;
&amp;lt;/mapper&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public interface OneToOneMapper {
    // 查询全部
    public abstract List&amp;lt;Card&amp;gt; selectAll();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.table01;

import com.lizicai.bean.Card;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class Test01 {
    @Test
    public void selectAll() throws IOException {
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        OneToOneMapper mapper = sqlSession.getMapper(OneToOneMapper.class);

        List&amp;lt;Card&amp;gt; list = mapper.selectAll();

        for(Card c : list){
            System.out.println(c);
        }

        sqlSession.close();

        is.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;一对多&#34;&gt;一对多&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;resultMap: 配置字段和对象属性的映射关系标签&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;id属性: 唯一标识&lt;/li&gt;
&lt;li&gt;type属性: 实体对象类型&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;id: 配置主键映射关系标签&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;result: 配置非主键映射关系标签&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;column属性: 表中字段名称&lt;/li&gt;
&lt;li&gt;property属性: 实体对象变量名称&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;collection: 配置被包含对象的映射关系标签&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;property属性: 被包含对象的变量名&lt;/li&gt;
&lt;li&gt;ofType属性: 集合中保存的对象的数据类型&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;数据准备&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE classes(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20)
);
INSERT INTO classes VALUES (NULL, &amp;#39;一班&amp;#39;);
INSERT INTO classes VALUES (NULL, &amp;#39;二班&amp;#39;);

CREATE TABLE student(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(30),
    age INT,
    cid INT,
    CONSTRAINT cs_fk FOREIGN KEY (cid) REFERENCES classes(id)
);

INSERT INTO student VALUES (NULL,&amp;#39;张三&amp;#39;,23,1);
INSERT INTO student VALUES (NULL,&amp;#39;李四&amp;#39;,24,1);
INSERT INTO student VALUES (NULL,&amp;#39;王五&amp;#39;,25,2);
INSERT INTO student VALUES (NULL,&amp;#39;赵六&amp;#39;,26,2);

SELECT * FROM student;
SELECT * FROM classes;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Classes {
    private Integer id;
    private String name;

    private List&amp;lt;Student&amp;gt; students;
    ...略
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Student {
    private Integer id;
    private String name;
    private Integer age;
    ...略
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&amp;lt;!DOCTYPE mapper
        PUBLIC &amp;#34;-//mybatis.org//DTA Mapper 3.0//EN&amp;#34;
        &amp;#34;http://mybatis.org/dtd/mybatis-3-mapper.dtd&amp;#34;&amp;gt;
&amp;lt;mapper namespace=&amp;#34;com.lizicai.table02.OneToManyMapper&amp;#34;&amp;gt;
    &amp;lt;!-- 配置字段和实体对象属性的映射关系 --&amp;gt;
    &amp;lt;resultMap id=&amp;#34;oneToMany&amp;#34; type=&amp;#34;classes&amp;#34;&amp;gt;
        &amp;lt;id column=&amp;#34;cid&amp;#34; property=&amp;#34;id&amp;#34; /&amp;gt;
        &amp;lt;result column=&amp;#34;cname&amp;#34; property=&amp;#34;name&amp;#34; /&amp;gt;

        &amp;lt;!-- collection: 配置被包含的集合对象映射关系
        property: 被包含对象的变量名
        ofType: 被包含对象的实际数据类型
        --&amp;gt;
        &amp;lt;collection property=&amp;#34;students&amp;#34; ofType=&amp;#34;student&amp;#34;&amp;gt;
            &amp;lt;id column=&amp;#34;sid&amp;#34; property=&amp;#34;id&amp;#34; /&amp;gt;
            &amp;lt;result column=&amp;#34;sname&amp;#34; property=&amp;#34;name&amp;#34; /&amp;gt;
            &amp;lt;result column=&amp;#34;sage&amp;#34; property=&amp;#34;age&amp;#34; /&amp;gt;
        &amp;lt;/collection&amp;gt;

    &amp;lt;/resultMap&amp;gt;
    &amp;lt;select id=&amp;#34;selectAll&amp;#34; resultMap=&amp;#34;oneToMany&amp;#34;&amp;gt;
        SELECT c.id cid,c.NAME cname,s.id sid,s.NAME sname,s.age sage FROM classes c, student s WHERE c.id = s.cid;
    &amp;lt;/select&amp;gt;
&amp;lt;/mapper&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;在MyBatisConfig.xml引入&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;mappers&amp;gt;
&amp;lt;!--        引入指定的映射配置文件 resource属性指定映射配置文件的名称--&amp;gt;
    &amp;lt;mapper resource=&amp;#34;com/lizicai/one_to_one/OneToOneMapper.xml&amp;#34; /&amp;gt;
    &amp;lt;mapper resource=&amp;#34;com/lizicai/one_to_many/OneToManyMapper.xml&amp;#34; /&amp;gt;
&amp;lt;/mappers&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.table02;

import com.lizicai.bean.Classes;

import java.util.List;

public interface OneToManyMapper {
    // 查询全部
    public abstract List&amp;lt;Classes&amp;gt; selectAll();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void selectAll() throws IOException {
    InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);

    List&amp;lt;Classes&amp;gt; list = mapper.selectAll();

    for(Classes cls : list){
        System.out.println(cls.getId()+cls.getName());
        for(Student stu : cls.getStudents()){
            System.out.println(&amp;#34;\t&amp;#34;+stu);
        }
    }

    sqlSession.close();

    is.close();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多对多&#34;&gt;多对多&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;多对多模型: 学生和课程, 一个学生可以选择多门课程, 一个课程也可以被多个学生所选择&lt;/li&gt;
&lt;li&gt;数据准备&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE course(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20)
);
INSERT INTO course VALUES (NULL,&amp;#39;语文&amp;#39;);
INSERT INTO course VALUES (NULL,&amp;#39;数学&amp;#39;);

CREATE TABLE stu_cr(
    id INT PRIMARY KEY AUTO_INCREMENT,
    sid INT,
    cid INT,
    CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id),
    CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id)
);
INSERT INTO stu_cr VALUES (NULL,1,1);
INSERT INTO stu_cr VALUES (NULL,1,2);
INSERT INTO stu_cr VALUES (NULL,2,1);
INSERT INTO stu_cr VALUES (NULL,2,2);

SELECT * FROM course;
SELECT * FROM stu_cr;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Course {
    private Integer id;
    private String name;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Student {
    private Integer id;
    private String name;
    private Integer age;

    private List&amp;lt;Course&amp;gt; courses;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&amp;lt;!DOCTYPE mapper
        PUBLIC &amp;#34;-//mybatis.org//DTA Mapper 3.0//EN&amp;#34;
        &amp;#34;http://mybatis.org/dtd/mybatis-3-mapper.dtd&amp;#34;&amp;gt;
&amp;lt;mapper namespace=&amp;#34;com.lizicai.table03.ManyToManyMapper&amp;#34;&amp;gt;
    &amp;lt;!-- 配置字段和实体对象属性的映射关系 --&amp;gt;
    &amp;lt;resultMap id=&amp;#34;manyToMany&amp;#34; type=&amp;#34;student&amp;#34;&amp;gt;
        &amp;lt;id column=&amp;#34;sid&amp;#34; property=&amp;#34;id&amp;#34; /&amp;gt;
        &amp;lt;result column=&amp;#34;sname&amp;#34; property=&amp;#34;name&amp;#34; /&amp;gt;
        &amp;lt;result column=&amp;#34;sage&amp;#34; property=&amp;#34;age&amp;#34; /&amp;gt;

        &amp;lt;!-- collection: 配置被包含的集合对象映射关系
        property: 被包含对象的变量名
        ofType: 被包含对象的实际数据类型
        --&amp;gt;
        &amp;lt;collection property=&amp;#34;courses&amp;#34; ofType=&amp;#34;course&amp;#34;&amp;gt;
            &amp;lt;id column=&amp;#34;cid&amp;#34; property=&amp;#34;id&amp;#34; /&amp;gt;
            &amp;lt;result column=&amp;#34;cname&amp;#34; property=&amp;#34;name&amp;#34; /&amp;gt;
        &amp;lt;/collection&amp;gt;

    &amp;lt;/resultMap&amp;gt;
    &amp;lt;select id=&amp;#34;selectAll&amp;#34; resultMap=&amp;#34;manyToMany&amp;#34;&amp;gt;
        SELECT sc.sid,s.NAME sname,s.age sage,sc.cid cid,c.NAME cname
        FROM student s,course c,stu_cr sc WHERE sc.sid=s.id AND sc.cid=c.id;
    &amp;lt;/select&amp;gt;
&amp;lt;/mapper&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public interface ManyToManyMapper {
    // 查询全部
    public abstract List&amp;lt;Student&amp;gt; selectAll();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void selectAll() throws IOException {
    InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    ManyToManyMapper mapper = sqlSession.getMapper(ManyToManyMapper.class);

    List&amp;lt;Student&amp;gt; students = mapper.selectAll();

    for(Student stu : students){
        System.out.println(stu.getId()+stu.getName()+stu.getAge());
        for(Course c : stu.getCourses()){
            System.out.println(&amp;#34;\t&amp;#34;+c);
        }
    }

    sqlSession.close();

    is.close();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多对多-1&#34;&gt;多对多&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;resultMap: 配置字段和对象属性的映射关系标签
&lt;ul&gt;
&lt;li&gt;id属性: 唯一标识&lt;/li&gt;
&lt;li&gt;type属性: 实体对象类型&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;id: 配置主键映射关系标签&lt;/li&gt;
&lt;li&gt;result: 配置非主键映射关系标签
&lt;ul&gt;
&lt;li&gt;column属性: 表中字段名称&lt;/li&gt;
&lt;li&gt;property属性: 实体对象变量名称&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;collection: 配置被包含对象的映射关系标签
&lt;ul&gt;
&lt;li&gt;property属性: 被包含对象的变量名&lt;/li&gt;
&lt;li&gt;ofType属性: 集合中保存的对象的数据类型&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>MyBatis框架一 Li.063</title>
      <link>https://lizicai.com/p/mybatis%E6%A1%86%E6%9E%B6%E4%B8%80-li.063/</link>
      <pubDate>Fri, 29 Oct 2021 14:45:49 +0800</pubDate>
      <guid>https://lizicai.com/p/mybatis%E6%A1%86%E6%9E%B6%E4%B8%80-li.063/</guid>
      <description>&lt;h2 id=&#34;mybatis-介绍&#34;&gt;MyBatis 介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MyBatis 是一个优秀的基于Java 的特久层框架，它内部封装了JDBC，使开发者只需要关注SQL语句本身， 而不需要花费精力去处理加载驱动、创建连接、创建执行者等复杂的操作。&lt;/li&gt;
&lt;li&gt;MyBatis通过xml 或注解的方式将要执行的各种Statement 配置起来，并通过Java对象和 Statement中 SQL 的动态参数进行映射生成最终要执行的SQL 语句。&lt;/li&gt;
&lt;li&gt;最后MyBatis 框架执行完 SQL 并将结果映射为 Java 对象并返回。采用ORM 思想解决了实体和数据库映射的问题，对JDBC 进行了封装，屏蔽了 JDBC API 底层访问细节，使我们不用与JDBC API打交道，就可以 完成对数据库的持久化操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;mybatis-使用示例&#34;&gt;MyBatis 使用示例&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;导入mariadb-java-client-2.7.4.jar和mybatis-3.5.7.jar&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE DATABASE db1;
use db1;
create table student(
   id int auto_increment primary key ,
   NAME VARCHAR(20),
   age int
);
INSERT INTO student VALUES
(null,&amp;#39;张三&amp;#39;,23),(null,&amp;#39;李四&amp;#39;,24),(null,&amp;#39;王五&amp;#39;,25);
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Student {
    private Integer id;
    private String name;
    private Integer age;
    ...略
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.dao;

import com.lizicai.bean.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class StudentTest01 {
    /**
     * 查询全部
     */
    public static void main(String[] args) throws IOException {
        StudentTest01 s = new StudentTest01();
        s.selectAll() ;
    }
    public void selectAll() throws IOException {
        // 1. 加载核心配置文件
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

        // 2.获取sqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        // 3.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 4. 获取执行结果
        List&amp;lt;Student&amp;gt;  list = sqlSession.selectList(&amp;#34;StudentMapper.selectAll&amp;#34;);

        // 5.打印结果
        for(Student stu : list){
            System.out.println(stu);
        }

        // 6. 关闭资源
        sqlSession.close();
        is.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&amp;lt;!DOCTYPE configuration
        PUBLIC &amp;#34;-//mybatis.org//DTA Mapper 3.0//EN&amp;#34;
        &amp;#34;http://mybatis.org/dtd/mybatis-3-config.dtd&amp;#34;&amp;gt;
&amp;lt;configuration&amp;gt;
    &amp;lt;environments default=&amp;#34;mariadb&amp;#34;&amp;gt;
        &amp;lt;environment id=&amp;#34;mariadb&amp;#34;&amp;gt;
            &amp;lt;transactionManager type=&amp;#34;JDBC&amp;#34;&amp;gt;&amp;lt;/transactionManager&amp;gt;
            &amp;lt;dataSource type=&amp;#34;POOLED&amp;#34;&amp;gt;
                &amp;lt;property name=&amp;#34;driver&amp;#34; value=&amp;#34;org.mariadb.jdbc.Driver&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;url&amp;#34; value=&amp;#34;jdbc:mariadb://192.168.0.100:3306/db1&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;username&amp;#34; value=&amp;#34;root&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;password&amp;#34; value=&amp;#34;rootPassword&amp;#34;/&amp;gt;
            &amp;lt;/dataSource&amp;gt;
        &amp;lt;/environment&amp;gt;
    &amp;lt;/environments&amp;gt;
    &amp;lt;mappers&amp;gt;
        &amp;lt;mapper resource=&amp;#34;StudentMapper.xml&amp;#34; /&amp;gt;
    &amp;lt;/mappers&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;mybatis-相关api&#34;&gt;MyBatis 相关API&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Resources: org.apache.ibatis.io.Resources&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值      方法名                               说明
InputStream getResourceAsStream(String.fileName) 通过类加载器返回指定资源的字节输入流
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;SqlSessionFactoryBuilder: org.apache.ibatis.session.SqlSessionFactoryBuilder 获取SqlSessionFactory工厂对象的功能类&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值            方法名                说明
SqlSessionFactory build(InputStream.is) 通过指定资源字节输入流获取SqlSession工厂对象
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;SqlSessionFactory: org.apache.ibatis.session.SqlSessionFactory: 获取SqlSession构建者对象的工厂接口&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名 说明
SqlSession openSession() 获取SqlSession构建对象,并开户手动提交事务
SqlSession openSession(boolean.autoCommit) 获取SqlSession构建者对象,如果参数为true,则开户自动提交事务
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;SqlSession: org.apache.ibatis.session.SqlSession 构建者对象接口. 用于执行SQL, 管理事务, 接口代理.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值  方法名                                       说明
List&amp;lt;E&amp;gt; selectList(String.statement,Object.paramter) 执行查询语句,返回List集合
T       selectOne(String.statement,Object.paramter)  执行查询语句,返回一个结果对象
int     insert(String.statement,Object.paramter)     执行新增语句,返回影响行数
int     update(String.statement,Object.paramter)     执行修改语句,返回影响行数
int     delete(String.statement,Object.paramter)     执行删除语句,返回影响行数
void    commit()                                     提交事务
void    rollback()                                   回滚事务
T       getMapper(Class&amp;lt;T&amp;gt;.cls)                      获取指定接口的代理实现类对象
void    close()                                      释放资源
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;public class Student {
private Integer id;
private String name;
private Integer age;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public Student(){}

public Student(Integer id, String name, Integer age) {
    this.id = id;
    this.name = name;
    this.age = age;
}
...get set略...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&amp;lt;!DOCTYPE mapper
        PUBLIC &amp;#34;-//mybatis.org//DTA Mapper 3.0//EN&amp;#34;
        &amp;#34;http://mybatis.org/dtd/mybatis-3-mapper.dtd&amp;#34;&amp;gt;
&amp;lt;!--
mapper: 核心根标签
namespace属性: 名称空间
--&amp;gt;
&amp;lt;mapper namespace=&amp;#34;StudentMapper&amp;#34;&amp;gt;
&amp;lt;!--
    select: 查询功能的标签
    id属性: 唯一标识
    resultType属性: 指定结果映射对象类型
    parameterType属性: 指定参数映射对象类型
--&amp;gt;
    &amp;lt;select id=&amp;#34;selectAll&amp;#34; resultType=&amp;#34;com.lizicai.bean.Student&amp;#34;&amp;gt;
        SELECT * FROM student
    &amp;lt;/select&amp;gt;

    &amp;lt;select id=&amp;#34;selectById&amp;#34; resultType=&amp;#34;com.lizicai.bean.Student&amp;#34; parameterType=&amp;#34;java.lang.Integer&amp;#34;&amp;gt;
        SELECT * FROM student WHERE id = #{id}
    &amp;lt;/select&amp;gt;

    &amp;lt;insert id=&amp;#34;insert&amp;#34; parameterType=&amp;#34;com.lizicai.bean.Student&amp;#34;&amp;gt;
        INSERT INTO student VALUES (#{id},#{name},#{age})
    &amp;lt;/insert&amp;gt;

    &amp;lt;update id=&amp;#34;updateById&amp;#34; parameterType=&amp;#34;com.lizicai.bean.Student&amp;#34;&amp;gt;
        UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}
    &amp;lt;/update&amp;gt;

    &amp;lt;delete id=&amp;#34;deleteById&amp;#34; parameterType=&amp;#34;java.lang.Integer&amp;#34;&amp;gt;
        DELETE FROM student WHERE id=#{id};
    &amp;lt;/delete&amp;gt;
&amp;lt;/mapper&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.dao;

import com.lizicai.bean.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.SwitchPoint;
import java.util.List;

public class StudentTest01 {
    /**
     * id查询
     */

    @Test
    public void selectById() throws IOException {

        // 1. 加载核心配置文件
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

        // 2.获取sqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        // 3.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        Student stu = sqlSession.selectOne(&amp;#34;StudentMapper.selectById&amp;#34;,1);

        System.out.println(stu);
        sqlSession.close();
        is.close();
    }

    /**
     * 更新用户信息
     */

    @Test
    public void updateById() throws IOException {
        // 1. 加载核心配置文件
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);
        // 2.获取sqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        // 3.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 4. 获取执行结果
        Student stu = new Student(2,&amp;#34;张三&amp;#34;,24);
        int update = sqlSession.update(&amp;#34;StudentMapper.updateById&amp;#34;, stu);
        sqlSession.commit();
        System.out.println(update);
        sqlSession.close();
        is.close();
    }


    /**
     * 插入数据
     * @throws IOException
     */
    @Test
    public void insert() throws IOException {

        // 1. 加载核心配置文件
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

        // 2.获取sqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        // 3.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        Student stu = new Student(4,&amp;#34;赵六&amp;#34;,26);

        int insert = sqlSession.insert(&amp;#34;StudentMapper.insert&amp;#34;, stu);

        sqlSession.commit();

        System.out.println(insert);

        // 6. 关闭资源
        sqlSession.close();
        is.close();
    }
    /**
     * 删除数据
     */

    @Test
    public void delete() throws IOException {
        // 1. 加载核心配置文件
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

        // 2.获取sqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        // 3.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        int delete = sqlSession.delete(&amp;#34;StudentMapper.deleteById&amp;#34;, 4);

        System.out.println(delete);

        sqlSession.commit();

        sqlSession.close();
        is.close();

    }

    /**
     * 查询全部
     */
    @Test
    public void selectAll() throws IOException {
        // 1. 加载核心配置文件
        InputStream is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

        // 2.获取sqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        // 3.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 4. 获取执行结果
        List&amp;lt;Student&amp;gt;  list = sqlSession.selectList(&amp;#34;StudentMapper.selectAll&amp;#34;);

        // 5.打印结果
        for(Student stu : list){
            System.out.println(stu);
        }

        // 6. 关闭资源
        sqlSession.close();
        is.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;引入数据库连接配置&#34;&gt;引入数据库连接配置&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;jdbc.properties&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;driver=org.mariadb.jdbc.Driver
url=jdbc:mariadb://192.168.0.100:3306/db1
username=root
password=rootPassword
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;MyBatisConfig.xml&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
    &amp;lt;properties resource=&amp;#34;jdbc.properties&amp;#34;&amp;gt;&amp;lt;/properties&amp;gt;
    &amp;lt;environments default=&amp;#34;mariadb&amp;#34;&amp;gt;
        &amp;lt;environment id=&amp;#34;mariadb&amp;#34;&amp;gt;
            &amp;lt;!-- 事务管理, 默认采用JDBC默认的事务--&amp;gt;
            &amp;lt;transactionManager type=&amp;#34;JDBC&amp;#34;&amp;gt;&amp;lt;/transactionManager&amp;gt;
&amp;lt;!--            dataSource数据源信息 type属性 连接池--&amp;gt;
            &amp;lt;dataSource type=&amp;#34;POOLED&amp;#34;&amp;gt;
                &amp;lt;property name=&amp;#34;driver&amp;#34; value=&amp;#34;${driver}&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;url&amp;#34; value=&amp;#34;${url}&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;username&amp;#34; value=&amp;#34;${username}&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;password&amp;#34; value=&amp;#34;${password}&amp;#34;/&amp;gt;
            &amp;lt;/dataSource&amp;gt;
        &amp;lt;/environment&amp;gt;
            &amp;lt;mappers&amp;gt;
&amp;lt;!--        引入指定的映射配置文件 resource属性指定映射配置文件的名称--&amp;gt;
        &amp;lt;mapper resource=&amp;#34;StudentMapper.xml&amp;#34; /&amp;gt;
    &amp;lt;/mappers&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;起别名&#34;&gt;起别名&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
    &amp;lt;properties resource=&amp;#34;jdbc.properties&amp;#34;&amp;gt;&amp;lt;/properties&amp;gt;

    &amp;lt;!-- 起别名 --&amp;gt;
     &amp;lt;typeAliases&amp;gt;
        &amp;lt;typeAlias type=&amp;#34;com.lizicai.bean.Student&amp;#34; alias=&amp;#34;student&amp;#34;&amp;gt;&amp;lt;/typeAlias&amp;gt;
        &amp;lt;package name=&amp;#34;com.lizicai.bean&amp;#34;/&amp;gt;
    &amp;lt;/typeAliases&amp;gt;

    &amp;lt;environments default=&amp;#34;mariadb&amp;#34;&amp;gt;
        &amp;lt;environment id=&amp;#34;mariadb&amp;#34;&amp;gt;
            &amp;lt;!-- 事务管理, 默认采用JDBC默认的事务--&amp;gt;
            &amp;lt;transactionManager type=&amp;#34;JDBC&amp;#34;&amp;gt;&amp;lt;/transactionManager&amp;gt;
&amp;lt;!--            dataSource数据源信息 type属性 连接池--&amp;gt;
            &amp;lt;dataSource type=&amp;#34;POOLED&amp;#34;&amp;gt;
                &amp;lt;property name=&amp;#34;driver&amp;#34; value=&amp;#34;${driver}&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;url&amp;#34; value=&amp;#34;${url}&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;username&amp;#34; value=&amp;#34;${username}&amp;#34;/&amp;gt;
                &amp;lt;property name=&amp;#34;password&amp;#34; value=&amp;#34;${password}&amp;#34;/&amp;gt;
            &amp;lt;/dataSource&amp;gt;
        &amp;lt;/environment&amp;gt;
            &amp;lt;mappers&amp;gt;
&amp;lt;!--        引入指定的映射配置文件 resource属性指定映射配置文件的名称--&amp;gt;
        &amp;lt;mapper resource=&amp;#34;StudentMapper.xml&amp;#34; /&amp;gt;
    &amp;lt;/mappers&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;select id=&amp;#34;selectAll&amp;#34; resultType=&amp;#34;student&amp;#34;&amp;gt;
    SELECT * FROM student
&amp;lt;/select&amp;gt;
&amp;lt;select id=&amp;#34;selectById&amp;#34; resultType=&amp;#34;com.lizicai.bean.Student&amp;#34; parameterType=&amp;#34;int&amp;#34;&amp;gt;
    SELECT * FROM student WHERE id = #{id}
&amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;常见别名&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;别名    数据类型
string  java.lang.String
long    java.lang.Long
int     java.lang.Integer
double  java.lang.Double
boolean java.lang.Boolean
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dao层实现&#34;&gt;dao层实现&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.mapper;

import com.lizicai.bean.Student;

import java.util.List;

public interface StudentMapper {
    // 查询全部
    public abstract List&amp;lt;Student&amp;gt; selectAll();

    // 根据id查询
    public abstract Student selectById(Integer id);

    // 新增数据
    public abstract Integer insert(Student stu);

    // 修改数据
    public abstract Integer update(Student stu);

    // 删除数据
    public abstract Integer delete(Integer id);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.mapper.impl;

import com.lizicai.bean.Student;
import com.lizicai.mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class StudentMapperImpl implements StudentMapper {
    // 查询所有学生
    @Override
    public List&amp;lt;Student&amp;gt; selectAll() {
        List&amp;lt;Student&amp;gt; list =null;
        InputStream is = null;
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession = null;

        try {
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            sqlSession = sqlSessionFactory.openSession();

            list = sqlSession.selectList(&amp;#34;StudentMapper.selectAll&amp;#34;);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if( sqlSession != null){
                sqlSession.close();
            }
        }

        return list;
    }

    // 根据id查询
    @Override
    public Student selectById(Integer id) {
        Student stu = null;
        InputStream is = null;
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession = null;

        try {
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            sqlSession = sqlSessionFactory.openSession();

            stu = sqlSession.selectOne(&amp;#34;StudentMapper.selectById&amp;#34;,id);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if( sqlSession != null){
                sqlSession.close();
            }
        }

        return stu;
    }

    // 新增数据
    @Override
    public Integer insert(Student stu) {
        Integer result = null;

        InputStream is = null;
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession = null;

        try {
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            sqlSession = sqlSessionFactory.openSession();

            result = sqlSession.insert(&amp;#34;StudentMapper.insert&amp;#34;, stu);

            sqlSession.commit();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if( sqlSession != null){
                sqlSession.close();
            }
        }
        return result;
    }

    // 新增数据
    @Override
    public Integer update(Student stu) {
        Integer result = null;
        InputStream is = null;
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession = null;

        try {
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            sqlSession = sqlSessionFactory.openSession();

            result = sqlSession.update(&amp;#34;StudentMapper.updateById&amp;#34;, stu);

            sqlSession.commit();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if( sqlSession != null){
                sqlSession.close();
            }
        }

        return result;
    }

    // 删除数据
    @Override
    public Integer delete(Integer id) {
        Integer result = null;

        InputStream is = null;
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession = null;

        try {
            is = Resources.getResourceAsStream(&amp;#34;MyBatisConfig.xml&amp;#34;);

            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            // 默认提交事务提交
            sqlSession = sqlSessionFactory.openSession(true);

            result = sqlSession.delete(&amp;#34;StudentMapper.deleteById&amp;#34;, id);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if( is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if( sqlSession != null){
                sqlSession.close();
            }
        }

        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.service;

import com.lizicai.bean.Student;

import java.util.List;

public interface StudentService {
    List&amp;lt;Student&amp;gt; selectAll();

    // 根据id查询
    Student selectById(Integer id);

    // 新增数据
    Integer insert(Student stu);

    // 修改数据
    Integer update(Student stu);

    // 删除数据
    Integer delete(Integer id);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.service.impl;

import com.lizicai.bean.Student;
import com.lizicai.mapper.StudentMapper;
import com.lizicai.mapper.impl.StudentMapperImpl;
import com.lizicai.service.StudentService;

import java.util.List;

public class StudentServiceImpl implements StudentService {

    private StudentMapper mapper = new StudentMapperImpl();

    // 查询全部
    @Override
    public List&amp;lt;Student&amp;gt; selectAll() {
        return mapper.selectAll();
    }

    // 根据id查询
    @Override
    public Student selectById(Integer id) {
        return mapper.selectById(id);
    }

    @Override
    public Integer insert(Student stu) {
        return mapper.insert(stu);
    }

    @Override
    public Integer update(Student stu) {
        return mapper.update(stu);
    }

    @Override
    public Integer delete(Integer id) {
        return mapper.delete(id);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.controller;

import com.lizicai.bean.Student;
import com.lizicai.service.StudentService;
import com.lizicai.service.impl.StudentServiceImpl;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

public class StudentController {
    // 创建业务层对象
    private StudentService service = new StudentServiceImpl();

    // 查询全部功能测试
    @Test
    public void selectAll(){
        List&amp;lt;Student&amp;gt; list = service.selectAll();
        for(Student stu : list){
            System.out.println(stu);
        }
    }

    // 根据id查询学生
    @Test
    public void selectById(){
        Student stu = service.selectById(1);
        System.out.println(stu);
    }

    // 新增学生
    @Test
    public void insert(){
        Student stu = new Student(4,&amp;#34;赵六&amp;#34;,26);
        Integer insert = service.insert(stu);
        System.out.println(insert);
    }

    //  更新学生信息
    @Test
    public void update(){
       Student stu = new Student(3,&amp;#34;王五五&amp;#34;,25);
       int update = service.update(stu);
        System.out.println(update );
    }

    //删除学生信息
    @Test
    public void delete(){
        int delete = service.delete(4);
        System.out.println(delete);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;log4j&#34;&gt;LOG4J&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;下载log4j-1.2.17.jar版本&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;加入libs中&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在MyBatisConfig.xml中引用log4j&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
&amp;lt;!--    数据库账号配置--&amp;gt;
    &amp;lt;properties resource=&amp;#34;jdbc.properties&amp;#34;&amp;gt;&amp;lt;/properties&amp;gt;

&amp;lt;!--    配置log4j--&amp;gt;
    &amp;lt;settings&amp;gt;
        &amp;lt;setting name=&amp;#34;logImpl&amp;#34; value=&amp;#34;log4j&amp;#34;/&amp;gt;
    &amp;lt;/settings&amp;gt;
&amp;lt;configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;log4j.properties&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Global logging configuration
# ERROR WARN INFO DEBUG
log4j.rootLogger=DEBUG, stdout
#Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>JDBC数据库连接三 Li.062</title>
      <link>https://lizicai.com/p/jdbc%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E4%B8%89-li.062/</link>
      <pubDate>Wed, 27 Oct 2021 17:31:17 +0800</pubDate>
      <guid>https://lizicai.com/p/jdbc%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E4%B8%89-li.062/</guid>
      <description>&lt;h2 id=&#34;自定义jdbc框架&#34;&gt;自定义JDBC框架&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用JDBC过程中有大量的重复代码, 核心功能仅仅执行一条SQL语句, 所以可以抽取一个JDBC模板类, 来封装一些方法(update query).&lt;/li&gt;
&lt;li&gt;专门帮我们执行增删改查SQL语句. 将之前那些重复的操作, 都抽取到模板类中的方法里, 就能大简化使用步骤&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;源信息&#34;&gt;源信息&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;DataeBaseMetaData: 数据库的源信息&lt;/li&gt;
&lt;li&gt;java.sql.DataBaseMetaData 封装了整个数据库的综合信息
&lt;ul&gt;
&lt;li&gt;例如 String getDatabaseProductName(): 获取数据库产品的名称&lt;/li&gt;
&lt;li&gt;例如int getDatabaseProductVersion: 获取数据库产品的版本号&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ParameterMetaData: 参数源信息
&lt;ul&gt;
&lt;li&gt;java.sql.ParameterMetaData 封装的是预编译执行者对象中每个参数的类型和属性, 这个对象可以通过预编译执行者对象中的getParameterMetaData()方法来获取&lt;/li&gt;
&lt;li&gt;int getParameterCount() 用于获取SQL语句中的参数个数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ResultSetMetaData: 结果集的源信息
&lt;ul&gt;
&lt;li&gt;java.sql.ResultSetMetaData: 封装的是结果集对象中列的类型和属性, 这个对象可以通过结果集对象中的getMetaData()方法来获取&lt;/li&gt;
&lt;li&gt;int getColumnCount() 用于获取列的总数, String getColumnName(int i)用于获取列名&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test005;

import com.lizicai.utils.DataSourceUtils;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.*;

public class JDBCTemplate {
    // 1. 定义参数变量(数据源, 连接对象, 执行者对象, 结果集对象
    private DataSource dataSource;
    private Connection con;
    private PreparedStatement pst;
    private ResultSet rs;

//    2. 通过有参构造为数据源赋值
    public JDBCTemplate(DataSource dataSource){
        this.dataSource = dataSource;
    }

//    3. 定义update方法, 参数 sql语句 sql语句中的参数

    public int update(String sql, Object... objs){
        int result = 0;

        try {
            con = dataSource.getConnection();

            pst = con.prepareStatement(sql);

            ParameterMetaData parameterMetaData = pst.getParameterMetaData();

            int count = parameterMetaData.getParameterCount();

            if( count != objs.length){
                throw new RuntimeException(&amp;#34;参数个数不匹配&amp;#34;);
            }

            for(int i=0; i&amp;lt; objs.length;i++){
                pst.setObject(i+1,objs[i]);
            }

            result = pst.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DataSourceUtils.close(con, pst);
        }

        return  result;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test005;

import com.lizicai.utils.DataSourceUtils;
import org.junit.Test;

public class JDBCTemplateTest1 {
    private JDBCTemplate template = new JDBCTemplate(DataSourceUtils.getDataSource());

    @Test
    public void insert(){
        String sql = &amp;#34;INSERT INTO student VALUES (?,?,?,?)&amp;#34;;
        Object[] params = {5,&amp;#34;周七&amp;#34;,27,&amp;#34;1997-07-07&amp;#34;};
        int result = template.update(sql, params);
        if(result != 0){
            System.out.println(&amp;#34;添加成功&amp;#34;);
        } else {
            System.out.println(&amp;#34;添加失败&amp;#34;);
        }
    }

    @Test
    public void update(){
        String sql = &amp;#34;UPDATE student SET age=? WHERE name=?&amp;#34;;
        Object[] params = {37,&amp;#34;周七&amp;#34;};
        int result = template.update(sql, params);
        System.out.println(result);
    }

    @Test
    public void delete(){
        String sql = &amp;#34;DELETE FROM student where name=?&amp;#34;;
        Object[] params = {&amp;#34;周七&amp;#34;};
        int result = template.update(sql, params);
        System.out.println(result);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;查询功能-框架编写&#34;&gt;查询功能-框架编写&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;查询一条记录并封装对象的方法: queryForObject()&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查询多条记录并封装集合的方法: queryForList()&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查询聚合函数并返回单条数据的方法: queryForScalar()&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实体类的编写&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;定义一个类, 提供一些成员变量( 成员变量的数据类型和表中的列保持一致)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test005.domain;

import java.util.Date;

public class Student {
    private Integer sid;
    private String name;
    private Integer age;
    private Date birthday;
    // get set constructor 略
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test005.handler;

import java.sql.ResultSet;

public interface ResultSetHandler&amp;lt;T&amp;gt; {
    &amp;lt;T&amp;gt; T handler(ResultSet rs);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test005.handler;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

// 1. 定义一个类, 实现ResultSetHandler 接口
public class BeanHandler&amp;lt;T&amp;gt; implements ResultSetHandler&amp;lt;T&amp;gt; {
//    2. 定义Class对象类型变量
    private Class&amp;lt;T&amp;gt; beanClass;

//    3. 通过有参构造为变量赋值
    public BeanHandler(Class&amp;lt;T&amp;gt; beanClass){
        this.beanClass = beanClass;
    }

//    4. 重写handler方法, 用于将一条记录封装到自定义对象中
    @Override
    public  T handler(ResultSet rs) {
        // 5. 声明自定义对象类型
        T bean = null;

        try {
            // 6. 创建传递参数的对象, 为自定义对象赋值
            bean =  beanClass.newInstance();

            // 7. 判断结果集中是否有数据
            if(rs.next()){
                // 8. 通过结果集对象获取结果集源信息的对象
                ResultSetMetaData metaData = rs.getMetaData();

                // 9. 通过结果集源信息对象获取列数
                int count = metaData.getColumnCount();

                // 10. 通过循环遍历列数
                for(int i=1;i&amp;lt;= count;i++){
                    // 11. 通过结果集源信息对象获取列名
                    String columnName = metaData.getColumnName(i);

                    // 12. 通过列名获取该列的数据
                    Object value = rs.getObject(columnName);

                    // 13. 创建属性描述器对象, 将获取到的值通过该对象的set方法进行赋值
                    PropertyDescriptor pd = new PropertyDescriptor
                            (columnName.toLowerCase(), beanClass);
                    Method writeMethod = pd.getWriteMethod();
                    writeMethod.invoke(bean, value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 14. 返回封装好的对象
        return bean;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; public &amp;lt;T&amp;gt; T queryForObject(String sql, ResultSetHandler&amp;lt;T&amp;gt; rsh, Object...objs){
        T obj = null;

        try {
            con = dataSource.getConnection();

            pst = con.prepareStatement(sql);

            ParameterMetaData parameterMetaData = pst.getParameterMetaData();

            int count = parameterMetaData.getParameterCount();

            if( count != objs.length){
                throw new RuntimeException(&amp;#34;参数个数不匹配&amp;#34;);
            }

            for(int i=0; i&amp;lt; objs.length;i++){
                pst.setObject(i+1,objs[i]);
            }

            rs = pst.executeQuery();

            obj = rsh.handler(rs);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DataSourceUtils.close(con, pst);
        }

        return  obj;
    }
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void queryForObject(){
    String sql = &amp;#34;SELECT * FROM student WHERE sid=?&amp;#34;;
    Student stu = template.queryForObject(sql, new BeanHandler&amp;lt;&amp;gt;(Student.class), 1);
    System.out.println(stu);
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;查询列表&#34;&gt;查询列表&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test005.handler;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

// 1. 定义一个类, 实现ResultSetHandler 接口
public class BeanListHandler&amp;lt;T&amp;gt; implements ResultSetHandler&amp;lt;T&amp;gt; {
//    2. 定义Class对象类型变量
    private Class&amp;lt;T&amp;gt; beanClass;

//    3. 通过有参构造为变量赋值
    public BeanListHandler(Class&amp;lt;T&amp;gt; beanClass){
        this.beanClass = beanClass;
    }

//    4. 重写handler方法, 用于将一条记录封装到自定义对象中
    @Override
    public List&amp;lt;T&amp;gt; handler(ResultSet rs) {
        // 5. 创建集合对象
        List&amp;lt;T&amp;gt; beanList = new ArrayList&amp;lt;&amp;gt;();

        try {

            // 6. 循环判断是否有值
            while (rs.next()){
                // 7. 创建传递参数的对象, 为自定义对象赋值
                T bean =  beanClass.newInstance();
                // 8. 通过结果集对象获取结果集源信息的对象
                ResultSetMetaData metaData = rs.getMetaData();

                // 9. 通过结果集源信息对象获取列数
                int count = metaData.getColumnCount();

                // 10. 通过循环遍历列数
                for(int i=1;i&amp;lt;= count;i++){
                    // 11. 通过结果集源信息对象获取列名
                    String columnName = metaData.getColumnName(i);

                    // 12. 通过列名获取该列的数据
                    Object value = rs.getObject(columnName);

                    // 13. 创建属性描述器对象, 将获取到的值通过该对象的set方法进行赋值
                    PropertyDescriptor pd = new PropertyDescriptor
                            (columnName.toLowerCase(), beanClass);
                    Method writeMethod = pd.getWriteMethod();
                    writeMethod.invoke(bean, value);
                }
                beanList.add(bean);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 14. 返回封装好的对象
        return beanList;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/**
 * 查询多条记录
 */
public &amp;lt;T&amp;gt; List&amp;lt;T&amp;gt; queryListForObject(String sql, ResultSetHandler&amp;lt;T&amp;gt; rsh, Object...objs){
    List&amp;lt;T&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();

    try {
        con = dataSource.getConnection();

        pst = con.prepareStatement(sql);

        ParameterMetaData parameterMetaData = pst.getParameterMetaData();

        int count = parameterMetaData.getParameterCount();

        if( count != objs.length){
            throw new RuntimeException(&amp;#34;参数个数不匹配&amp;#34;);
        }

        for(int i=0; i&amp;lt; objs.length;i++){
            pst.setObject(i+1,objs[i]);
        }

        rs = pst.executeQuery();

        list = rsh.handler(rs);

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        DataSourceUtils.close(con, pst);
    }

    return  list;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void queryForList(){
    String sql = &amp;#34;SELECT * FROM student&amp;#34;;
    List&amp;lt;Student&amp;gt; list = template.queryListForObject(sql, new BeanListHandler&amp;lt;&amp;gt;(Student.class));
    for(Student stu : list){
        System.out.println(stu);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;查询聚合函数&#34;&gt;查询聚合函数&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test005.handler;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

/**
 * 1. 定义一个类, 实现ResultSetHandler接口
 * 2. 我一定handler方法
 * 3. 定义一个Long类型变量
 * 4. 判断结果集对象中是否还有数据
 * 5. 获取结果集源信息的对象
 * 6. 获取第一列的列名
 * 7. 根据列名获取该列的值
 * 8. 返回结果
 */
// * 1. 定义一个类, 实现ResultSetHandler接口
public class ScalarHandler &amp;lt;T&amp;gt; implements ResultSetHandler&amp;lt;T&amp;gt;{

    //2. 我一定handler方法
    @Override
    public Long handler(ResultSet rs) {
        // 3. 定义一个Long类型变量
        Long value = null;

        try {
            // 4. 判断结果集对象中是否还有数据
            if(rs.next()){
                // 5. 获取结果集源信息的对象
                ResultSetMetaData metaData = rs.getMetaData();

                //6. 获取第一列的列名
                String columnName = metaData.getColumnName(1);
                // 7. 根据列名获取该列的值
                value = rs.getLong(columnName);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/**
 *  聚合聚合函数的查询结果
 */
public Long queryForScalar(String sql, ResultSetHandler&amp;lt;Long&amp;gt; rsh, Object...objs){
    Long value = null;

    try {
        con = dataSource.getConnection();

        pst = con.prepareStatement(sql);

        ParameterMetaData parameterMetaData = pst.getParameterMetaData();

        int count = parameterMetaData.getParameterCount();

        if( count != objs.length){
            throw new RuntimeException(&amp;#34;参数个数不匹配&amp;#34;);
        }

        for(int i=0; i&amp;lt; objs.length;i++){
            pst.setObject(i+1,objs[i]);
        }

        rs = pst.executeQuery();

        value = rsh.handler(rs);

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        DataSourceUtils.close(con, pst);
    }

    return  value;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void queryForScalar(){
    String sql = &amp;#34;SELECT COUNT(*) FROM student&amp;#34;;

    Long value = template.queryForScalar(sql, new ScalarHandler&amp;lt;Long&amp;gt;());
    System.out.println(value);
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>JDBC数据库连接二 Li.061</title>
      <link>https://lizicai.com/p/jdbc%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E4%BA%8C-li.061/</link>
      <pubDate>Tue, 26 Oct 2021 18:21:18 +0800</pubDate>
      <guid>https://lizicai.com/p/jdbc%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E4%BA%8C-li.061/</guid>
      <description>&lt;h2 id=&#34;数据库连接池&#34;&gt;数据库连接池&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;数据库连接池&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现在的数据库连接,而不是再重新建立一个. 这项技术能明显提高对数据库操作的性能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DataSource接口概述&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;javax.sql.DataSource接口: 数据源(数据库连接池). Java官方提供的数据库连接池规范(接口)&lt;/li&gt;
&lt;li&gt;如果想完成数据库连接池技术, 就必须实现DataSource接口&lt;/li&gt;
&lt;li&gt;核心功能: 获取数据库连接对象: Connection getConnection()&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自定义数据库连接池&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;定义一个类, 实现DataSource接口&lt;/li&gt;
&lt;li&gt;定义一个容器, 用于保存多个Connection连接对象&lt;/li&gt;
&lt;li&gt;定义静态代码块, 通过JDBC工具类获取10个连接保存到容器中&lt;/li&gt;
&lt;li&gt;重写getConnection方法, 从容器中获取一个连接并返回&lt;/li&gt;
&lt;li&gt;定义getSize方法, 用于获取窗口的大小并返回&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test001;

import com.lizicai.utils.JDBCUtils;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;

public class MyDataSource implements DataSource {
    // 1. 准备窗口, 用于保存多个连接对象, 变成线程安全的
    private static List&amp;lt;Connection&amp;gt; pool = Collections.synchronizedList(new ArrayList&amp;lt;&amp;gt;());

    // 2. 定义代码块, 通过工具类获取10个连接对象
    static {
        for(int i=0;i&amp;lt;10;i++){
            Connection con = JDBCUtils.getConnection();
            pool.add(con);
        }
    }
    //3 重写getConnection() , 用于获取一个连接对象
    @Override
    public Connection getConnection() throws SQLException {
        if( pool.size()&amp;gt; 0){
            Connection con = pool.remove(0);
            return con;
        } else {
            throw new RuntimeException(&amp;#34;连接数量已用尽&amp;#34;);
        }
    }

    // 4. 定义getSize方法, 获取连接池窗口的大小
    public int getSize(){
        return pool.size();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test001;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MyDataSourceTest {
    public static void main(String[] args) throws SQLException {
        MyDataSource pool = new MyDataSource();

        System.out.println(pool.getSize());

        Connection con = pool.getConnection();

        String sql = &amp;#34;SELECT * FROM student&amp;#34;;

        PreparedStatement pst = con.prepareStatement(sql);

        ResultSet rs = pst.executeQuery();

        while (rs.next()){
            System.out.println(rs.getInt(&amp;#34;sid&amp;#34;)+&amp;#34;\t&amp;#34;+rs.getString(&amp;#34;NAME&amp;#34;)
            +&amp;#34;\t&amp;#34;+rs.getInt(&amp;#34;age&amp;#34;)+&amp;#34;\t&amp;#34;+rs.getDate(&amp;#34;birthday&amp;#34;));
        }

        rs.close();

        pst.close();

        con.close();

        System.out.println(pool.getSize());

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;归还方式&#34;&gt;归还方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;归还数据库连接的方式
&lt;ul&gt;
&lt;li&gt;继承方式&lt;/li&gt;
&lt;li&gt;装饰设计模式&lt;/li&gt;
&lt;li&gt;我在适配器设计模式&lt;/li&gt;
&lt;li&gt;动态 代理方式&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;归还方式---继承方式&#34;&gt;归还方式 - 继承方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;继承方式归还数据库连接的思想。
&lt;ul&gt;
&lt;li&gt;通过打印连接对象，发现 DriverManager 获取的连接实现类是 JDBC4Connection&lt;/li&gt;
&lt;li&gt;那我们就可以自定义一个类，继承JDBC4Connection这个类，重写closeQ 方法，完成连接对象的归还&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;继承方式归还数据库连接的实现步骤。
&lt;ul&gt;
&lt;li&gt;定义一个类，继承JDBC4Connection。&lt;/li&gt;
&lt;li&gt;定义 Connection 连接对象和连接池容器对象的成员变量。&lt;/li&gt;
&lt;li&gt;通过有参构造方法完成对成员变量的赋值。&lt;/li&gt;
&lt;li&gt;重写cose 方法，将连接对象添加到池中。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;继承方式日还数据库连接存任的问题。
&lt;ul&gt;
&lt;li&gt;通过查看 JDBC 工具类获取连接的方法发现：我们星然白定义了一个子类，完成了归还连接的操作。但是&lt;/li&gt;
&lt;li&gt;DriverManager 获取的还是JDBC4Connection这个对象，并不是我们的子类对象，而我们又不能整体去修改驱动包中类的功能，所继承这种方式行不通！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;归还连接---装饰设计模式&#34;&gt;归还连接 - 装饰设计模式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;装饰设计模式日还数据库连接的思想。
&lt;ul&gt;
&lt;li&gt;我们可以自定义一个类，实现 Connection接口。这样就具备了和 JDBC4Connection相同的行为了&lt;/li&gt;
&lt;li&gt;重写close()方法，完成连接的归还。其余的功能还调用 mysql驱动包实现类原有的方法即可&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;装饰设计模式归还数据库连接的实现步骤。
&lt;ul&gt;
&lt;li&gt;定义一个类，实现 Connection 接口&lt;/li&gt;
&lt;li&gt;定义 Connection 连接对象和连接池容器对象的成员变量&lt;/li&gt;
&lt;li&gt;通过有参构造方法完成对成员变量的赋值&lt;/li&gt;
&lt;li&gt;重写close()方法，将连接对象添加到池中&lt;/li&gt;
&lt;li&gt;剩余方法，只需要调用mysql驱动包的连接对象完成即可&lt;/li&gt;
&lt;li&gt;在自定义连接池中，将获取的连接对象通过自定义连接对象进行包装&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;装饰设计模式归还数据库连接存在的问题。
&lt;ul&gt;
&lt;li&gt;实现 Connection接口后，有大量的方法需要在自定义类中进行重写&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test002;

import java.sql.*;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
 * 1. 定义一个类, 实现Connection接口
 * 2. 定义连接对象和连接池容器对象的成员变量
 * 3. 通过有参构造方法为成员变量赋值
 * 4. 重写close()方法, 完成归还连接
 * 5. 剩余方法, 还是调用原有的连接对象中的功能即可
 */

public class MyConnection2 implements Connection {
    private Connection con;
    private List&amp;lt;Connection&amp;gt; pool;

    public MyConnection2(Connection con, List&amp;lt;Connection&amp;gt; pool) {
        this.con = con;
        this.pool = pool;
    }

    @Override
    public void close() throws SQLException {
        pool.add(con);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class MyDataSource implements DataSource {
    //3 重写getConnection() , 用于获取一个连接对象
    @Override
    public Connection getConnection() throws SQLException {
        if( pool.size()&amp;gt; 0){
            Connection con = pool.remove(0);
            MyConnection2 myCon = new MyConnection2(con,pool);
            return myCon;
        } else {
            throw new RuntimeException(&amp;#34;连接数量已用尽&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;归还连接---适配器设计模式&#34;&gt;归还连接 - 适配器设计模式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;适配器设计模式归还数据库连接的思想。
&lt;ul&gt;
&lt;li&gt;我们可以提供一个适配器类，实现 Connection 接口，将所有方法进行实现(除了close方法）&lt;/li&gt;
&lt;li&gt;自定义连接类只需要继承这个适配器类，重写需要改进的close0 方法即可&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;适配器设计模式归还数据库连接的实现步骤。
&lt;ul&gt;
&lt;li&gt;定义一个适配器类, 实现 Connection 接口。&lt;/li&gt;
&lt;li&gt;定义 Connection 连接对象的成员变量。&lt;/li&gt;
&lt;li&gt;通过有参构造方法完成对成员变量的赋值。&lt;/li&gt;
&lt;li&gt;重写所有方法(除了close), 调用mysq驱动包的连接对象完成即可。&lt;/li&gt;
&lt;li&gt;定义一个连接类，继承适配器类。&lt;/li&gt;
&lt;li&gt;定义 Connection 连接对象和连接池容器对象的成员变量，并通过有参构造进行赋值。&lt;/li&gt;
&lt;li&gt;重写close()方法，完成归还连接。&lt;/li&gt;
&lt;li&gt;在自定义连接池中，将获取的连接对象通过自定义连接对象进行包装。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;适配器设计模式归还数据库连接存在的问题。
&lt;ul&gt;
&lt;li&gt;自定义连接类虽然很简洁, 但我在楼下器还是自己编写的, 也比较麻烦&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public abstract class MyAdapter implements Connection {
    private Connection con;

    public MyAdapter(Connection con){
        this.con = con;
    }
    //省略其他实现的方法
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test002;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public class MyConnection3 extends MyAdapter{
    private Connection con;
    private List&amp;lt;Connection&amp;gt; pool;

    public MyConnection3(Connection con, List&amp;lt;Connection&amp;gt; pool) {
        super(con);
        this.con = con;
        this.pool = pool;
    }

    @Override
    public void close() throws SQLException {
        pool.add(con);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;动态代理&#34;&gt;动态代理&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;动态代理: 在不改变目标对象方法的情况下对方法进行增强&lt;/li&gt;
&lt;li&gt;组成
&lt;ul&gt;
&lt;li&gt;被代理对象: 真实的对象&lt;/li&gt;
&lt;li&gt;代理对象: 内存的一个对象&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要求
&lt;ul&gt;
&lt;li&gt;代理对象必须和被代理对象实现相同的接口&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;实现
&lt;ul&gt;
&lt;li&gt;Proxy.newProxyInstance()&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.eat(&amp;#34;饭&amp;#34;);
        stu.study();

        /**
         * 要求: 在不改Student类中任何代码前提下, 通过study方法输出一句话
         * 类加载器: 和被代理对象使用相同的类加载器
         * 接口类型Class数组: 和被代理对象使用相同接口
         * 代理规则: 完成代理增加的功能
         */
        StudentInterface proxyStu = (StudentInterface) Proxy.newProxyInstance(stu.getClass().getClassLoader(), new Class[]{StudentInterface.class}, new InvocationHandler() {
            /**
             * 执行student类中所有方法都会经过invoke方法
             * 对method方法进行判断
             *  如果是study, 则对其增强
             *  如果不是, 还调用学生对象原的功能即可
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if(method.getName().equals(&amp;#34;study&amp;#34;)){
                    System.out.println(&amp;#34;学快点&amp;#34;);
                    return null;
                } else {
                    return method.invoke(stu, args);
                }
            }
        });

        proxyStu.eat(&amp;#34;米饭&amp;#34;);
        proxyStu.study();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;归还连接---动态代理方式&#34;&gt;归还连接 - 动态代理方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;动态代理方式归还数据库连接的思想。
&lt;ul&gt;
&lt;li&gt;我们可以通过 Proxy 来完成对 Connection 实现类对象的代理&lt;/li&gt;
&lt;li&gt;代理过程中判断如果执行的是 close 方法，就将连接归还池中。如果是其他方法则调用连接对象原来 的功能即可&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;动态代理方式归还数据库连接的实现步骤。
&lt;ul&gt;
&lt;li&gt;定义一个类，实现 DataSource接口&lt;/li&gt;
&lt;li&gt;定义一个容器，用于保存多个Connection连接对象&lt;/li&gt;
&lt;li&gt;定义静态代码块，通过JDBC工具类获取 10 个连接保存到容器中&lt;/li&gt;
&lt;li&gt;重马getConnection 方法，从容器中获取一个连接&lt;/li&gt;
&lt;li&gt;通过 Proxy 代理，如果是close 方法，就将连接归还池中。如果是其他方法则调用原有功能&lt;/li&gt;
&lt;li&gt;定义 getsize 方法，用于获取容器的大小并返回&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;动态代理方式归还数据库连接存在的问题。
&lt;ul&gt;
&lt;li&gt;我们自己写的连接池技术不够完善，功能也不够强大&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test001;

import com.lizicai.utils.JDBCUtils;
import com.test002.MyConnection2;
import com.test002.MyConnection3;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;

public class MyDataSource implements DataSource {
    // 1. 准备窗口, 用于保存多个连接对象, 更改List为线程安全的
    private static List&amp;lt;Connection&amp;gt; pool = Collections.synchronizedList(new ArrayList&amp;lt;&amp;gt;());

    // 2. 定义代码块, 通过工具类获取10个连接对象
    static {
        for(int i=0;i&amp;lt;10;i++){
            Connection con = JDBCUtils.getConnection();
            pool.add(con);
        }
    }
    // 动态代理归还Connection
    @Override
    public Connection getConnection() throws SQLException {
        if( pool.size()&amp;gt; 0){
            Connection con = pool.remove(0);
            Connection proxyCon =(Connection) Proxy.newProxyInstance(con.getClass().getClassLoader(), new Class[]{Connection.class}, new InvocationHandler() {
                /** 执行Connection 实现类连接对象所有的方法都会经过invoke
                 * 如果是close方法, 归还连接
                 * 如果不是, 直接执行连接对象原有的功能即可
                 *
                 */
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if(method.getName().equals(&amp;#34;close&amp;#34;)){
                        pool.add(con);
                        return null;
                    } else {
                        return method.invoke(con, args);
                    }
                }
            });
            return proxyCon;
        } else {
            throw new RuntimeException(&amp;#34;连接数量已用尽&amp;#34;);
        }
    }

    // 4. 定义getSize方法, 获取连接池窗口的大小
    public int getSize(){
        return pool.size();
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public &amp;lt;T&amp;gt; T unwrap(Class&amp;lt;T&amp;gt; iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class&amp;lt;?&amp;gt; iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;使用c3p0数据库连接池的使用步骤&#34;&gt;使用C3P0数据库连接池的使用步骤&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;导入Jar包, c3p0-0.9.5.5.jar和mchange-commons-java-0.2.19.jar&lt;/li&gt;
&lt;li&gt;导入配置文件到src目录下&lt;/li&gt;
&lt;li&gt;创建C3P0连接池对象&lt;/li&gt;
&lt;li&gt;获取数据库连接进行使用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://sourceforge.net/projects/c3p0/&#34; target=&#34;_blank&#34;&gt;C3P0下载, 开头/c3p0-bin/c3p0-0.9.5.5/c3p0-0.9.5.5.bin.zip&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/swaldman/c3p0/tree/master/src/test-properties&#34; target=&#34;_blank&#34;&gt;配置文件示例下载Github地址&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; standalone=&amp;#34;no&amp;#34; ?&amp;gt;

&amp;lt;!--
&amp;lt;!DOCTYPE c3p0-config [
   &amp;lt;!ENTITY extra SYSTEM &amp;#34;https://www.mchange.com/projects/c3p0/extra.xml&amp;#34;&amp;gt;
]&amp;gt;--&amp;gt;

&amp;lt;c3p0-config&amp;gt;
  &amp;lt;default-config&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;automaticTestTable&amp;#34;&amp;gt;con_test&amp;lt;/property&amp;gt; --&amp;gt;
     &amp;lt;property name=&amp;#34;checkoutTimeout&amp;#34;&amp;gt;30000&amp;lt;/property&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;idleConnectionTestPeriod&amp;#34;&amp;gt;30&amp;lt;/property&amp;gt; --&amp;gt;
     &amp;lt;property name=&amp;#34;initialPoolSize&amp;#34;&amp;gt;10&amp;lt;/property&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;maxIdleTime&amp;#34;&amp;gt;30&amp;lt;/property&amp;gt; --&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;maxIdleTimeExcessConnections&amp;#34;&amp;gt;10&amp;lt;/property&amp;gt; --&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;maxConnectionAge&amp;#34;&amp;gt;60&amp;lt;/property&amp;gt; --&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;propertyCycle&amp;#34;&amp;gt;1&amp;lt;/property&amp;gt; --&amp;gt;
     &amp;lt;property name=&amp;#34;maxPoolSize&amp;#34;&amp;gt;5&amp;lt;/property&amp;gt;
     &amp;lt;property name=&amp;#34;minPoolSize&amp;#34;&amp;gt;2&amp;lt;/property&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;maxStatements&amp;#34;&amp;gt;0&amp;lt;/property&amp;gt; --&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;maxStatementsPerConnection&amp;#34;&amp;gt;5&amp;lt;/property&amp;gt; --&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;maxAdministrativeTaskTime&amp;#34;&amp;gt;4&amp;lt;/property&amp;gt; --&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;connectionCustomizerClassName&amp;#34;&amp;gt;com.mchange.v2.c3p0.test.TestConnectionCustomizer&amp;lt;/property&amp;gt; --&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;unreturnedConnectionTimeout&amp;#34;&amp;gt;15&amp;lt;/property&amp;gt; --&amp;gt;
    &amp;lt;!-- &amp;lt;property name=&amp;#34;debugUnreturnedConnectionStackTraces&amp;#34;&amp;gt;true&amp;lt;/property&amp;gt; --&amp;gt;

    &amp;lt;!-- &amp;lt;property name=&amp;#34;dataSourceName&amp;#34;&amp;gt;poop&amp;lt;/property&amp;gt; --&amp;gt;

     &amp;lt;property name=&amp;#34;driverClass&amp;#34;&amp;gt;org.mariadb.jdbc.Driver&amp;lt;/property&amp;gt;
     &amp;lt;property name=&amp;#34;jdbcUrl&amp;#34;&amp;gt;jdbc:mariadb://192.168.0.100:3306/db14&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;#34;user&amp;#34;&amp;gt;root&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;#34;password&amp;#34;&amp;gt;rootPassword&amp;lt;/property&amp;gt;

    &amp;lt;extensions&amp;gt;
      &amp;lt;!-- &amp;lt;property name=&amp;#34;myXmlKey&amp;#34;&amp;gt;myXmlVal&amp;lt;/property&amp;gt; --&amp;gt;
      &amp;lt;!-- &amp;lt;property name=&amp;#34;myKey&amp;#34;&amp;gt;myOverriddenVal&amp;lt;/property&amp;gt; --&amp;gt;
    &amp;lt;/extensions&amp;gt;


    &amp;lt;user-overrides user=&amp;#34;swaldman&amp;#34;&amp;gt;
      &amp;lt;!--
      &amp;lt;property name=&amp;#34;unreturnedConnectionTimeout&amp;#34;&amp;gt;5&amp;lt;/property&amp;gt;
      &amp;lt;property name=&amp;#34;debugUnreturnedConnectionStackTraces&amp;#34;&amp;gt;true&amp;lt;/property&amp;gt;
      --&amp;gt;
      &amp;lt;!-- &amp;lt;property name=&amp;#34;preferredTestQuery&amp;#34;&amp;gt;select poop from doop&amp;lt;/property&amp;gt; --&amp;gt;&amp;lt;!-- intentionally broken --&amp;gt;
    &amp;lt;/user-overrides&amp;gt;

&amp;lt;!--    &amp;amp;extra;--&amp;gt;

  &amp;lt;/default-config&amp;gt;


&amp;lt;!--
  &amp;lt;named-config name=&amp;#34;dumbTestConfig&amp;#34;&amp;gt;
    &amp;lt;property name=&amp;#34;maxStatements&amp;#34;&amp;gt;200&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;#34;jdbcUrl&amp;#34;&amp;gt;jdbc:test&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;#34;dataSourceName&amp;#34;&amp;gt;scoop&amp;lt;/property&amp;gt;
    &amp;lt;user-overrides user=&amp;#34;poop&amp;#34;&amp;gt;
      &amp;lt;property name=&amp;#34;maxStatements&amp;#34;&amp;gt;300&amp;lt;/property&amp;gt;
    &amp;lt;/user-overrides&amp;gt;
   &amp;lt;/named-config&amp;gt;
--&amp;gt;

&amp;lt;/c3p0-config&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;使用默认的配置拿到连接, 可以正常使用了&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; DataSource dataSource = new ComboPooledDataSource();
        Connection con = dataSource.getConnection();
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test003;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class C3P0Test2 {
    public static void main(String[] args) throws SQLException {
        DataSource dataSource = new ComboPooledDataSource();

        for(int i=1;i&amp;lt;=11;i++){
            Connection con = dataSource.getConnection();
            System.out.println(i+&amp;#34;:&amp;#34;+con);
//            if( 5 == i){
//                con.close();
//            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;druid连接池的使用&#34;&gt;Druid连接池的使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Druid 数据库连接池的使用步骡。
&lt;ul&gt;
&lt;li&gt;导入jar包, druid-1.2.8.jar&lt;/li&gt;
&lt;li&gt;编写配置文件，放在src目录下。&lt;/li&gt;
&lt;li&gt;通过 Properties 集合加载配置文件。&lt;/li&gt;
&lt;li&gt;通过 Druid 连接池工厂类获取数据库连接池对象。&lt;/li&gt;
&lt;li&gt;获取数据库连接进行使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Druid不会自动加载配置文件，需要我们手动加载，但是文样的名称可以自定义&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;driverClassName=org.mariadb.jdbc.Driver
url=jdbc:mariadb://192.168.0.100:3306/db14
username=root
password=rootPassword
initialSize=5
maxActive=10
maxWait=3000
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test004;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

public class DruidTest1 {
    public static void main(String[] args) throws Exception {

//        获取配置文件的流对象
        InputStream is = DruidTest1.class.getClassLoader().getResourceAsStream(&amp;#34;druid.properties&amp;#34;);

//        1. 通过 Properties 集合, 加载配置文件
        Properties prop = new Properties();
        prop.load(is);

//        2. 通过Druid连接池工厂类获取数据库连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

//        3. 通过连接池对象获取数据库进行使用
        Connection con = dataSource.getConnection();

        String sql = &amp;#34;SELECT * FROM student&amp;#34;;

        PreparedStatement pst = con.prepareStatement(sql);

        ResultSet rs = pst.executeQuery();

        while (rs.next()){
            System.out.println(rs.getInt(&amp;#34;sid&amp;#34;)+&amp;#34;\t&amp;#34;+rs.getString(&amp;#34;NAME&amp;#34;)
                    +&amp;#34;\t&amp;#34;+rs.getInt(&amp;#34;age&amp;#34;)+&amp;#34;\t&amp;#34;+rs.getDate(&amp;#34;birthday&amp;#34;));
        }

        rs.close();

        pst.close();

        con.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;创建druid-工具类&#34;&gt;创建Druid 工具类&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 数据库连接池的工具类
 */

public class DataSourceUtils {
    // 1. 私有构造方法
    private DataSourceUtils(){}

    // 2. 声明数据源变量
    private static DataSource dataSource;

    // 3. 提供静态代码块, 完成配置文件加载和获取数据库连接池对象
    static {
        try {
            InputStream is = DataSourceUtils.class.getClassLoader().getResourceAsStream(&amp;#34;druid.properties&amp;#34;);
            Properties prop = new Properties();
            prop.load(is);
            dataSource =  DruidDataSourceFactory.createDataSource(prop);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 4. 提供一个获取数据库连接的方法
    public static Connection getConnection()  {
        Connection con = null;
        try {
            con = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return con;
    }


    // 5. 提供一个获取数据库连接池对象的方法
    public static DataSource getDataSource() throws Exception {
        return dataSource;
    }



    // 6. 释放资源的方法

    public static void close(Connection con, Statement stat, ResultSet rs){
        if(con != null){
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stat != null){
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void close(Connection con, Statement stat){
        if(con != null){
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stat != null){
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.test004;

import com.lizicai.utils.DataSourceUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DruidTest2 {
    public static void main(String[] args) throws SQLException {
        Connection con = DataSourceUtils.getConnection();

        String sql = &amp;#34;SELECT * FROM student&amp;#34;;

        PreparedStatement pst = con.prepareStatement(sql);

        ResultSet rs = pst.executeQuery();

        while (rs.next()){
            System.out.println(rs.getInt(&amp;#34;sid&amp;#34;)+&amp;#34;\t&amp;#34;+rs.getString(&amp;#34;NAME&amp;#34;)
                    +&amp;#34;\t&amp;#34;+rs.getInt(&amp;#34;age&amp;#34;)+&amp;#34;\t&amp;#34;+rs.getDate(&amp;#34;birthday&amp;#34;));
        }

       DataSourceUtils.close(con,pst,rs);
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>JDBC数据库连接一 Li.060</title>
      <link>https://lizicai.com/p/jdbc%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E4%B8%80-li.060/</link>
      <pubDate>Sun, 24 Oct 2021 19:03:55 +0800</pubDate>
      <guid>https://lizicai.com/p/jdbc%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E4%B8%80-li.060/</guid>
      <description>&lt;h2 id=&#34;jdbc-的概念&#34;&gt;JDBC 的概念&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JDBC的概念
&lt;ul&gt;
&lt;li&gt;JDBC(Java DataBase Connectivity Java数据库连接)是一种用于执行SQL语句的Java API, 可以为多种关系型数据库提供统一访问,它是由一组用Java语文编写的类和接口组成的&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;JDBC的本质
&lt;ul&gt;
&lt;li&gt;其实就是Java官方提供的一套规范(接口). 用于帮助开发人员快速实现不同关系型数据库的连接.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;JDBC 的快速入门程序
&lt;ul&gt;
&lt;li&gt;导入Jar包&lt;/li&gt;
&lt;li&gt;注册驱动&lt;/li&gt;
&lt;li&gt;获取数据库连接&lt;/li&gt;
&lt;li&gt;获取执行者对象&lt;/li&gt;
&lt;li&gt;执行SQL语句并返回结果&lt;/li&gt;
&lt;li&gt;处理结果&lt;/li&gt;
&lt;li&gt;释放资源&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://mariadb.com/downloads/connectors/connectors-data-access/java8-connector/&#34; target=&#34;_blank&#34;&gt;JDBC包下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.jdbc;

import java.sql.*;

public class JDBCDemo1 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 导入Jar包, 已导入
        // 注册驱动, 也可以省略掉
        Class.forName(&amp;#34;org.mariadb.jdbc.Driver&amp;#34;);

        // 获取数据库连接
        Connection connection = DriverManager.getConnection
                (&amp;#34;jdbc:mariadb://192.168.0.100:3306/db10&amp;#34;, &amp;#34;root&amp;#34;, &amp;#34;rootPassword&amp;#34;);

        // 获取执行者对象
        Statement statement = connection.createStatement();

        // 执行SQL语句并返回结果
        String sql = &amp;#34;SELECT * FROM city&amp;#34;;
        ResultSet rs = statement.executeQuery(sql);

        // 处理结果
        while (rs.next()){
            System.out.println(rs.getInt(&amp;#34;id&amp;#34;)+&amp;#34;,&amp;#34;+rs.getString(&amp;#34;NAME&amp;#34;)+&amp;#34;,&amp;#34;+rs.getInt(&amp;#34;VERSION&amp;#34;));
        }

        // 释放资源
        connection.close();
        statement.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;drivermanager&#34;&gt;DriverManager&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;DriverManger驱动管理对象
&lt;ul&gt;
&lt;li&gt;注册驱动
&lt;ul&gt;
&lt;li&gt;注册给定的驱动程序: static void registerDriver(Driver driver)&lt;/li&gt;
&lt;li&gt;写代码使用: Class.forName(&amp;ldquo;org.mariadb.jdbc.Driver&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;在org.mariadb.jdbc.Driver类中存在静态代码块&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;static {
    try {
        DriverManager.registerDriver(new Driver(), new DeRegister());
    } catch (SQLException var1) {
        throw new RuntimeException(&amp;#34;Could not register driver&amp;#34;, var1);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;不需要通过DriverManager调用静态方法registerDriver(),因为只要Driver类被使用,则会执行其静态代码块完成注册驱动&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MySQL5.0(MariaDB同样适用)之后可以省略注册驱动的步骤.在Jar包中,存在一个java.sql.Driver配置文件,文件中指定了com.mysql.jdbc.Driver&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;获取数据库连接
&lt;ul&gt;
&lt;li&gt;获取数据库连接对象static Connection getConnection(String url, String user, String password)&lt;/li&gt;
&lt;li&gt;参数:
&lt;ul&gt;
&lt;li&gt;url数据库连接路径jdbc:mariadb://ip:端口/数据库,(mysql是jdbc:mysql://192.168.0.100:3306/db10)&lt;/li&gt;
&lt;li&gt;user用户名&lt;/li&gt;
&lt;li&gt;password&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;connection&#34;&gt;Connection&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Connection 数据库连接对象
&lt;ul&gt;
&lt;li&gt;获取执行者对象
&lt;ul&gt;
&lt;li&gt;获取普通执行都对象: Statement createStatement();&lt;/li&gt;
&lt;li&gt;获取预编译执行者对象: PreparedStatement prepareStatement(String sql)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;管理事务
&lt;ul&gt;
&lt;li&gt;开启事务: setAutoCommit(boolean autoCommit); 参数为false,则开启事务&lt;/li&gt;
&lt;li&gt;提交事务: commit();&lt;/li&gt;
&lt;li&gt;回滚事务: rollback();&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;释放资源
&lt;ul&gt;
&lt;li&gt;立即将数据库连接对象释放: void close();&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;statement&#34;&gt;Statement&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Statement执行SQL语句的对象
&lt;ul&gt;
&lt;li&gt;执行DML语句: int executeUpdate(String sql);
&lt;ul&gt;
&lt;li&gt;返回值int: 返回影响的行数&lt;/li&gt;
&lt;li&gt;参数sql: 可能执行insert,update,delete语句&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;执行DQL语句: ResultSet executeQuery(String sql);
&lt;ul&gt;
&lt;li&gt;返回值ResultSet: 封装查询的结果&lt;/li&gt;
&lt;li&gt;参数sql: 可能执行select语句&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;释放资源
&lt;ul&gt;
&lt;li&gt;立即将执行者对象释放: void close();&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;resultset&#34;&gt;ResultSet&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ResultSet结果集对象
&lt;ul&gt;
&lt;li&gt;判断结果集中是否还有数据:boolean next();
&lt;ul&gt;
&lt;li&gt;有数据返回true,并将索引向移动一行&lt;/li&gt;
&lt;li&gt;没有数据返回false&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获取结果集中的数据: XXX getXxx(&amp;ldquo;列名&amp;rdquo;);
&lt;ul&gt;
&lt;li&gt;XXX代表数据类型(要获取某列数据,这一列的数据类型).&lt;/li&gt;
&lt;li&gt;String getString(&amp;ldquo;name&amp;rdquo;) int getInt(&amp;ldquo;age&amp;rdquo;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;释放资源
&lt;ul&gt;
&lt;li&gt;立即将结果集对象释放: void close();&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;jdbc案例需要&#34;&gt;JDBC案例需要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用JDBC完成对student表的CRUD操作&lt;/li&gt;
&lt;li&gt;数据准备&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 数据准备
CREATE DATABASE db14;
USE db14;

CREATE TABLE student(
    id INT PRIMARY KEY auto_increment,
    NAME VARCHAR(50),
    age INT,
    birthday DATE
);
INSERT INTO student VALUES (NULL,&amp;#39;张三&amp;#39;,23,&amp;#39;1999-09-23&amp;#39;);
INSERT INTO student VALUES (NULL,&amp;#39;李四&amp;#39;,24,&amp;#39;1998-08-10&amp;#39;);
INSERT INTO student VALUES (NULL,&amp;#39;五五&amp;#39;,25,&amp;#39;1996-06-06&amp;#39;);
INSERT INTO student VALUES (NULL,&amp;#39;赵六&amp;#39;,26,&amp;#39;1994-10-20&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;创建Student类&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;自定义类的功能是为了封装表中的系列数据,成员变量和列保持一致&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;所有基本数据类型需要使用对应包装类,以免表中NULL值无法赋值&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Student {
    private Integer sid;
    private String name;
    private Integer age;
    private Date birthday;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习&#34;&gt;练习&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;查询所有学生信息&lt;/li&gt;
&lt;li&gt;根据id查询学生信息&lt;/li&gt;
&lt;li&gt;新增学生信息&lt;/li&gt;
&lt;li&gt;修改学生信息&lt;/li&gt;
&lt;li&gt;删除学生信息&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.domain;

import java.util.Date;

public class Student {
    private Integer sid;
    private String name;
    private Integer age;
    private Date birthday;
    public Student(){}

    public Student(Integer id, String name, Integer age, Date birthday) {
        this.sid = id;
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    public Integer getSid() {
        return sid;
    }

    public void setSid(Integer sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return &amp;#34;Student{&amp;#34; +
                &amp;#34;sid=&amp;#34; + sid +
                &amp;#34;, name=&amp;#39;&amp;#34; + name + &amp;#39;\&amp;#39;&amp;#39; +
                &amp;#34;, age=&amp;#34; + age +
                &amp;#34;, birthday=&amp;#34; + birthday +
                &amp;#39;}&amp;#39;;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.dao;

import com.lizicai.domain.Student;

import java.util.ArrayList;

public interface StudentDao {
    // 查询所有学生信息
    public abstract ArrayList&amp;lt;Student&amp;gt; findAll();

    // 条件查询, 根据id获取学生信息
    public abstract Student findById(Integer id);

    //新增学生信息
    public abstract int insert(Student stu);

    //修改学生信息
    public abstract int update(Student stu);

    //删除学生信息
    public abstract int delete(Integer id);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.domain.Student;

import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class StudentDaoImpl implements StudentDao{
    /**
     * 查询所有学生
     * @return
     */
    @Override
    public ArrayList&amp;lt;Student&amp;gt; findAll() {
        ArrayList&amp;lt;Student&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        Connection connection = null;
        Statement statement = null;
        ResultSet rs  = null;
        try {
            Class.forName(&amp;#34;org.mariadb.jdbc.Driver&amp;#34;);

            connection = DriverManager.getConnection
                    (&amp;#34;jdbc:mariadb://192.168.0.100:3306/db14&amp;#34;, &amp;#34;root&amp;#34;, &amp;#34;rootPassword&amp;#34;);

            statement = connection.createStatement();

            String sql = &amp;#34;SELECT * FROM student&amp;#34;;

            rs = statement.executeQuery(sql);

            while (rs.next()){
                Integer sid = rs.getInt(&amp;#34;sid&amp;#34;);
                String name = rs.getString(&amp;#34;name&amp;#34;);
                Integer age = rs.getInt(&amp;#34;age&amp;#34;);
                Date birthday = rs.getDate(&amp;#34;birthday&amp;#34;);
                list.add(new Student(sid,name,age,birthday));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(connection != null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(statement != null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return list;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.service;

import com.lizicai.domain.Student;

import java.util.ArrayList;

public interface StudentService {
    // 查询所有学生信息
    public abstract ArrayList&amp;lt;Student&amp;gt; findAll();

    // 条件查询, 根据id获取学生信息
    public abstract Student findById(Integer id);

    //新增学生信息
    public abstract int insert(Student stu);

    //修改学生信息
    public abstract int update(Student stu);

    //删除学生信息
    public abstract int delete(Integer id);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.service;

import com.lizicai.dao.StudentDao;
import com.lizicai.dao.StudentDaoImpl;
import com.lizicai.domain.Student;

import java.util.ArrayList;

public class StudentServiceImpl implements StudentService{

    private StudentDao dao = new StudentDaoImpl();

    @Override
    public ArrayList&amp;lt;Student&amp;gt; findAll() {
        return dao.findAll();
    }

    @Override
    public Student findById(Integer id) {
        return dao.findById(id);
    }

    @Override
    public int insert(Student stu) {
        return dao.insert(stu);
    }

    @Override
    public int update(Student stu) {
        return dao.update(stu);
    }

    @Override
    public int delete(Integer id) {
        return dao.delete(id);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.controller;

import com.lizicai.domain.Student;
import com.lizicai.service.StudentService;
import com.lizicai.service.StudentServiceImpl;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Date;

public class StudentController {

    private StudentService service = new StudentServiceImpl();

    @Test
    public void findAll(){
        ArrayList&amp;lt;Student&amp;gt; list = service.findAll();
        for(Student stu:list){
            System.out.println(stu);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jdbc-工具类&#34;&gt;JDBC 工具类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;编写配置文件
&lt;ul&gt;
&lt;li&gt;在src目录下创建config.properties配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;driverClass=org.mariadb.jdbc.Driver
url=jdbc:mariadb://192.168.0.100:3306/db14
username=root
password=rootPassword
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;编写JDBC 工具类&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.utils;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * JDBC 工具类
 */
public class JDBCUtils {


    // 1. 私有构造方法
    private JDBCUtils(){}

    //    2. 声明所需要的配置变量
    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;
    private static Connection con;

    //    3. 提供静态代码块. 读取配置文件信息为变量赋值,注册驱动
    static {

        try {
            // 读取配置文件的信息为变量赋值
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream(&amp;#34;config.properties&amp;#34;);
            Properties properties = new Properties();
            properties.load(is);

            driverClass = properties.getProperty(&amp;#34;driverClass&amp;#34;);
            url = properties.getProperty(&amp;#34;url&amp;#34;);
            username = properties.getProperty(&amp;#34;username&amp;#34;);
            password = properties.getProperty(&amp;#34;password&amp;#34;);

            // 注册驱动
            Class.forName(driverClass);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    4. 提供获取数据库连接方法
    public static Connection getConnection(){
        try {
            con = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return con;
    }
//    5. 提供释放资源的方法

    public static void close(Connection con, Statement stat, ResultSet rs){
        if(con != null){
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stat != null){
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void close(Connection con, Statement stat){
        if(con != null){
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stat != null){
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.dao;

import com.lizicai.domain.Student;
import com.lizicai.utils.JDBCUtils;

import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class StudentDaoImpl2 implements StudentDao{
    /**
     * 查询所有学生
     * @return
     */
    @Override
    public ArrayList&amp;lt;Student&amp;gt; findAll() {
        ArrayList&amp;lt;Student&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        Connection con = null;
        Statement stat = null;
        ResultSet rs  = null;
        try {

            con = JDBCUtils.getConnection();

            stat = con.createStatement();

            String sql = &amp;#34;SELECT * FROM student&amp;#34;;

            rs = stat.executeQuery(sql);

            while (rs.next()){
                Integer sid = rs.getInt(&amp;#34;sid&amp;#34;);
                String name = rs.getString(&amp;#34;name&amp;#34;);
                Integer age = rs.getInt(&amp;#34;age&amp;#34;);
                Date birthday = rs.getDate(&amp;#34;birthday&amp;#34;);
                list.add(new Student(sid,name,age,birthday));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(con,stat,rs);
        }

        return list;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;student表的crud操作整合页面&#34;&gt;Student表的CRUD操作整合页面&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 数据准备
use db14;
CREATE TABLE USER(
    uid VARCHAR(50) PRIMARY KEY ,
    ucode VARCHAR(50),
    loginname VARCHAR(100),
    PASSWORD VARCHAR(100),
    username VARCHAR(100),
    gender VARCHAR(10),
    birthday DATE,
    dutydate DATE
);
INSERT INTO USER VALUES
(&amp;#39;11111111&amp;#39;,&amp;#39;zhangsan001&amp;#39;,&amp;#39;zhangsan&amp;#39;,&amp;#39;1234&amp;#39;,&amp;#39;张三&amp;#39;,&amp;#39;男&amp;#39;,&amp;#39;2008-10-28&amp;#39;,&amp;#39;2018-10-28&amp;#39;);
select * from USER;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;sql-注入攻击&#34;&gt;SQL 注入攻击&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;什么是SQL注入攻击
&lt;ul&gt;
&lt;li&gt;就是利用SQL语句的漏洞来对系统进行攻击&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SQL注入解决
&lt;ul&gt;
&lt;li&gt;PreparedStatement预编译执行者对象
&lt;ul&gt;
&lt;li&gt;在执行SQL语句前, 将SQL语句&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;PreparedStatement stat = null;
String sql = &amp;#34;SELECT * FROM USER WHERE loginname=? AND PASSWORD=?&amp;#34;;
stat = con.prepareStatement(sql);
stat.setString(1,user.getLoginname());
stat.setString(2,user.getPASSWORD());
rs = stat.executeQuery();
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jdbc-事务&#34;&gt;JDBC 事务&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JDBC 管理事务
&lt;ul&gt;
&lt;li&gt;管理事务的功能类:Connection
&lt;ul&gt;
&lt;li&gt;开启事务: setAutoCommit(boolean autoCommit); 参数为false, 则开启事务&lt;/li&gt;
&lt;li&gt;提交事务: commit();&lt;/li&gt;
&lt;li&gt;关闭事务: close();&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;事务的控制放在service层做, dao层只存放, 下为dao层&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Override
public void save(Connection con, User user) {
    PreparedStatement stat = null;
    ResultSet rs = null;

    String sql = &amp;#34;insert into USER values (?,?,?,?,?,?,?,?)&amp;#34;;
    java.sql.Date birthday = new java.sql.Date(user.getBirthday().getTime());
    java.sql.Date dutyday = new java.sql.Date(user.getDutyday().getTime());
    try {
        stat = con.prepareStatement(sql);
        stat.setString(1, user.getUid());
        stat.setString(2, user.getUcode());
        stat.setString(3, user.getLoginname());
        stat.setString(4, user.getPASSWORD());
        stat.setString(5, user.getUsername());
        stat.setString(6, user.getGender());
        stat.setDate(7, birthday);
        stat.setDate(8, dutyday);
        stat.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;int a = 1/0;模拟异常,去掉则可以正常存进来数据,service层&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Override
public void batchAdd(List&amp;lt;User&amp;gt; userList) {
    Connection con = JDBCUtils.getConnection();
    try{
        //开户事务
        con.setAutoCommit(false);
        for(User user : userList){
            //创建id, 并把uuid
            String uid = UUID.randomUUID().toString().replace(&amp;#34;-&amp;#34;,&amp;#34;&amp;#34;).toUpperCase(Locale.ROOT);
            user.setUid(uid);
            user.setUcode(uid);
            int a = 1/0;
            userDao.save(con, user);
        }
        // 提交事务
        con.commit();
    } catch (Exception e){
        // 回滚
        try {
            con.rollback();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        e.printStackTrace();
    } finally {
        JDBCUtils.close(con,null);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Test
public void batchAddTest()  {
    ArrayList&amp;lt;User&amp;gt; userList = new ArrayList&amp;lt;&amp;gt;();
    SimpleDateFormat sdf = new SimpleDateFormat(&amp;#34;yyyy-MM-dd&amp;#34;);
    try {
        userList.add(new User(null,null,&amp;#34;lisi&amp;#34;,
                    &amp;#34;123456&amp;#34;,&amp;#34;李四&amp;#34;,&amp;#34;男&amp;#34;,sdf.parse(&amp;#34;1992-02-04&amp;#34;),sdf.parse(&amp;#34;2000-10-09&amp;#34;)));
        userList.add(new User(null,null,&amp;#34;wangwu&amp;#34;,
                    &amp;#34;123456&amp;#34;,&amp;#34;王五&amp;#34;,&amp;#34;男&amp;#34;,sdf.parse(&amp;#34;1992-02-05&amp;#34;),sdf.parse(&amp;#34;2000-10-09&amp;#34;)));
        userList.add(new User(null,null,&amp;#34;zhaoliu&amp;#34;,
                    &amp;#34;123456&amp;#34;,&amp;#34;赵六&amp;#34;,&amp;#34;男&amp;#34;,sdf.parse(&amp;#34;1992-02-06&amp;#34;),sdf.parse(&amp;#34;2000-10-09&amp;#34;)));
        userService.batchAdd(userList);
    } catch (ParseException e) {
        e.printStackTrace();
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>MySQL数据库二 Li.059</title>
      <link>https://lizicai.com/p/mysql%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8C-li.059/</link>
      <pubDate>Wed, 20 Oct 2021 18:00:28 +0800</pubDate>
      <guid>https://lizicai.com/p/mysql%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8C-li.059/</guid>
      <description>&lt;h2 id=&#34;视图&#34;&gt;视图&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;视图介绍
&lt;ul&gt;
&lt;li&gt;视图：是一种虛拟存在的数据表，这个虚拟表并不在数据库中实际存在。&lt;/li&gt;
&lt;li&gt;作用：将一些较为复系的查询语句的结果，封装到-个虚拟表中，后期再有相同需求时，直接道询该虚拟表即可&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 准备数据
create database mydb5;
use mydb5;
create table country(
    id int primary key auto_increment,
    NAME varchar(30)
);
insert into country values (null,&amp;#39;中国&amp;#39;),(null,&amp;#39;美国&amp;#39;),(null,&amp;#39;俄罗斯&amp;#39;);
create table city(
    id int primary key auto_increment,
    NAME varchar(30),
    cid int,
    constraint cc_fk1 foreign key (cid) references country(id)
);
insert into city values (null,&amp;#39;北京&amp;#39;,1),(null,&amp;#39;上海&amp;#39;,1),(null,&amp;#39;纽约&amp;#39;,2),(null,&amp;#34;莫斯科&amp;#34;,3);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;视图的创建和查询&#34;&gt;视图的创建和查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;创建视图语法: create view 视图名称 [(列名列表)] as 查询语句;&lt;/li&gt;
&lt;li&gt;查询视图语法: select * from 视图名称;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## 创建视图
create view city_country (city_id,city_name,country_name) as
select c1.id,c1.NAME,c2.NAME
from city c1,
     country c2
where c1.cid = c2.id;
select * from city_country;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;修改视图数据语法: update 视图名称 set 列名=值 where 条件;
&lt;strong&gt;修改视图的数据,原表的数据也会修改&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## 修改视图数据
update city_country set city_name =&amp;#39;深圳&amp;#39; where city_name=&amp;#39;北京&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;修改视图结构语法: alter view 视图名称 (列名列表) as 查询语句;&lt;/li&gt;
&lt;li&gt;删除视图语法: drop view [if exists] 视图名称;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## 修改视图结构
alter view city_country (city_id,city_name,NAME) as
   select c1.id,c1.NAME,c2.NAME
from city c1,
     country c2
where c1.cid = c2.id;
## 删除视图
drop view if exists city_country;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;数据库备份和恢复&#34;&gt;数据库备份和恢复&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;备份-命令行方式
&lt;ul&gt;
&lt;li&gt;登录到MySQL服务器, mysqldump -uroot -p 数据库名称&amp;gt;文件保存路径(sql结尾文件)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;恢复
&lt;ul&gt;
&lt;li&gt;登录MySQL数据库&lt;/li&gt;
&lt;li&gt;删除已备份的数据库&lt;/li&gt;
&lt;li&gt;重新创建名称相同的数据库&lt;/li&gt;
&lt;li&gt;使用该数据库&lt;/li&gt;
&lt;li&gt;导入文件执行: source 备份文件全路径&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 备份-命令行操作
mysqldump -uroot -p backupdatabase &amp;gt; /root/backupdatabase.sql

# 恢复-命令行操作
mysqldump -uroot -p

show databases;
drop backupdatabase;
create database backupdatabase;
use backupdatabase;
source /root/backupdatabase.sql;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;备份-使用Datagrip
&lt;ul&gt;
&lt;li&gt;Export with &amp;lsquo;mysqldump&amp;rsquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;恢复
&lt;ul&gt;
&lt;li&gt;使用Datagrip&lt;/li&gt;
&lt;li&gt;删除已备份的数据库&lt;/li&gt;
&lt;li&gt;重新创建名称相同的数据库&lt;/li&gt;
&lt;li&gt;在数据库右键 Run SQL Script, 选择导出的文件.sql&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;存储过程和函数介绍&#34;&gt;存储过程和函数介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;存储过程和函数是事先经过编译并存储在数据库的一段SQL说一句的集合&lt;/li&gt;
&lt;li&gt;存储过程和函数的好处
&lt;ul&gt;
&lt;li&gt;提高代码的复用性&lt;/li&gt;
&lt;li&gt;减少数据在数据库和应用服务器之间的传输, 提高效率&lt;/li&gt;
&lt;li&gt;减少代码层面的业务处理&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;存储过程和函数的区别
&lt;ul&gt;
&lt;li&gt;存储函数必须有返回值&lt;/li&gt;
&lt;li&gt;存储过程可以没有返回值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;存储过程的创建和调用&#34;&gt;存储过程的创建和调用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;创建存储过程&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 修改结束分隔符
delimiter $

# 创建存储过程
create procedure 存储过程名称(参数列表)
BEGIN
    SQL语句列表;
END$

# 修改结束分隔符
DELIMITER ;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;调用存储过程
&lt;ul&gt;
&lt;li&gt;CALL 存储过程名称(实际参数);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## 存储过程数据准备
create database mydb6;
use mydb6;
create table student(
    id int primary key auto_increment,
    NAME varchar(20),
    age int,
    gender varchar(5),
    score  int
);
insert into student values
(null,&amp;#39;张三&amp;#39;,23,&amp;#39;男&amp;#39;,95),
(null,&amp;#39;李四&amp;#39;,24,&amp;#39;男&amp;#39;,98),
(null,&amp;#39;王五&amp;#39;,25,&amp;#39;女&amp;#39;,100),
(null,&amp;#39;赵六&amp;#39;,26,&amp;#39;女&amp;#39;,90);

# 按照性别进行分级, 查询每组学生的总成绩. 按钮总成绩的升序排序
select gender,SUM(score) as getSum from student group by gender order by getSum asc;

delimiter $
create procedure stu_group()
BEGIN
    select gender,SUM(score) as getSum from student group by gender order by getSum asc;
END $
delimiter ;

call stu_group();
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;存储过程的查看和删除&#34;&gt;存储过程的查看和删除&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;查看数据库中所有的存储过程
&lt;ul&gt;
&lt;li&gt;select * from mysql.proc where db=&amp;lsquo;数据库名称&amp;rsquo;;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;删除存储过程
&lt;ul&gt;
&lt;li&gt;drop procedure [if exists] 存储过程名称;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查看存储过程
select * from mysql.proc where db=&amp;#39;mydb6&amp;#39;;
# 删除存储过程
drop procedure if exists stu_group;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;存储过程语法---变量&#34;&gt;存储过程语法 - 变量&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;定义变量: declare 变量名 数据类型 [default 默认值];&lt;/li&gt;
&lt;li&gt;变量赋值方式一: set 变量名=变量值;&lt;/li&gt;
&lt;li&gt;变量赋值二: select 列名 into 变量名 from 表名 [where 条件];&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 按照性别进行分级, 查询每组学生的总成绩. 按钮总成绩的升序排序
select gender,SUM(score) as getSum from student group by gender order by getSum asc;

delimiter $
create procedure stu_group()
BEGIN
    select gender,SUM(score) as getSum from student group by gender order by getSum asc;
END $
delimiter ;

call stu_group();

# 查看存储过程
select * from mysql.proc where db=&amp;#39;mydb6&amp;#39;;
# 删除存储过程
drop procedure if exists stu_group;

delimiter $
create procedure pro_test1()
begin
    declare  num int default 10;
    select num;
end $
delimiter ;
call pro_test1();

delimiter $
create procedure pro_test2()
begin
    declare NAME varchar(10);
    set NAME=&amp;#39;存储过程&amp;#39;;
    select NAME;
end $
delimiter ;

call pro_test2();

delimiter $
create procedure pro_test3()
begin
    declare woman_sum_score,man_sum_score int;
    select sum(score) into woman_sum_score from student where gender=&amp;#39;女&amp;#39;;
    select sum(score) into man_sum_score from student where gender=&amp;#39;男&amp;#39;;
    select woman_sum_score,man_sum_score;
end $
delimiter ;

call pro_test3();
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;存储过程语法---if语句&#34;&gt;存储过程语法 - if语句&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;if语句&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;if 判断条件1 then 执行的SQL语句1;
    [elseif 判断条件2 then 执行的SQL语句2]
    ...
    [else 执行的SQL语句n]
end if;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 定义变量int 存储班级总成绩
# 定义vachar变量量, 用于存储分数描述
# 根据总成绩判断: 380分以上 学习优秀, 320~380 学习不错, 320以下 学习一般
delimiter $
create procedure pro_test4()
begin
    declare all_sum_score int;
    declare info varchar(30);
    select sum(score) into all_sum_score from student;
    if all_sum_score&amp;gt;380 then set info=&amp;#39;学习优秀&amp;#39;;
    elseif (all_sum_score&amp;lt;=380 &amp;amp;&amp;amp; all_sum_score &amp;gt;=320) then set info=&amp;#39;学习不错&amp;#39;;
    else set info=&amp;#39;学习一般&amp;#39;;
    end if;
    select all_sum_score,info;
end $
delimiter ;

call pro_test4();
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;存储过程语法---参数传递&#34;&gt;存储过程语法 - 参数传递&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;存储过程的参数和返回值&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;delimiter $
create procedure 存储过程名称 ([IN|OUT|INOUT] 参数名 数据类型)
begin
    SQL语句;
end$
delimiter ;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;参数
&lt;ul&gt;
&lt;li&gt;IN: 代表输入参数,需要由调用者传递实际数据(默认)&lt;/li&gt;
&lt;li&gt;OUT: 代表输入参数, 该参数可以作为返回值&lt;/li&gt;
&lt;li&gt;INOUT: 代表既可以作为输入参数, 也可以作为输入参数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;delimiter $
create procedure pro_test5(IN all_sum_score int,OUT info varchar(30))
begin
    if all_sum_score&amp;gt;380 then set info=&amp;#39;学习优秀&amp;#39;;
    elseif (all_sum_score&amp;lt;=380 &amp;amp;&amp;amp; all_sum_score &amp;gt;=320) then set info=&amp;#39;学习不错&amp;#39;;
    else set info=&amp;#39;学习一般&amp;#39;;
    end if;
end $
delimiter ;

call pro_test5(320,@info);
call pro_test5((select sum(score) from student),@info);
select @info;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;存储过程语法---while循环&#34;&gt;存储过程语法 - while循环&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;while循环语法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;初始化语句;
while 条件判断语句 do
    循环体语句;
    条件控制语句;
end while;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;delimiter $
create procedure pro_test6()
begin
    declare result int default 0;
    declare i int default 1 ;
    while i &amp;lt; 101 do
        if i%2=0 then
       set result = result + i;
       end if;
        set i = i + 1;
    end while;
    select result;
end $
delimiter ;
call pro_test6;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;存储函数&#34;&gt;存储函数&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;存储函数和存储过程是非常相似的, 区别在于存储函数必须有返回值&lt;/li&gt;
&lt;li&gt;创建存储函数&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;delimiter $
create function 函数名称(参数列表)
returns 返回值类型
begin
    SQL语句列表;
    RETURN结果;
end$
delimiter ;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;调用存储函数
&lt;ul&gt;
&lt;li&gt;select 函数名称(实际参数);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;删除存储函数
&lt;ul&gt;
&lt;li&gt;drop function 函数名称;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;delimiter $
create function fun_test1()
RETURNS int
begin
    declare num int;
    select count(*) into num from student where score&amp;gt;95;
    return num;
end $
delimiter ;

select fun_test1();

drop function fun_test1;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;mysql-触发器&#34;&gt;MySQL 触发器&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;触发器是与表有关的数据库对象, 可以在insert,update,delete之前或之后触发并执行触发器中定义的SQL语句.&lt;/li&gt;
&lt;li&gt;这种特性可以协助应用系统在数据库端确保数据的完整性,日志记录,数据校验等操作.&lt;/li&gt;
&lt;li&gt;使用别名NEW和OLD来引用触发器中发生变化的内容记录&lt;/li&gt;
&lt;li&gt;触发器分类&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;触发器类型     OLD                           NEW
INSERT型触发器 无(插入前无数据)              NEW表示将要或者已经新增的数据
UPDATE型触发器 OLD表示修改之前的数据         NEW表示将要或已经修改后的数据
DELETE型触发器 OLD表示将要或者已经删除的数据 无(删除删除后状态无数据)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;触发器的操作&#34;&gt;触发器的操作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;创建触发器&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;delimiter $
create trigger 触发器名称
before|after insert|update|delete
on 表名
fro each row
begin
    触发器要执行的功能;
end $
delimiter ;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 数据准备
create database mydb7;
use mydb7;

create table account(
    id int primary key auto_increment,
    NAME varchar(20),
    money double
);
insert into account values (null,&amp;#39;张三&amp;#39;,1000),(null,&amp;#39;李四&amp;#39;,1000);
create table account_log(
    id int primary key auto_increment,
    operation varchar(20),
    operation_time datetime,
    operation_id int,
    operation_params varchar(200)
);

# 插入触发器
delimiter $
create trigger account_insert
    after INSERT
    on account
    for each row
    begin
        insert into account_log values (null,&amp;#39;INSERT&amp;#39;,now(),new.id,
                                        CONCAT(&amp;#39;插入后{id=&amp;#39;,new.id,&amp;#39;,name=&amp;#39;,new.NAME,&amp;#39;,money=&amp;#39;,new.money,&amp;#39;}&amp;#39;));
    end $
delimiter ;
insert into account values (null,&amp;#39;王五&amp;#39;,2000);
select * from account;
select * from account_log;

# 更新触发器
delimiter $
create trigger account_update
    after UPDATE
    on account
    for each row
    begin
        insert into account_log values (null,&amp;#39;UPDATE&amp;#39;,now(),new.id,
                                        CONCAT(&amp;#39;更新前{id=&amp;#39;,old.id,&amp;#39;,name=&amp;#39;,old.NAME,&amp;#39;,money=&amp;#39;,old.money,&amp;#39;}&amp;#39;,
                                            &amp;#39;更新后{id=&amp;#39;,new.id,&amp;#39;,name=&amp;#39;,new.NAME,&amp;#39;,money=&amp;#39;,new.money,&amp;#39;}&amp;#39;));
    end $
delimiter ;
select * from account;
update account set money=2000 where id=2;
select * from account_log;

# 删除触发器
delimiter $
create trigger account_delete
    after DELETE
    on account
    for each row
    begin
        insert into account_log values (null,&amp;#39;DELETE&amp;#39;,now(),old.id,
                                        CONCAT(&amp;#39;删除前{id=&amp;#39;,old.id,&amp;#39;,name=&amp;#39;,old.NAME,&amp;#39;,money=&amp;#39;,old.money,&amp;#39;}&amp;#39;));
    end $
delimiter ;
select * from account;
delete from account where id=3;
select * from account_log;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;触发器的操作-1&#34;&gt;触发器的操作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;查看触发器: show triggers;&lt;/li&gt;
&lt;li&gt;删除触发器: drop trigger 触发器名称;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查看触发器
show triggers ;
# 删除触发器
drop trigger account_delete;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;mysql-事务&#34;&gt;MySQL 事务&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;事务: 一条或多条SQL语句组成一个执行单元, 其特点是这个单元要么同时成功要么同时失败&lt;/li&gt;
&lt;li&gt;单元中的每条SQL语句都相互依赖, 形成一个整体&lt;/li&gt;
&lt;li&gt;如果某条SQL语句执行失败或者出现错误, 那么整个单元就会撤回到事务最初的状态.&lt;/li&gt;
&lt;li&gt;如果单元中所有的SQL语句都执行成功, 则事务就顺利执行.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;事务的操作&#34;&gt;事务的操作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;开启事务: start transaction;&lt;/li&gt;
&lt;li&gt;回滚事务: rollback;&lt;/li&gt;
&lt;li&gt;提交事务: commit;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 准备数据
create database db8;
use db8;
create table account(
    id int primary key auto_increment,
    NAME varchar(20),
    money double
);
insert into account values (null,&amp;#39;张三&amp;#39;,1000),(null,&amp;#39;李四&amp;#39;,1000);
select * from account;


# 开启事务
start transaction ;
update account set money=money-500 where NAME=&amp;#39;张三&amp;#39;;
update account set money=money+500 where NAME=&amp;#39;李四&amp;#39;;
# 回滚事务
rollback ;
# 提交事务
commit ;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;事务的提交方式&#34;&gt;事务的提交方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;事务提交方式的分类
&lt;ul&gt;
&lt;li&gt;自动提交(MySQL默认)&lt;/li&gt;
&lt;li&gt;手动提交&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;查看事务提交方式
&lt;ul&gt;
&lt;li&gt;select @@autocommit;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;修改事务提交方式
&lt;ul&gt;
&lt;li&gt;set @@autocommit=数字;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询事务的提交方式
select @@autocommit;
# 修改事务的提交方式
# 默认是1, 不可修改
set @@autocommit=0;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;事务的四大特征&#34;&gt;事务的四大特征&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;原子性(Atomicity)
&lt;ul&gt;
&lt;li&gt;原子性是指事务包含的所有操作要么全部成功 ，要么全部失败回滚。&lt;/li&gt;
&lt;li&gt;因此事务的操作如果成功就必须要完全应用到数据库，如果操作失败则不能对数据库有任何影响。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;一致性(Consistency)
&lt;ul&gt;
&lt;li&gt;一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态。&lt;/li&gt;
&lt;li&gt;也就是说一个事务执行之前和执行之后都必须处于一致性状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;隔离性(isolcation)
&lt;ul&gt;
&lt;li&gt;隔离性是当多个用户并发访问数据库时，比如操作同一张表时，数据库为每一个用户开启的事务。&lt;/li&gt;
&lt;li&gt;不能被其他事务的操作所千扰，多个并发事务之问要相互隔离。卜&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;持久性(durability)
&lt;ul&gt;
&lt;li&gt;持久性是指 一个事务一旦被提交了，那么对数据库中的数据的改变就是永久性的。&lt;/li&gt;
&lt;li&gt;即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;事务的隔离级别&#34;&gt;事务的隔离级别&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;事务的隔离级别
&lt;ul&gt;
&lt;li&gt;多个客户端操作时，各个客户端的事务之间应该是隔离的，相互独立的，不受影响的。&lt;/li&gt;
&lt;li&gt;而如果多个事务操作同一批数据时，就会产生不同的问题，我们需要设置不同的隔离级别来解决这些问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;隔离级别分类&lt;/th&gt;
          &lt;th&gt;隔离级别&lt;/th&gt;
          &lt;th&gt;会引发的问题&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;read uncommitted&lt;/td&gt;
          &lt;td&gt;读末提交&lt;/td&gt;
          &lt;td&gt;脏读、不可重复读、幻读&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;read committed&lt;/td&gt;
          &lt;td&gt;读已提交&lt;/td&gt;
          &lt;td&gt;不可重复读、幻读&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;repeatable read&lt;/td&gt;
          &lt;td&gt;可重复读&lt;/td&gt;
          &lt;td&gt;幻读&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;serializable&lt;/td&gt;
          &lt;td&gt;串行化&lt;/td&gt;
          &lt;td&gt;无&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;引发的问题&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;问题&lt;/th&gt;
          &lt;th&gt;现象&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;脏读&lt;/td&gt;
          &lt;td&gt;在一个事务处理过程中读取到了另一个未提交事务中的数据,导致2次查询结果不一致&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;不可重复读&lt;/td&gt;
          &lt;td&gt;在一个事务处理过程中读取到了另一个事务中修改并已提交的数据,导致2次查询结果不一对我&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;幻读&lt;/td&gt;
          &lt;td&gt;查询某数据不存在,准备插入此记录,但执行插入时发现此记录已存在,无法插入.或查询数据不存在执行删除操作,却发现删除成功&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;事务的隔离级别-1&#34;&gt;事务的隔离级别&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;查询数据库隔离级别
&lt;ul&gt;
&lt;li&gt;select @@tx_isolation;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;修改数据库隔离级别(需要重新连接)
&lt;ul&gt;
&lt;li&gt;set global transaction isolation level 级别字符串;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询事务隔离级别
select @@tx_isolation;
# 修改事务隔离级别(修改后需要重新连接)
set global transaction isolation level read committed ;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;隔离级别问题演示
&lt;ul&gt;
&lt;li&gt;脏读问题演示&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;set global transaction isolation level read uncommitted ;
start transaction ;
update account set money=money-500 where NAME=&amp;#39;张三&amp;#39;;
update account set money=money+500 where NAME=&amp;#39;李四&amp;#39;;
# 提交事务
select * from account;
rollback ;

# 同时开启, 在上一用户transaction执行期间查询, 把transcation未commit的数据读取出来了.
start transaction ;
select * from account;
COMMIT;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;解决脏读设置为: set global transaction isolation level read committed ;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不可重复读问题演示和解决
&lt;ul&gt;
&lt;li&gt;不可重复读: 一个事务中读取到其他事务已提交的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;set global transaction isolation level read committed;
start transaction ;
update account set money=money-500 where NAME=&amp;#39;张三&amp;#39;;
update account set money=money+500 where NAME=&amp;#39;李四&amp;#39;;
# 提交事务
select * from account;
COMMIT;

# 同时开启, 在上一用户transaction执行期间查询, 把transcation未commit的数据读取出来了.
# 第2次读, 前面commit;完成后读, 数据变化了.
start transaction ;
select * from account;
COMMIT;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;解决不可重复读解决: set global transaction isolation level repeatable read ; 在事务2中读多次,还是事务1提交前的数据.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;幻读的问题演示
&lt;ul&gt;
&lt;li&gt;查询某记录是否存在, 不存在&lt;/li&gt;
&lt;li&gt;准备插入此记录, 但执行插入时发现此记录&lt;/li&gt;
&lt;li&gt;或某记录不存在执行删除, 却发现删除成功&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;start transaction ;
insert into account values (3,&amp;#39;王五&amp;#39;,2000);
select * from account;
commit ;

# 同时事务, 插入操作, 事务2执行失败
start transaction ;

select * from account;
insert into account values (3,&amp;#39;王五&amp;#39;,2000);
COMMIT;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;解决幻读: set global transaction isolation level serializable;&lt;/p&gt;
&lt;h2 id=&#34;事务的隔离级别-2&#34;&gt;事务的隔离级别&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;序号&lt;/th&gt;
          &lt;th&gt;隔离级别&lt;/th&gt;
          &lt;th&gt;名称&lt;/th&gt;
          &lt;th&gt;脏读&lt;/th&gt;
          &lt;th&gt;不可重复读&lt;/th&gt;
          &lt;th&gt;幻读&lt;/th&gt;
          &lt;th&gt;数据库默认隔离级别&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;1&lt;/td&gt;
          &lt;td&gt;read uncommitted&lt;/td&gt;
          &lt;td&gt;读未提交&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2&lt;/td&gt;
          &lt;td&gt;read committed&lt;/td&gt;
          &lt;td&gt;读已提交&lt;/td&gt;
          &lt;td&gt;否&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;Oracle&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;3&lt;/td&gt;
          &lt;td&gt;repeatable read&lt;/td&gt;
          &lt;td&gt;可重复读&lt;/td&gt;
          &lt;td&gt;否&lt;/td&gt;
          &lt;td&gt;否&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;MySQL&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;4&lt;/td&gt;
          &lt;td&gt;serializable&lt;/td&gt;
          &lt;td&gt;串行化&lt;/td&gt;
          &lt;td&gt;否&lt;/td&gt;
          &lt;td&gt;否&lt;/td&gt;
          &lt;td&gt;否&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;隔离级别从小到大安全性越来越高, 但是效率越来越低, 不建议修改数据库默认的隔离级别&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;mysql-体系结构-存储引擎&#34;&gt;MySQL 体系结构-存储引擎&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;客户端连接
&lt;ul&gt;
&lt;li&gt;支持接口：支持的客户端连接，例如 C、Java、PHP等语言来连接MySQL数据库。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第一层：网络连接层
&lt;ul&gt;
&lt;li&gt;连接池：管理、缓冲用户的连接，线程处理等需要缓存的需求。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第二层：核心服务层
&lt;ul&gt;
&lt;li&gt;管理服务和工具：系统的管理和控制工具，例如备份恢复、 复制、集群等。&lt;/li&gt;
&lt;li&gt;SQL 接口：接受 SQL 命令，并且返回查询结果。&lt;/li&gt;
&lt;li&gt;查询解析器：验证和解析 SQL 命令，例如过滤条件、语法结构等。&lt;/li&gt;
&lt;li&gt;查询优化器：在执行查询之前，使用默认的一套优化机制进行优化sql语句。&lt;/li&gt;
&lt;li&gt;缓存：如果缓存当中有想查询的数据，则直接将缓存中的数据返回。没有的话再重新查询。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第三层：存储 擎层
&lt;ul&gt;
&lt;li&gt;插件式存储引(擎：管理和操作数据的一种机制 ，包括(存储数据、如何更新、查询数据等&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第四层：系统文件层
&lt;ul&gt;
&lt;li&gt;文件系统：配置文件、数据文件、日志文件、 错误文件、二进制文件等等的保存。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;存储引擎介绍&#34;&gt;存储引擎介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MysQL 数据库使用不同的机制存取表文件，包括存储方式、索引技巧、 锁定水平等不同的功能。这些不同的技术以及配套的 功能称为存储引擎。&lt;/li&gt;
&lt;li&gt;Oracle、SalServer 等数据库只有一种存储引擎。而MySQL针对不同的需求,配置不同的存储引1擎,就会让数据库采取不同处 理数据的方式和扩展功能。&lt;/li&gt;
&lt;li&gt;MysQL 支持的存储引l擎有很多，常用的有三种：InnoDB、 MyISAM、MEMORY。&lt;/li&gt;
&lt;li&gt;特性对比
&lt;ul&gt;
&lt;li&gt;MyISAM 存储引擎：访问快，不支持事务和外键操作。&lt;/li&gt;
&lt;li&gt;InnoDB 存储引擎：支持事务和外键操作，支持并发控制，占用磁盘空间大。(MySQL5.5版本后默认&lt;/li&gt;
&lt;li&gt;MEMORY 存储引!擎：内存存储，速度快，不安全。适合小量快速访问的数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;特性&lt;/th&gt;
          &lt;th&gt;MyISAM&lt;/th&gt;
          &lt;th&gt;InnoDB&lt;/th&gt;
          &lt;th&gt;MEMORY&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;存储限制&lt;/td&gt;
          &lt;td&gt;有(平台对文件系统大小的限制)&lt;/td&gt;
          &lt;td&gt;64TB&lt;/td&gt;
          &lt;td&gt;有(平台的内存限制)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;事务安全&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;不支持&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;不支持&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;锁机制&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;表锁&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;表锁/行锁&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;表锁&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;B+Tree索引&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;哈希索引&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;全文索引&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;集群索引&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;数据索引&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;数据缓存&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;索引缓存&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;数据可压缩&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;空间使用&lt;/td&gt;
          &lt;td&gt;低&lt;/td&gt;
          &lt;td&gt;高&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;内存使用&lt;/td&gt;
          &lt;td&gt;低&lt;/td&gt;
          &lt;td&gt;高&lt;/td&gt;
          &lt;td&gt;中等&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;批量插入速度&lt;/td&gt;
          &lt;td&gt;高&lt;/td&gt;
          &lt;td&gt;低&lt;/td&gt;
          &lt;td&gt;高&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;外键&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
          &lt;td&gt;支持&lt;/td&gt;
          &lt;td&gt;不支持&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;存储引擎的操作&#34;&gt;存储引擎的操作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;查询数据库支持的存储引擎: show engines;&lt;/li&gt;
&lt;li&gt;查询某个数据库中的所有数据表的存储引擎: show table status from 数据库名称;&lt;/li&gt;
&lt;li&gt;查询某个数据库中某个数据表的存储引擎: show table status from 数据库名称 where name=&amp;lsquo;数据表名称&amp;rsquo;;&lt;/li&gt;
&lt;li&gt;创建数据表,指定存储引擎&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table 表名(
    列名, 数据类型,
    ...
)ENGINE = 引擎名称;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;修改数据表的存储引擎: alter table 表名 ENGINE=引擎名称;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询数据库支持的存储引擎:
show engines;
# 查询某个数据库中的所有数据表的存储引擎:
show table status from mydb4;
# 查询某个数据库中某个数据表的存储引擎:
show table status from mydb4 where name=&amp;#39;USER&amp;#39;;
# 创建数据表,指定存储引擎
use db8;
create table test_engine(
    id int
)engine = MyISAM;
show table status from db8;
# 修改数据表的存储引擎
alter table test_engine engine = INNODB;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;存储引擎的选择&#34;&gt;存储引擎的选择&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MyISAM
&lt;ul&gt;
&lt;li&gt;特点: 不支持事务和外键. 读取速度快, 节约资源&lt;/li&gt;
&lt;li&gt;使用场景: 以查询操作为主, 只有很少的更新和删除操作, 并且对事务的完整性,并发性要求不是很高&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;InnoDB
&lt;ul&gt;
&lt;li&gt;特点: MySQL的默认存储引擎&lt;/li&gt;
&lt;li&gt;使用场景: 对事务的完整性有比较高的要求, 在并发条件下要求数据的一致性, 读写频繁的操作&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MEMORY
&lt;ul&gt;
&lt;li&gt;特点: 将所有数据保存在内存中, 在需要快速定位记录和其他类似数据环境下, 可以提供更快的访问.&lt;/li&gt;
&lt;li&gt;使用场景: 通常用于更新不太频繁的小表, 用来快速得到访问的结果&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;如果不确定,则使用数据库默认的存储引擎&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;mysql-的索引&#34;&gt;MySQL 的索引&lt;/h2&gt;
&lt;h3 id=&#34;索引介绍&#34;&gt;索引介绍&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;MySQL索引: 是帮助MySQL高效获取数据的一种数据结构. 所以, 索引的本质就是数据结构&lt;/li&gt;
&lt;li&gt;在表数据之外, 数据库系统还维护着满足特写查找算法的数据结构, 这些数据结构以某种方式指向数据, 这样就可以在这些数据结构上实现高级查找算法, 这种数据结构就是索引&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;索引的操作&#34;&gt;索引的操作&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;按照功能分类
&lt;ul&gt;
&lt;li&gt;普通索引：最基本的索引，没有任何限制。&lt;/li&gt;
&lt;li&gt;唯一索引：索引列的值必须唯—，但允许有空值。如果是组合素引，则列值组合必须唯一&lt;/li&gt;
&lt;li&gt;主键索引：一种特殊的唯一索引，不允许有空值。在建表时有主键列同时创建主键奈引。&lt;/li&gt;
&lt;li&gt;联合素引：顾名思义，就是将单列索引进行组合。&lt;/li&gt;
&lt;li&gt;外键索引：只有InnoDB 引李支持外键索引，用来保证数据的一致性、完整性和实现级联操作。&lt;/li&gt;
&lt;li&gt;全文素引：快速匹配全部文档的方式。InnoDB引擎 5.6版本后才支持全文素引。MEMORY 引擎不支持。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;按照结构分类
&lt;ul&gt;
&lt;li&gt;BTree 索引：MySQL使用最频繁的一个素引（数据结构，是lInnoDB 和 MyISAM 存储引草默认的索号类型， 底层基于 B+Tree 数据结构。&lt;/li&gt;
&lt;li&gt;Hash 奈引：MySQL 中 Memory 存储引擎默认支持的奈引类型。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;创建索引&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 无索引名称,则是默认BTree
create [unique|fulltext] index 索引名称 [using 索引类型]
on 表名(列名...);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;查看索引: show index from 表名;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 数据准备
create database db9;
use db9;
create table student(
    id int primary key auto_increment,
    NAME varchar(20),
    age int,
    score int
);
insert into student values
(null,&amp;#39;张三&amp;#39;,23,98),
(null,&amp;#39;李四&amp;#39;,24,95),
(null,&amp;#39;王五&amp;#39;,25,96),
(null,&amp;#39;赵六&amp;#39;,26,94),
(null,&amp;#39;周七&amp;#39;,27,99);
select * from student;

# 为student表的name列创建一个普通索引
create index idx_name on student(NAME);
# 为student表的age列创建一个唯一索引
create unique index idx_age on student(age);
# 查询student索引 (主键列自带主键索引)
show index from student;
# 查询mydb4数据库的product表(外键列自带外键索引)
show index from mydb4.product;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;添加索引&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加索引&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;普通索引：ALTER TABLE 表名 ADD INDEX索引名称（列名);&lt;/li&gt;
&lt;li&gt;组合索引：ALTER TABLE 表名 ADD INDEX索引名称(列名1,列名2….);&lt;/li&gt;
&lt;li&gt;主键索引：ALTER TABLE 表名 ADD PRIMARY KEY(主键列名);&lt;/li&gt;
&lt;li&gt;外键索引：ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY （本表外键列名)REFERENCES 主表名(主键列名);&lt;/li&gt;
&lt;li&gt;唯一索引：ALTER TABLE 表名 ADD UNIQUE 索引名称(列名);&lt;/li&gt;
&lt;li&gt;全文索引：ALTER TABLE 表名 ADD FULLTEXT 索引名称(列名);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;删除索引&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;drop index 索引名 on 表名;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 添加index
alter table student add unique idx_score(score);
# 删除index
alter table student drop index idx_name1;
drop index idx_name1 on student;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;索引的原理&#34;&gt;索引的原理&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;BTree数据结构
&lt;ul&gt;
&lt;li&gt;每个节点中不仅包含key值,还有数据. 会增加查询数据时磁盘的IO次数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;B+Tree数据红塔区
&lt;ul&gt;
&lt;li&gt;非叶子节点只存储key值&lt;/li&gt;
&lt;li&gt;所有数据存储在叶子节点&lt;/li&gt;
&lt;li&gt;所有叶子节点之间都有连接指针&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;B+Tree好处
&lt;ul&gt;
&lt;li&gt;提高查询速度&lt;/li&gt;
&lt;li&gt;减少磁盘的IO次数&lt;/li&gt;
&lt;li&gt;树形结构较小&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;索引的设计原则&#34;&gt;索引的设计原则&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;创建索引遵循的原则&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对查询频次较高, 且数据量比较大的表建立索引&lt;/li&gt;
&lt;li&gt;使用唯一索引,区分度越高,使用索引的效率越高&lt;/li&gt;
&lt;li&gt;索引字段的选择,最佳做眉毛列应当从where子句的条件中提取&lt;/li&gt;
&lt;li&gt;索引虽然可以有效的提升查询数据的效率, 也并不是多多益善&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;最左匹配原则(适合组合索引)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例如: 为user中的name,address,phone列添加组合索引&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;alter table user add index idx_three(name,address,phone);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;此时,组合索引idx_three实际建立了(name),(name,address),(name,address,phone)三个索引&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下面的三个SQL语句都可以命中索引&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * from user where address=&amp;#39;北京&amp;#39; and phone=&amp;#39;12345&amp;#39; and name=&amp;#39;张三&amp;#39;;
select * from user where name=&amp;#39;张三&amp;#39; and address=&amp;#39;北京&amp;#39;;
select * from user where name=&amp;#39;张三&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;这三条SQL语句在检索时分别会使用以下索引进行数据匹配&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(name,address,phone)&lt;/li&gt;
&lt;li&gt;(name,address)&lt;/li&gt;
&lt;li&gt;(name)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;索引字段出现的顺序可以是任意的, MySQL优化器会帮我们自动的调整where条件中的顺序&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果组合索引中最左边的列不在查询条件中, 则不会命中索引&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;select * from user where address=&amp;lsquo;北京&amp;rsquo;;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;mysql-锁机制&#34;&gt;MySQL 锁机制&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;锁机制: 数据库为了保证数据的一致性, 在共享的资源被管他访问时变得案例所设计的一种规则&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;锁机制类似多线程的同步, 作用可以保证数据的一致性和案例性&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;按操作分类&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;共享锁: 也叫读锁. 针对同一份数据, 多个事务读取操作可以同时加锁而互相不影响, 但是不能修改数据&lt;/li&gt;
&lt;li&gt;揍他锁: 也叫写锁. 当前的操作没有完成前, 会阻断其他操作的读取和写入.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;按粒度分类&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;表级锁: 会锁定整个表. 开销小, 加锁快. 锁定力度大, 发生锁冲突概率高, 并发低. 不会出现死锁情况.&lt;/li&gt;
&lt;li&gt;行级锁: 会锁定当前行. 开销大, 加锁慢. 锁定粒度小, 发生锁冲突概率低, 并发度高. 会出现死锁情况.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;按使用方式分类&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;悲观锁: 第次查询数据时都认为别人会修改, 很悲观, 所有查询时加锁&lt;/li&gt;
&lt;li&gt;乐观锁: 第次查询数据时都认为别人不会修改, 很乐观, 但是更新时会判断一下在此期间别人有没有去更新这个数据.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不同存储引擎支持的锁&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;存储引擎&lt;/th&gt;
          &lt;th&gt;表锁&lt;/th&gt;
          &lt;th&gt;行锁&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;InnoDB&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;MyISAM&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;MEMORY&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;innodb-共享锁&#34;&gt;InnoDB 共享锁&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;共享锁特点
&lt;ul&gt;
&lt;li&gt;数据可以被多个事务查询, 但是不能修改&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;创建共享锁格式
&lt;ul&gt;
&lt;li&gt;select 语句 lock in share mode;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:red;&#34;&gt;InnoDB带索引的列是行锁&lt;/a&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;start transaction ;
select * from student where id = 1 lock in share mode ;
commit ;

# 同时开启事务, 更新这行数据
start transaction ;
update student set NAME=&amp;#39;张三三&amp;#39; where id =1;
update student set NAME=&amp;#39;李四四&amp;#39; where id =2;
commit;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:red;&#34;&gt;InnoDB非索引列,加的就表锁&lt;/a&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;start transaction ;
select * from student where score=98 lock in share mode ;
commit ;

# 同时开启事务, 更新这行数据
start transaction ;
update student set NAME=&amp;#39;王五五&amp;#39; where id =3;
commit;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;innodb-排他锁&#34;&gt;InnoDB 排他锁&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;揍他锁特点
&lt;ul&gt;
&lt;li&gt;加锁的数据, 不能被其他事务加锁查询或修改&lt;/li&gt;
&lt;li&gt;普通查询则可以&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;创建排他锁格式
&lt;ul&gt;
&lt;li&gt;select语句 for update;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;start transaction ;
select * from student where id=1 for update;
commit ;

# 同时开启事务
start transaction;
# 普通查询没有问题
select * from student where id=1 ;
# 查询id为1的数据, 并加入共享锁, 不能
select * from student where id=1 lock in share mode ;
# 查询id为1的数据, 并加入排他锁, 不能
select * from student where id=1 for update;
# 修改数据也是, 不能
update student set NAME=&amp;#39;张三&amp;#39; where id=1;
commit;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;myisam-读锁&#34;&gt;MyISAM 读锁&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;读锁特点
&lt;ul&gt;
&lt;li&gt;所有的连接只能查询数据,不能修改&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;读锁语法格式
&lt;ul&gt;
&lt;li&gt;加锁: lock table 表名 read;&lt;/li&gt;
&lt;li&gt;解锁: unlocak tables;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 准备数据
create table product(
    id int primary key auto_increment,
    NAME varchar(20),
    price int
) engine = MYISAM;
insert into product values
(null,&amp;#39;华为手机&amp;#39;,4999),
(null,&amp;#39;苹果&amp;#39;,8999),
(null,&amp;#39;中兴&amp;#39;,1999);
select * from product;
show table status from db10 where name=&amp;#39;product&amp;#39;;

# 窗口1, 增加读锁
lock tables product read;
select * from product;
unlock tables ;


# 窗口2, 可查询
select * from product;
# 不可修改, 只有窗口1解锁后才能修改
update product set price=5999 where id=1;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;myisam-写锁&#34;&gt;MyISAM 写锁&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;写锁特点
&lt;ul&gt;
&lt;li&gt;其他连接不能查询和修改数据&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;写锁语法格式
&lt;ul&gt;
&lt;li&gt;加锁: lock table 表名 write;&lt;/li&gt;
&lt;li&gt;解锁: unlocak tables;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 窗口1, 增加写锁
lock tables product write ;
# 可在窗口1查询
select * from product;
# 可在窗口1更新
update product set price=5999 where id=1;
unlock tables ;

# 窗口2, 不可查询, 只有窗口1解锁才能查询
select * from product;
# 不可修改, 只有窗口1解锁后才能修改
update product set price=4999 where id=1;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;悲观锁和乐观锁&#34;&gt;悲观锁和乐观锁&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;悲观锁
&lt;ul&gt;
&lt;li&gt;就是很悲观, 它对于数据被外界修改的操作持保守感谢感谢, 认为数据随时会修改&lt;/li&gt;
&lt;li&gt;整个数据处理中需要将数据加锁. 悲观锁一般都是依靠关系型数据库提供的锁机制&lt;/li&gt;
&lt;li&gt;之前所学的锁机制都是悲观锁&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;乐观锁
&lt;ul&gt;
&lt;li&gt;就是很乐观, 第次自己操作数据的时候认为没有人会来修改它, 所有不去加锁&lt;/li&gt;
&lt;li&gt;但是在更新的时候会去判断在此期间数据有没有被修改&lt;/li&gt;
&lt;li&gt;需要用户自己去实现, 不会发生并发抢占资源, 只有在提交操作的时候检查是否违反数据完整性.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;乐观锁的解决方式&#34;&gt;乐观锁的解决方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;方式一&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;给数据表中添加一个version 列，每次更新后都将这个列的值加1.&lt;/li&gt;
&lt;li&gt;读取数据时，将版本号读取出来，在执行更新的时候，比较版本号。&lt;/li&gt;
&lt;li&gt;如果相同则执行更新，如果不相同 ，说明此条数据已经发生了变化。&lt;/li&gt;
&lt;li&gt;用户自行根据这个通知来决定怎么处理，比如重新开始一遍，或者放弃本次更新。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;方式二&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;和版本号方式基本一样，给数据表中添加一个列，名称无所谓，数据类型需要是timestamp。&lt;/li&gt;
&lt;li&gt;每次更新后都将最新时间插入到此列。&lt;/li&gt;
&lt;li&gt;读取数据时 ，将时问读取出来，在执行更新的时候，比较时间。&lt;/li&gt;
&lt;li&gt;如果相同则执行更新，如果不相同 ，说明此条数据已经发生了变化。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 准备数据
create table city(
    id int primary key auto_increment,
    NAME varchar(20),
    VERSION int
);
insert into city values
(null,&amp;#39;北京&amp;#39;,1),
(null,&amp;#39;上海&amp;#39;,1),
(null,&amp;#39;广州&amp;#39;,1),
(null,&amp;#39;深圳&amp;#39;,1) ;
select * from city;

select VERSION from city where NAME=&amp;#39;北京&amp;#39;;
update city set NAME=&amp;#39;北京市&amp;#39;,VERSION=VERSION+1 where NAME=&amp;#39;北京&amp;#39; and VERSION=1;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>MySQL数据库一 Li.058</title>
      <link>https://lizicai.com/p/mysql%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%80-li.058/</link>
      <pubDate>Thu, 14 Oct 2021 20:54:38 +0800</pubDate>
      <guid>https://lizicai.com/p/mysql%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%80-li.058/</guid>
      <description>&lt;h2 id=&#34;数据库安装和设置utf-8&#34;&gt;数据库安装和设置UTF-8&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/%e5%ae%89%e8%a3%85mariadb%e5%92%8c%e8%ae%be%e7%bd%aeutf-8mb4%e5%ad%97%e7%ac%a6%e9%9b%86li.011/&#34; target=&#34;_blank&#34;&gt;数据库安装和设置UTF-8&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;sql-介绍&#34;&gt;SQL 介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SQL (Structured Query Language): 结构化查询语文. 其实就是定义了操作所有关系型数据库的一种规则&lt;/li&gt;
&lt;li&gt;通用语法规则
&lt;ul&gt;
&lt;li&gt;SQL 语句可以单选或多行书写, 以分号结尾&lt;/li&gt;
&lt;li&gt;可使用空格和缩进来增强语句的可读性&lt;/li&gt;
&lt;li&gt;MySQL数据库的SQL语句不区分大小写, 关键字建议使用大写&lt;/li&gt;
&lt;li&gt;单选注释: &amp;ndash; 注释内容&lt;/li&gt;
&lt;li&gt;多行注释 /* 注释内容 */&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SQL 分类
&lt;ul&gt;
&lt;li&gt;DDL(Data Definition Language): 数据定义语文. 用来操作数据库,表,列等&lt;/li&gt;
&lt;li&gt;DML(Data Manipulation Language): 数据操作语文. 用来对数据库中表的数据进行增删改.&lt;/li&gt;
&lt;li&gt;DQL(Data Query Language): 数据查询语言. 用来查询数据库表的记录(数据).&lt;/li&gt;
&lt;li&gt;DCL(Data Control Language): 数据控制语言. 用来定义数据库的访问权限和安全级别, 及创建用户.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;ddl-查询和创建数据库&#34;&gt;DDL 查询和创建数据库&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询所有数据库
show databases ;
# 查询数据的创建的创建语句
show create database mysql;
# 创建数据库
create database mydb;
# 创建数据库(判断,如果不存在则创建)
create database if not exists mydb2;
# 创建数据库(指定字符集)
create database mydb3 character set UTF8mb4;
# 练习创建mydb4, 不存在则创建, 并指定UTF8字符
create database if not exists mydb4 character set UTF8mb4;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ddl-修改-删除-使用数据库&#34;&gt;DDL 修改 删除 使用数据库&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 修改数据库(修饰字符集)
ALTER DATABASE mydb4 CHAR SET gbk;
show create database mydb4;
# 删除数据库
drop database mydb4;
# 删除数据库(判断, 如果存在则删除)
drop database if exists mydb4;
# 使用数据库
use mydb3;
# 查看当前使用的数据库
select DATABASE();
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ddl-查询数据表&#34;&gt;DDL 查询数据表&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询所有的数据表
use mysql;
show tables ;
# 查询表结构
desc user;
# 查询表字符集
show table status from mysql like &amp;#39;user&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ddl-创建数据表&#34;&gt;DDL 创建数据表&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;格式&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table 表名(
    列名 数据类型 约束,
    列名 数据类型 约束,
    列名 数据类型 约束
);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;数据类型&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;int:           整数类型
double:        小数类型
datetime:      日期类型.包含年月日,格式yyyy-MM-dd         HH:mm:ss
timestamp:     日间戮类型.包含年月日时分秒,格式yyyy-MM-dd HH:mm:ss(如不赋值或赋值null,默认使用系统时间赋值)
varchar(长度): 字符串类型
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 创建一个product商品表(商品编号, 商品名称, 商品价格, 商品库存, 上架时间)
create table product(
    id INT,
    name VARCHAR(20),
    price DOUBLE,
    stock INT,
    insert_time DATE
);
desc product;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ddl--修改数据表&#34;&gt;DDL  修改数据表&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 修改表名
alter table product rename to newProduct;
show tables ;
# 修改表的字符集
alter table newProduct character set utf8mb4;
show table status from mydb3 like &amp;#39;newProduct&amp;#39;;
# 单独添加一列
alter table newProduct add color VARCHAR(10);
desc newProduct;
# 修改某列的数据类型
alter table newProduct modify color INT;
desc newProduct;
# 修改列名和数据类型
alter table newProduct change color address VARCHAR(200);
desc newProduct;
# 删除某一列
alter table newProduct drop address;
desc newProduct;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ddl-删除数据表&#34;&gt;DDL 删除数据表&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 删除数据表
drop table product;
show tables ;
# 删除数据表(判断, 如果存在则删除)
drop table if exists newProduct;
show tables ;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dml-新增表数据&#34;&gt;DML 新增表数据&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 给指定列添加数据
desc product;
insert into product(id,name) values (1, &amp;#39;电饭煲&amp;#39;);
select * from product;
# 给全部列添加数据
insert into product values (2,&amp;#39;iPhone&amp;#39;,8000.0,1,null);
select * from product;
# 批量添加数据
insert into product(id,name) values (3,&amp;#39;XiaoMi&amp;#39;),(4,&amp;#39;Vivo&amp;#39;);
insert into product values (5,&amp;#39;MacBookPro&amp;#39;,8000.0,1,&amp;#39;2020-02-02&amp;#39;),(6,&amp;#39;Mac Mini&amp;#39;,5000.0,2,&amp;#39;2021-06-06&amp;#39;);
select * from product;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dml-修改和删除表数据&#34;&gt;DML 修改和删除表数据&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;update和delete未加where会更新或删除全表数据&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 修改表中的数据
update product set name=&amp;#39;高压电饭煲&amp;#39;,price=1000 where id=1;
update product set stock=2;
select * from product;

# 删除表中的数据
delete from product where id=2 or id=3;
delete from product ;
select * from product;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dql-表数据查询数据准备&#34;&gt;DQL 表数据查询&amp;ndash;数据准备&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 数据准备, 商品编号 商品名称 商品价格 商品品牌 商品库存 添加时间
use mydb3;
create table product(
    id INT,
    name VARCHAR(20),
    price DOUBLE,
    brand VARCHAR(10),
    stock INT,
    insert_time DATE
);
insert into mydb3.product values
(1,&amp;#39;华为手机&amp;#39;,3999,&amp;#39;华为&amp;#39;,23,&amp;#39;2088-03-10&amp;#39;),
(2,&amp;#39;小米手机&amp;#39;,2999,&amp;#39;小米&amp;#39;,30,&amp;#39;2088-05-15&amp;#39;),
(3,&amp;#39;苹果手机&amp;#39;,5999,&amp;#39;苹果&amp;#39;,18,&amp;#39;2088-08-20&amp;#39;),
(4,&amp;#39;华为电脑&amp;#39;,6999,&amp;#39;华为&amp;#39;,14,&amp;#39;2088-06-16&amp;#39;),
(5,&amp;#39;小米电脑&amp;#39;,4999,&amp;#39;小米&amp;#39;,26,&amp;#39;2088-07-08&amp;#39;),
(6,&amp;#39;苹果电脑&amp;#39;,8999,&amp;#39;苹果&amp;#39;,15,&amp;#39;2088-10-25&amp;#39;),
(7,&amp;#39;联想电脑&amp;#39;,7999,&amp;#39;联想&amp;#39;,null,&amp;#39;2088-11-11&amp;#39;);
select * from mydb3.product;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dql-表数据查询查询全部&#34;&gt;DQL 表数据查询&amp;ndash;查询全部&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/*
select 字段列表 from 表名列表
where 条件列表
group by 分组字段
having 分组后的过滤条件
order by 排序
limit 分页;  */

# 查询全部的表数据
select * from product;
# 查询指定字段的表数据
select name,price,brand from mydb3.product;
# 去除重复查询
select brand from product;
select distinct brand from product;
# 计算列的值(四则运算)
select name,stock+10 from mydb3.product;
# 如果一列为null, 可以进行替换ifnull(表达式1,表达式2), 表达式1:想替换的列, 表达式2:想替换的值
select name,ifnull(stock,0)+10 from mydb3.product;
# 起别名查询, 别名as关键字也可以省略的
select name,ifnull(stock,0)+10 as getSum from mydb3.product;
select name,ifnull(stock,0)+10 getSum from mydb3.product;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dql-表数据查询条件查询&#34;&gt;DQL 表数据查询&amp;ndash;条件查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;查询条件分类&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;符号             功能
&amp;gt;                大于
&amp;lt;                小于
&amp;gt;=               大于等于
&amp;lt;=               小于等于
=                等于
&amp;lt;&amp;gt;或!=           不等于
between...and... 在某个范围之内(都包含)
in(...)          多选一
like占位符       模糊查询_单个任意字符%多个任意字符
is.null          是null
is.not.null      不是null
and或&amp;amp;&amp;amp;          并且
or或||           或者
not或!           非,不是
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;条件查询语法&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;select 列名列表 from 表名where 条件;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询库存大于20的商品信息
select * from mydb3.product where stock&amp;gt;20;
# 查询品牌为华为的商品信息
select * from product where brand= &amp;#39;华为&amp;#39;;
# 查询金额在4000 ~ 6000 之间的商品信息
select * from product where price&amp;gt;=4000 and price&amp;lt;=6000;
select * from product where price between 4000 and 6000;
# 查询库存为14,30,23的商品信息
select * from product where stock=14 or stock=30 or stock=23;
select * from product where stock in (14,30,23);
# 查询库存为null的商品信息
select * from product where stock is null;
# 查询库存不为null的商品信息
select * from product where stock is not null;
# 查询名称以小米为开头的商品信息
select * from product where name like &amp;#39;小米%&amp;#39;;
# 查询名称第二个字是是&amp;#39;为&amp;#39;的商品信息
select * from product where name like &amp;#39;_为%&amp;#39;;
# 查询名称为四个字符的商品信息
select * from product where name like &amp;#39;____&amp;#39;;
# 查询名称中包含电脑的商品信息
select * from product where name like &amp;#39;%电脑%&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dql-表数据查询聚合函数查询&#34;&gt;DQL 表数据查询&amp;ndash;聚合函数查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;聚合函数的介绍
&lt;ul&gt;
&lt;li&gt;将一列数据作为一个整体, 进行纵向的计算&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;聚合函数的分类&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;函数名      功能
count(列名) 统计数量(一般选用不为null的列)
max(列名)   最大值
min(列名)   最小值
sum(列名)   求和
avg(列名)   平均值
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;聚合函数查询语法
&lt;ul&gt;
&lt;li&gt;select 函数名(列名) from 表名 [where条件];&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 计算product 表中总记录条件
select count(*) from product;
# 获取最高价格
select max(price) from product;
# 获取最低库存
select min(stock) from product;
# 获取总库存数量
select sum(stock) from product;
# 获取品牌为苹果的总库存数量
select sum(stock) from product where brand=&amp;#39;苹果&amp;#39;;
# 获取品牌为小米的平均商品价格
select avg(price) from product where brand=&amp;#39;小米&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dql-表数据查询排序查询&#34;&gt;DQL 表数据查询&amp;ndash;排序查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;排序查询语法
select 列名列表 from 表名 [where 条件] order by 列名 排序方式,列名 排序方式&amp;hellip;;&lt;/li&gt;
&lt;li&gt;排序方式
&lt;ul&gt;
&lt;li&gt;ASC 升序&lt;/li&gt;
&lt;li&gt;DESC 降序&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;如果有多个排序条件, 只有当前边的条件值一值时, 才会判断第二条件.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 按照库存升序排序
select * from product order by stock asc ;
# 查询名称中包含手机的商品信息, 按照金额降序排序
select * from product where name like &amp;#39;%手机%&amp;#39; order by price desc;
# 按照金额升序排序, 如果金额相同, 按照库存降序排序
update product set price=6999 where id=6;
select * from product order by price asc ,stock desc;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dql-表数据查询分级查询&#34;&gt;DQL 表数据查询&amp;ndash;分级查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;分级查询语法
&lt;ul&gt;
&lt;li&gt;select 列名列表 from 表名 [where 条件] group by 分级列名 [having 分级后的条件过滤] [order by 排序列名 排序方式] ;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 按照品牌分组, 获取每组商品的总金额
select  brand,sum(price) from product group by brand;
# 对金额大于4000元的商品, 按照品牌分组, 获取每组商品的总金额
select brand,sum(price) from product where price&amp;gt;4000 group by brand;
# 对金额大于4000元的商品, 按照品牌分组, 获取每组商品的总金额, 只显示总金额大于7000元的
select brand,sum(price) getSum from product where price&amp;gt;4000 group by brand having getSum&amp;gt;7000;
# 对金额大于4000元的商品, 按照品牌分级, 获取每组商品的总金额, 只显示总金额大于7000元的, 并按照总金额的降序排列
select brand,sum(price) getSum from product where price&amp;gt;4000 group by brand having getSum&amp;gt;7000 order by getSum desc ;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dql-表数据查询分页查询&#34;&gt;DQL 表数据查询&amp;ndash;分页查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;分页查询语法
&lt;ul&gt;
&lt;li&gt;select 列名列表 from 表名 [where 条件] group by 分级列名 [having 分级后的条件过滤] [order by 排序列名 排序方式] limit 当前大岁数,每页显示的条数;&lt;/li&gt;
&lt;li&gt;公式: 当前页数 = (当前页数-1) * 每页显示的条数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 每页显示3条数据
# 第1页 当前页数=(1-1)*3
select * from product limit 0,3;
# 第2页 当前页数=(2-1)*3
select * from product limit  3,3;
# 第3页 当前页数=(3-1)*3
select * from product limit  6,3;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;mysql-外键约束&#34;&gt;MySQL 外键约束&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;为什么要有外键约束
&lt;ul&gt;
&lt;li&gt;当表与表之间的数据有相关联性的时候, 如果没有相关的数据约束, 则无法保证数据的准确性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;外键约束的作用
&lt;ul&gt;
&lt;li&gt;让表与表之间产生关联关系&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;建表时添加外键约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table 表名(
    列名 数据类型 约束,
    ...
    constraint 外键名 foreign key(本表外键列名) references 主表名(主表主键列名)
);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;删除外键约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 drop foreign key 外键名;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;建表后单独添加外键约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 constraint 外键名 foreign key(本表外键列名) references 主表名(主表主键列名);
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## 建立数据
use mydb3;
create table USER(
    id int primary key auto_increment,
    NAME varchar(20) not null
);
insert into USER values (null,&amp;#39;张三&amp;#39;),(null,&amp;#39;李四&amp;#39;);

create table orderlist(
    id int primary key auto_increment,
    number varchar(20) not null,
    uid int,
    constraint ou_fk1 foreign key (uid) references USER(id)
);
insert into orderlist values (null,&amp;#39;hm001&amp;#39;,1),(null,&amp;#39;hm002&amp;#39;,1),
                             (null,&amp;#39;hm003&amp;#39;,2),(null,&amp;#39;hm004&amp;#39;,2);
select * from orderlist;

# 添加一个订单, 但是没有真实用户
insert into orderlist values (null,&amp;#39;hm005&amp;#39;,3);
# 删除李四用户
delete from USER where NAME = &amp;#39;李四&amp;#39;;
# 删除外键约束
alter table orderlist drop foreign key ou_fk1;
# 添加外键约束
alter table  orderlist add constraint ou_fk1 foreign key (uid) references USER(id);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;外键的级联更新和级联删除&#34;&gt;外键的级联更新和级联删除&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;添加级联更新&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 constraint 外键名 foreign key(本表外键列名)
references 主表名(主表主键列名)
on update cascade;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;添加级联删除&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 constraint 外键名 foreign key(本表外键列名)
references 主表名(主表主键列名)
on delete cascade;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;同时添加级联更新和级联删除&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 constraint 外键名 foreign key(本表外键列名)
references 主表名(主表主键列名)
on update cascade on delete cascade;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 先删除外键
alter table orderlist drop foreign key ou_fk1;
## 级联更新和删除
alter table  orderlist add constraint ou_fk1 foreign key (uid)
    references USER(id)
on update cascade on delete cascade ;
# 将李四用户id修改为3
update USER set id=3 where id=2;
select * from USER;
select * from orderlist;
# 删除李四这个用户
delete from USER where id=3;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;约束&#34;&gt;约束&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;什么是约束
&lt;ul&gt;
&lt;li&gt;对表中的数据进行限定 保证数据的正确性, 有效性, 完整性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;约束的分类&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;约束                          | 作用
primary key                   | 主键约束
primary key auto_increment    | 主键自增
unique                        | 唯一约束
not null                      | 非空约束
foreign key                   | 外键约束
foreign key on update cascade | 外键级联更新
foreign key on delete cascade | 外键级联删除
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;主键约束&#34;&gt;主键约束&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;主键约束的特点
&lt;ul&gt;
&lt;li&gt;主键约束默认包含非空和唯一两个功能&lt;/li&gt;
&lt;li&gt;一张表只能有一个主键&lt;/li&gt;
&lt;li&gt;主键一般用于表中数据的唯一标识&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;建表时添加主键约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table 表名(
    列名 数据类型 primary key,
    ...
    列名 数据类型 约束
);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;删除主键主键约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 drop primary key;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;键表后单独添加主键约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 modify 列名 数据类型 primary key;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 创建学生表(编号,姓名,年龄) 编号设为主键
create table student(
    id int primary key ,
    NAME varchar(50),
    age int
);
# 查询学生表的详细信息
desc student;
# 添加数据
insert into student values (null,&amp;#39;张三&amp;#39;,23);
insert into student values (1,&amp;#39;张三&amp;#39;,23);
insert into student values (1,&amp;#39;李四&amp;#39;,24);
insert into student values (2,&amp;#39;李四&amp;#39;,24);
# 删除主键
alter table student drop primary key ;
# 添加主键约束
alter table student modify id int primary key ;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;主键自增约束&#34;&gt;主键自增约束&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;建表时添加主键自增约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table 表名(
    列名 数据类型 primary key auto_increment,
    ...
    列名 数据类型 约束
);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;删除主键自增约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 modify 列名 数据类型;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;建表后单独添加主键自增约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 modify 列名 数据类型 auto_increment;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;MySQL中的自增约束,必须配合键的约束一起使用!&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 创建学生表(编号,姓名,年龄) 编号设为主键 自增
drop table student;
create table student(
    id int primary key auto_increment,
    NAME varchar(50),
    age int
);
# 查询学生表的详细信息
desc student;
# 添加数据
insert into student values (null,&amp;#39;张三&amp;#39;,23);
insert into student values (null,&amp;#39;李四&amp;#39;,23);
select * from student;
# 删除自增约束
alter table student modify id INT;
# 建表后单独添加自增约束
alter table student modify id INT auto_increment;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;唯一约束&#34;&gt;唯一约束&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;建表时添加唯一约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table 表名(
    列名 数据类型 unique,
    ...
    列名 数据类型 约束
);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;删除唯一约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 drop index 列名;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;建表后单独添加主键自增约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 modify 列名 数据类型 unique;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 创建学生表(编号,姓名,年龄) 编号设为主键 自增 年龄唯一
drop table student;
create table student(
    id int primary key auto_increment,
    NAME varchar(50),
    age int unique
);
# 查询学生表的详细信息
desc student;
# 添加数据
insert into student values (null,&amp;#39;张三&amp;#39;,23);
insert into student values (null,&amp;#39;李四&amp;#39;,23);
select * from student;
# 删除唯一约束
alter table student drop index age;
desc student;
# 建表后单独添加唯一约束
alter table student modify age INT unique ;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;非空约束&#34;&gt;非空约束&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;建表时添加非空约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table 表名(
    列名 数据类型 not null,
    ...
    列名 数据类型 约束
);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;删除非空约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 modify 列名 数据类型;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;建表后单独添加非空约束&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table 表名 modify 列名 数据类型 not null;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 创建学生表(编号,姓名,年龄) 编号设为主键 自增 姓名非空 年龄唯一
drop table student;
create table student(
    id int primary key auto_increment,
    NAME varchar(50) not null ,
    age int unique
);
# 查询学生表的详细信息
desc student;
# 添加数据
insert into student values (null,null,24);
insert into student values (null,&amp;#39;张三&amp;#39;,23);
select * from student;
# 删除非空
alter table student modify NAME VARCHAR(50);
desc student;
# 建表后单独添加非空
alter table student modify NAME varchar(50) not null ;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多表操作&#34;&gt;多表操作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;多表概念
&lt;ul&gt;
&lt;li&gt;多张数据表, 而表与表之间是可以有一定的关联关系, 这种关联关系通过外键约束实现&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;多表的分类
&lt;ul&gt;
&lt;li&gt;一对一&lt;/li&gt;
&lt;li&gt;一对多&lt;/li&gt;
&lt;li&gt;多对多&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;一对一
&lt;ul&gt;
&lt;li&gt;适用场景
&lt;ul&gt;
&lt;li&gt;人和身份证. 一个人只有一个身份证, 一个身份证只能对应一个人&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;建表原则
&lt;ul&gt;
&lt;li&gt;在什么问题一个表建立外键, 去关联另外一个表的主键&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## 一对一
use mydb3;
create table person(
  id int primary key auto_increment,
  NAME varchar(20)
);
insert into person values (null,&amp;#39;张三&amp;#39;),(null,&amp;#39;李四&amp;#39;);
create  table card(
    id INT primary key auto_increment,
    number varchar(20) unique not null ,
    pid int unique,
    constraint cp_fk1 foreign key (pid) references person(id)
);
insert into card values (null,&amp;#39;12345&amp;#39;,1),(null,&amp;#39;56789&amp;#39;,2);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;一对多
&lt;ul&gt;
&lt;li&gt;适用场景
&lt;ul&gt;
&lt;li&gt;用户和订单. 一个用户可以有多个订单&lt;/li&gt;
&lt;li&gt;商品分类和商品. 一个分类下可以有多个商品&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;建表原则
&lt;ul&gt;
&lt;li&gt;在多的一方, 建立外键约束, 来关联一的一方主键&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## 一对多
use mydb3;
create table USER(
    id int primary key auto_increment,
    NAME varchar(20)
);
insert into USER values (null,&amp;#39;张三&amp;#39;),(null,&amp;#39;李四&amp;#39;);

create table orderlist(
    id int primary key auto_increment,
    number varchar(20),
    uid int,
    constraint ou_fk1 foreign key (uid) references USER(id)
);
insert into orderlist values (null,&amp;#39;hm001&amp;#39;,1),(null,&amp;#39;hm002&amp;#39;,1),(null,&amp;#39;hm003&amp;#39;,2),(null,&amp;#39;hm004&amp;#39;,2);

## 一对多示例二
create table category(
    id int primary key auto_increment,
    NAEM varchar(10)
);
insert into category values (null,&amp;#39;手机数码&amp;#39;),(null,&amp;#39;电脑办公&amp;#39;);
create table product(
    id int primary key auto_increment,
    NAME varchar(30),
    cid int,
    constraint pc_fk1 foreign key (cid) references category(id)
);
insert into product values (null,&amp;#39;华为P30&amp;#39;,1),(null,&amp;#39;小米note3&amp;#39;,1),(null,&amp;#39;联想电脑&amp;#39;,2),(null,&amp;#39;苹果电脑&amp;#39;,2);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;多对多
&lt;ul&gt;
&lt;li&gt;适用场景
&lt;ul&gt;
&lt;li&gt;学生和谭程. 一个学生可以选择多个课程, 一个课程也可以被多个学生选择&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;建表原则
&lt;ul&gt;
&lt;li&gt;需要借助第三张中间表, 中间表至少包含2个列. 这2个列作为中间表的外键, 分别关联2张表的主键.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;use mydb3;
show tables ;
create table student(
    id int primary key auto_increment,
    NAME varchar(20)
);
insert into student values (null,&amp;#39;张三&amp;#39;),(null,&amp;#39;李四&amp;#39;);

create table course(
    id int primary key auto_increment,
    NAME varchar(10)
);
insert into course values (null,&amp;#39;语文&amp;#39;),(null,&amp;#39;数学&amp;#39;);

create table stu_course(
    id int primary key auto_increment,
    sid int,
    cid int,
    constraint sc_fk1 foreign key (sid) references student(id),
    constraint sc_fk2 foreign key (cid) references course(id)
);
insert into stu_course values (null,1,1),(null,1,2),(null,2,1),(null,2,2);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多表查询&#34;&gt;多表查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;多表查询分类
&lt;ul&gt;
&lt;li&gt;内连接查询&lt;/li&gt;
&lt;li&gt;外连接查询&lt;/li&gt;
&lt;li&gt;子查询&lt;/li&gt;
&lt;li&gt;自关联查询&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;多表查询数据准备&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 多表操作数据准备
create database mydb4;
use mydb4;
create table USER(
    id int primary key auto_increment,
    NAME varchar(20),
    age int
);
insert into USER values (1,&amp;#39;张三&amp;#39;,23);
insert into USER values (2,&amp;#39;李四&amp;#39;,24);
insert into USER values (3,&amp;#39;王五&amp;#39;,25);
insert into USER values (4,&amp;#39;赵六&amp;#39;,26);

create table orderlist(
    id int primary key auto_increment,
    number varchar(30),
    uid int,
    constraint ou_fk1 foreign key (uid) references USER(id)
);
insert into orderlist values (1,&amp;#39;hm001&amp;#39;,1);
insert into orderlist values (2,&amp;#39;hm002&amp;#39;,1);
insert into orderlist values (3,&amp;#39;hm003&amp;#39;,2);
insert into orderlist values (4,&amp;#39;hm004&amp;#39;,2);
insert into orderlist values (5,&amp;#39;hm005&amp;#39;,3);
insert into orderlist values (6,&amp;#39;hm006&amp;#39;,3);
insert into orderlist values (7,&amp;#39;hm007&amp;#39;,null);

create table category(
    id int primary key auto_increment,
    NAEM varchar(10)
);
insert into category values (1,&amp;#39;手机数码&amp;#39;);
insert into category values (2,&amp;#39;电脑办公&amp;#39;);
insert into category values (3,&amp;#39;烟酒茶糖&amp;#39;);
insert into category values (4,&amp;#39;靴靴箱包&amp;#39;);
insert into category values (null,&amp;#39;靴靴箱包&amp;#39;);

create table product(
    id int primary key auto_increment,
    NAME varchar(30),
    cid int,
    constraint cp_fk1 foreign key (cid) references category(id)
);
insert into product values (1,&amp;#39;华为手机&amp;#39;,1);
insert into product values (2,&amp;#39;小米手机&amp;#39;,1);
insert into product values (3,&amp;#39;联想电脑&amp;#39;,2);
insert into product values (4,&amp;#39;苹果电脑&amp;#39;,2);
insert into product values (5,&amp;#39;中华香烟&amp;#39;,3);
insert into product values (6,&amp;#39;玉溪香烟&amp;#39;,3);
insert into product values (7,&amp;#39;计生用品&amp;#39;,null);

create table us_pro(
    upid int primary key auto_increment,
    uid int,
    pid int,
    constraint up_fk1 foreign key (uid) references USER(id),
    constraint up_fk2 foreign key (pid) references product(id)
);
insert into us_pro values (null,1,1);
insert into us_pro values (null,1,2);
insert into us_pro values (null,1,3);
insert into us_pro values (null,1,4);
insert into us_pro values (null,1,5);
insert into us_pro values (null,1,6);
insert into us_pro values (null,1,7);
insert into us_pro values (null,2,1);
insert into us_pro values (null,2,2);
insert into us_pro values (null,2,3);
insert into us_pro values (null,2,4);
insert into us_pro values (null,2,5);
insert into us_pro values (null,2,6);
insert into us_pro values (null,2,7);
insert into us_pro values (null,3,1);
insert into us_pro values (null,3,2);
insert into us_pro values (null,3,3);
insert into us_pro values (null,3,4);
insert into us_pro values (null,3,5);
insert into us_pro values (null,3,6);
insert into us_pro values (null,3,7);
insert into us_pro values (null,4,1);
insert into us_pro values (null,4,2);
insert into us_pro values (null,4,3);
insert into us_pro values (null,4,4);
insert into us_pro values (null,4,5);
insert into us_pro values (null,4,6);
insert into us_pro values (null,4,7);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;内连接查询&#34;&gt;内连接查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;查询原理
&lt;ul&gt;
&lt;li&gt;内连接查询的是两张表有交集的部分数据(有主外键关联的数据)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;查询语法
&lt;ul&gt;
&lt;li&gt;显式内连接: select 列名 from 表名1 [inner]join 表名2 on 条件;&lt;/li&gt;
&lt;li&gt;隐式内连接: select 列名 from 表名1,表名2 where 条件;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 显式内连接查询, 查询用户信息和对应的订单信息
select * from USER inner join orderlist on USER.id = orderlist.uid;
# 查询用户信息和对应的订单信息, 起别名
select * from USER as u inner join orderlist as o on u.id = o.uid;
# 查询用户姓名, 年龄 和 订单编号
select
    u.NAME,
    u.age,
    o.number
from
    USER u
        inner join
    orderlist o
    on
            u.id = o.uid;

# 隐式内连接, 查询用户姓名, 年龄 和 订单编号
select
    u.NAME,
    u.age,
    o.number
from
    USER u,
    orderlist o
where
        u.id = o.uid;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;外连接查询&#34;&gt;外连接查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;左外连接
&lt;ul&gt;
&lt;li&gt;查询原理: 查询左表的全部数据, 和左右两张表有交集部分的数据&lt;/li&gt;
&lt;li&gt;查询语法: select 列名 from 表名1 left [outer] join 表名2 on 条件;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;右外连接
&lt;ul&gt;
&lt;li&gt;查询原理: 查询右表的全部数据, 和左右两张表有交集部分的数据&lt;/li&gt;
&lt;li&gt;查询语法: select 列名 from 表名1 right [outer] join 表名2 on 条件;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询语法: select 列名 from 表名1 left [outer] join 表名2 on 条件;
select
    u.*,o.number
from
    USER u
        left join
    orderlist o
    on u.id = o.uid;
# 查询语法: select 列名 from 表名1 right [outer] join 表名2 on 条件;
select
    o.*,u.name
from
    USER u
        right join
    orderlist o
    on u.id = o.uid;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;子查询&#34;&gt;子查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;子查询概念
&lt;ul&gt;
&lt;li&gt;查询语句中嵌套了查询语句, 我们就将嵌套的查询称为子查询.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;结果是单行单列的
&lt;ul&gt;
&lt;li&gt;查询作用: 可以将查询的结果作用为另一条语句的查询条件, 使用运算符判断. =&amp;raquo;=&amp;laquo;=等.&lt;/li&gt;
&lt;li&gt;查询语法: select 列名 from 表名 where 列名=(select 列名from 表名 [where 条件])&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询年龄最高的用户姓名
select * from USER;
select name,max(age) from USER; # 错误使用
select NAME,age from USER where age=(select max(age) from USER);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;结果是多行单列的
&lt;ul&gt;
&lt;li&gt;查询作用: 可以作为条件, 使用运算符IN或NOT IN进行判断&lt;/li&gt;
&lt;li&gt;查询语法: select 列名 from 表名 where 列名 [not] in (select 列名 from 表名 [where 条件]);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询张三和李四的订单信息
select * from orderlist where uid in (1,2);
select id from USER where NAME in (&amp;#39;张三&amp;#39;,&amp;#39;李四&amp;#39;);
select * from orderlist where uid in (select id from USER where NAME in (&amp;#39;张三&amp;#39;,&amp;#39;李四&amp;#39;));
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;结果是多行多列的
&lt;ul&gt;
&lt;li&gt;查询作用: 查询结果可以作为一张虚拟表参与查询&lt;/li&gt;
&lt;li&gt;查询语法: select 列名 from 表名 [别名],(select 列名 from 表名 [where条件]) [别名][where 条件];&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询订单表中id大于4的订单信息和所属用户信息
select * from orderlist where id&amp;gt;4;
select
    u.name,
    o.number
from
    USER u,
     (select * from orderlist where id&amp;gt;4) o
where
    o.uid = u.id;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;自关联查询&#34;&gt;自关联查询&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自关联查询
&lt;ul&gt;
&lt;li&gt;在同一张表中数据有关联性, 我们可以把这张表当成多个表来查询&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 创建数据
create table employee(
    id int primary key auto_increment,
    NAME varchar(20),
    mgr int,
    salary double
);
insert into employee values
(1001,&amp;#39;孙悟空&amp;#39;,1005,9000.00),
(1002,&amp;#39;猪八戒&amp;#39;,1005,8000.00),
(1003,&amp;#39;沙和尚&amp;#39;,1005,8500.00),
(1004,&amp;#39;小白龙&amp;#39;,1005,7900.00),
(1005,&amp;#39;唐僧&amp;#39;,null,15000.00),
(1006,&amp;#39;武松&amp;#39;,1009,7600.00),
(1007,&amp;#39;李逵&amp;#39;,1009,7400.00),
(1008,&amp;#39;林冲&amp;#39;,1009,8100.00),
(1009,&amp;#39;宋江&amp;#39;,null,16000.00);
# 查询所有员工的姓名及其直接上级的姓名, 没有上级的员工也需要查询
# empployee.mgr = employee.id
# 左表的全部数据, 和左右2张表有交集的部分, 左外连接
select
    e1.id,
    e1.NAME,
    e1.mgr,
    e2.id,
    e2.NAME
from
    employee e1
        left join
    employee e2
    on
            e1.mgr=e2.id;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多表查询练习&#34;&gt;多表查询练习&lt;/h2&gt;
&lt;h3 id=&#34;搞清哪几个表&#34;&gt;搞清哪几个表&lt;/h3&gt;
&lt;h3 id=&#34;表之间的连接方式&#34;&gt;表之间的连接方式&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;left join 不能与 on和where后and联用,会不起作用&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询用户的编号,姓名,年龄,订单编号
select u.id,u.NAME,u.age, o.number
from USER u inner join orderlist o
on u.id=o.uid;
select u.id,u.NAME,u.age, o.number
from USER u, orderlist o
where u.id=o.uid;
# 查询所有的用户. 用户的编号,姓名,年龄,订单编号
select u.id,u.NAME,u.age,o.number
from USER u left join orderlist o
on u.id=o.uid;
# 查询所有的订单. 用户的编号,姓名,年龄,订单编号
select u.id,u.NAME,u.age,o.number
from USER u right join orderlist o
on u.id=o.uid;
# 查询用户年龄大于23岁的信息. 显示用户的编号,姓名,年龄,订单编号
select u.id,u.NAME,u.age,o.number
from
    (select * from USER where age&amp;gt;23) as u,
    orderlist o
where u.id = o.uid;
select u.id,u.NAME,u.age,o.number
from USER u ,orderlist o
 where u.id = o.uid and u.age&amp;gt;23;
# 查询张三和李四用户的信息. 显示用户的编号,姓名,年龄,订单编号
select u.id,u.NAME,u.age,o.number
from USER u inner join orderlist o on u.id = o.uid and u.NAME in (&amp;#39;张三&amp;#39;,&amp;#39;李四&amp;#39;);
# 查询商品分类的编号,分类名称,分类下的商品名称
select c.id,c.NAEM,p.NAME
from category c ,product p
where c.id = p.cid;
# 查询所有的商品分类. 商品分类的编号,分类名称,分类下的商品名称
select c.id,c.NAEM,p.NAME
from category c left join product p
on c.id = p.cid;
# 查询所有的商品信息. 商品分类的编号,分类名称,分类下的商品名称
select c.id,c.NAEM,p.NAME
from category c right join product p
on c.id = p.cid;
# 查询所有用户和所有的商品. 显示用户的编号,姓名,年龄,商品名称
# USER product us_pro中间表
# 条件 USER.id=us_pro.uid and us_pro.pid = product.id
select u.id,u.NAME,u.age,p.NAME
from USER u, product p, us_pro up
where u.id = up.uid and p.id = up.pid;
# 查询张三和李四这2个用户可以看到的商品. 显示用户的编号,姓名,年龄,商品名称
# USER product us_pro中间表
# 条件 USER.id=us_pro.uid and us_pro.pid = product.id and USER.NAME in (&amp;#39;张三&amp;#39;,&amp;#39;李四&amp;#39;)
select u.id,u.NAME,u.age,p.NAME
from USER u, product p, us_pro up
where u.id = up.uid and p.id = up.pid and u.NAME in (&amp;#39;张三&amp;#39;,&amp;#39;李四&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>JavaWeb核心四 Li.057</title>
      <link>https://lizicai.com/p/javaweb%E6%A0%B8%E5%BF%83%E5%9B%9B-li.057/</link>
      <pubDate>Wed, 13 Oct 2021 14:42:33 +0800</pubDate>
      <guid>https://lizicai.com/p/javaweb%E6%A0%B8%E5%BF%83%E5%9B%9B-li.057/</guid>
      <description>&lt;h2 id=&#34;el-表达式&#34;&gt;EL 表达式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;EL (Expression Language): 表达式语言.&lt;/li&gt;
&lt;li&gt;在JSP 2.0规范中加入的内容, 也是Servlet规范的一部分.&lt;/li&gt;
&lt;li&gt;作用: 在JSP页面中获取数据. 让我们的JSP脱离java代码块和JSP表达式&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-jsp&#34; data-lang=&#34;jsp&#34;&gt;&amp;lt;%--请求域中添加username数据--%&amp;gt;
&amp;lt;% request.setAttribute(&amp;#34;username&amp;#34;,&amp;#34;zhangsan&amp;#34;); %&amp;gt;

&amp;lt;%--获取请求域的username 3种方式--%&amp;gt;

&amp;lt;%--Java代码块--%&amp;gt;
&amp;lt;% out.println(request.getAttribute(&amp;#34;username&amp;#34;)); %&amp;gt; &amp;lt;br/&amp;gt;

&amp;lt;%--JSP表达式获取--%&amp;gt;
&amp;lt;%= request.getAttribute(&amp;#34;username&amp;#34;)%&amp;gt; &amp;lt;br/&amp;gt;

&amp;lt;%--EL表达式获取--%&amp;gt;
${username}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;el-表达式获取数据类型&#34;&gt;EL 表达式获取数据类型&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;获取基本数据类型的数据&lt;/li&gt;
&lt;li&gt;获取自定义对象类型的数据&lt;/li&gt;
&lt;li&gt;获取数组类型的数据&lt;/li&gt;
&lt;li&gt;获取List集合类型的数据&lt;/li&gt;
&lt;li&gt;获取Map集合类型的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-jsp&#34; data-lang=&#34;jsp&#34;&gt;&amp;lt;%@ page import=&amp;#34;com.lizicai.bean.Student&amp;#34; %&amp;gt;
&amp;lt;%@ page import=&amp;#34;java.util.ArrayList&amp;#34; %&amp;gt;
&amp;lt;%@ page import=&amp;#34;java.util.HashMap&amp;#34; %&amp;gt;
&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;% pageContext.setAttribute(&amp;#34;num&amp;#34;,10); %&amp;gt;
基本数据类型 ${num} &amp;lt;br/&amp;gt;

&amp;lt;% Student stu = new Student(&amp;#34;李明&amp;#34;, 23);
pageContext.setAttribute(&amp;#34;stu&amp;#34;,stu);
%&amp;gt;
自定义对象: ${stu} &amp;lt;br/&amp;gt;
${stu.name}
${stu.age}  &amp;lt;br/&amp;gt;

&amp;lt;%
    String[] arr = {&amp;#34;Haha&amp;#34;, &amp;#34;go&amp;#34;};
    pageContext.setAttribute(&amp;#34;arr&amp;#34;,arr);
%&amp;gt;

数组: ${arr} &amp;lt;br/&amp;gt;
${arr[0]} ${arr[1]} ${arr[2]} &amp;lt;br/&amp;gt;


&amp;lt;%
    ArrayList&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
    list.add(&amp;#34;aaa&amp;#34;);
    list.add(&amp;#34;bbb&amp;#34;);
    pageContext.setAttribute( &amp;#34;list&amp;#34;,list);
%&amp;gt;
List集合 ${list}  ${list[0]} &amp;lt;br/&amp;gt;

&amp;lt;%
    HashMap&amp;lt;String, Student&amp;gt; map = new HashMap&amp;lt;&amp;gt;();
    map.put(&amp;#34;s01&amp;#34;,new Student(&amp;#34;李明&amp;#34;,20));
    map.put(&amp;#34;s02&amp;#34;,new Student(&amp;#34;张三&amp;#34;,20));
    pageContext.setAttribute( &amp;#34;map&amp;#34;,map);
%&amp;gt;
Map 集合: ${map} &amp;lt;br/&amp;gt;
第一个学生 ${map.s01} &amp;lt;br&amp;gt;
第一个学生的姓名 ${map.s01.name} &amp;lt;br&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;el-表达式注意事项&#34;&gt;EL 表达式注意事项&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;EL 表达式没有空指针异常&lt;/li&gt;
&lt;li&gt;EL 表达式没有索引越界异常&lt;/li&gt;
&lt;li&gt;EL 表达式没有字符串的拼接&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%
    Student s = null;
    String [] arr2 = {&amp;#34;Hello&amp;#34;, &amp;#34;World&amp;#34;};
    pageContext.setAttribute( &amp;#34;s&amp;#34;,s);
    pageContext.setAttribute( &amp;#34;arr2&amp;#34;,arr2);
%&amp;gt;
${s}
${arr2[10]}
${arr2[0]}+${arr2[1]}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;el-表达式运算符&#34;&gt;EL 表达式运算符&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;关系运算符&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;关系运算符 作用     示例 结果
==或eq     等于     略   略
!=或ne     不等于   略   略
&amp;lt;或lt      小于     略   略
&amp;gt;或gt      大于     略   略
&amp;lt;=或le     小于等于 略   略
&amp;gt;=或ge     大于等于 略   略
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;逻辑运算符&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;运算符  作用 示例 结果
&amp;amp;&amp;amp;或and 并且 略   略
||或or  或者 略   略
!或not  取反 略   略
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;其他运算符&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;运算符               作用
empty                1判断对象是否为null.2判断字符串是否为空字符串.3判断窗口元素是否为0
条件?表达式1:表达式2 三元运算符
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;EL 表达式运算符&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;%
    String ss = null;
    String ss2 = &amp;#34;&amp;#34;;
    int[] arr = {};
%&amp;gt;
${empty ss} &amp;lt;br/&amp;gt;
${empty ss2} &amp;lt;br/&amp;gt;
${empty arr} &amp;lt;br/&amp;gt;

&amp;lt;% pageContext.setAttribute(&amp;#34;gender&amp;#34;, &amp;#34;man&amp;#34;); %&amp;gt;
&amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; value=&amp;#34;man&amp;#34; ${gender == &amp;#34;man&amp;#34; ? &amp;#34;checked&amp;#34; : &amp;#34;&amp;#34;}&amp;gt; 男
&amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; value=&amp;#34;woman&amp;#34; ${gender == &amp;#34;woman&amp;#34; ? &amp;#34;checked&amp;#34; : &amp;#34;&amp;#34;}&amp;gt; 女
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;el-表达式使用细节&#34;&gt;EL 表达式使用细节&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;EL 表达式能够获取四大域对象的数据, 根据名称从小到大在域对象中查找.&lt;/li&gt;
&lt;li&gt;还可以获取JSP其他八个隐式对象, 并调用对象中的方法.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;%
    pageContext.setAttribute(&amp;#34;username&amp;#34;, &amp;#34;zhangsan1&amp;#34;);
    request.setAttribute(&amp;#34;username&amp;#34;, &amp;#34;zhangsan2&amp;#34;);
    session.setAttribute(&amp;#34;username&amp;#34;, &amp;#34;zhangsan3&amp;#34;);
    application.setAttribute(&amp;#34;username&amp;#34;, &amp;#34;zhangsan4&amp;#34;);
%&amp;gt;
${username} &amp;lt;br&amp;gt;

&amp;lt;%= request.getContextPath() %&amp;gt;
${pageContext.request.contextPath}

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;el-表达式隐式对象&#34;&gt;EL 表达式隐式对象&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;隐式对象名称     对应JSP隐式对象 说明
pageContext      pageContext     功能完全相同
applicationScope 没有            操作应用域对象数据
sessionScope     没有            操作会话域对象数据
requestScop      没有            操作请求域对象数据
pageScope        没有            操作页面域对象数据
header           没有            操作请求头数据
headerValues     没有            获取请求头数据(多个值)
param            没有            获取请求参数数据
paramValues      没有            获取请求参数数据(多个值)
initParam        没有            获取全局配置参数数据
cookie           没有            获取Cookie 对象
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-jsp&#34; data-lang=&#34;jsp&#34;&gt;&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;%-- pageContext 对象, 可以获取其他3个域对象和JSP中八个隐式对象--%&amp;gt;
${pageContext.request.contextPath} &amp;lt;br/&amp;gt;

&amp;lt;%--applicationScope sessionScope requestScop pageScope--%&amp;gt;
&amp;lt;% request.setAttribute(&amp;#34;username&amp;#34;, &amp;#34;zhangsan1&amp;#34;); %&amp;gt;
&amp;lt;% pageContext.setAttribute(&amp;#34;username&amp;#34;, &amp;#34;zhangsan2&amp;#34;); %&amp;gt;
${username} &amp;lt;br/&amp;gt;
${requestScope.username} &amp;lt;br/&amp;gt;
${pageScope.username} &amp;lt;br/&amp;gt;

&amp;lt;%--header headerValues 获取的数组--%&amp;gt;
${header[&amp;#34;connection&amp;#34;]} &amp;lt;br&amp;gt;
${headerValues[&amp;#34;connection&amp;#34;][0]} &amp;lt;br&amp;gt;


&amp;lt;%--param paramValues 获取请求参数--%&amp;gt;
${param.username} &amp;lt;br/&amp;gt;
${paramValues.hobby[0]} &amp;lt;br/&amp;gt;
${paramValues.hobby[1]} &amp;lt;br/&amp;gt;


&amp;lt;%--initParam 获取全局配置参数--%&amp;gt;
${initParam.pname} &amp;lt;br&amp;gt;


&amp;lt;%--cookie--%&amp;gt;
${cookie} &amp;lt;br&amp;gt;
${cookie.JSESSIONID} &amp;lt;br&amp;gt;  &amp;lt;%-- 获取集合元素--%&amp;gt;
${cookie.JSESSIONID.name} &amp;lt;br&amp;gt; &amp;lt;%-- 获取cookie对象的名称 --%&amp;gt;
${cookie.JSESSIONID.value} &amp;lt;br&amp;gt;  &amp;lt;%-- 获取cookie对象的数据值 --%&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jstl-介绍&#34;&gt;JSTL 介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JSTL (Java Servler Pages Standarded Tag Library): JSP标准标签库&lt;/li&gt;
&lt;li&gt;主要提供给开发人员一个标准通用的标签库&lt;/li&gt;
&lt;li&gt;开发人员可以利用这些标签取代JSP页面上的Java代码, 从而提高程序的可读性, 降低程序的维护难度.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;组成      作用       说明
core      核心标签库 通用的逻辑处理
fmt       国际化     不同地域显示不同语言
functions EL函数     EL表达式可以使用的方法
sql       操作数据库 了解
xml       操作XML    了解
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;JSTL 核心标签库&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;标签名称           功能分类         属性       作用
&amp;lt;标签名:if&amp;gt;        流程控制         核心标签库 用于条件判断
&amp;lt;标签名:choose&amp;gt;    ifelseif流程控制 核心标签库 用于多条件判断
&amp;lt;标签名:when&amp;gt;      ifelseif流程控制 核心标签库 用于多条件判断
&amp;lt;标签名:otherwise&amp;gt; ifelseif流程控制 核心标签库 用于多条件判断
&amp;lt;标签名:forEach&amp;gt;   迭代遍历         核心标签库 用于循环遍历
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/&#34;&gt;http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/&lt;/a&gt;解压lib的包导入tomcatlib中&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-jsp&#34; data-lang=&#34;jsp&#34;&gt;&amp;lt;%@taglib uri=&amp;#34;http://java.sun.com/jsp/jstl/core&amp;#34; prefix=&amp;#34;ss&amp;#34; %&amp;gt;
&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;JSTL演示&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
${pageContext.setAttribute(&amp;#34;score&amp;#34;,&amp;#34;A&amp;#34;)}
&amp;lt;ss:if test=&amp;#34;${score eq &amp;#39;F&amp;#39;}&amp;#34;&amp;gt;
    优秀
&amp;lt;/ss:if&amp;gt;

&amp;lt;ss:choose&amp;gt;
    &amp;lt;ss:when test=&amp;#34;A&amp;#34;&amp;gt;优&amp;lt;/ss:when&amp;gt;
    &amp;lt;ss:when test=&amp;#34;B&amp;#34;&amp;gt;良&amp;lt;/ss:when&amp;gt;
    &amp;lt;ss:when test=&amp;#34;C&amp;#34;&amp;gt;及格&amp;lt;/ss:when&amp;gt;
    &amp;lt;ss:otherwise&amp;gt;成绩不合法&amp;lt;/ss:otherwise&amp;gt;
&amp;lt;/ss:choose&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ taglib prefix=&amp;#34;ss&amp;#34; uri=&amp;#34;http://java.sun.com/jsp/jstl/core&amp;#34; %&amp;gt;
&amp;lt;%@ page import=&amp;#34;java.util.ArrayList&amp;#34; %&amp;gt;
&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;%
    ArrayList&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
    list.add(&amp;#34;aaa&amp;#34;);
    list.add(&amp;#34;bbb&amp;#34;);
    list.add(&amp;#34;ccc&amp;#34;);
    list.add(&amp;#34;ddd&amp;#34;);
    pageContext.setAttribute(&amp;#34;list&amp;#34;,list);
%&amp;gt;
&amp;lt;ss:forEach  items=&amp;#34;${list}&amp;#34; var=&amp;#34;str&amp;#34;&amp;gt;
    ${str} &amp;lt;br&amp;gt;
&amp;lt;/ss:forEach&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;过滤器介绍&#34;&gt;过滤器介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在程序中访问服务器资源时, 当一个请求到来, 服务器首先判断是否有过滤器与请求资源相关联&lt;/li&gt;
&lt;li&gt;如果有, 过滤器可以将请求拦截下来, 完成一些特定的功能, 再由过滤器决定是否交给请求资源&lt;/li&gt;
&lt;li&gt;如果没有, 则像之前那样直接请求资源了. 响应也是类似&lt;/li&gt;
&lt;li&gt;过滤器一般用于完成通用的操作, 例如: 登录验证, 统一编码处理,敏感字符过滤等等``````&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;filter&#34;&gt;Filter&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Filter 是一个接口. 如果想实现过滤器的功能, 必须实现该接口&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                                                      作用
void   init(FilterConfig.filterConfig)                                             初始化方法
void   doFilter(ServletRequest.request,ServletResponse.response,FilterChain.chain) 对请求资源和响应资源过滤
void   destroy()                                                                   销毁方法
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;配置方法
&lt;ul&gt;
&lt;li&gt;注解方式&lt;/li&gt;
&lt;li&gt;配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;filterchain&#34;&gt;FilterChain&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FilterChain 是一个接口, 代表过滤器链对象. 由Servlet容器提供实现类对象. 直接使用即可.&lt;/li&gt;
&lt;li&gt;过滤器可以定义多个, 就会组成过滤器链&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名 作用
void doFilter(ServletRequest.request,ServletResponse.response) 放行方法
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;如果有多个过滤器, 在第一个过滤器中调用下一个过滤器, 依次类推. 走到访问最终资源&lt;/strong&gt;
&lt;strong&gt;如果只有一个过滤器, 放行时, 就会直接到达最终访问资源&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet ( value = &amp;#34;/demo1Filter&amp;#34;)
public class Demo1Filter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(&amp;#34;Demo1Filter 执行了...&amp;#34;);
        resp.getWriter().write(&amp;#34;Demo1Filter 执行了...&amp;#34;);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(&amp;#34;/*&amp;#34;)
public class Filter implements javax.servlet.Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println(&amp;#34;Filte&amp;#34;);

        servletResponse.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);

        filterChain.doFilter(servletRequest,servletResponse);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;过滤器使用细节&#34;&gt;过滤器使用细节&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;配置方式
&lt;ul&gt;
&lt;li&gt;注解方式 @WebFilter(拦截路径)&lt;/li&gt;
&lt;li&gt;配置文件方式&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;filter2&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;com.lizicai.filter.Filter2&amp;lt;/filter-class&amp;gt;
&amp;lt;/filter&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;filter2&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/demo2Filter&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet ( value = &amp;#34;/demo2Filter&amp;#34;)
public class Demo2Filter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(&amp;#34;Demo2Filter 执行了...&amp;#34;);
        resp.getWriter().write(&amp;#34;Demo2Filter 执行了...&amp;#34;);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

public class Filter2 implements javax.servlet.Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println(&amp;#34;Filte&amp;#34;);

        servletResponse.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);

        filterChain.doFilter(servletRequest,servletResponse);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;多个过滤器使用顺序
&lt;ul&gt;
&lt;li&gt;如果有多个过滤器, 取决于过滤器映射的顺序&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;filter2&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;com.lizicai.filter.Filter2&amp;lt;/filter-class&amp;gt;
&amp;lt;/filter&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;filter2&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/demo2Filter&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;filter3&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;com.lizicai.filter.Filter3&amp;lt;/filter-class&amp;gt;
&amp;lt;/filter&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;filter3&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/demo3Filter&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;过滤器生命周期&#34;&gt;过滤器生命周期&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;创建
&lt;ul&gt;
&lt;li&gt;当应用加载时实例化对象并执行init初始化方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;服务
&lt;ul&gt;
&lt;li&gt;对象提供服务的过程, 执行doFilter方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;销毁
&lt;ul&gt;
&lt;li&gt;当应用卸载时或服务器停止时对象销毁. 执行detory()方法.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.*;
import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * 过滤器生命周期
 */

@WebFilter(&amp;#34;/demo3Filter&amp;#34;)
public class Filter3 implements javax.servlet.Filter {

    /**
     * 初始化方法
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println(&amp;#34;对象初始化成功了&amp;#34;);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println(&amp;#34;Filte&amp;#34;);

        servletResponse.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);

        filterChain.doFilter(servletRequest,servletResponse);
    }

    /**
     * 对象销毁
     */
    @Override
    public void destroy() {
        System.out.println(&amp;#34;对象销毁了&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;filterconfig-介绍&#34;&gt;FilterConfig 介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FilterConfig是一个接口. 代表过滤器的配置对象, 可以加载一此初始化参数.&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值              方法名                        作用
String              getFilterName()               获取过滤器对象名称
String              getInitParameter(String.name) 根据key获取value
Enumeration&amp;lt;String&amp;gt; getInitParameterNames()       获取所有参数的key
ServletContext      getServletContext()           获取应用上下文对象
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;filter4&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;com.lizicai.filter.Filter4&amp;lt;/filter-class&amp;gt;
    &amp;lt;init-param&amp;gt;
        &amp;lt;param-name&amp;gt;username&amp;lt;/param-name&amp;gt;
        &amp;lt;param-value&amp;gt;xiaoming&amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
&amp;lt;/filter&amp;gt;
    &amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;filter4&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/demo4Filter&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;过滤器五种拦截行为&#34;&gt;过滤器五种拦截行为&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Filter过滤器默认拦截的是请求, 但是在实际开发中, 我们还有请求转发和请求包含, 以及由服务器触发的全局错误页面.&lt;/li&gt;
&lt;li&gt;默认情况下过滤器是不参与过滤的, 要想使用, 就需要我们配置&lt;/li&gt;
&lt;li&gt;拦截方式&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    &amp;lt;filter&amp;gt;
        &amp;lt;filter-name&amp;gt;filter5&amp;lt;/filter-name&amp;gt;
        &amp;lt;filter-class&amp;gt;com.lizicai.filter.Filter5&amp;lt;/filter-class&amp;gt;
        &amp;lt;async-supported&amp;gt;true&amp;lt;/async-supported&amp;gt;
    &amp;lt;/filter&amp;gt;
    &amp;lt;filter-mapping&amp;gt;
        &amp;lt;filter-name&amp;gt;filter5&amp;lt;/filter-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/index.jsp&amp;lt;/url-pattern&amp;gt;

&amp;lt;!--        过滤请求, 默认值--&amp;gt;
        &amp;lt;dispatcher&amp;gt;REQUEST&amp;lt;/dispatcher&amp;gt;

&amp;lt;!--        过滤全局错误页面--&amp;gt;
        &amp;lt;dispatcher&amp;gt;ERROR&amp;lt;/dispatcher&amp;gt;

&amp;lt;!--        过滤转发--&amp;gt;
        &amp;lt;dispatcher&amp;gt;FORWARD&amp;lt;/dispatcher&amp;gt;

&amp;lt;!--        当请求包含时, 过滤器工作, 只能过滤动态包含. JSP 的include是静态包含, 过滤器不会过滤--&amp;gt;
        &amp;lt;dispatcher&amp;gt;INCLUDE&amp;lt;/dispatcher&amp;gt;

&amp;lt;!--        过滤异步类型, 它要求我们在filter标签中配置开启异步支持--&amp;gt;
        &amp;lt;dispatcher&amp;gt;ASYNC&amp;lt;/dispatcher&amp;gt;
    &amp;lt;/filter-mapping&amp;gt;
    &amp;lt;error-page&amp;gt;
        &amp;lt;exception-type&amp;gt;java.lang.Exception&amp;lt;/exception-type&amp;gt;
        &amp;lt;location&amp;gt;/error.jsp&amp;lt;/location&amp;gt;
    &amp;lt;/error-page&amp;gt;
    &amp;lt;error-page&amp;gt;
        &amp;lt;error-code&amp;gt;404&amp;lt;/error-code&amp;gt;
        &amp;lt;location&amp;gt;/error.jsp&amp;lt;/location&amp;gt;
    &amp;lt;/error-page&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;监听器介绍&#34;&gt;监听器介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;观察者设计模式, 所有的监听器都是基于观察者设计模式的&lt;/li&gt;
&lt;li&gt;三个组成部分
&lt;ul&gt;
&lt;li&gt;事件源: 触发事件的对象&lt;/li&gt;
&lt;li&gt;事件: 触发的动作, 封装了事件源&lt;/li&gt;
&lt;li&gt;监听器: 当事件源触发事件后, 可以完成功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;在程序当中, 我们可以地: 对象的创建销毁, 域对象中属性的变化, 会话相关内容进行监听&lt;/li&gt;
&lt;li&gt;Servlet 规范中共计8个监听器, 监听器都是以接口形式提供, 具体功能需要我们自己来完成.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;监听对象的监听器&#34;&gt;监听对象的监听器&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ServletContextListener: 用于咋啦ServletContext对象的创建和销毁&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                      作用
void   contextInitialized(ServletContextEvent.sce) 对象创建时执行该方法
void   contextDestroyed(ServletContextEvent.sce)   对象销毁时执行该方法
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数: ServletContextEvent代表事件对象&lt;/p&gt;
&lt;p&gt;事件对象中封装了事件源,也就是ServletContext&lt;/p&gt;
&lt;p&gt;真正的事件指的是创建或销毁ServletContext对象的操作&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HttpSessionListener: 用于监听HttpSession对象的创建和销毁&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                作用
void   sessionCreated(HttpSessionEvent.se)   对象创建时执行该方法
void   sessionDestroyed(HttpSessionEvent.se) 对象销毁时执行该方法
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数: Httpsessionevent代表事件对象&lt;/p&gt;
&lt;p&gt;事件对象中封装了事件源,也就是Httpsession&lt;/p&gt;
&lt;p&gt;真正的事件指的是创建或销毁Httpsession对象的操作&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ServletRequesListener: 用于监听ServletRequest对象的创建和销毁&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                      作用
void   requestInitialized(ServletRequestEvent.sre) 对象创建时执行该方法
void   requestDestroyed(ServletRequestEvent.sre)   对象销毁时执行该方法
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数: ServletRequestEvent代表事件对象&lt;/p&gt;
&lt;p&gt;事件对象中封装了事件源,也就是ServletRequest&lt;/p&gt;
&lt;p&gt;真正的事件指的是创建或销毁ServletRequest对象的操作&lt;/p&gt;
&lt;h2 id=&#34;监听域对象属性变化的监听器&#34;&gt;监听域对象属性变化的监听器&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ServletContextAttributeListener: 用于监听ServletContext应用域属性的变化&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                               作用
void   attributeAdded(ServletContextAttributeEvent.scae)    域中添加属性时执行该方法
void   attributeRemoved(ServletContextAttributeEvent.scae)  域中移除属性时执行该方法
void   attributeReplaced(ServletContextAttributeEvent.scae) 域中替换属性时执行该方法
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数: ServletContextAttributeEvent代表事件对象&lt;/p&gt;
&lt;p&gt;事件对象中封装了事件源,也就是ServletContext&lt;/p&gt;
&lt;p&gt;真正的事件指的添加, 移除, 替换应用域中属性的操作&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HttpSessionAttributeListenen: 用于监听HttpSession会话域中属性的变化&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                        作用
void   attributeAdded(HttpSessionBindingEvent.se)    域中添加属性时执行该方法
void   attributeRemoved(HttpSessionBindingEvent.se)  域中移除属性时执行该方法
void   attributeReplaced(HttpSessionBindingEvent.se) 域中替换属性时执行该方法
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数: HttpSessionBindingEvent代表事件对象&lt;/p&gt;
&lt;p&gt;事件对象中封装了事件源,也就是HttpSession&lt;/p&gt;
&lt;p&gt;真正的事件指的添加, 移除, 替换会话域中属性的操作&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ServletRequestAttributeListener: 用于监听ServletRequest请求域中属性的变化&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                               作用
void   attributeAdded(ServletRequestAttributeEvent.srae)    域中添加属性时执行该方法
void   attributeRemoved(ServletRequestAttributeEvent.srae)  域中移除属性时执行该方法
void   attributeReplaced(ServletRequestAttributeEvent.srae) 域中替换属性时执行该方法
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数: ServletRequestAttributeEvent代表事件对象&lt;/p&gt;
&lt;p&gt;事件对象中封装了事件源,也就是ServletRequest&lt;/p&gt;
&lt;p&gt;真正的事件指的添加, 移除, 替换请求域中属性的操作&lt;/p&gt;
&lt;h2 id=&#34;监听会话相关的感知型监听器&#34;&gt;监听会话相关的感知型监听器&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HttpSessionBindingListener: 用于感知对象和会话域绑定的监听器&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                      作用
void   valueBound(HttpSessionBindingEvent.event)   数据添加到会话域中(绑定)时执行该方法
void   valueUnBound(HttpSessionBindingEvent.event) 数据从会话域移除(解绑)时执行该方法
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数: HttpSessionBindingEvent 代表事件对象&lt;/p&gt;
&lt;p&gt;事件对象中封装了事件源, 也就是HttpSession&lt;/p&gt;
&lt;p&gt;真正的事件指的是添加, 移除会话域中数据的操作&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HttpSessionActivationListener: 用于感知会话域中对象钝化和活化的监听器&lt;/li&gt;
&lt;li&gt;核心方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                    作用
void   sessionWillPassivate(HttpSessionEvent.se) 会话域中数据钝化时执行该方法
void   sessionWillActivate(HttpSessionEvent.se)  会话域中数据活化时执行该方法
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数: HttpSessionEvent代表事件对象&lt;/p&gt;
&lt;p&gt;事件对象中封装了事件源, 也就是HttpSession&lt;/p&gt;
&lt;p&gt;真正的事件指的是会话域中数据钝化, 活化的操作&lt;/p&gt;
&lt;h2 id=&#34;监听器的使用&#34;&gt;监听器的使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;监听对象的
&lt;ul&gt;
&lt;li&gt;ServletContextListener&lt;/li&gt;
&lt;li&gt;HttpSessionListener&lt;/li&gt;
&lt;li&gt;ServletRequestListener&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;监听属性变化的
&lt;ul&gt;
&lt;li&gt;ServletContextAttributeListener&lt;/li&gt;
&lt;li&gt;HttpSessionAttributeListener&lt;/li&gt;
&lt;li&gt;ServletRequestAttributeListener&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;会话相关的感知
&lt;ul&gt;
&lt;li&gt;HttpSessionBindingListener&lt;/li&gt;
&lt;li&gt;HttpSessionActivationListener&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class ServletContextListenerDemo implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println(&amp;#34;监听到对象的创建...&amp;#34;);
        ServletContext servletContext = sce.getServletContext();
        System.out.println(servletContext);
        // 更改ServletContext 属性监听
        servletContext.setAttribute(&amp;#34;username&amp;#34;, &amp;#34;zhangsan&amp;#34;);

        servletContext.setAttribute(&amp;#34;username&amp;#34;,&amp;#34;liming&amp;#34;);

        servletContext.removeAttribute(&amp;#34;username&amp;#34;);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println(&amp;#34;监听到对象的销毁...&amp;#34;);

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent event) {
        System.out.println(&amp;#34;监听到应用域对象添加...&amp;#34;);
        ServletContext servletContext = event.getServletContext();
        Object value = servletContext.getAttribute(&amp;#34;username&amp;#34;);
        System.out.println(value);
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent event) {
        System.out.println(&amp;#34;监听到应用域对象删除...&amp;#34;);
        ServletContext servletContext = event.getServletContext();
        Object value = servletContext.getAttribute(&amp;#34;username&amp;#34;);
        System.out.println(value);
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent event) {
        System.out.println(&amp;#34;监听到应用域对象替换...&amp;#34;);
        ServletContext servletContext = event.getServletContext();
        Object value = servletContext.getAttribute(&amp;#34;username&amp;#34;);
        System.out.println(value);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;配置文件方式&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;listener&amp;gt;
    &amp;lt;listener-class&amp;gt;com.lizicai.listener.ServletContextAttributeListenerDemo&amp;lt;/listener-class&amp;gt;
&amp;lt;/listener&amp;gt;
&amp;lt;listener&amp;gt;
    &amp;lt;listener-class&amp;gt;com.lizicai.listener.ServletContextListenerDemo&amp;lt;/listener-class&amp;gt;
&amp;lt;/listener&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;学生管理系统优化&#34;&gt;学生管理系统优化&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;解决乱码
&lt;ul&gt;
&lt;li&gt;使用过滤器实现所有资源的编码统一&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;检查登录
&lt;ul&gt;
&lt;li&gt;使用过滤器实现校验是否登录问题&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;优化JSP页面
&lt;ul&gt;
&lt;li&gt;通过EL表达和JSTL替换之前的Java代码块和JSP表达式&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(&amp;#34;/*&amp;#34;)
public class FilterEncodingUTF8 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//        请求和响应对象转换为 HTTP 协议相关
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

//        设置编码格式
        request.setCharacterEncoding(&amp;#34;UTF-8&amp;#34;);
        response.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);

//        放行
        filterChain.doFilter(request,response);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter( value = {&amp;#34;/addStudent.jsp&amp;#34;, &amp;#34;/listStudent.jsp&amp;#34;})
public class FilterLogin implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//        1. 请求和响应对象转换为 HTTP 协议相关
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

//        2. 获取会话域对象中数据
        Object name = request.getSession().getAttribute(&amp;#34;username&amp;#34;);

//        3. 判断用户名
        if( name == null || &amp;#34;&amp;#34;.equals(name)){
//            resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
            response.getWriter().write(&amp;#34;未登录, 跳转到登录页面...&amp;#34;);
            response.setHeader(&amp;#34;Refresh&amp;#34;, request.getContextPath()+&amp;#34;2;URL=/stuLogin.jsp&amp;#34;);
            return;
        }

//        放行
        filterChain.doFilter(request,response);

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;最后一个优化, 项目是03_JavaWeb_test4&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>JavaWeb核心三 Li.056</title>
      <link>https://lizicai.com/p/javaweb%E6%A0%B8%E5%BF%83%E4%B8%89-li.056/</link>
      <pubDate>Fri, 08 Oct 2021 10:39:35 +0800</pubDate>
      <guid>https://lizicai.com/p/javaweb%E6%A0%B8%E5%BF%83%E4%B8%89-li.056/</guid>
      <description>&lt;h2 id=&#34;cookie-属性&#34;&gt;Cookie 属性&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;属性名  作用                   是否重要
name    Cookie的名称           必须属性
value   Cookie的值(不支持中文) 必须属性
path    Cookie的路径           重要
domain  Cookie的域名           重要
maxAge  Cookie的存活时间       重要
version Cookie的版本号         不重要
comment Cookie的描述           不重要
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;cookie-方法&#34;&gt;Cookie 方法&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;方法名                           作用
Cookie(String.name,String.Value) 构造方法创建对象
属性对应的set和get就去           赋值和获取值
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;cooke-添加和获取&#34;&gt;Cooke 添加和获取&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;添加 HttpServletResponse&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                   说明
void   addCookie(Cookie.cookie) 向客户端添加Cookie
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;获取 HttpServletRequest&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值   方法名       说明
Cookie[] getCookies() 获取所有的Cookie
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;cookie-细节&#34;&gt;Cookie 细节&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;数量限制
&lt;ul&gt;
&lt;li&gt;每个网站最多只能有20个Cookie, 且大小不能超过4KB. 所有网站的Cookie总数不能超过300个&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;名称限制
&lt;ul&gt;
&lt;li&gt;Cookie的名称只能包含ASCCI码表中字母,数字字符. 不能包含逗号,分号,空格, 不能以$开头&lt;/li&gt;
&lt;li&gt;Cookie的值不支持中文&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;存活时间限制setMaxAge()方法接收数字
&lt;ul&gt;
&lt;li&gt;负整数: 当前会放有效, 浏览器关闭则清除&lt;/li&gt;
&lt;li&gt;0: 立即清除&lt;/li&gt;
&lt;li&gt;正整数: 以秒为单位设置存活时间&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;访问路径限制
&lt;ul&gt;
&lt;li&gt;默认路径: 取自第1次访问的资源路径前缀. 只要以这个路径开头就能访问到&lt;/li&gt;
&lt;li&gt;设置路径: setPath()方法设置指定路径&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet ( value = &amp;#34;/demo1Cookie&amp;#34;)
public class Demo1Cookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
        PrintWriter pw = resp.getWriter();
        pw.write(&amp;#34;欢迎访问本网站, 你的最后访问时间为:&amp;#34;);

        Cookie cookie = new Cookie(&amp;#34;time&amp;#34;, System.currentTimeMillis()+&amp;#34;&amp;#34;);
        cookie.setMaxAge(10);

        resp.addCookie(cookie);

        Cookie[] arr = req.getCookies();
        for(Cookie c : arr){
            if(&amp;#34;time&amp;#34;.equals(c.getName())){
                String value = c.getValue();
                SimpleDateFormat sdf = new SimpleDateFormat(&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;);
                pw.write(sdf.format(new Date(Long.parseLong(value))));
            }
        }

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;httpsession-介绍&#34;&gt;HttpSession 介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HttpSession: 服务器端会话管理技术
&lt;ul&gt;
&lt;li&gt;本质也采用客户端会话管理技术&lt;/li&gt;
&lt;li&gt;只不过在客户保存一个特殊标识, 而共享的数据保存到了服务端的内存对象中.&lt;/li&gt;
&lt;li&gt;第次请求时, 会将特殊标识带到服务器端, 根据这个标识来找到对应的内存空间, 从而实现数据共享.&lt;/li&gt;
&lt;li&gt;是Servlet规范中四大域对象之一的会话域对象&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;作用: 可以实现数据共享&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;域对象         功能   作用
ServletContext 应用域 在整个应用之间实现共享数据
ServletRequest 请求域 在当前的请求或请求转发之间实现数据共享
HttpSession    会话域 在当前会话范围之间实现数据共享
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;httpsession-常用方法&#34;&gt;HttpSession 常用方法&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                 说明
void   setAttribute(String.name,Object.value) 设置共享数据
Object getAttribute(String.name)              获取共享数据
void   removeAttribute(String.name)           移除共享数据
String getId()                                获取唯一标识名称
void   involidate()                           让session立即失效
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;httpsession-获取&#34;&gt;HttpSession 获取&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值      方法名                     说明
HttpSession getSession()               获取HttpSession对象
HttpSession getSession(boolean.create) 获取HttpSession,未获取到是否自动创建
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet( value = &amp;#34;/demo1Session&amp;#34;)
public class Demo1Session extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter(&amp;#34;username&amp;#34;);
        HttpSession session = req.getSession();
        System.out.println(session);
        System.out.println(session.getId());
        session.setAttribute(&amp;#34;username&amp;#34;,username);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet( value = &amp;#34;/demo2Session&amp;#34;)
public class Demo2Session extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();

        System.out.println(session);

        System.out.println(session.getId());

        Object username = session.getAttribute(&amp;#34;username&amp;#34;);

        resp.getWriter().write(username+&amp;#34;&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;禁用Cookie 就获取不到了&lt;/li&gt;
&lt;li&gt;可以使用手动拼接链接&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;resp.getWriter().write(&amp;#34;&amp;lt;a href=&amp;#39;&amp;#34;+resp.encodeURL(&amp;#34;http://localhost:8080/demo3Session&amp;#34;)+&amp;#34;&amp;#39;&amp;gt;go to servlet&amp;lt;/a&amp;gt;&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;httpsession-的细节&#34;&gt;HttpSession 的细节&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;浏览器禁用Cookie, 禁止访问&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;手动拼接URL, 不推荐&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;钝化和泛化&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;什么是钝化和活化
&lt;ul&gt;
&lt;li&gt;钝化: 序列化. 把长时间不用, 但还不到过期时间的HttpSession进行序列化, 写到磁盘上&lt;/li&gt;
&lt;li&gt;活化: 相反动作&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;何时钝化
&lt;ul&gt;
&lt;li&gt;每一种情况: 当访问量很大时, 服务器会根据getLastAccessTime来进行排序,对长时不用,还没过期的HttpSession进行序列化&lt;/li&gt;
&lt;li&gt;第二种飞速: 当服务器进行重启的时候, 为了保持客户HttpSession中的数据, 也要对其序列化.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;注意
&lt;ul&gt;
&lt;li&gt;HttpSession的序列化由服务器自动完成, 无需关心&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;jsp-介绍&#34;&gt;JSP 介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JSP(Java Server Pages): 是一种动态见面技术标准&lt;/li&gt;
&lt;li&gt;JSP部署在服务器上, 可以处理客户端发送的请求, 并根据请求内容动态的生成HTML,XML,或其他格式文件的Web见面, 然后再响应给客户端&lt;/li&gt;
&lt;li&gt;JSP是基于Java语文的, 它的本质就是Servlet&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;类别       使用场景
HTML       开发静态资源,无法添加动态资源
CSS        美化页面
JavaScript 给网页添加一些动态效果
Servlet    编写Java代码,实现抬功能处理
JSP        包含显示页面技术,也具备Java代码功能
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jsp-执行过程&#34;&gt;JSP 执行过程&lt;/h2&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/java/jsp.png&#34; alt=&#34;JSP执行过程&#34;  /&gt;
&lt;/p&gt;
&lt;h2 id=&#34;jsp-语法&#34;&gt;JSP 语法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JSP 注释&lt;/li&gt;
&lt;li&gt;Java 代码块&lt;/li&gt;
&lt;li&gt;JSP 表达式&lt;/li&gt;
&lt;li&gt;JSP 声明&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-jsp&#34; data-lang=&#34;jsp&#34;&gt;&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;%--这是一行注释--%&amp;gt;

&amp;lt;%--输出在控制台上--%&amp;gt;
&amp;lt;% System.out.println(&amp;#34;Hello&amp;#34;);%&amp;gt;
&amp;lt;%--输出在页面上, out是jspWriter对象--%&amp;gt;
&amp;lt;% out.println(&amp;#34;Hello&amp;lt;br&amp;gt;&amp;#34;); %&amp;gt;
&amp;lt;%
String str = &amp;#34;World&amp;#34;;
out.println(str);
%&amp;gt;
&amp;lt;br/&amp;gt;

&amp;lt;%--JSP表达式,等效out.println--%&amp;gt;
&amp;lt;%=&amp;#34;Hello World&amp;lt;br&amp;gt;&amp;#34;%&amp;gt;

&amp;lt;%--JSP声明, !是成员变量, 不加是局部方法变量, 方法里不能再定义方法 --%&amp;gt;
&amp;lt;%! String s = &amp;#34;AAAA&amp;lt;br&amp;gt;&amp;#34;; %&amp;gt;
&amp;lt;%=s%&amp;gt;
&amp;lt;%! public void he(){} %&amp;gt;
&amp;lt;%--&amp;lt;% public void hehe(){}%&amp;gt;--%&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jsp-指令&#34;&gt;JSP 指令&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;page 指令&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page 属性名=属性值 属性名=属性值... %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;属性名       作用
contentType  响应正文支持的类型和设置编码格式
language     使用的语文,默认使用java
errorPage    当前页面出现异常后跳转的页面
isErrorPage  是否抓住异常,如果为true则页面中就可以使用异常对象,默认是false
import       展示导包import=&amp;#34;java.util.ArrayList&amp;#34;
session      是否创建HttpSession对象,默认是true
buffer       设置JspWriter输入jsp内容缓存的大小,默认8kb
pageEncoding 翻译jsp时所用的编码格式
isElgnored   是否忽略EL表达式,默认false
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page import=&amp;#34;java.util.ArrayList&amp;#34; %&amp;gt;
&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; errorPage=&amp;#34;error.jsp&amp;#34;  %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;% int a = 1/0; %&amp;gt;

&amp;lt;% ArrayList&amp;lt;String&amp;gt; s = new ArrayList&amp;lt;&amp;gt;(); %&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;include 指令: 可以包含页面&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@include file=包含的页面 %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;%! String str = &amp;#34;Hahaha&amp;#34;; %&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page import=&amp;#34;java.util.ArrayList&amp;#34; %&amp;gt;
&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; errorPage=&amp;#34;error.jsp&amp;#34;  %&amp;gt;
&amp;lt;%@ include file=&amp;#34;include.jsp&amp;#34;%&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;%--&amp;lt;% int a = 1/0; %&amp;gt;--%&amp;gt;

&amp;lt;% ArrayList&amp;lt;String&amp;gt; s = new ArrayList&amp;lt;&amp;gt;(); %&amp;gt;

&amp;lt;%--引入include.jsp, 可使用其中参数--%&amp;gt;
&amp;lt;%=str%&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;taglib 指令: 可以引入外部标签库&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ taglib uri=标签库的地址 prefix=前缀名称 %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jsp-细节&#34;&gt;JSP 细节&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;九大隐式对象&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;隐式对象名称 代表实际对象
request      javax.servlet.http.HttpServletRequest
reponse      javax.servlet.http.HttpServletResponse
session      javax.servlet.http.HttpSession
application  javax.servlet.ServletContext
page         java.lang.Object
config       java.servlet.ServletConfig
exception    java.lang.Throwable
out          javax.servlet.jsp.JspWriter
pageContext  javax.servlet.jsp.PageContext
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;PageContext 对象&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是JSP独有的, Servlet中没有&lt;/li&gt;
&lt;li&gt;是四大域对象之一的页面域对象, 还可以操作其他三个域对象中的属性&lt;/li&gt;
&lt;li&gt;还可以获取其他八个隐藏对象&lt;/li&gt;
&lt;li&gt;生命周期随着JSP的创建而存在,随着JSP的结束而消失. 每个JSP页面都有一个PageContext对象.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;四大域对象&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;域对象名称 范围 级别 备注
PageContext 页面范围 最小,只能在当前页面用 国范围太小,开发中用的小
ServletRequest 请求范围 一次请求或当前请求转发用 请求转发之后,再次转发时请求域丢失
HttpSession 会话范围 多次请求数据共享使用 多次请求共享数据,但不同的客户端不能共享
ServletContext 应用范围 最大整个应用都可以使用 尽量少用,如果对数据有修改需要做同步处理
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;mvc-模型&#34;&gt;MVC 模型&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;M(Model): 模型. 用于封装数据, 封装的是数据模型&lt;/li&gt;
&lt;li&gt;V(View): 视图. 用于显示数据, 动态资源用JSP页面, 静态资源用HTML页面&lt;/li&gt;
&lt;li&gt;C(Controller): 控制器. 用于处理请求和响应, 例如Servlet&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/java/mvc.png&#34; alt=&#34;mvc&#34;  /&gt;
&lt;/p&gt;
&lt;h2 id=&#34;学生管理&#34;&gt;学生管理&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;index&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;%
        Object username = session.getAttribute(&amp;#34;username&amp;#34;);
        if( username == null){
    %&amp;gt;
    &amp;lt;a href=&amp;#34;/stuLogin.jsp&amp;#34; &amp;gt;请求登录&amp;lt;/a&amp;gt;
    &amp;lt;% } else { %&amp;gt;
    &amp;lt;a href=&amp;#34;/addStudent.jsp&amp;#34;&amp;gt;添加学生&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;#34;/listStudentServlet&amp;#34;&amp;gt;查看学生&amp;lt;/a&amp;gt;
    &amp;lt;% } %&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form action=&amp;#34;/loginServlet&amp;#34; method=&amp;#34;get&amp;#34; autocomplete=&amp;#34;off&amp;#34;&amp;gt;
    &amp;lt;label for=&amp;#34;username&amp;#34;&amp;gt;账户名称:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;username&amp;#34; id=&amp;#34;username&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;label for=&amp;#34;password&amp;#34;&amp;gt;账户密码:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;password&amp;#34; name=&amp;#34;password&amp;#34; id=&amp;#34;password&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;button type=&amp;#34;submit&amp;#34;&amp;gt;登录&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;添加学生&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form action=&amp;#34;/addStudent&amp;#34; method=&amp;#34;get&amp;#34; autocomplete=&amp;#34;off&amp;#34;&amp;gt;
    &amp;lt;label for=&amp;#34;username&amp;#34;&amp;gt;学生姓名:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;username&amp;#34; id=&amp;#34;username&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;label for=&amp;#34;age&amp;#34;&amp;gt;学生年龄:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;age&amp;#34; id=&amp;#34;age&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;label for=&amp;#34;chenji&amp;#34;&amp;gt;学生成绩:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;chenji&amp;#34; id=&amp;#34;chenji&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;button type=&amp;#34;submit&amp;#34;&amp;gt;添加&amp;lt;/button&amp;gt;
    &amp;lt;button type=&amp;#34;reset&amp;#34;&amp;gt;重置&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page import=&amp;#34;java.util.ArrayList&amp;#34; %&amp;gt;
&amp;lt;%@ page import=&amp;#34;com.lizicai.bean.Student&amp;#34; %&amp;gt;
&amp;lt;%@ page contentType=&amp;#34;text/html;charset=UTF-8&amp;#34; language=&amp;#34;java&amp;#34; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;学生列表&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;%
Object name = session.getAttribute(&amp;#34;username&amp;#34;);
if( name == null){
response.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
response.getWriter().write(&amp;#34;未登录, 跳转到登录页面...&amp;#34;);
response.setHeader(&amp;#34;Refresh&amp;#34;, &amp;#34;2;URL=/stuLogin.jsp&amp;#34;);
return;
}
%&amp;gt;
&amp;lt;table border=&amp;#34;1px&amp;#34; cellspacing=&amp;#34;0&amp;#34;&amp;gt;
    &amp;lt;thead&amp;gt;
    &amp;lt;th&amp;gt;学生姓名
    &amp;lt;/th&amp;gt;
    &amp;lt;th&amp;gt;
        学生年龄
    &amp;lt;/th&amp;gt;
    &amp;lt;th&amp;gt;
        学生成绩
    &amp;lt;/th&amp;gt;
    &amp;lt;/thead&amp;gt;
    &amp;lt;tbody&amp;gt;
        &amp;lt;%
            ArrayList&amp;lt;Student&amp;gt; list =(ArrayList&amp;lt;Student&amp;gt;) session.getAttribute(&amp;#34;students&amp;#34;);
            for(Student s: list){
        %&amp;gt;
            &amp;lt;tr align=&amp;#34;center&amp;#34;&amp;gt;
                &amp;lt;td&amp;gt;&amp;lt;%=s.getUsername() %&amp;gt;&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;&amp;lt;%=s.getAge() %&amp;gt;&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;&amp;lt;%=s.getChenji() %&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
        &amp;lt;% } %&amp;gt;
    &amp;lt;/tbody&amp;gt;
&amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet (value = &amp;#34;/loginServlet&amp;#34;)
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取用户名和密码
        String username = req.getParameter(&amp;#34;username&amp;#34;);
        String password = req.getParameter(&amp;#34;password&amp;#34;);

        // 判断用户名是否为空或null,   有效则写入session中
        HttpSession session = req.getSession();

        if( username.equals(null) || &amp;#34;&amp;#34;.equals(username)){
            resp.sendRedirect(&amp;#34;/stuLogin.jsp&amp;#34;);
            return;
        } else  {
            session.setAttribute(&amp;#34;username&amp;#34;, username);
            resp.sendRedirect(&amp;#34;/stuIndex.jsp&amp;#34;);
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

@WebServlet (value = &amp;#34;/addStudent&amp;#34;)
public class AddStudent extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        HttpSession session = req.getSession();
        Object name = session.getAttribute(&amp;#34;username&amp;#34;);
        if( name == null){
            resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
            resp.getWriter().write(&amp;#34;未登录, 跳转到登录页面...&amp;#34;);
            resp.setHeader(&amp;#34;Refresh&amp;#34;, &amp;#34;3;URL=/stuLogin.jsp&amp;#34;);
            return;
        }

        String username = req.getParameter(&amp;#34;username&amp;#34;);
        String age = req.getParameter(&amp;#34;age&amp;#34;);
        String chenji = req.getParameter(&amp;#34;chenji&amp;#34;);
        Student s = new Student(username, age, chenji);

        String realpath = getServletContext().getRealPath(&amp;#34;/stu.txt&amp;#34;);
        BufferedWriter bw = new BufferedWriter(new FileWriter(realpath,true));

        bw.write(s.getUsername()+&amp;#34;,&amp;#34;+s.getAge()+&amp;#34;,&amp;#34;+s.getChenji());
        bw.newLine();
        bw.close();
        resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
        resp.getWriter().write(&amp;#34;添加成功, 跳转到回添加页面&amp;#34;);
        resp.setHeader(&amp;#34;Refresh&amp;#34;, &amp;#34;3;URL=/addStudent.jsp&amp;#34;);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.ArrayList;

@WebServlet ( value = &amp;#34;/listStudentServlet&amp;#34;)
public class ListStudent extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 查询前校验有没有登录
        HttpSession session = req.getSession();
        Object name = session.getAttribute(&amp;#34;username&amp;#34;);
        if( name == null){
            resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
            resp.getWriter().write(&amp;#34;未登录, 跳转到登录页面...&amp;#34;);
            resp.setHeader(&amp;#34;Refresh&amp;#34;, &amp;#34;3;URL=/stuLogin.jsp&amp;#34;);
            return;
        }

        String realPath = getServletContext().getRealPath(&amp;#34;/stu.txt&amp;#34;);


        ArrayList&amp;lt;Student&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        BufferedReader br = new BufferedReader(new FileReader(realPath));
        String line;
        while ( (line = br.readLine()) != null ){
            String[] split = line.split(&amp;#34;,&amp;#34;);
            Student s = new Student();
            s.setUsername(split[0]);
            s.setAge(split[1]);
            s.setChenji(split[2]);
            list.add(s);
            System.out.println(split[0]+split[1]+split[2]);
        }

        // 集合对象放到会话里
        session.setAttribute(&amp;#34;students&amp;#34;, list);

        resp.sendRedirect(&amp;#34;/listStudent.jsp&amp;#34;);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>JavaWeb核心二 Li.055</title>
      <link>https://lizicai.com/p/javaweb%E6%A0%B8%E5%BF%83%E4%BA%8C-li.055/</link>
      <pubDate>Wed, 29 Sep 2021 00:30:39 +0800</pubDate>
      <guid>https://lizicai.com/p/javaweb%E6%A0%B8%E5%BF%83%E4%BA%8C-li.055/</guid>
      <description>&lt;h2 id=&#34;请求对象&#34;&gt;请求对象&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名           说明
String getContextPath() 获取虚拟目录名称
String getServletPath() 获取Servlet映射路径
String getRemoteAddr()  获取访问者ip地址
String getQueryString() 获取请求的消息数据
String getRequestURI()  获取统一资源标识符
String getRequestURL()  获取统一资源定位符
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = &amp;#34;demo1GetPath&amp;#34;, value = &amp;#34;/demo1GetPath&amp;#34;)
public class Demo1GetPath extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String contextPath = req.getContextPath();
        System.out.println(contextPath);

        String servletPath = req.getServletPath();
        System.out.println(servletPath);

        String remoteAddr = req.getRemoteAddr();
        System.out.println(remoteAddr);

        String queryString = req.getQueryString();
        System.out.println(queryString);

        String requestURI = req.getRequestURI();
        System.out.println(requestURI);

        StringBuffer requestURL = req.getRequestURL();
        System.out.println(requestURL);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;请求头信息&#34;&gt;请求头信息&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值              方法名                  说明
String              getHeader(String.name)  根据请求头名获取一个值
Enumeration&amp;lt;String&amp;gt; getHeaders(String.name) 根据请求头名获取多个值
Enumeration&amp;lt;String&amp;gt; getHeaderNames()        获取所有请求头名称
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet(name = &amp;#34;demo2GetPath&amp;#34;, value = &amp;#34;/demo2GetPath&amp;#34;)
public class Demo2GetPath extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String host = req.getHeader(&amp;#34;Host&amp;#34;);
        System.out.println(host);

        Enumeration&amp;lt;String&amp;gt; headers = req.getHeaders(&amp;#34;Accept-Encoding&amp;#34;);
        System.out.println(&amp;#34;----------------------------------------------&amp;#34;);
        while (headers.hasMoreElements()){
            String header = headers.nextElement();
            System.out.println(header);
        }
        Enumeration&amp;lt;String&amp;gt; headerNames = req.getHeaderNames();
        System.out.println(&amp;#34;================================&amp;#34;);
        while (headerNames.hasMoreElements()){
            String headerName = headerNames.nextElement();
            System.out.println(headerName+&amp;#34;....&amp;#34;+ req.getHeader(headerName));
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;获取请求参数信息&#34;&gt;获取请求参数信息&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值               方法名                          说明
String               getParameter(String.name)       根据名称获取数据
String[]             getParameterValues(String.name) 根据名称获取所有数据
Enumeration&amp;lt;String&amp;gt;  getParameterNames()             获取所有名称
Map&amp;lt;String,String[]&amp;gt; getParameterMap()               获取所有参数的键值对
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

@WebServlet(name = &amp;#34;Demo3GetRequestParamter&amp;#34;, value = &amp;#34;/demo3GetRequestParamter&amp;#34;)
public class Demo3GetRequestParamter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter(&amp;#34;username&amp;#34;);
        String password = req.getParameter(&amp;#34;password&amp;#34;);
        System.out.println(name+&amp;#34;...&amp;#34;+password);
        System.out.println(&amp;#34;----------------&amp;#34;);

        String[] hobbies = req.getParameterValues(&amp;#34;hobby&amp;#34;);
        for(String hobby:hobbies){
            System.out.println(hobby);
        }
        System.out.println(&amp;#34;====================&amp;#34;);

        Enumeration&amp;lt;String&amp;gt; parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String pname = parameterNames.nextElement();
            System.out.println(pname);
        }
        System.out.println(&amp;#34;===================&amp;#34;);

        Map&amp;lt;String, String[]&amp;gt; parameterMap = req.getParameterMap();
        for(Map.Entry&amp;lt;String,String[]&amp;gt; parameter : parameterMap.entrySet()){
            System.out.print(parameter.getKey());
            for(String s:parameter.getValue()){
                System.out.print(&amp;#34;,&amp;#34;+s);
            }
            System.out.println();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;获取请求参数并封装对象&#34;&gt;获取请求参数并封装对象&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;手动封装方式&lt;/li&gt;
&lt;li&gt;反射封装方式&lt;/li&gt;
&lt;li&gt;工具类封装方式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;手动封装的方式&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Arrays;

public class Student {
    private String username;
    private String password;
    private String[] hobby;
    public Student(){}
    public Student(String username, String password, String[] hobby) {
        this.username = username;
        this.password = password;
        this.hobby = hobby;
    }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public String[] getHobby() { return hobby; }
    public void setHobby(String[] hobby) { this.hobby = hobby; }
    @Override
    public String toString() {
        return &amp;#34;Student{&amp;#34; +
                &amp;#34;username=&amp;#39;&amp;#34; + username + &amp;#39;\&amp;#39;&amp;#39; +
                &amp;#34;, password=&amp;#39;&amp;#34; + password + &amp;#39;\&amp;#39;&amp;#39; +
                &amp;#34;, hobby=&amp;#34; + Arrays.toString(hobby) +
                &amp;#39;}&amp;#39;;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

@WebServlet(name = &amp;#34;demo4GetQequestStudent&amp;#34;, value = &amp;#34;/demo4GetQequestStudent&amp;#34;)
public class Demo4GetQequestStudent extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter(&amp;#34;username&amp;#34;);
        String password = req.getParameter(&amp;#34;password&amp;#34;);
        String[] hobby = req.getParameterValues(&amp;#34;hobby&amp;#34;);
        Student student = new Student(name,password,hobby);
        System.out.println(student);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;反射封装方式&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@WebServlet(name = &amp;#34;demo5GetQequestStudent&amp;#34;, value = &amp;#34;/demo5GetQequestStudent&amp;#34;)
public class Demo5GetQequestStudent extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Map&amp;lt;String,String[]&amp;gt; map = req.getParameterMap();
        Student stu = new Student();

        for(String name : map.keySet()){
            String[] values = map.get(name);

            try {
                PropertyDescriptor pd = new PropertyDescriptor(name, stu.getClass());
                Method writeMethod = pd.getWriteMethod();
                if( values.length&amp;gt;1){
                    writeMethod.invoke(stu,(Object)values);

                }else{
                    writeMethod.invoke(stu, values);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println(stu);

    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;工具类封装&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在webapp/lib/中添加commons-beanutils-1.9.4.jar和commons-logging-1.2.jar&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在本机的tomcat目录中lib目录也要添加上面2个文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;是在我的电脑或者Finder中添加到tomcat目录中lib里上面2个文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;否则提示如下问题&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;java.lang.NoClassDefFoundError: org/apache/commons/beanutils/BeanUtils
    com.lizicai.servlet.Demo6GetQequestStudent.doGet(Demo6GetQequestStudent.java:25)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.bean.Student;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet(name = &amp;#34;demo6&amp;#34;, value = &amp;#34;/demo6&amp;#34;)
public class Demo6GetQequestStudent extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Map&amp;lt;String,String[]&amp;gt; map = req.getParameterMap();
        Student stu = new Student();

        try {
            BeanUtils.populate(stu, map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        System.out.println(stu);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;流对象获取请求信息-了解即可-&#34;&gt;流对象获取请求信息( 了解即可 )&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值             方法名         说明
BufferedReader     getReader()    获取字符输入流
ServletInputStream getInputStream 获取字节输入流
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;** 流对象仅支持Post, 不支持Get**&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.example.javaweb_test3.HelloServlet;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;

@WebServlet(value = &amp;#34;/demo7&amp;#34;)
public class Demo7StreamPost extends HelloServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        BufferedReader br = req.getReader();
        String line;
        while (( line = br.readLine()) != null){
            System.out.println(line);
        }

        System.out.println(&amp;#34;------------------&amp;#34;);
        byte[] arr = new byte[1024];
        int len;
        ServletInputStream sis = req.getInputStream();
        while ( (len = sis.read(arr)) != -1){
            System.out.println(new String(arr,0,len));
        }

    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        super.doGet(request, response);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;post-请求中文乱码问题&#34;&gt;Post 请求中文乱码问题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GET 方式, 没有乱码, 在Tomcat8版本后已经解决&lt;/li&gt;
&lt;li&gt;POST 方式, 有乱码问题. 可以通过setCharacterEncoding()方法来解决&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = &amp;#34;/demo8&amp;#34;)
public class Demo8TestUTF8 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding(&amp;#34;UTF-8&amp;#34;);
        String username = req.getParameter(&amp;#34;username&amp;#34;);
        System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;请求域&#34;&gt;请求域&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;请求域(request域) 可以在一次请求范围内进行共享数据.&lt;/li&gt;
&lt;li&gt;PC请求 -&amp;gt; ServletA -&amp;gt; ServletB&lt;/li&gt;
&lt;li&gt;请求对象操作共享数据方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名 说明
void setAttribute(String.name,Object.value) 向请求域对象存储数据
Object getAttribute(String.name) 通过名称获取请求域对象的数据
void removeAttribute(String.name) 通过名称移除请求域对象中的数据
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;请求转发-客户端的一次请求到达后-发现需要借助其他servlet来实现啊啊练车&#34;&gt;请求转发, 客户端的一次请求到达后, 发现需要借助其他Servlet来实现啊啊练车&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;特点
&lt;ul&gt;
&lt;li&gt;浏览器地址栏不变&lt;/li&gt;
&lt;li&gt;域对象中的数据不丢失&lt;/li&gt;
&lt;li&gt;负责转发的Servlet转发前后的响应正文会丢失,(转发的Servelet不能响应)&lt;/li&gt;
&lt;li&gt;由转发的目的地来响应客户端&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值           方法名                                            说明
RequestDispacher getRequestDispatcher(String.name)                 获取请求高度对象

void             forward(ServletResquest.req,ServletRestpose.resp) 实现转发
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = &amp;#34;/demo9&amp;#34;)
public class Demo9Froward extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute(&amp;#34;name&amp;#34;, &amp;#34;isnewname&amp;#34;);

        RequestDispatcher requestDispatcher = req.getRequestDispatcher(&amp;#34;/demo10&amp;#34;);
        requestDispatcher.forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = &amp;#34;/demo10&amp;#34;)
public class Demo10Froward extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object name = req.getAttribute(&amp;#34;name&amp;#34;);
        System.out.println(name);

        System.out.println(&amp;#34;demo10&amp;#34;);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;请求包含&#34;&gt;请求包含&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;请求包含: 可以合并其他Servlet中的功能一起响应给客户端&lt;/li&gt;
&lt;li&gt;特点:
&lt;ul&gt;
&lt;li&gt;浏览器地址栏不变&lt;/li&gt;
&lt;li&gt;域对象中的数据不丢失&lt;/li&gt;
&lt;li&gt;被包含的Servlet响应头会丢失,( 转发的Servlet不能响应 )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值            方法名                            说明
RequestDispatcher getRequestDispatcher(String.name) 获取请求高度对象
void include(ServletResquest.req,ServletRestpose.resp) 实现包含
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = &amp;#34;/demo11&amp;#34;)
public class Demo11Froward extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute(&amp;#34;name&amp;#34;, &amp;#34;isnewname&amp;#34;);
        RequestDispatcher requestDispatcher = req.getRequestDispatcher(&amp;#34;/demo12&amp;#34;);
        requestDispatcher.include(req, resp);
        System.out.println(&amp;#34;demo11&amp;#34;);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = &amp;#34;/demo12&amp;#34;)
public class Demo12Froward extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object name = req.getAttribute(&amp;#34;name&amp;#34;);
        System.out.println(name);

        System.out.println(&amp;#34;demo12&amp;#34;);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;响应对象&#34;&gt;响应对象&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;响应: 回馈结果. 在BS架构中, 就是服务器给客户端浏览器反馈结果&lt;/li&gt;
&lt;li&gt;响应对象: 就是在项目中用于发送响应的对象.&lt;/li&gt;
&lt;li&gt;ServletResponse 和 HttpServletResponse&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;状态码 说明
200    成功
302    重定向
304    请求资源未改变,使用缓存
400    请求错误,常见于请求参数错误
404    请求资源未找到
405    请求方式不支持
500    服务器错误
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值              方法名                                    说明
ServletOutputStream getOutputStream()                         获取响应字节输出流对象
void                setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;) 设置响应内容类型,解决中文乱码问题
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = &amp;#34;/responseDemo1&amp;#34;)
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);

        ServletOutputStream sos = resp.getOutputStream();
        String str = &amp;#34;哈哈&amp;#34;;
        sos.write(str.getBytes());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值      方法名                                    说明
PrintWriter getWriter()                               获取响应输入流对象
void        setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;) 设置响应内容类型,解决中文乱码
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(value = &amp;#34;/responseDemo2&amp;#34;)
public class ResponseDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
        String str = &amp;#34;你好&amp;#34;;

        PrintWriter pw = resp.getWriter();
        pw.write(str);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;响应图片&#34;&gt;响应图片&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;创建字节输入流对象, 关联读取的图片路径&lt;/li&gt;
&lt;li&gt;通过响应对象获取字节输出流对象&lt;/li&gt;
&lt;li&gt;循环读取和写出图片&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;图片路径,由相对路径获取到war包的绝对路径,才能访问到&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其他资源也是一样的方式&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

@WebServlet(value = &amp;#34;/responseDemo3&amp;#34;)
public class ResponseDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String realPath = getServletContext().getRealPath(&amp;#34;/img/Steve_Halama.jpg&amp;#34;);

        System.out.println(realPath);
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream
                (realPath));

        ServletOutputStream outputStream = resp.getOutputStream();
        int len;
        byte[] arr = new byte[8192];
        while ( (len = bis.read(arr)) != -1){
            outputStream.write(arr,0,len);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;设置缓存&#34;&gt;设置缓存&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;缓存: 对象不经常变化的数据, 我们可以设置合理缓存时间, 以避免浏览器频繁请求服务器. 以此提高效率.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                               说明
void   setDateHeader(String.name,long.time) 设置消息头添加缓存
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Chrome无效&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

@WebServlet(value = &amp;#34;/responseDemo4&amp;#34;)
public class ResponseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);

        resp.setDateHeader(&amp;#34;Expires&amp;#34;,System.currentTimeMillis()+5*60*1000);
        resp.getWriter().println(&amp;#34;缓存&amp;#34;);

        System.out.println(&amp;#34;请求一次&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;定时刷新&#34;&gt;定时刷新&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名 说明
void setHeader(String.name,String.value) 设置消息头定时刷新
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = &amp;#34;/responseDemo5&amp;#34;)
public class ResponseDemo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String str = &amp;#34;你的用户名或密码有误, 3秒后自动跳转登录页~&amp;#34;;

        resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
        resp.getWriter().write(str);

        resp.setHeader(&amp;#34;Refresh&amp;#34;, &amp;#34;3;URL=/stu/login/register.html&amp;#34;);

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;请求重定向&#34;&gt;请求重定向&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;请求重定向: 客户端的一次请求到达后, 发现需要借助其他Servlet来实现功能&lt;/li&gt;
&lt;li&gt;特点: 浏览器地址栏会发生改变, 两次请求, 请求域对象中不能共享数据, 可以重定向到其他服务器&lt;/li&gt;
&lt;li&gt;重写向实现原理
&lt;ul&gt;
&lt;li&gt;设置响应状态码为302 resp.setStatus(302)&lt;/li&gt;
&lt;li&gt;设置响应的资源路径(响应到哪里去, 通过响应消息头location来指定)resp.setHeader(&amp;ldquo;location&amp;rdquo;,&amp;quot;/stu/responseDemo7&amp;quot;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名 说明
void sendRedirect(String.name) 设置重定向
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = &amp;#34;/responseDemo6&amp;#34;)
public class ResponseDemo6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute(&amp;#34;name&amp;#34;,&amp;#34;zhangsan&amp;#34;);

        resp.sendRedirect(req.getContextPath() +&amp;#34;/responseDemo7&amp;#34;);
        resp.sendRedirect(&amp;#34;http://baidu.com&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = &amp;#34;/responseDemo7&amp;#34;)
public class ResponseDemo7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Object name = req.getAttribute(&amp;#34;name&amp;#34;);
        System.out.println(name);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;文件下载&#34;&gt;文件下载&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;创建字节输入流, 关联文件&lt;/li&gt;
&lt;li&gt;设置响应消息头支持的类型&lt;/li&gt;
&lt;li&gt;设置响应消息头f以下载方式打开资源&lt;/li&gt;
&lt;li&gt;通过响应对象获取字节输出流对象&lt;/li&gt;
&lt;li&gt;循环读写&lt;/li&gt;
&lt;li&gt;释放资源&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

@WebServlet( value = &amp;#34;/responseDemo8&amp;#34;)
public class ResponseDemo8 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String realPath = getServletContext().getRealPath(&amp;#34;/img/Steve_Halama.jpg&amp;#34;);

//        Content-Type 消息头名称, 支持的类型
//        application/octet-stream消息头参数 应用类型为字节流
        resp.setHeader(&amp;#34;Content-Type&amp;#34;, &amp;#34;application/octet-stream&amp;#34;);

//        Content-Disposition  消息头名称 处理的形式
//        attachment;filename=Steve_Halama.jpg 消息头参数 附件形式处理 指定下载文件名称
        resp.setHeader(&amp;#34;Content-Disposition&amp;#34;, &amp;#34;attachment;filename=Steve_Halama.jpg&amp;#34;);

        InputStream in = new FileInputStream(realPath);
        BufferedInputStream bis = new BufferedInputStream(in);
        byte[] arr = new byte[10240];
        int len;
        ServletOutputStream sos = resp.getOutputStream();
        while ( (len = bis.read(arr)) != -1){
            sos.write(arr,0,len);
        }

        bis.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;案例-学生管理系统&#34;&gt;案例 学生管理系统&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;首页, 2个超链接, 添加学生, 查看学生&lt;/li&gt;
&lt;li&gt;添加学生, 添加成功后自动跳转到首页&lt;/li&gt;
&lt;li&gt;查看学生&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&amp;#34;text/html; charset=UTF-8&amp;#34; pageEncoding=&amp;#34;UTF-8&amp;#34; %&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;JSP - Hello World&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;a href=&amp;#34;login/addStudent.html&amp;#34;&amp;gt;添加学生&amp;lt;/a&amp;gt; &amp;lt;a href=&amp;#34;/stu/studentList&amp;#34;&amp;gt;查看学生&amp;lt;/a&amp;gt;
&amp;lt;br/&amp;gt;
&amp;lt;%--&amp;lt;a href=&amp;#34;hello-servlet&amp;#34;&amp;gt;Hello Servlet&amp;lt;/a&amp;gt;--%&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;添加学生&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form method=&amp;#34;post&amp;#34; action=&amp;#34;/stu/studentAdd&amp;#34; autocomplete=&amp;#34;off&amp;#34;&amp;gt;
  &amp;lt;label for=&amp;#34;username&amp;#34;&amp;gt;学生姓名:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;username&amp;#34; id=&amp;#34;username&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;label for=&amp;#34;age&amp;#34;&amp;gt;学生年龄:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;age&amp;#34; id=&amp;#34;age&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;label for=&amp;#34;chenji&amp;#34;&amp;gt;学生成绩:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;chenji&amp;#34; id=&amp;#34;chenji&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;button type=&amp;#34;submit&amp;#34;&amp;gt;保存&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Student {
    private String name;
    private int age;
    private int chenji;
    public Student(){}

    public Student(String name, int age, int chenji) {
        this.name = name;
        this.age = age;
        this.chenji = chenji;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getChenji() {
        return chenji;
    }

    public void setChenji(int chenji) {
        this.chenji = chenji;
    }

    @Override
    public String toString() {
        return
                 name + &amp;#34;,&amp;#34; +
                 age +&amp;#34;,&amp;#34;+
                chenji ;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * 写入学生
 */
@WebServlet(value = &amp;#34;/studentAdd&amp;#34;)
public class StudentAdd extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding(&amp;#34;UTF-8&amp;#34;);
        Student s = new Student();
        s.setName(req.getParameter(&amp;#34;username&amp;#34;));
        s.setAge( Integer.parseInt(req.getParameter(&amp;#34;age&amp;#34;)) ) ;
        s.setChenji(Integer.parseInt(req.getParameter(&amp;#34;chenji&amp;#34;)));


        String realPath = getServletContext().getRealPath(&amp;#34;/img/student.txt&amp;#34;);

        Writer out;
        PrintWriter pw = new PrintWriter(new FileWriter(realPath,true));
        pw.println(s);
        pw.close();

        String str = &amp;#34;添加用户成功, 2秒后自动学生添加页~&amp;#34;;

        resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
        resp.getWriter().write(str);

        resp.setHeader(&amp;#34;Refresh&amp;#34;, &amp;#34;3;URL=/stu/index.jsp&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;

/**
 * 查询学生信息
 */

@WebServlet(value = &amp;#34;/studentList&amp;#34;)
public class StudentList extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String realPath = getServletContext().getRealPath(&amp;#34;/img/student.txt&amp;#34;);
        ArrayList&amp;lt;Student&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        BufferedReader br = new BufferedReader(new FileReader(realPath));
        String line;
        while ( (line = br.readLine()) != null ){
            String[] split = line.split(&amp;#34;,&amp;#34;);
            Student s = new Student();
            s.setName(split[0]);
            s.setAge(Integer.parseInt(split[1]));
            s.setChenji(Integer.parseInt(split[2]));
            list.add(s);
        }


        resp.setContentType(&amp;#34;text/html;charset=UTF-8&amp;#34;);
        PrintWriter pw = resp.getWriter();
        for(Student s : list){
            pw.print(s);
            pw.write(&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>JavaWeb核心一 Li.054</title>
      <link>https://lizicai.com/p/javaweb%E6%A0%B8%E5%BF%83%E4%B8%80-li.054/</link>
      <pubDate>Sun, 26 Sep 2021 13:20:52 +0800</pubDate>
      <guid>https://lizicai.com/p/javaweb%E6%A0%B8%E5%BF%83%E4%B8%80-li.054/</guid>
      <description>&lt;h2 id=&#34;1-idea-创建-javaweb-项目&#34;&gt;1. IDEA 创建 JavaWeb 项目&lt;/h2&gt;
&lt;h3 id=&#34;11-选择javaee-项目&#34;&gt;1.1 选择JavaEE 项目&lt;/h3&gt;
&lt;h3 id=&#34;12-project-tempate中选择--web-application&#34;&gt;1.2 Project tempate中选择  Web Application&lt;/h3&gt;
&lt;h3 id=&#34;13-一路创建&#34;&gt;1.3 一路创建&lt;/h3&gt;
&lt;h3 id=&#34;14-在edit-configurations-设置tomcat-下面为brew-安装的tomcat地址&#34;&gt;1.4 在Edit Configurations 设置tomcat, 下面为brew 安装的tomcat地址&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/usr/local/Cellar/tomcat@9/9.0.53/libexec
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;15-设置on-update-action-update-resources-on-frame-deactivation-update-resources&#34;&gt;1.5 设置On update action: update resources, On frame deactivation: update resources&lt;/h3&gt;
&lt;h3 id=&#34;16-设置第二栏deployment-application-text-web_demo&#34;&gt;1.6 设置第二栏Deployment: Application text: /web_demo&lt;/h3&gt;
&lt;h3 id=&#34;17-启动tomcat-即可自动在浏览器上预览&#34;&gt;1.7 启动tomcat 即可自动在浏览器上预览&lt;/h3&gt;
&lt;h2 id=&#34;2-打包javaweb-项目&#34;&gt;2. 打包JavaWeb 项目&lt;/h2&gt;
&lt;h3 id=&#34;21-在本地wepapp文件夹内-使用jar--cvf-mywebwar-打包&#34;&gt;2.1 在本地wepapp文件夹内, 使用jar -cvf myweb.war .打包&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;jar -cvf myweb.war .
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;22-上传到tomcat服务器中的webapps中-重启tomcat即可看到发布结果&#34;&gt;2.2 上传到tomcat服务器中的webapps中, 重启tomcat即可看到发布结果&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;scp myweb.war webserver:tomcat9.0/webapps/

./shutdown.sh
./startup.sh
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-更改tomcat-端口&#34;&gt;3. 更改Tomcat 端口&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;conf中server.xml 8080更改为80端口
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;4-在serverxml中添加其它目录做为tomcat项目&#34;&gt;4. 在server.xml中添加其它目录做为tomcat项目&lt;/h2&gt;
&lt;p&gt;**在Host中间添加&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;Context path=&amp;#34;/myweb&amp;#34; docBase=&amp;#34;/Users/lizicai/IdeaProjects/web_demo/src/main/webapp&amp;#34; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;访问ip:8080/myweb 即可&lt;/p&gt;
&lt;h2 id=&#34;5-设置域名访问tomcat&#34;&gt;5. 设置域名访问tomcat&lt;/h2&gt;
&lt;h3 id=&#34;51-在serverxml中添加配置&#34;&gt;5.1 在server.xml中添加配置&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 在&amp;lt;Engine name=&amp;#34;Catalina&amp;#34; defaultHost=&amp;#34;localhost&amp;#34;&amp;gt; 下添加
&amp;lt;Host name=&amp;#34;tom.lizicai.com&amp;#34; appbase=&amp;#34;webapps&amp;#34;
    unpackWARs=&amp;#34;true&amp;#34; autoDeploy=&amp;#34;true&amp;#34; &amp;gt;
    &amp;lt;Context path=&amp;#34;/s&amp;#34; docBase=&amp;#34;web_demo&amp;#34; /&amp;gt;
&amp;lt;/Host&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;name 域名
appbase 项目存放路径
unpackWARs 解压
autoDeploy 自动发布
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;52-设置dns-或者更改本机hosts&#34;&gt;5.2 设置dns, 或者更改本机hosts&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 添加dns
192.168.0.100 tom.lizicai.com

# 更改本机hosts
127.0.0.1 tom.lizicai.com
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;6-http-协议的响应&#34;&gt;6. HTTP 协议的响应&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;常见状态码&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;200 一切OK
302/307 请求重定向,两次请求,地址栏发生变化
304 请求资源未发生变化,使用缓存
404 请求资源未找到
500 服务器错误
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;HTTP 响应头&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Location               请求重定向的地址,常与302,307配合使用
Server                 服务器相关信息
Content-Type           响应正文的MIME类型
Content-Length         响应正文的长度
Content-Dispositio     告知客户端浏览器,以下载的方式打开响应正文
Refresh                定时刷新
Lash-Modified          服务器资源的最后修改时间
Set-Cookie             会放管理相关,非常重要
Expires:-1             服务器资源到客户端浏览器后的缓存时间
Catch-Control:no-catch 不要缓存
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;servlet&#34;&gt;Servlet&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Servlet的介绍
&lt;ul&gt;
&lt;li&gt;Servlet是运行在Java 服务器端的程序，用于接收和响应来自客户端基于HTTP协议的请求。&lt;/li&gt;
&lt;li&gt;如果想实现Servlet的功能，可以通过实现javax.servlet.Servlet接口或者继承它的实现类。&lt;/li&gt;
&lt;li&gt;核心方法：service(),任何客户端的请求都会经过该方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;对应项目案例在03_javaweb&#34;&gt;对应项目案例在03_JavaWeb&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Servlet 的执行流程
&lt;ul&gt;
&lt;li&gt;浏览器地址&lt;/li&gt;
&lt;li&gt;web.xml的地址/url&lt;/li&gt;
&lt;li&gt;/url匹配web.xml的servlet name&lt;/li&gt;
&lt;li&gt;servlet name 匹配servlet class&lt;/li&gt;
&lt;li&gt;执行servlet calss中的service()方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;实现-genericservlet&#34;&gt;实现 GenericServlet&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.test;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

public class Demo1GenericServlet extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println(&amp;#34;Servlet 执行了&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;实现httpservlet&#34;&gt;实现HttpServlet&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Demo2HttpServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(&amp;#34;DoPost 执行了&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;servlet-详细执行过程&#34;&gt;servlet 详细执行过程&lt;/h3&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/java/servlet-run-process.png&#34; alt=&#34;servlet执行过程&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;servlet-genericservlet-httpservlet-之间的关系&#34;&gt;Servlet GenericServlet HttpServlet 之间的关系&lt;/h3&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/java/servlet-generic-httpservlet.png&#34; alt=&#34;Servlet GenericServlet HttpServlet关系&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;servlet-实现方式&#34;&gt;Servlet 实现方式&lt;/h3&gt;
&lt;p&gt;Servlet 实现方式&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一种
&lt;ul&gt;
&lt;li&gt;实现Servlet接口，实现所有的抽象方法。该方式支持最大程度的自定义。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第二种
&lt;ul&gt;
&lt;li&gt;继承 GenericServlet抽象类，必须重写 service方法，其他方法可选择重写。该方式让我们开发Servlet变得简单。&lt;/li&gt;
&lt;li&gt;但是这种方式和HTTP协议无关。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第三种
&lt;ul&gt;
&lt;li&gt;继承 Httpser/let抽象类&lt;/li&gt;
&lt;li&gt;需要重写doGet和doPost方法。该方式表示请求和响应都需要和HTTP协议相关。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;servlet-生命周期&#34;&gt;Servlet 生命周期&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;出生: 请求第一次到达Servlet时,对象就创建出来, 并且初始化. 只出生一次, 放到内存中.&lt;/li&gt;
&lt;li&gt;活着: 服务器提供服务的整个过程中, 该对象一直存在, 每次都执行service() 方法&lt;/li&gt;
&lt;li&gt;死亡: 当前服务停止时, 或者服务器宕机时, 对象死亡.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;结论: Servlet 对象只会创建一次, 销毁一次, 所以Servlet对象只有一个实例, 如果对象实例在应用中是唯一存在, 就是单例模式&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;servlet-线程案例问题&#34;&gt;Servlet 线程案例问题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;由于Servlet 采用的单例模式, 也就是整个应用中只有一个实例, 这个实例是否是线程案例的&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;模拟2个用户同时访问HttpServlet时, doGet中打印用户名, 其中一个sleep3000&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;结论: 2个用户返回同一个用户名, 线程不安全的.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;解决:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;定义类成员要谨慎. 如果是共用的, 并且只会在初始化时赋值, 其他时间都是获取的话,那没问题的.&lt;/li&gt;
&lt;li&gt;如果不是共用的, 或者每次使用都有可能对其赋值, 那就要考虑线程安全问题了.&lt;/li&gt;
&lt;li&gt;变量可以定义到doGet doPost方法内&lt;/li&gt;
&lt;li&gt;在doGet doPost 使用同步功能, 如 synchronized (this)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class Demo4HttpServletFixed extends HttpServlet {
    private String username;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = null;
        username = req.getParameter(&amp;#34;username&amp;#34;);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        PrintWriter pw = resp.getWriter();
        pw.println(&amp;#34;welcome   &amp;#34;+username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        synchronized (this){
            username = req.getParameter(&amp;#34;username&amp;#34;);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            PrintWriter pw = resp.getWriter();
            pw.println(&amp;#34;welcome   &amp;#34;+username);
        }

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;serlet-映射方式&#34;&gt;Serlet 映射方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;第一种
&lt;ul&gt;
&lt;li&gt;具体名称的方式, 访问的资源路径必须和映射配置安全相同&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第二种
&lt;ul&gt;
&lt;li&gt;/开头 + 通配符的方式. 只要符合目录结构即可, 不用是考虑结尾&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第三种
&lt;ul&gt;
&lt;li&gt;通配符 + 固定格式结尾的方式. 只要符合固定结尾格式即可, 不用考虑前面的路径&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;**优先级的问题, 越时具体优化级越高, 第一种 &amp;gt; 第二种 &amp;gt; 第三种&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!--    Servlet 映射方式1   --&amp;gt;
    &amp;lt;servlet&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo5HttpServlet&amp;lt;/servlet-name&amp;gt;
        &amp;lt;servlet-class&amp;gt;com.lizicai.test.Demo5HttpServlet&amp;lt;/servlet-class&amp;gt;
    &amp;lt;/servlet&amp;gt;
    &amp;lt;servlet-mapping&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo5HttpServlet&amp;lt;/servlet-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/demo5HttpServlet&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/servlet-mapping&amp;gt;

&amp;lt;!--    Servlet 映射方式2 --&amp;gt;
    &amp;lt;servlet&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo5HttpServlet&amp;lt;/servlet-name&amp;gt;
        &amp;lt;servlet-class&amp;gt;com.lizicai.test.Demo5HttpServlet&amp;lt;/servlet-class&amp;gt;
    &amp;lt;/servlet&amp;gt;
    &amp;lt;servlet-mapping&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo5HttpServlet&amp;lt;/servlet-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/demo/*&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/servlet-mapping&amp;gt;

    &amp;lt;!--    Servlet 映射方式3 --&amp;gt;
    &amp;lt;servlet&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo5HttpServlet&amp;lt;/servlet-name&amp;gt;
        &amp;lt;servlet-class&amp;gt;com.lizicai.test.Demo5HttpServlet&amp;lt;/servlet-class&amp;gt;
    &amp;lt;/servlet&amp;gt;
    &amp;lt;servlet-mapping&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo5HttpServlet&amp;lt;/servlet-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;*.do&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/servlet-mapping&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Servlet 多映射使用的场景&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Demo6HttpServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int sum = 100;
        String url = req.getRequestURI();
        String vUrl = url.substring(url.lastIndexOf(&amp;#34;/&amp;#34;));
        if( &amp;#34;/vip&amp;#34;.equals(vUrl)){
            sum = 95;
        } else if( &amp;#34;/vvip&amp;#34;.equals(vUrl)){
            sum = 90;
        } else {
            sum = 100;
        }
        System.out.println(url+&amp;#34;...&amp;#34;+vUrl+&amp;#34;您的商品价格是&amp;#34;+sum+&amp;#34;元&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;servlet-创建时机&#34;&gt;Servlet 创建时机&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;第一次访问时创建
&lt;ul&gt;
&lt;li&gt;优势: 减少对服务器内存的浪费. 提高了服务器启动的效率&lt;/li&gt;
&lt;li&gt;弊端: 如果有一些要在应用加载时就做的初始化操作, 无法完成&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;服务器加载时创建
&lt;ul&gt;
&lt;li&gt;优势: 提前创建好对象, 提高了首次执行的效率. 可以完成一些应用加载时要做的初始化操作&lt;/li&gt;
&lt;li&gt;弊端: 对服务器内存占用较多, 影响了服务器启动的效率.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;**修改Servlet 创建时机, 在&lt;servlet&gt;标签中, 添加&lt;load-on-startup&gt;标签
**正整数代表服务器加载时间创建, 值越小优先级越高. 负整数或不写代表第一次访问创建.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;servlet&amp;gt;
    &amp;lt;servlet-name&amp;gt;demo6HttpServlet&amp;lt;/servlet-name&amp;gt;
    &amp;lt;servlet-class&amp;gt;com.lizicai.test.Demo6HttpServlet&amp;lt;/servlet-class&amp;gt;
    &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
&amp;lt;/servlet&amp;gt;
&amp;lt;servlet-mapping&amp;gt;
    &amp;lt;servlet-name&amp;gt;demo6HttpServlet&amp;lt;/servlet-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/demo/*&amp;lt;/url-pattern&amp;gt;
&amp;lt;/servlet-mapping&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;默认servlet&#34;&gt;默认Servlet&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;默认Servlet 是由服务器提供的一个Servlet. 它配置在Tomcat的conf目录中的web.xml中.&lt;/li&gt;
&lt;li&gt;它的映射路径是&lt;url-pattern&gt;/&lt;/url-pattern&gt;, 我们在发送请求时, 首先会在我们项目中的web中查看映射配置, 找到则执行.&lt;/li&gt;
&lt;li&gt;但是当找不到对应的Servlet路径时, 就去找默认的Servlet, 由默认Servlet处理, 一切都Servlet.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;servletconfig&#34;&gt;ServletConfig&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ServletConfig 是Servlet 的配置参数对象, 在Servlet的规范中, 允许为每一个Servlet都提供一个初始化的配置. 所以每个Servlet都有一个自己的ServletConfig&lt;/li&gt;
&lt;li&gt;作用: 在Servlet的初始化时, 把一些配置信息传递给Servlet&lt;/li&gt;
&lt;li&gt;生命周期: 和Servlet 相同.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;servlet&amp;gt;
    &amp;lt;servlet-name&amp;gt;demo7ServletConfig&amp;lt;/servlet-name&amp;gt;
    &amp;lt;servlet-class&amp;gt;com.lizicai.test.Demo7ServletConfig&amp;lt;/servlet-class&amp;gt;
    &amp;lt;init-param&amp;gt;
        &amp;lt;param-name&amp;gt;encoding&amp;lt;/param-name&amp;gt;
        &amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
&amp;lt;/servlet&amp;gt;
&amp;lt;servlet-mapping&amp;gt;
    &amp;lt;servlet-name&amp;gt;demo7ServletConfig&amp;lt;/servlet-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/demo7&amp;lt;/url-pattern&amp;gt;
&amp;lt;/servlet-mapping&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;servletconfig-常用方法&#34;&gt;ServletConfig 常用方法&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值              方法名                       说明
String              getInitParameter(Stringname) 根据参数名称获取参数值
Enumeration&amp;lt;String&amp;gt; getInitParameterNames()      获取所有参数名称的枚举
String              getServletName()             获取Servlet名称
ServletContext      getServletContext()          获取ServletContext对象
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

public class Demo7ServletConfig extends HttpServlet {
    private ServletConfig config;

    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String enCodingValue = config.getInitParameter(&amp;#34;encoding&amp;#34;);
        System.out.println(enCodingValue);

        Enumeration&amp;lt;String&amp;gt; initParameterNames = this.config.getInitParameterNames();

        while ( initParameterNames.hasMoreElements()){
            String key = initParameterNames.nextElement();
            String value = config.getInitParameter(key);
            System.out.println(key+&amp;#34;....&amp;#34;+value);
        }

        String sereletName = config.getServletName();
        System.out.println(sereletName);

        ServletContext servletContext = config.getServletContext();
        System.out.println(servletContext);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;servletcontext-介绍&#34;&gt;ServletContext 介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ServletContext 是应用上下文对象(应用域对象). 每一个应用中只有一个SeverContext对象&lt;/li&gt;
&lt;li&gt;作用: 可以配置和获得应用的全局初始化参数, 可以实现Servlet之间的数据共享.&lt;/li&gt;
&lt;li&gt;生命周期: 应用一加载则创建, 应用被停止则销毁&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;域对象&#34;&gt;域对象&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;域对象指的是对象有作用域. 也就是有作用范围. 域对象可以实现数据的共享. 不同的作用范围的域对象, 共享数据的能力也不一样&lt;/li&gt;
&lt;li&gt;在Servlet规范中, 一共有4个域对象. ServletContext就是其中的一个, 它也是Web应用中最大的作用域, 也&lt;/li&gt;
&lt;li&gt;叫application域. 它可以实现整个应用之间的数据共享.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/java/servletContext.png&#34; alt=&#34;ServletContext与下面Servlet关系&#34;  /&gt;
&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;servlet&amp;gt;
    &amp;lt;servlet-name&amp;gt;demo8ServletContext&amp;lt;/servlet-name&amp;gt;
    &amp;lt;servlet-class&amp;gt;com.lizicai.test.Demo8ServletContext&amp;lt;/servlet-class&amp;gt;
&amp;lt;/servlet&amp;gt;
&amp;lt;servlet-mapping&amp;gt;
    &amp;lt;servlet-name&amp;gt;demo8ServletContext&amp;lt;/servlet-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/demo8ServletContext&amp;lt;/url-pattern&amp;gt;
&amp;lt;/servlet-mapping&amp;gt;

&amp;lt;context-param&amp;gt;
    &amp;lt;param-name&amp;gt;globalEncoding&amp;lt;/param-name&amp;gt;
    &amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt;
&amp;lt;/context-param&amp;gt;
&amp;lt;context-param&amp;gt;
    &amp;lt;param-name&amp;gt;globalDesc&amp;lt;/param-name&amp;gt;
    &amp;lt;param-value&amp;gt;ServletContext cc&amp;lt;/param-value&amp;gt;
&amp;lt;/context-param&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;servlet-常用方法&#34;&gt;Servlet 常用方法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;返回值 方法名                                  说明
String getInitParameter(String.name)           根据名称获取全局配置的参数
String getContextPath()                        获取虚拟路径,这是run配置的delployment的context路径
String getRealPath(String.path)                根据虚拟目录获取应用部署的磁盘绝对路径
void   setAttribute(String.name,Object.object) 向应用域对象中存储数据
Object getAttribute(String.name)               通过名称获取应用域对象中的数据
void   removeAttribute(String.name)            通过名称移除应用域对象中的数据
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Demo8ServletContext extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();

        String value = servletContext.getInitParameter(&amp;#34;globalEncoding&amp;#34;);
        System.out.println(value);

        String contextPath = servletContext.getContextPath();
        System.out.println(contextPath);

        String realPath = servletContext.getRealPath(&amp;#34;/&amp;#34;);
        System.out.println(realPath);

        String realPath2 = servletContext.getRealPath(&amp;#34;/b.txt&amp;#34;);
        System.out.println(realPath2);
        String realPath3 = servletContext.getRealPath(&amp;#34;/WEB-INF/c.txt&amp;#34;);
        System.out.println(realPath3);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;多个servlet-之间从servletcontext-获取数据&#34;&gt;多个Servlet 之间从ServletContext 获取数据&lt;/h3&gt;
&lt;h3 id=&#34;先访问demo8servletcontext2再访问demo8servletcontext3&#34;&gt;先访问demo8ServletContext2再访问demo8ServletContext3&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!--    多Servlet间共享数据, 通过ServletContext, Demo8ServletContext2和 Demo8ServletContext3之间--&amp;gt;

    &amp;lt;servlet&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo8ServletContext2&amp;lt;/servlet-name&amp;gt;
        &amp;lt;servlet-class&amp;gt;com.lizicai.test.Demo8ServletContext2&amp;lt;/servlet-class&amp;gt;
    &amp;lt;/servlet&amp;gt;
    &amp;lt;servlet-mapping&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo8ServletContext2&amp;lt;/servlet-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/demo8ServletContext2&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/servlet-mapping&amp;gt;

    &amp;lt;servlet&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo8ServletContext3&amp;lt;/servlet-name&amp;gt;
        &amp;lt;servlet-class&amp;gt;com.lizicai.test.Demo8ServletContext3&amp;lt;/servlet-class&amp;gt;
    &amp;lt;/servlet&amp;gt;
    &amp;lt;servlet-mapping&amp;gt;
        &amp;lt;servlet-name&amp;gt;demo8ServletContext3&amp;lt;/servlet-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/demo8ServletContext3&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/servlet-mapping&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Demo8ServletContext2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        servletContext.setAttribute(&amp;#34;name&amp;#34;, new String(&amp;#34;Zhangsan&amp;#34;));
        System.out.println(&amp;#34;访问Demo8ServletContext2...写入Attribute&amp;#34;);

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Demo8ServletContext3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        String value = (String) servletContext.getAttribute(&amp;#34;name&amp;#34;);
        System.out.println(&amp;#34;从ServletContext 取出之前2存入name&amp;#34;+value);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;注解开发servlet&#34;&gt;注解开发Servlet&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(&amp;#34;/demo9Servlet&amp;#34;)
public class Demo9Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(&amp;#34;处理请求...&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;手动创建容器&#34;&gt;手动创建容器&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;创建Demo10ManualServle 继承 HttpServlet&lt;/li&gt;
&lt;li&gt;MyRegister implements ServletContainerInitializer&lt;/li&gt;
&lt;li&gt;在src/main/java文件夹下创建包META-INF.services, 创建文件javax.servlet.ServletContainerInitializer, 添加一行com.lizicai.test.MyRegister&lt;/li&gt;
&lt;li&gt;在MyRegister中执行
&lt;ul&gt;
&lt;li&gt;Demo10ManualServle demo10ManualServle = new Demo10ManualServle();&lt;/li&gt;
&lt;li&gt;ServletRegistration.Dynamic registration = servletContext.addServlet (&amp;ldquo;demo10ManualServle&amp;rdquo;, demo10ManualServle);&lt;/li&gt;
&lt;li&gt;registration.addMapping(&amp;quot;/demo10ManualServle&amp;quot;);&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;浏览器访问 /demo10ManualServle&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Demo10ManualServle extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(&amp;#34;Demo10ManualServle处理请求...&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class MyRegister implements ServletContainerInitializer {
    @Override
    public void onStartup(Set&amp;lt;Class&amp;lt;?&amp;gt;&amp;gt; set, ServletContext servletContext) throws ServletException {
        // 创建servlet
        Demo10ManualServle demo10ManualServle = new Demo10ManualServle();

        // ServletContext  对象添加Servlet, 并得到Servlet 的动态配置对象
       ServletRegistration.Dynamic registration = servletContext.addServlet
               (&amp;#34;demo10ManualServle&amp;#34;, demo10ManualServle);

        registration.addMapping(&amp;#34;/demo10ManualServle&amp;#34;);

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;com.lizicai.test.MyRegister
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;案例-提交学生信息-保存文件中-同时返回一个保存成功信息给浏览器&#34;&gt;案例, 提交学生信息-&amp;gt;保存文件中-&amp;gt;同时返回一个保存成功信息给浏览器&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

@WebServlet(&amp;#34;/demo11StudentServlet&amp;#34;)
public class Demo11StudentServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = (req.getParameter(&amp;#34;name&amp;#34;));
        String  age =  req.getParameter(&amp;#34;age&amp;#34;) ;
        String  chenji = req.getParameter(&amp;#34;chenji&amp;#34;) ;

        File file = new File(&amp;#34;/Users/lizicai/workplace/test/b.txt&amp;#34;);
        BufferedWriter bw = new BufferedWriter(new FileWriter(file,true));
        String sStr = name+&amp;#34;,&amp;#34;+age+&amp;#34;,&amp;#34;+chenji;
        System.out.println(sStr);
        bw.write(sStr);
        bw.close();

        PrintWriter pw2 = resp.getWriter();

        pw2.println(&amp;#34;save success&amp;#34;);
        pw2.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;学生信息保存页&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;form action=&amp;#34;/stu/demo11StudentServlet&amp;#34; method=&amp;#34;get&amp;#34; autocomplete=&amp;#34;on&amp;#34;&amp;gt;
    &amp;lt;label for=&amp;#34;name&amp;#34;&amp;gt;学生姓名:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;name&amp;#34; id=&amp;#34;name&amp;#34;&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;label for=&amp;#34;age&amp;#34;&amp;gt;学生年龄:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;age&amp;#34; id=&amp;#34;age&amp;#34;&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;label for=&amp;#34;chenji&amp;#34;&amp;gt;学生成绩:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;chenji&amp;#34; id=&amp;#34;chenji&amp;#34;&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;button type=&amp;#34;submit&amp;#34;&amp;gt;保存信息&amp;lt;/button&amp;gt;
  &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Linux下Java的JDK安装设置和Tomcat安装 Li.053</title>
      <link>https://lizicai.com/p/linux%E4%B8%8Bjava%E7%9A%84jdk%E5%AE%89%E8%A3%85%E8%AE%BE%E7%BD%AE%E5%92%8Ctomcat%E5%AE%89%E8%A3%85-li.053/</link>
      <pubDate>Sun, 26 Sep 2021 11:31:57 +0800</pubDate>
      <guid>https://lizicai.com/p/linux%E4%B8%8Bjava%E7%9A%84jdk%E5%AE%89%E8%A3%85%E8%AE%BE%E7%BD%AE%E5%92%8Ctomcat%E5%AE%89%E8%A3%85-li.053/</guid>
      <description>&lt;h2 id=&#34;1-卸载原有jdk&#34;&gt;1. 卸载原有JDK&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rpm -qa | grep &amp;#34;java&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;yum remove 上面筛选内容&lt;/p&gt;
&lt;h2 id=&#34;2-下载jdk8-解压&#34;&gt;2. 下载JDK8, 解压&lt;/h2&gt;
&lt;p&gt;进入 &lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.oracle.com/java/technologies/downloads/#java8&#34; target=&#34;_blank&#34;&gt;官网Java JDK8下载地址&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;右键选择linux x64 jdk-8u301-linux-x64.tar.gz的下载地址&lt;/p&gt;
&lt;p&gt;使用wget下载, 并解压&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;wget --no-check-certificate --no-cookies --header &amp;#34;Cookie: oraclelicense=accept-securebackup-cookie&amp;#34; https://download.oracle.com/otn/java/jdk/8u301-b09/d3c52aa6bfa54d3ca74e617f18309292/jdk-8u301-linux-x64.tar.gz

tar -zxvf jdk-8u301-linux-x64.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-root用户移动文件-并设置java_home环境变量&#34;&gt;3. root用户移动文件, 并设置JAVA_HOME环境变量&lt;/h2&gt;
&lt;h3 id=&#34;31-移动文件夹&#34;&gt;3.1 移动文件夹&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mv jdk1.8.0_301 /usr/local
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;32-设置java_home环境变量&#34;&gt;3.2 设置JAVA_HOME环境变量&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;vim /etc/profile 可以对所有用户生效&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对当前用户生效则可放在.bashrc中&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;添加下列信息&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;export JAVA_HOME=/usr/local/jdk1.8.0_301
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib/dt.JAVA_HOME/lib/tools.jar:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:${PATH}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;33-重新生效etcprofile或bashrc&#34;&gt;3.3 重新生效/etc/profile或.bashrc&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;source /etc/profile

# source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;34-检测java安装成功&#34;&gt;3.4 检测Java安装成功&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;java -version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;弹出java的版本, 即是安装成功&lt;/p&gt;
&lt;h2 id=&#34;4-tomcat-安装&#34;&gt;4 Tomcat 安装&lt;/h2&gt;
&lt;h3 id=&#34;41-hahahugoshortcode54s1hbhb&#34;&gt;4.1 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://tomcat.apache.org/download-90.cgi&#34; target=&#34;_blank&#34;&gt;Tomcat官网下载&lt;/a&gt; 

&lt;/h3&gt;
&lt;p&gt;**以Tomcat 9.0 版本为例&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.53/bin/apache-tomcat-9.0.53.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;42-解压&#34;&gt;4.2 解压&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;tar -zxvf apache-tomcat-9.0.53.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;43-启动tomcat-依赖java-环境设置&#34;&gt;4.3 启动Tomcat, 依赖Java 环境设置&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd apache-tomcat-9.0.53/bin/

./startup.sh
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;44-添加安全组端口-如腾讯云-阿里云&#34;&gt;4.4 添加安全组端口, 如腾讯云 阿里云&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;来源      协议端口 策略 备注
0.0.0.0/0 TCP:8080 允许 tomcat
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;45-添加防火墙端口&#34;&gt;4.5 添加防火墙端口&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;46-浏览器访问-ip8080&#34;&gt;4.6 浏览器访问 ip:8080&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;访问http:ip:8080&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>CSS基础 Li.052</title>
      <link>https://lizicai.com/p/css%E5%9F%BA%E7%A1%80-li.052/</link>
      <pubDate>Fri, 24 Sep 2021 17:39:51 +0800</pubDate>
      <guid>https://lizicai.com/p/css%E5%9F%BA%E7%A1%80-li.052/</guid>
      <description>&lt;h2 id=&#34;css-cascading-style-sheets-层叠样式表&#34;&gt;CSS (Cascading Style Sheets) 层叠样式表&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;选择器: 选择HTML元素的方式, 可以使用标签名, class属性值, id值等多种方式&lt;/li&gt;
&lt;li&gt;样式声明: 用于给HTML元素设置具体的样式. 格式是属性名: 属性值.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;选择器{
    属性名: 属性值;
    属性名: 属性值;
    属性名: 属性值;
}
h1{
    color: red;
    font-size: 5px;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;入门案例&#34;&gt;入门案例&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;入门案例&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        h1{
            font-size: 100px;
            color: red;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1 &amp;gt;今天开始爱学习!&amp;lt;/h1&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;css-的引用方式&#34;&gt;CSS 的引用方式&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;* 内联样式
    在标签中通过style属性来控制样式, 只能影响当前这一行
    格式 &amp;lt;标签 style=&amp;#34;属性名:属性值; 属性名:属性值;&amp;#34;&amp;gt;内容&amp;lt;/标签&amp;gt;
* 内部样式
    在&amp;lt;head&amp;gt;标签中通过&amp;lt;style&amp;gt;标签来控制样式, 只能影响当前文件
    格式&amp;lt;head&amp;gt;&amp;lt;style&amp;gt; 选择器{ 属性名:属性值; }&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;
* 外部样式
    在&amp;lt;head&amp;gt;标签中通过&amp;lt;link&amp;gt;标签来引入独立css文件, 可以影响不同的文件
    格式&amp;lt;link rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;sample.css&amp;#34;&amp;gt; 相对路径css文件或网络css文件都可
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;CSS 的注释&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/* 注释内容 */
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;CSS 选择器分类
&lt;ul&gt;
&lt;li&gt;基本选择器&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;元素选择器 标签名 根据标签名匹配元素      div{}
类选择器   .      根据class属性值匹配元素 .center{}
id选择器   #      根据id属性值匹配元素    #username{}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;CSS 选择器分类
&lt;ul&gt;
&lt;li&gt;属性选择器&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;属性选择器 [] 根据指定属性匹配元素 [type]{}[type=text]{}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;CSS 选择器分类
&lt;ul&gt;
&lt;li&gt;伪类选择器&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;标签名:link    未访问的状态   a:link{}
标签名:visited 已访问的状态   a:visited{}
标签名:hover   鼠标悬浮的状态 a:hover{}
标签名:active  已选中的状态   a:active{}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;CSS伪类选择器&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        a:link{
            color: black;
            text-decoration: none;
        }
        a:visited{
            color: blue;
            text-decoration: none;
        }
        a:hover{
            color: red;
            text-decoration: none;
            font-weight: bold;
        }
        a:active{
            color: yellow;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;a href=&amp;#34;01-入门案例.html&amp;#34; &amp;gt;入门案例&amp;lt;/a&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;CSS 选择器分类
&lt;ul&gt;
&lt;li&gt;组合选择器&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;后代选择器 空格 使用空格结合多个选择器,基于第一个选择器,匹配第二2选择的所有元素 .center li{}
分组选择器 ,    可能同时匹配多个元素                div,span,p{}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;CSS组合选择器(后台选择器和分组选择器)&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        .center li{
            color: red;
        }
        div,span,p{
            color: green;
            font-size: 30px;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div&amp;gt;asf&amp;lt;/div&amp;gt;
&amp;lt;a&amp;gt;&amp;lt;span&amp;gt;asdf&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;
&amp;lt;p&amp;gt;asdf&amp;lt;/p&amp;gt;
&amp;lt;ol class=&amp;#34;center&amp;#34; &amp;gt;
    &amp;lt;li&amp;gt;列表&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;列表&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;边框样式-border&#34;&gt;边框样式 border&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;border        设置所有边框
border-top    设置上边框
border-left   设置左边框
border-right  设置右边框
border-bottom 设置下边框
border-radius 设置边框弧度

solid         实线
double        双实线
dotted        圆点
dashed        虚线
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;文本样式&#34;&gt;文本样式&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;color           文本颜色     颜色单词(red),RGB(#000000)
font-family     字体         微信雅黑,宋体
font-size       字体大小     像素点20px
text-decoration 文字下划线   none无underline下划线overline上划线line-through
text-align      水平对齐方式 left居左right居右center居中
line-height     行间距       像素点20px
vertical-algn   垂直对齐方式 top居上bottom居下middle居中(还可百分比调节)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;新闻头条&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;news.css&amp;#34;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;div class=&amp;#34;divTop&amp;#34;&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34; class=&amp;#34;divTopA&amp;#34;&amp;gt;登录&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34; class=&amp;#34;divTopA&amp;#34;&amp;gt;注册&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34; class=&amp;#34;divTopA&amp;#34;&amp;gt;更多&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;divNav&amp;#34;&amp;gt;
    &amp;lt;img src=&amp;#34;background.png&amp;#34; width=&amp;#34;100px&amp;#34; height=&amp;#34;40px&amp;#34;&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;首页&amp;lt;/a&amp;gt;&amp;lt;span&amp;gt;&amp;amp;nbsp;/&amp;lt;/span&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;科技&amp;lt;/a&amp;gt;&amp;lt;span&amp;gt;&amp;amp;nbsp;/&amp;lt;/span&amp;gt;
    &amp;lt;font color=&amp;#34;gray&amp;#34;&amp;gt;正文&amp;lt;/font&amp;gt;
&amp;lt;/div &amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;hr/&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;divContend&amp;#34;&amp;gt;
    &amp;lt;div class=&amp;#34;divLeft&amp;#34;&amp;gt;
        &amp;lt;div&amp;gt;
            &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;&amp;lt;img src=&amp;#34;test.png&amp;#34;&amp;gt;&amp;lt;span&amp;gt;&amp;amp;nbsp;评论&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;hr/&amp;gt;
        &amp;lt;div&amp;gt;
            &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;&amp;lt;img src=&amp;#34;test.png&amp;#34;&amp;gt;&amp;lt;span&amp;gt;&amp;amp;nbsp;评论&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;
            &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;&amp;lt;img src=&amp;#34;test.png&amp;#34;&amp;gt;&amp;lt;span&amp;gt;&amp;amp;nbsp;评论&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;
            &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;&amp;lt;img src=&amp;#34;test.png&amp;#34;&amp;gt;&amp;lt;span&amp;gt;&amp;amp;nbsp;评论&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;#34;divCenter&amp;#34;&amp;gt;
        &amp;lt;p&amp;gt;弹性布局flex是一个几年前的CSS属性了，说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
            之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
            早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
            好在现在已经是2018年了，不必再担心那些老旧的设备，希望这篇文章能帮你加深对flex的认识。
        &amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;
            首先，flex被称为一个弹性盒模型，也有称弹性布局的。
            总之，盒子也好、布局也罢，我们总是需要有一个容器Container的：
        &amp;lt;/p&amp;gt;
        &amp;lt;ol&amp;gt;
            &amp;lt;li&amp;gt;首先，flex被称为一个弹性盒模型，也有称弹性布局的。kskdfjksjdfk&amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;总之，盒子也好、布局也罢，我们总是需要有一个容器Container的&amp;lt;/li&amp;gt;
        &amp;lt;/ol&amp;gt;
        &amp;lt;img src=&amp;#34;background.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;

        &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;加粗1&amp;lt;/strong&amp;gt;弹性布局flex是一个几年前的CSS属性了，说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
            之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
            早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
            好在现在已经是2018年了，不必再担心那些老旧的设备，希望这篇文章能帮你加深对flex的认识。
        &amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;加粗2&amp;lt;/strong&amp;gt;弹性布局flex是一个几年前的CSS属性了，说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
            之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
            早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
            好在现在已经是2018年了，不必再担心那些老旧的设备，希望这篇文章能帮你加深对flex的认识。
        &amp;lt;/p&amp;gt;
        &amp;lt;img src=&amp;#34;background.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
        &amp;lt;p&amp;gt;
            之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
            早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
            好在现在已经是2018年了，不必再担心那些老旧的设备，希望这篇文章能帮你加深对flex的认识。
        &amp;lt;/p&amp;gt;
    &amp;lt;/div &amp;gt;
    &amp;lt;div class=&amp;#34;divRight&amp;#34;&amp;gt;
        &amp;lt;img src=&amp;#34;test.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
        &amp;lt;img src=&amp;#34;background.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
        &amp;lt;img src=&amp;#34;test.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
        &amp;lt;img src=&amp;#34;background.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;divFooter&amp;#34;&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;内容&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;内容&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;内容&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34;&amp;gt;内容&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;.divTop{
    background: black;
    height: 50px;
    text-align: right;
    font-size: 25px;
}
.divTop a{
    color: white;
}

.divNav{
    height: 50px;
}

a{
    color: black;
    text-decoration: none;
    font-size: 25px;
}

a:hover{
    color: red;
}

.divContend{
    float: left;
}

.divLeft{
    width: 20%;
    float: left;
    text-align: center;
    vertical-align: 50%;
}

.divLeft img{
    width: 38px;
    height: 38px;
}
.divLeft span{
    vertical-align: 50%;
}

.divCenter{
    width: 60%;
    float: left;
}

.divRight{
    width: 20%;
    float: left;
}


.divFooter{
    clear: both;
    background: blue;
    text-align: center;
}
.divFooter a{
    color: white;
}

.divFooter a:hover{
    color: red;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;表格标签&#34;&gt;表格标签&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;table  表格标签           width-宽度height-高度border-边框align-对齐方式
tr     行标签             align-对齐方式
td     单元格标签(列标签) rowspan-合并行colspan-合并列
th     表头标签(加粗和居中)
thread 表头语文标签
tbody  课外书语义标签
tfoot  表脚语义标签
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;表格标签演示&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;table width=&amp;#34;500px&amp;#34; border=&amp;#34;1px&amp;#34;&amp;gt;
    &amp;lt;thead&amp;gt;
    &amp;lt;tr&amp;gt;
        &amp;lt;th&amp;gt;姓名&amp;lt;/th&amp;gt;
        &amp;lt;th&amp;gt;性别&amp;lt;/th&amp;gt;
        &amp;lt;th&amp;gt;年龄&amp;lt;/th&amp;gt;
        &amp;lt;th&amp;gt;数学&amp;lt;/th&amp;gt;
        &amp;lt;th&amp;gt;语文&amp;lt;/th&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;/thead&amp;gt;
    &amp;lt;tbody&amp;gt;
    &amp;lt;tr align=&amp;#34;center&amp;#34;&amp;gt;
        &amp;lt;td&amp;gt;张三&amp;lt;/td&amp;gt;
        &amp;lt;td rowspan=&amp;#34;2&amp;#34;&amp;gt;男&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;20&amp;lt;/td&amp;gt;
        &amp;lt;td colspan=&amp;#34;2&amp;#34;&amp;gt;90&amp;lt;/td&amp;gt;
        &amp;lt;!--        &amp;lt;td&amp;gt;90&amp;lt;/td&amp;gt;--&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;tr align=&amp;#34;center&amp;#34;&amp;gt;
        &amp;lt;td&amp;gt;李四&amp;lt;/td&amp;gt;
        &amp;lt;!--        &amp;lt;td&amp;gt;男&amp;lt;/td&amp;gt;--&amp;gt;
        &amp;lt;td&amp;gt;21&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;95&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;90&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;/tbody&amp;gt;
    &amp;lt;tfoot&amp;gt;
    &amp;lt;tr align=&amp;#34;center&amp;#34;&amp;gt;
        &amp;lt;td&amp;gt;总分:&amp;lt;/td&amp;gt;
        &amp;lt;td colspan=&amp;#34;4&amp;#34;&amp;gt;365&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;/tfoot&amp;gt;
&amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;css-样式控制&#34;&gt;CSS 样式控制&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;background-repeat 控制背景重复 no-repeat不重复,repeat-x水平重复,repeat-y垂直重复,repeat水平和垂直重复
outline 控制轮廓 double双实线,dotted圆点,dashed虚线,none无
display 控制元素 inline肉联元素(无换行,无长宽),block块级元素(有换行),inline-block肉联元素(有长宽),none隐藏元素
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;背景 轮廓 元素控制&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        body{
            background: url(&amp;#34;bg.png&amp;#34;);
            /*background-repeat: no-repeat;*/
            /*background-repeat: repeat-x;*/
            /*background-repeat: repeat-y;*/
            background-repeat: repeat;
        }
        input{
            /*outline: none;*/
            /*outline: none;*/
            outline: double;
        }
        div{
            /*display: none;*/
            /*display: inline;*/
            display: inline-block;
            width: 50px;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
姓名: &amp;lt;input type=&amp;#34;text&amp;#34;&amp;gt;
&amp;lt;br&amp;gt;
&amp;lt;div&amp;gt;春香&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;夏香&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;秋香&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;冬香&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;css-灵魂-盒子模型&#34;&gt;CSS 灵魂, 盒子模型&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;盒子模型是通过设置边框和元素内容的边距, 从而实现布局的方式. 分为内边距和外边距两种方式&lt;/li&gt;
&lt;li&gt;如果想实现布局, 可以采用设置内边距或外边距来实现.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/css/cssbox.png&#34; alt=&#34;cssbox&#34;  /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;内外边距的设置, 取决于所在的视角. 一般常用是外边距.&lt;/strong&gt;
&lt;strong&gt;内边距会导致盒子大小变化&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;margin-top    上外边距                             margin-top:50px;
margin-left   左外边距                             margin-left:50px;
margin-right  右外边距                             margin-rigth:50px;
margin-bottom 下外边距                             margin-bottom:50px;
margin        通用相同距离                         margin:50px;
margin        单独设置上右下左(从上开始顺时针)边距 margin: 50px 60px 70px 80px;
margin        自动计算外边距并水平居中             margin:auto


padding-top    上外边距                             padding-top:50px;
padding-left   左外边距                             padding-left:50px;
padding-right  右外边距                             padding-rigth:50px;
padding-bottom 下外边距                             padding-bottom:50px;
padding        通用相同距离                         padding:50px;
padding        单独设置上右下左(从上开始顺时针)边距 padding: 50px 60px 70px 80px;
padding        自动计算外边距并水平居中             padding:auto
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;登录页面&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;login.css&amp;#34;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;img src=&amp;#34;bg.png&amp;#34; &amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;#34;center&amp;#34;&amp;gt;
        &amp;lt;form action=&amp;#34;#&amp;#34; method=&amp;#34;get&amp;#34; autocomplete=&amp;#34;off&amp;#34;&amp;gt;
            &amp;lt;table width=&amp;#34;100%&amp;#34;&amp;gt;
                &amp;lt;thead&amp;gt;
                    &amp;lt;tr&amp;gt;
                        &amp;lt;th colspan=&amp;#34;2&amp;#34;&amp;gt;账&amp;amp;nbsp;号&amp;amp;nbsp;登&amp;amp;nbsp;录&amp;amp;nbsp;&amp;lt;hr/&amp;gt;&amp;lt;/th&amp;gt;
                    &amp;lt;/tr&amp;gt;
                &amp;lt;/thead&amp;gt;
                &amp;lt;tbody&amp;gt;
                    &amp;lt;tr&amp;gt;
                        &amp;lt;td&amp;gt; &amp;lt;label for=&amp;#34;username&amp;#34;&amp;gt;账&amp;amp;nbsp;号&amp;amp;nbsp;&amp;lt;/label&amp;gt; &amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;&amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;username&amp;#34; id=&amp;#34;username&amp;#34; placeholder=&amp;#34;请输入账号&amp;#34; required&amp;gt;&amp;lt;/td&amp;gt;
                    &amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;
                        &amp;lt;td&amp;gt;&amp;lt;label for=&amp;#34;password&amp;#34;&amp;gt;密&amp;amp;nbsp;码&amp;amp;nbsp;&amp;lt;/label&amp;gt;&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;&amp;lt;input type=&amp;#34;password&amp;#34; name=&amp;#34;password&amp;#34; id=&amp;#34;password&amp;#34; placeholder=&amp;#34;请输入密码&amp;#34; required&amp;gt;&amp;lt;/td&amp;gt;
                    &amp;lt;/tr&amp;gt;
                &amp;lt;/tbody&amp;gt;
                &amp;lt;tfoot&amp;gt;
                    &amp;lt;tr&amp;gt;
                        &amp;lt;td colspan=&amp;#34;2&amp;#34;&amp;gt;&amp;lt;button type=&amp;#34;submit&amp;#34;&amp;gt;确定&amp;lt;/button&amp;gt; &amp;lt;/td&amp;gt;
                    &amp;lt;/tr&amp;gt;
                &amp;lt;/tfoot&amp;gt;
            &amp;lt;/table&amp;gt;
        &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;#34;footer&amp;#34;&amp;gt;
        &amp;lt;br/&amp;gt;
        &amp;lt;br/&amp;gt;
        登录/注册即表示您同意&amp;amp;nbsp;&amp;amp;nbsp;
        &amp;lt;a href=&amp;#34;#&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;用户协议&amp;lt;/a&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;
        和
        &amp;lt;a href=&amp;#34;#&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;隐私条款&amp;lt;/a&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;

        &amp;lt;a href=&amp;#34;#&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;忘记密码&amp;lt;/a&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;

    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;body{
    background: url(&amp;#34;bg2.png&amp;#34;);
    background-repeat: no-repeat;
}
.center{
    background: white;
    width: 40%;
    margin: auto;
    margin-top: 100px;
    text-align: center;
    border-radius: 15px;
}
table th{
    color: orangered;
    font-size: 30px;
}

table label{
    font-size: 20px;
}

table input{
    outline: none;
    border-radius: 5px;
    border: 1px solid gray;
    width: 90%;
    height: 40px;
}

table tr{
    line-height: 80px;
}

tfoot button{
    border: 1px solid crimson;
    height: 40px;
    width: 95%;
    border-radius: 5px;
    background: crimson;
    color: white;
    font-size: 20px;
}

.footer{
    width: 35%;
    /*color: gray;*/
    margin: auto;
    font-size: 18px;
}
a{
    font-size: 18px;
    text-decoration: none;

}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;nginx-安装&#34;&gt;Nginx 安装&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/%e5%ae%89%e8%a3%85nginx%e5%8f%af%e7%94%a8%e6%9c%8d%e5%8a%a1li.012/&#34; target=&#34;_blank&#34;&gt;安装Nginx&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/%e7%bc%96%e8%af%91%e5%ae%89%e8%a3%85nginx%e6%94%af%e6%8c%81tls1.3li.013/&#34; target=&#34;_blank&#34;&gt;编译安装Nginx支持tls1.3&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;上传则可用scp就可&#34;&gt;上传则可用scp就可&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 账号密码上传
scp -r folder -P 22 root@10.10.10.10:

# ssh key上传
scp -r folder -P 22 mineFuWuQi:
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/rsycn%e5%90%8c%e6%ad%a5%e5%9b%be%e7%89%87%e6%88%96%e5%85%b6%e4%bb%96%e8%b5%84%e6%ba%90%e5%88%b0%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8ali.025/&#34; target=&#34;_blank&#34;&gt;也可使用rsycn同步图片或其他资源到服务器上&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>HTML基础 Li.051</title>
      <link>https://lizicai.com/p/html%E5%9F%BA%E7%A1%80-li.051/</link>
      <pubDate>Wed, 22 Sep 2021 23:40:44 +0800</pubDate>
      <guid>https://lizicai.com/p/html%E5%9F%BA%E7%A1%80-li.051/</guid>
      <description>&lt;h2 id=&#34;html-标签简单介绍&#34;&gt;html 标签简单介绍&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# html5文件声明
&amp;lt;!DOCTYPE html&amp;gt;

# 根标签
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
# 头
&amp;lt;head&amp;gt;
# 字符集
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
# 文档标题, 标签页标题
    &amp;lt;title&amp;gt;01入门案例&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;

# 身体, 所有文档内容
&amp;lt;body&amp;gt;
&amp;lt;h1 align=&amp;#34;center&amp;#34;&amp;gt;这是我的第一个HTML入门案例&amp;lt;/h1&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;html-注释-标签&#34;&gt;HTML 注释 标签&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;注释&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!-- 注释 --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;标签&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;开始和结束标签  &amp;lt;h1&amp;gt;&amp;lt;/h1&amp;gt;

自闭合标签&amp;lt;br/&amp;gt; &amp;lt;hr/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;标签的嵌套&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;正确嵌套 &amp;lt;h1&amp;gt;&amp;lt;u&amp;gt;sefe&amp;lt;/u&amp;gt;&amp;lt;/h1&amp;gt;
错误嵌套 &amp;lt;h1&amp;gt;&amp;lt;u&amp;gt;sefe&amp;lt;/h1&amp;gt;&amp;lt;/u&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;块级元素和行内元素&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;块级元素: 在页面中以块的形式展现, 自己独占一行, 后面内容会自动换行&amp;lt;p&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;div&amp;gt;
行内元素: 在页面中以行的形式展现, 不会换行&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;&amp;lt;u&amp;gt;&amp;lt;span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;div和span&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;div&amp;gt;:  是一个通用的内容容器, 没有特殊语义. 一般用来对其它元素进行分组, 用于样式化相关的需求
&amp;lt;span&amp;gt;: 是一个通用的行内容器, 没有特殊语义. 一般用来纺织元素以达到某种样式.
&amp;lt;div&amp;gt;和&amp;lt;span&amp;gt;标签核心作用是布局页面
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;html-的属性&#34;&gt;HTML 的属性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;什么是属性
&lt;ul&gt;
&lt;li&gt;属性可以提供一些额外的信息, 这些信息不会显示在内容中, 但可以改变标签的形式或提供的数据使用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;定义格式
&lt;ul&gt;
&lt;li&gt;属性名=属性值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;属性的规范
&lt;ul&gt;
&lt;li&gt;同一个标签中属性的名称必须唯一&lt;/li&gt;
&lt;li&gt;不区分大小写, 推荐小写&lt;/li&gt;
&lt;li&gt;属性值可以使用单引号或双引号, 推荐双引号&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;常用的属性
&lt;ul&gt;
&lt;li&gt;class 定义元素的类名, 用户选择或访问特定的元素&lt;/li&gt;
&lt;li&gt;id 定义元素的唯一标识, 在整个文档中必须是唯一的&lt;/li&gt;
&lt;li&gt;name 定义元素的名称, 一般用于表单数据提交到服务器&lt;/li&gt;
&lt;li&gt;value 定义在元素内显示的默认值, 一般常用于表单标签中&lt;/li&gt;
&lt;li&gt;style 定义元素的css样式&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;html-的特殊字符&#34;&gt;HTML 的特殊字符&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;特殊字符&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;在html中, 像&amp;lt; &amp;gt; &amp;#34; &amp;#39; 空格 &amp;amp; 都是特殊字符, 它们是语法本身的一部分
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;字符表示&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;    &amp;amp;lt;
&amp;gt;    &amp;amp;gt;
&amp;#34;    &amp;amp;quot;
&amp;#39;    &amp;amp;apos;
&amp;amp;    &amp;amp;amp;
空格 &amp;amp;nbsp;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;html-练习一&#34;&gt;HTML 练习一&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;样式演示&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;样式演示&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        div{
            border: 1px solid red;
            width: 60%;
            height: 500px;
            /* 边框外边距 */
            margin: auto;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div&amp;gt;第一个div&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;文本标签&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;p      表示文件的一个段落
h      表示文档标题,&amp;lt;h1&amp;gt;-&amp;lt;h6&amp;gt;,呈现六个不同级别的标题,h1最高h6最低
hr     表示段落级元素之间的主题转换,一般显示为水平线
ul     表示一个无序列表,可含多个元素,无编号显示
ol     表示一个有序列表,通过渲染为带编号的列表
li     表示列表里的条目
em     表示文本着重,一般用斜体显示
i      表示文本斜体
strong 表示文本重要,一般用粗体显示
b      表示加粗文本
font   表示字体,可以设置样式(已过时)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;新闻标题案例&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        .divCenter{
            width: 60%;
            margin: auto;
        }
        .headCenter{
            text-align: center;
        }
        p{
            font-size: 18px;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div class=&amp;#34;divCenter&amp;#34;&amp;gt;
    &amp;lt;h1 class=&amp;#34;headCenter&amp;#34; &amp;gt;这是一个标题&amp;lt;/h1&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;divCenter&amp;#34;&amp;gt;
    &amp;lt;em&amp;gt;&amp;lt;font size=&amp;#34;2&amp;#34; color=&amp;#34;gray&amp;#34;&amp;gt;作者: 李小明  2021年10月1日&amp;lt;/font&amp;gt;&amp;lt;/em&amp;gt;
    &amp;lt;hr/&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;divCenter&amp;#34;&amp;gt;
    &amp;lt;h3&amp;gt;弹性布局flex是一个几年前的CSS属性了&amp;lt;/h3&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;divCenter&amp;#34;&amp;gt;
    &amp;lt;p&amp;gt;弹性布局flex是一个几年前的CSS属性了，说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
        之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
        早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
    &amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;
        首先，flex被称为一个弹性盒模型，也有称弹性布局的。
        总之，盒子也好、布局也罢，我们总是需要有一个容器Container的：
    &amp;lt;/p&amp;gt;
    &amp;lt;ol&amp;gt;
        &amp;lt;li&amp;gt;首先，flex被称为一个弹性盒模型，也有称弹性布局的。kskdfjksjdfk&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;总之，盒子也好、布局也罢，我们总是需要有一个容器Container的&amp;lt;/li&amp;gt;
    &amp;lt;/ol&amp;gt;

    &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;加粗1&amp;lt;/strong&amp;gt;弹性布局flex是一个几年前的CSS属性了，说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
        之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
        早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
    &amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;加粗2&amp;lt;/strong&amp;gt;弹性布局flex是一个几年前的CSS属性了，说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
        之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
        早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
    &amp;lt;/p&amp;gt;

&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;案例二头条页&#34;&gt;案例二头条页&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;div 样式布局&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;.left{
width: 20%;
float: left;
}
.center{
width: 59%;
float: left;
}
.right{
width: 20%;
float: left;
}
&amp;lt;div class=&amp;#34;left&amp;#34;&amp;gt;left&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;center&amp;#34;&amp;gt;center&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;right&amp;#34;&amp;gt;right&amp;lt;/div&amp;gt;

float 浮动(left right none) clear清除浮动(both) text-align(left  right center) background背景色
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;图片标签&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;img    可以显示图片,本地或网络

src    必需,图片地址
title  鼠标悬停(hover)时显示文本
alt    图形不显示时的替换文本
height 图像高度
width  图像宽度
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;图片样式演示&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;img src=&amp;#34;login.png&amp;#34; title=&amp;#34;说明&amp;#34; alt=&amp;#34;图片不存在&amp;#34; width=&amp;#34;1000&amp;#34; height=&amp;#34;30px&amp;#34;/&amp;gt;
&amp;lt;img src=&amp;#34;no.png&amp;#34; title=&amp;#34;说明&amp;#34; alt=&amp;#34;图片不存在&amp;#34; width=&amp;#34;1000&amp;#34; height=&amp;#34;30px&amp;#34;/&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;超链接标签&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;a 表示超链接

href                  表示超链接指向的URL 本地或网络都可
targe                 页面打开方式(_self当前页_blank新标签页)
a:hover               鼠标悬停样式
text-decoration:none; 去掉下划线
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;样式演示&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        div{
            /*border: 1px solid red;*/
        }
        .left{
            width: 20%;
            float: left;
        }
        .center{
            width: 60%;
            float: left;
        }
        .right{
            width: 20%;
            float: left;
        }
        .footer{
            clear: both;
            text-align: center;
            background: blue;
        }
        a{
            color: white;
            text-decoration: none;

        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div&amp;gt;&amp;lt;img src=&amp;#34;top.png&amp;#34; alt=&amp;#34;top.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;&amp;lt;img src=&amp;#34;navibar.png&amp;#34; alt=&amp;#34;navibar.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt; &amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;div class=&amp;#34;left&amp;#34;&amp;gt;
        &amp;lt;img src=&amp;#34;left.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;#34;center&amp;#34;&amp;gt;
        &amp;lt;p&amp;gt;弹性布局flex是一个几年前的CSS属性了，说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
            之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
            早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
            好在现在已经是2018年了，不必再担心那些老旧的设备，希望这篇文章能帮你加深对flex的认识。
        &amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;
            首先，flex被称为一个弹性盒模型，也有称弹性布局的。
            总之，盒子也好、布局也罢，我们总是需要有一个容器Container的：
        &amp;lt;/p&amp;gt;
        &amp;lt;ol&amp;gt;
            &amp;lt;li&amp;gt;首先，flex被称为一个弹性盒模型，也有称弹性布局的。kskdfjksjdfk&amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;总之，盒子也好、布局也罢，我们总是需要有一个容器Container的&amp;lt;/li&amp;gt;
        &amp;lt;/ol&amp;gt;
        &amp;lt;img src=&amp;#34;center1.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;

        &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;加粗1&amp;lt;/strong&amp;gt;弹性布局flex是一个几年前的CSS属性了，说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
            之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
            早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
            好在现在已经是2018年了，不必再担心那些老旧的设备，希望这篇文章能帮你加深对flex的认识。
        &amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;加粗2&amp;lt;/strong&amp;gt;弹性布局flex是一个几年前的CSS属性了，说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
            之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
            早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
            好在现在已经是2018年了，不必再担心那些老旧的设备，希望这篇文章能帮你加深对flex的认识。
        &amp;lt;/p&amp;gt;
        &amp;lt;img src=&amp;#34;center2.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
        &amp;lt;p&amp;gt;
            之前网上流行的各种XX布局，什么postion: absolute+margin，float+padding，各种都可以使用flex来取代之。
            早两年在使用的时候，还是会担心有兼容性问题的，某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。
            好在现在已经是2018年了，不必再担心那些老旧的设备，希望这篇文章能帮你加深对flex的认识。
        &amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;#34;right&amp;#34;&amp;gt;
        &amp;lt;img src=&amp;#34;right.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
        &amp;lt;img src=&amp;#34;right.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
        &amp;lt;img src=&amp;#34;right.png&amp;#34; width=&amp;#34;100%&amp;#34;&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div class=&amp;#34;footer&amp;#34;&amp;gt;
    &amp;lt;a href=&amp;#34;http://lizicai.com&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;李子菜&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;#34;http://lizicai.com&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;李子菜&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;#34;http://lizicai.com&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;李子菜&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;#34;#&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;李子菜&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;案例三-注册&#34;&gt;案例三 注册&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;div样式布局, 背景图片&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;背景图片演示&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        body{
            background: url(&amp;#34;Halcrow.jpg&amp;#34;);
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;表单标签&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;form 表单标签

action 用于提交数据的路径
method 用于提交数据的方式( get 和post )
(get 表单数据会显示在地址栏中, 不安全, 地址栏长度有限制)
(post 表单数据不会显示在地址栏中, 数据封装在请求体中, 安全, 长度无限制)
autocomplete 是否记录补全( on 和 off )
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;表单项标签&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;lable       表单元素说明,配置表单项标签使用

for         属性值必须和表单项的id属性值一致


input       表单项标签,多种输入类型来接收用户数据

type        数据的类型
id          唯一标识
name        提交服务器的标识
value       默认数据值
placeholder 默认提示信息
required    是否必须有数据


button      按钮标签,不同的按钮有不同的作用

type        属性,按钮的功能(submit,reset,button)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;表单项标签演示&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form method=&amp;#34;get&amp;#34; action=&amp;#34;#&amp;#34; autocomplete=&amp;#34;on&amp;#34;&amp;gt;
    &amp;lt;label for=&amp;#34;username&amp;#34;&amp;gt;用户名: &amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;username&amp;#34; id=&amp;#34;username&amp;#34; value=&amp;#34;&amp;#34; placeholder=&amp;#34;请输入用户名&amp;#34; required&amp;gt;
    &amp;lt;button type=&amp;#34;submit&amp;#34;&amp;gt;提交&amp;lt;/button&amp;gt;
    &amp;lt;button type=&amp;#34;reset&amp;#34;&amp;gt;重置&amp;lt;/button&amp;gt;
    &amp;lt;button type=&amp;#34;button&amp;#34;&amp;gt;普通按钮&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;表单项标签type属性值&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;text 普通文本框
password 密码框
email 邮箱框,简单验证
radio 单选框 选择必须有相同的name属性值, value属性设置实际提交的值, checked属性代表默认选中
checkbox 得选框 选项必须有相同的name属性值, value属性设置实际提交的值, checked属性代表默认选中

date           日期框
time           时间框
datetime-local 时间日期框
number         数字框
range          滚动条数值框,min最小值,max最大值,step步进值
search         可清除文本框
tel            电话框
url            网址框
file           文件上传框
hidden         隐藏域 value属性设置实际提交的值
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;表单标签type属性演示&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form method=&amp;#34;get&amp;#34; action=&amp;#34;#&amp;#34;&amp;gt;
    &amp;lt;label for=&amp;#34;username&amp;#34;&amp;gt;用户名:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;username&amp;#34; id=&amp;#34;username&amp;#34; placeholder=&amp;#34;请输入用户名&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;password&amp;#34;&amp;gt;密码:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;password&amp;#34; name=&amp;#34;password&amp;#34; id=&amp;#34;password&amp;#34; placeholder=&amp;#34;请输入密码&amp;#34; &amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;email&amp;#34;&amp;gt;邮箱:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;email&amp;#34; name=&amp;#34;email&amp;#34; id=&amp;#34;email&amp;#34; placeholder=&amp;#34;请输入邮箱&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;gender&amp;#34;&amp;gt;性别:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; value=&amp;#34;male&amp;#34; id=&amp;#34;gender&amp;#34;&amp;gt;男
    &amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; value=&amp;#34;female&amp;#34;&amp;gt;女
    &amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; value=&amp;#34;other&amp;#34; checked&amp;gt;保密
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;hobby&amp;#34;&amp;gt;爱好:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;checkbox&amp;#34; name=&amp;#34;profession&amp;#34; value=&amp;#34;music&amp;#34; id=&amp;#34;hobby&amp;#34;&amp;gt;音乐
    &amp;lt;input type=&amp;#34;checkbox&amp;#34; name=&amp;#34;profession&amp;#34; value=&amp;#34;game&amp;#34; &amp;gt;游戏
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;birthday&amp;#34;&amp;gt;日期:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;date&amp;#34; name=&amp;#34;birthday&amp;#34; id=&amp;#34;birthday&amp;#34; &amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;time&amp;#34;&amp;gt;时间:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;time&amp;#34; name=&amp;#34;time&amp;#34; id=&amp;#34;time&amp;#34; &amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;datetime&amp;#34;&amp;gt;日期和时间:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;datetime-local&amp;#34; name=&amp;#34;datetime&amp;#34; id=&amp;#34;datetime&amp;#34; &amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;label for=&amp;#34;number&amp;#34;&amp;gt;number:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;number&amp;#34; name=&amp;#34;number&amp;#34; id=&amp;#34;number&amp;#34; &amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;range&amp;#34;&amp;gt;rang:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;range&amp;#34; name=&amp;#34;range&amp;#34; id=&amp;#34;range&amp;#34; min=&amp;#34;0&amp;#34; max=&amp;#34;10&amp;#34; step=&amp;#34;2&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;search&amp;#34;&amp;gt;search:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;search&amp;#34; name=&amp;#34;search&amp;#34; id=&amp;#34;search&amp;#34; &amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;tel&amp;#34;&amp;gt;tel:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;tel&amp;#34; name=&amp;#34;tel&amp;#34; id=&amp;#34;tel&amp;#34; &amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;url&amp;#34;&amp;gt;url:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;url&amp;#34; name=&amp;#34;url&amp;#34; id=&amp;#34;url&amp;#34; &amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;label for=&amp;#34;file&amp;#34;&amp;gt;file:&amp;lt;/label&amp;gt;
    &amp;lt;input type=&amp;#34;file&amp;#34; name=&amp;#34;file&amp;#34; id=&amp;#34;file&amp;#34; &amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;input type=&amp;#34;hidden&amp;#34; name=&amp;#34;hidden&amp;#34; id=&amp;#34;hidden&amp;#34; value=&amp;#34;see&amp;#34;&amp;gt;
    &amp;lt;br/&amp;gt;

    &amp;lt;button name=&amp;#34;submit&amp;#34; type=&amp;#34;submit&amp;#34; &amp;gt;提交&amp;lt;/button&amp;gt;
    &amp;lt;button name=&amp;#34;重置&amp;#34; type=&amp;#34;reset&amp;#34;&amp;gt;重置&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;其他常用表单项标签&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select   表示下拉列表标签
optgroup 不用接列表分组标签 label属性,设置分组名称
option   表示下拉列表项标签
textarea 表示文本域标签     rows属性代表行数,cols属性代表列数
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;其他常用表单项标签演示&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form method=&amp;#34;get&amp;#34; action=&amp;#34;#&amp;#34; autocomplete=&amp;#34;off&amp;#34;&amp;gt;
    &amp;lt;label for=&amp;#34;city&amp;#34;&amp;gt;所在城市&amp;lt;/label&amp;gt;
    &amp;lt;select name=&amp;#34;city&amp;#34; id=&amp;#34;city&amp;#34;&amp;gt;
        &amp;lt;option&amp;gt;请选择城市&amp;lt;/option&amp;gt;
        &amp;lt;optgroup label=&amp;#34;直辖市&amp;#34;&amp;gt;
            &amp;lt;option&amp;gt;北京&amp;lt;/option&amp;gt;
            &amp;lt;option&amp;gt;上海&amp;lt;/option&amp;gt;
            &amp;lt;option&amp;gt;深圳&amp;lt;/option&amp;gt;
        &amp;lt;/optgroup&amp;gt;
        &amp;lt;optgroup label=&amp;#34;省会市&amp;#34;&amp;gt;
            &amp;lt;option&amp;gt;广州&amp;lt;/option&amp;gt;
            &amp;lt;option&amp;gt;杭州&amp;lt;/option&amp;gt;
        &amp;lt;/optgroup&amp;gt;
    &amp;lt;/select&amp;gt;
    &amp;lt;br/&amp;gt;
    个人介绍:
    &amp;lt;textarea name=&amp;#34;desc&amp;#34; rows=&amp;#34;10&amp;#34; cols=&amp;#34;20&amp;#34;&amp;gt;
    &amp;lt;/textarea&amp;gt;
    &amp;lt;button name=&amp;#34;submit&amp;#34; type=&amp;#34;submit&amp;#34; &amp;gt;提交&amp;lt;/button&amp;gt;
    &amp;lt;button name=&amp;#34;重置&amp;#34; type=&amp;#34;reset&amp;#34;&amp;gt;重置&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;演示案例三&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;#34;UTF-8&amp;#34;&amp;gt;
    &amp;lt;title&amp;gt;注册页面&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        body{
            background: url(&amp;#34;background.png&amp;#34;);
        }
        .divForm{
            background: white;
            width: 400px;
            margin: auto;
            text-align: center;
        }
        .divFormLeft{
            background: white;
            width: 60%;
            margin: auto;
            text-align: left;
        }

    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;img src=&amp;#34;navibar.png&amp;#34; width=100%&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;#34;divForm&amp;#34;&amp;gt;
    &amp;lt;div class=&amp;#34;divFormLeft&amp;#34;&amp;gt;&amp;lt;a&amp;gt;注册详情&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;hr/&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;form method=&amp;#34;get&amp;#34; autocomplete=&amp;#34;on&amp;#34; action=&amp;#34;#&amp;#34;&amp;gt;
            &amp;lt;div class=&amp;#34;divFormLeft&amp;#34;&amp;gt;
                &amp;lt;div &amp;gt;
                    &amp;lt;label for=&amp;#34;username&amp;#34;&amp;gt;姓名:&amp;lt;/label&amp;gt;
                    &amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;username&amp;#34; id=&amp;#34;username&amp;#34; placeholder=&amp;#34;在此输入姓名&amp;#34;&amp;gt;
                    &amp;lt;br/&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div&amp;gt;
                    &amp;lt;label for=&amp;#34;password&amp;#34;&amp;gt;密码:&amp;lt;/label&amp;gt;
                    &amp;lt;input type=&amp;#34;password&amp;#34; name=&amp;#34;password&amp;#34; id=&amp;#34;password&amp;#34; placeholder=&amp;#34;在此输入密码&amp;#34;&amp;gt;
                    &amp;lt;br/&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div&amp;gt;
                    &amp;lt;label for=&amp;#34;email&amp;#34;&amp;gt;邮箱:&amp;lt;/label&amp;gt;
                    &amp;lt;input type=&amp;#34;email&amp;#34; name=&amp;#34;email&amp;#34; id=&amp;#34;email&amp;#34; placeholder=&amp;#34;在此输入邮箱&amp;#34;&amp;gt;
                    &amp;lt;br/&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div&amp;gt;
                    &amp;lt;label for=&amp;#34;tel&amp;#34;&amp;gt;手机:&amp;lt;/label&amp;gt;
                    &amp;lt;input type=&amp;#34;tel&amp;#34; name=&amp;#34;tel&amp;#34; id=&amp;#34;tel&amp;#34; placeholder=&amp;#34;在此输入手机&amp;#34;&amp;gt;
                    &amp;lt;br/&amp;gt;

                &amp;lt;/div&amp;gt;

            &amp;lt;/div&amp;gt;
            &amp;lt;hr/&amp;gt;
            &amp;lt;div class=&amp;#34;divFormLeft&amp;#34;&amp;gt;
                &amp;lt;div &amp;gt;
                    &amp;lt;label for=&amp;#34;gender&amp;#34;&amp;gt;性别:&amp;lt;/label&amp;gt;
                    &amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; id=&amp;#34;gender&amp;#34; value=&amp;#34;male&amp;#34;&amp;gt;男&amp;amp;nbsp;
                    &amp;lt;input type=&amp;#34;radio&amp;#34; name=&amp;#34;gender&amp;#34; value=&amp;#34;femal&amp;#34; &amp;gt;女&amp;amp;nbsp;
                    &amp;lt;br/&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div&amp;gt;
                    &amp;lt;label for=&amp;#34;hobby&amp;#34;&amp;gt;爱好:&amp;lt;/label&amp;gt;
                    &amp;lt;input type=&amp;#34;checkbox&amp;#34; name=&amp;#34;hobby&amp;#34; id=&amp;#34;hobby&amp;#34; value=&amp;#34;music&amp;#34;&amp;gt;音乐&amp;amp;nbsp;
                    &amp;lt;input type=&amp;#34;checkbox&amp;#34; name=&amp;#34;hobby&amp;#34; value=&amp;#34;movie&amp;#34; &amp;gt;电影&amp;amp;nbsp;
                    &amp;lt;input type=&amp;#34;checkbox&amp;#34; name=&amp;#34;hobby&amp;#34; value=&amp;#34;game&amp;#34; &amp;gt;游戏&amp;amp;nbsp;
                    &amp;lt;br/&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div&amp;gt;

                    &amp;lt;label for=&amp;#34;birthday&amp;#34;&amp;gt;出生日期:&amp;lt;/label&amp;gt;
                    &amp;lt;input type=&amp;#34;date&amp;#34; name=&amp;#34;birthday&amp;#34; id=&amp;#34;birthday&amp;#34;&amp;gt;
                    &amp;lt;br/&amp;gt;
                &amp;lt;/div &amp;gt;
                &amp;lt;div&amp;gt;
                    &amp;lt;label &amp;gt;所在城市: &amp;lt;/label&amp;gt;
                    &amp;lt;select id=&amp;#34;city&amp;#34; name=&amp;#34;city&amp;#34;&amp;gt;
                        &amp;lt;option&amp;gt;请选择城市&amp;lt;/option&amp;gt;
                        &amp;lt;optgroup label=&amp;#34;直辖市&amp;#34;&amp;gt;
                            &amp;lt;option&amp;gt;北京&amp;lt;/option&amp;gt;
                            &amp;lt;option&amp;gt;上海&amp;lt;/option&amp;gt;
                            &amp;lt;option&amp;gt;深圳&amp;lt;/option&amp;gt;
                        &amp;lt;/optgroup&amp;gt;
                        &amp;lt;optgroup label=&amp;#34;省会城市&amp;#34;&amp;gt;
                            &amp;lt;option&amp;gt;杭州&amp;lt;/option&amp;gt;
                            &amp;lt;option&amp;gt;广州&amp;lt;/option&amp;gt;
                            &amp;lt;option&amp;gt;南京&amp;lt;/option&amp;gt;
                        &amp;lt;/optgroup&amp;gt;
                    &amp;lt;/select&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;hr/&amp;gt;
            &amp;lt;div&amp;gt;
                &amp;lt;label for=&amp;#34;sign&amp;#34;&amp;gt;个性签名:&amp;lt;/label&amp;gt;
                &amp;lt;textarea  name=&amp;#34;sign&amp;#34; id=&amp;#34;sign&amp;#34; rows=&amp;#34;6&amp;#34; cols=&amp;#34;30&amp;#34; placeholder=&amp;#34;请写出你的与众不同&amp;#34;&amp;gt;&amp;lt;/textarea&amp;gt;
                &amp;lt;br/&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div &amp;gt;
                &amp;lt;button type=&amp;#34;submit&amp;#34;&amp;gt;提交&amp;lt;/button&amp;gt;
                &amp;lt;button type=&amp;#34;reset&amp;#34;&amp;gt;重置&amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;hr/&amp;gt;
        &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Linux常用命令与shell语言 Li.050</title>
      <link>https://lizicai.com/p/linux%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E4%B8%8Eshell%E8%AF%AD%E8%A8%80-li.050/</link>
      <pubDate>Tue, 21 Sep 2021 12:58:11 +0800</pubDate>
      <guid>https://lizicai.com/p/linux%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E4%B8%8Eshell%E8%AF%AD%E8%A8%80-li.050/</guid>
      <description>&lt;h2 id=&#34;user-用户相关命令&#34;&gt;user 用户相关命令&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;useradd username

passwd username

usermod -l usernewname username

userdel usernewname

# 强制删除用户usertest主目录和邮件池
userdel -rf usertest
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;group-用户组相关命令&#34;&gt;group 用户组相关命令&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;groupadd groupname

# 查看用户所在的组
groups username

# 更改组名
groupmod -n groupname groupnewname

groupdel groupnewname
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;管理用户与组&#34;&gt;管理用户与组&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 往group1中添加用户test
gpasswd -a test group1

# 删除group1中的test
gpasswd -d test group1

# 查看组中有几个用户
cat /etc/group | grep groupname
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;时间&#34;&gt;时间&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;date

date -d &amp;#34;2021-09-09 12:00:01&amp;#34;

# 修改时间
date -s &amp;#34;2021-09-09 12:00:01&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;logname-显示登录用户名&#34;&gt;logname 显示登录用户名&lt;/h2&gt;
&lt;h2 id=&#34;su-切换用户&#34;&gt;su 切换用户&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 切换到root用户执行命令, 再切换回当前用户, 需要输入root密码
su -c ls root
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;id-查看用户id-用户组id&#34;&gt;id 查看用户id 用户组id&lt;/h2&gt;
&lt;h2 id=&#34;top-命令-实时监控进程&#34;&gt;top 命令 实时监控进程&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 停止监控
q

# 显示完整命令
top -c

# 指定pid
top -p 3550
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ps&#34;&gt;PS&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 当前正在运行
ps

# 全部运行
ps -A

# 查看更全的信息
ps -ef

# 指定用户进程信息
ps -u username
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;kill&#34;&gt;Kill&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 杀掉进程
kill 999

# 彻底杀掉
kill -9 999

# 杀掉用户进程
kill -9 $(ps -ef | grep username)
killall -u username
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shutdown&#34;&gt;shutdown&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 关机
shutdown

# 取消关机
shutdown -c

# 立即关机
shutdown -h now

# 警告 1分钟后关机
shutdown +1 &amp;#34;1分钟关机&amp;#34;

# 警告 1分钟后重启
shutdown -r +1 &amp;#34;1分钟重启&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;who-当前登录系统的用户&#34;&gt;who 当前登录系统的用户&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;who

who -H
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;timedatectl-设置时间&#34;&gt;timedatectl 设置时间&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查看所有时区
timedatectl list-timezones

# 设置野区
timedatectl set-timezone Asia/Shanghai

# 禁用ntp
timedatectl set-ntp false

# 启用ntp
timedatectl set-ntp true
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;clear-清屏-command--l-同样能做到&#34;&gt;clear 清屏 command + L 同样能做到&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;clear
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ls&#34;&gt;ls&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ls

# 显示文件夹(不隐藏的文件与文件夹详细信息)
ls -l

# 全部文件夹与文件(包含隐藏)
ls -a

ls -al
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;pwd-打印目录&#34;&gt;pwd 打印目录&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;pwd
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;cd-切换路径&#34;&gt;cd 切换路径&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/ag-fasd-fzf%e7%bb%88%e7%ab%af%e6%a8%a1%e7%b3%8a%e6%90%9c%e7%b4%a2%e7%a5%9e%e5%99%a8li.009/&#34; target=&#34;_blank&#34;&gt;Fasd 跳转比cd更快&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 相对路径
cd testdir

# 绝对
cd /home/test

# 返回上一级
cd ..

# 返回home
cd

# 返回前一个目录
cd -
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;mkdir-创建文件夹&#34;&gt;mkdir 创建文件夹&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mkdir folder

# 创建多级目录
mkdir -p test/folder
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;rmdir-删除空文件夹&#34;&gt;rmdir 删除空文件夹&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rmdir folder

# 删除多级空文件夹
rmdir -p test/test
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;rm-删除文件或文件夹&#34;&gt;rm 删除文件或文件夹&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rm a.txt

# 删除里面的目录和文件, 可删除多级目录和文件
rm -r test

# 强制删除
rm -f a.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;cp-文件复制&#34;&gt;cp 文件复制&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cp test/a.txt copy.txt

# 复制test文件夹, test文件夹内的文件夹与文件, 全量复制
cp -r test testnew

# 与上面的含义不同, 把test文件夹内的文件夹与文件, 复制到目录testnew下
cp -r test/ testnew

# 复制所有文件

cp * testnew
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;mv-移动文件夹或文件-同一目录就有改名的效果&#34;&gt;mv 移动文件夹或文件, 同一目录就有改名的效果&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mv test/a.txt testnew

# 改名
mv a.txt aaa.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;文件drwxr-xr-x&#34;&gt;文件drwxr-xr-x&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 第1位
# d 文件夹 - 文件 l链接
# r读 w 写 x可执行

# 第2-4位
# 当前用户的权限

# 第5-7 属组的权限

# 第8-10位 其他组的权限
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;chgrp-change-group&#34;&gt;chgrp (change group)&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;chgrp root a.txt

# 多了提示语句, 功能和去掉一样
chgrp -v test a.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;chown-change-own-修改用户和用户组&#34;&gt;chown (change own) 修改用户和用户组&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;chown root a.txt

# 目录及内文件夹与文件都修改组
chown -R root folder

# 修改用户与用户组, root(用户):root(用户组)
chown -R root:root folder
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;chmod-修改权限-010-权限设置数字二进制0-则无此权限-1则有权限-一个文件有3组这样的&#34;&gt;chmod 修改权限, 010 权限设置数字二进制,0 则无此权限, 1则有权限, 一个文件有3组这样的&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;chmod 755 a.xtx

# folder 文件夹内全部文件与文件夹
chmod 755 folder

# u 当前用户, g当前用户组, o其他组
chmod u=rwx,g=rx,o=r a.txt

chmod -R u=rwx,g=rx,o=r folder

# 去掉其他组的权限
chmod -R o-rwx folder
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习java-html-swift-用户可操作一个文件夹&#34;&gt;练习java html swift 用户可操作一个文件夹&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 创建用户
useradd java
useradd web
useradd swift

# 创建用户组
groupadd dev

# 用户java web swift添加到用户组dev
gpasswd -a java dev
gpasswd -a web dev
gpasswd -a swift dev

# 创建文件夹
mkdir -p /tmp/work

# 文件夹添加dev组
chgrp -R dev /tmp/work

# 文件夹增加读写执行权限
chmod -R 770 /tmp/work
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;vimvi&#34;&gt;vim/vi&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 普通模式 -&amp;gt; 退出文件
# :q   退出
# :q!  强制退出
# :wq  保存退出
# :wq! 强制保存退出

# 普通模式-&amp;gt;编辑模式
# i 当前字进入编辑模式
# I 在行首进入编辑模式
# a 当前字尾进入编辑模式
# A 行尾进入编辑模式
# o 当前行下一行进入编辑模式
# O 当前行上一行进入编辑模式

# 编辑模式 -&amp;gt; 普通模式
# esc 返回键到普通模式

# 普通模式中, 移动光标
# j 向下一行
# k 向上一行
# h 向前
# l 向后

# 移动指定12行
# 12G
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;touch-创建文件&#34;&gt;touch 创建文件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 不存在则创建, 存在则更新修改时间属性
touch a.txt

# 创建a 1-10.xt文件
touch a{1..10}.txt

# 查看文件详细信息
stat a.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;cat-查看小文件内容bat-类似软件&#34;&gt;cat 查看小文件内容(bat 类似软件)&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cat a.txt

# 显示行号
cat -n a.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;less-分屏显示文件内容&#34;&gt;less 分屏显示文件内容&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;less a.txt

# 查看时显示行号
less -N a.txt

# 快捷键同vim
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;tail-查看文件尾&#34;&gt;tail 查看文件尾&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 默认展示最后10行
tail a.txt

# 展示3行
tail -3 a.txt

# 动态展示, 会不断刷新
tail -f a.txt

# 5行动态展示
tail -5f a.txt

# 从2行展示到末尾
tail -n+2 a.txt

# 展示最后60字
tail -c 60 a.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;head-查看文件头-与tail-一致&#34;&gt;head 查看文件头, 与tail 一致&lt;/h2&gt;
&lt;h2 id=&#34;grep-搜索文件内容ag同样也可搜索&#34;&gt;grep 搜索文件内容(ag同样也可搜索)&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查看指定文件的内容
grep &amp;#34;word&amp;#34; a.txt

# 查看指定文件的内容, 并显示行号
grep -n &amp;#34;word&amp;#34; a.txt

# 忽略大小写
grep -i &amp;#34;w&amp;#34; a.txt

# 不包含w则展示这一行
grep -v &amp;#34;w&amp;#34; a.txt

# 与其他命令连用, 查看包含ssh的进程
ps -ef | grep &amp;#34;ssh&amp;#34;

# 查看包含ssh的进程, 不包含本次查询进程
ps -ef | grep ssh | grep -v &amp;#34;grep&amp;#34;

# 查看匹配数量
ps -ef | grep -c ssh
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;echo&#34;&gt;echo&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;echo &amp;#34;hello&amp;#34;

# 覆盖写入hello 到 a.txt
echo &amp;#34;hello&amp;#34; &amp;gt; a.txt

# 追加写入hello 到 a.txt
echo &amp;#34;hello&amp;#34; &amp;gt;&amp;gt; a.txt

# 把错误或正确的日志追加写入到 error.log中
cat nofile.txt &amp;amp;&amp;gt;&amp;gt; error.log
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;awk&#34;&gt;awk&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;aa 90 93 90
bb 100 93 90
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查看包含aa和bb在文件的内容, 不能有空格
cat a.txt | awk &amp;#39;/aa|bb/&amp;#39;

# 空格切割, 再打印出来
# -F &amp;#39;,&amp;#39; 以,切割
# $ + 数字 获取第几段
# $0 获取 当前行
cat a.txt | awk -F &amp;#39; &amp;#39; &amp;#39;{print $1,$2,$3,$4}&amp;#39;

# &amp;#39;{OFS=&amp;#34;===&amp;#34;}&amp;#39; 代替切割符
cat a.txt | awk -F &amp;#39; &amp;#39; &amp;#39;{OFS=&amp;#34;===&amp;#34;}{print $1,$2,$3,$4}&amp;#39;

# 制表符 \t 替换切割符
cat a.txt | awk -F &amp;#39; &amp;#39; &amp;#39;{OFS=&amp;#34;\t&amp;#34;}{print $1,$2,$3,$4}&amp;#39;

# 切割完, 第一段内容转成大写
# toupper() 转成大写
# tolower() 转成小写
# length() 返回字符长度
cat a.txt | awk -F &amp;#39; &amp;#39; &amp;#39;{print toupper($1),$2,$3,$4}&amp;#39;

# &amp;#39;BEGIN{}{totel=totel+$3}END{print totel}&amp;#39;
# 求最后一位合
cat a.txt | awk -F &amp;#39; &amp;#39; &amp;#39;BEGIN{}{totel=totel+$3}END{print totel}&amp;#39;

# 总分和总人数
cat a.txt | awk -F &amp;#39; &amp;#39; &amp;#39;BEGIN{}{totel=totel+$3}END{print totel,NR}&amp;#39;

# 总分和总人数 平均分
cat a.txt | awk -F &amp;#39; &amp;#39; &amp;#39;BEGIN{}{totel=totel+$3}END{print totel,NR,(totel/NR)}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ln-软链接&#34;&gt;ln 软链接&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# ln -s 源 软链, 源可以是文件和文件夹
ln -s test/a.txt a.txt

ln -s test/folder folder
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;find-查找文件&#34;&gt;find 查找文件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;find . -name a.c

# 查找修改时间1天内的
find . -ctime -1

find ~ -ctime -1
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;gzip-压缩&#34;&gt;gzip 压缩&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# gzip 压缩, 会删除原文件
gzip a.txt

# 解压-d, 打印过程, 解压同样会删除原压缩文件
gzip -dv a.txt.gz

# 压缩全部文件
gzip *
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;gunzip&#34;&gt;gunzip&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 解压同样会删除原压缩文件
gunzip a.txt.gz

gunzip *
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;tar-本身不具有压缩功能-只是调用其他压缩软件&#34;&gt;tar, 本身不具有压缩功能, 只是调用其他压缩软件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# -c 建立新的压缩文件
# -v 显示指令执行过程
# -f &amp;lt;备份文件&amp;gt; 指定压缩文件
# -z 通过gzip处理压缩文件
# -t 列出压缩文件中的内容
# -x 表示解压

# 仅打包文件
tar -cvf a.tar a.txt

# 打包并压缩
tar -zcvf a.gz a.txt

# 仅查看压缩包中内容
tar -ztvf error.gz

# 解压压缩包
tar -zxvf error.gz
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;zip&#34;&gt;zip&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# -q 不显示指令执行过程
# -r 递归处理, 指定目录和子目录 子文件一并处理
zip -rq test.zip test
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;unzip&#34;&gt;unzip&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# -l 显示压缩包中的文件
unzip -l test.zip

# 直接解压
unzip test.zip

# 解压到指定文件夹内
unzip -d ~/dev test.zip
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;bzip2-压缩时间长-压缩率高&#34;&gt;bzip2, 压缩时间长, 压缩率高&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bzip2 a.txt

# 打印过程
bunzip2 -v a.txt.bz2
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ifconfig&#34;&gt;ifconfig&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查看网卡信息
ifconfig

# 关闭网卡
ifconfig eth0 down

# 启用网卡
ifconfig eth0 up

# 配置ip
ifconfig eth0 192.168.1.200

# 配置ip 和 子网掩码
ifconfig eth0 192.168.1.200 netmask 255.255.255.0
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ping&#34;&gt;ping&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ping 192.168.0.100
ping www.baidu.com

# -c 10 ping 指定10次
ping -c 10 192.168.0.100
ping -c 10 www.baidu.com
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;netstat-显示网络状况&#34;&gt;netstat 显示网络状况&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 所有的连接情况
netstate -a

# -i 显示网卡列表
netstat -i
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;lsblk-list-block缩写-列出硬盘使用情况&#34;&gt;lsblk (list block缩写) 列出硬盘使用情况&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 硬盘 硬盘分区信息
lsblk

# 显示详细系统信息
lsblk -f
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;df-硬盘使用情况&#34;&gt;df 硬盘使用情况&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;df

# 查看文件硬盘情况
df folder

# 查看所有详细信息
df --total

# -h MB GB KB显示
df -h
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;mount-挂载&#34;&gt;mount 挂载&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mkdir folder

# 自动挂载
mount -t auto /dev/cdrom folder

# 解除
unmount folder
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;yum-yellow-dog-updatermodified&#34;&gt;yum (Yellow dog Updater,Modified)&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查看可用更新
yum check-update

# 更新所有
yum update

# 安装 更新tree
yum install tree
yum update tree

# 卸载
yum remove tree

# 搜索
yum search tree

# 清除缓存目录下的软件包
yum clean packages

# 清除缓存目录下的headers
yum clean headers

# 清除缓存目录下的旧的headers
yum clean oldheaders

# 清除缓存
yum clean
yum clean all
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;更改yum源-或添加其他yum源&#34;&gt;更改yum源, 或添加其他yum源&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;yum install wget

cd /etc/yum.repos.d

mv CentOS-BaseOS.repo CentOS-BaseOS.repo-backup

wget -O CentOS-BaseOS.repo http://mirrors.aliyun.com/repo/Centos-7.repo

# 清空之前的缓存
yum clean all

# 使用新的源做缓存
yum makecache
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;rpm-安装下载本地并安装-不常用&#34;&gt;rpm, 安装下载本地并安装, 不常用&lt;/h2&gt;
&lt;h2 id=&#34;shell-命令解释器-bash-zsh-多种shell&#34;&gt;shell 命令解释器, bash zsh 多种shell&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查看默认shell
echo $SHELL

# vim a.sh
# 写入内容

#!/bin/zsh
# 注释
echo &amp;#34;Hello&amp;#34;

# 增加执行权限
chmod 755 a.sh
chmod +x a.sh

# 执行
./a.sh

# 多行注释
:&amp;lt;&amp;lt;! 内容
内容
!
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-变量&#34;&gt;shell 变量&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;普通变量
&lt;ul&gt;
&lt;li&gt;方式一
&lt;ul&gt;
&lt;li&gt;变量名=变量值  变量值必须是一个整体, 中间没有特殊字符&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;方式二
&lt;ul&gt;
&lt;li&gt;变量名=&amp;lsquo;变量值&amp;rsquo; 单引号中的内容, 原样赋值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;方式三
&lt;ul&gt;
&lt;li&gt;变量名=&amp;ldquo;变量值&amp;rdquo; 如果双引号里面有其他变量, 会把变量的结果进行拼接, 然后赋值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;number=10
echo $number
echo ${number}

a=&amp;#39;10&amp;#39;
echo $a
echo ${a}
b=&amp;#39;$number&amp;#39;
echo $a

c=&amp;#34;10&amp;#34;
echo $b
echo ${b}
d=&amp;#34;$number&amp;#34;
echo $d
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;命令变量
&lt;ul&gt;
&lt;li&gt;方式一
&lt;ul&gt;
&lt;li&gt;变量名=&lt;code&gt;命令&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;方式二
&lt;ul&gt;
&lt;li&gt;变量名=$(命令)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;e=`date`
echo $e

# 推荐方式二
f=$(date)
echo $f
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;使用变量
&lt;ul&gt;
&lt;li&gt;方式一
&lt;ul&gt;
&lt;li&gt;$变量名 非标准&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;方式二
&amp;ldquo;$变量名&amp;rdquo; 非标准&lt;/li&gt;
&lt;li&gt;方式三
${变量名} 在双号里面使用变量的值&lt;/li&gt;
&lt;li&gt;方式四
&amp;ldquo;${变量名}&amp;rdquo; 标准使用方式&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;f=$(date)
result=&amp;#34;时间${f}&amp;#34;

# 标准使用
echo &amp;#34;${result}&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;只读变量&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;echo &amp;#34;${result}&amp;#34;

readonly result
result=&amp;#34;aaa&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;删除变量&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;f=$(date)

echo &amp;#34;${f}&amp;#34;
unset f
echo &amp;#34;${f}&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-数组&#34;&gt;shell 数组&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;定义数组, 数组名=(值1 值2&amp;hellip;)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;arr=(1 2 3 4 5)
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;给数组的元素赋值, 数组名[索引]=值, bash(0开始) 和 zsh(1开始)的脚标开始位置不一致&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;arr[1]=10
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;获取元素, ${数组名[下标]}&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;${arr[1]}

echo ${arr[1]}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;获取长度, ${#数组名[*]} ${#数组名[@]}&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;${#arr[*]}
${#arr[@]}

echo ${#arr[*]}
echo ${#arr[@]}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-算术运算符-原生bash不支持数学运算&#34;&gt;shell 算术运算符, 原生bash不支持数学运算&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 格式中有空格, 注意
# +  expr $a + $b
# -  expr $a - $b
# *  expr $a \* $b
# /  expr $a / $b
# %  expr $a % $b
# =  $a = $b
# ++ -- 自增自减 ((a++))


num1=`expr 2 + 2`
echo $num1

num2=`expr 2 \* 2`
echo $num2

a=10
b=20
num3=`expr $a + $b`
echo $num3

c=30
num4=&amp;#34;$c&amp;#34;
echo $num4

e=1
((e++))
echo $e
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-字符串运算符-1为假-0为真&#34;&gt;shell 字符串运算符, 1为假 0为真&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 运算符, []之间必须有空格
# =     检测2个字符串是否相等 [ $a = $b ]
# !=    检测2个字符串是否不相等 [ $a != $b ]
# -z    检测字符串长度是否为0 [ -z $a ]
# -n    检测字符串长度是否不为0 [ -n &amp;#34;$a&amp;#34; ]
# $     检测字符串是否为空 [ $a ]

#!/bin/bash
a=&amp;#34;aaa&amp;#34;
b=&amp;#34;bbb&amp;#34;

[ &amp;#34;${a}&amp;#34; = &amp;#34;${b}&amp;#34; ]
echo $?

[ &amp;#34;${a}&amp;#34; != &amp;#34;${b}&amp;#34; ]
echo $?

[ -z &amp;#34;${a}&amp;#34; ]
echo $?

[ -n &amp;#34;${a}&amp;#34; ]
echo $?

[ $&amp;#34;${a}&amp;#34; ]
echo $?

# 其中$?, 获取上一语句运行结果
# 获取字条串长度
echo ${#a}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-关系运算符-只支持数字-不支持字符串-除非字符串是数字&#34;&gt;shell 关系运算符, 只支持数字, 不支持字符串, 除非字符串是数字&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1为假, 0为真&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# -eq 检测2个数是否相等 [ $a -eq $b ]
# -ne 检测2个数是否不相等 [ $a -ne $b ]
# -gt 检测左边的数大于右边 [ $a -gt $b ]
# -lt 检测左边的数小于右边 [ $a -lt $b ]
# -ge 检测左边的数是否大于等于右边 [ $a -ge $b ]
# -le 检测左边的数是否小于等于右边 [ $a -le $b ]


#!/bin/bash
a=&amp;#34;111&amp;#34;
b=&amp;#34;222&amp;#34;

[ &amp;#34;${a}&amp;#34; -eq &amp;#34;${b}&amp;#34; ]
echo $?

[ &amp;#34;${a}&amp;#34; -ne &amp;#34;${b}&amp;#34; ]
echo $?

[ &amp;#34;${a}&amp;#34; -gt &amp;#34;${b}&amp;#34; ]
echo $?

[ &amp;#34;${a}&amp;#34; -lt &amp;#34;${b}&amp;#34; ]
echo $?

[ &amp;#34;${a}&amp;#34; -ge &amp;#34;${b}&amp;#34; ]
echo $?

[ &amp;#34;${a}&amp;#34; -le &amp;#34;${b}&amp;#34; ]
echo $?
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-布尔运算符&#34;&gt;shell 布尔运算符&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# ! 取反运算 [ ! false ]
# -o 或运行, 有一个表达式为true 则返回true [ $a lt 20 -o $b -gt 100 ]
# -a 与运行, 2个表达式都为true 才返回true [ $a lt 20 -a $b -gt 100 ]

#!/bin/bash
a=111
b=222

[ ! &amp;#34;${a}&amp;#34; -eq &amp;#34;${b}&amp;#34; ]
echo $?

[ &amp;#34;${a}&amp;#34; -gt 100 -o &amp;#34;${a}&amp;#34; -lt 100 ]
echo $?

[ &amp;#34;${a}&amp;#34; -gt 100 -a &amp;#34;${a}&amp;#34; -lt 100 ]
echo $?

[ &amp;#34;${a}&amp;#34; -ge 100 -a &amp;#34;${a}&amp;#34; -le 200 ]
echo $?
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-逻辑运算符&#34;&gt;shell 逻辑运算符&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 运算符
# &amp;amp;&amp;amp; 逻辑的AND [[ true &amp;amp;&amp;amp; true ]] 返回true
# || 逻辑OR   [[ false || false ]] 返回false

#!/bin/bash
a=111
b=222

[[ &amp;#34;${a}&amp;#34; -gt 100 &amp;amp;&amp;amp; &amp;#34;${a}&amp;#34; -lt 100 ]]
echo $?

[[ &amp;#34;${a}&amp;#34; -gt 100 || &amp;#34;${a}&amp;#34; -lt 100 ]]
echo $?

[[ &amp;#34;${a}&amp;#34; -ge 100 || &amp;#34;${a}&amp;#34; -le 200 ]]
echo $?
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-判断&#34;&gt;shell 判断&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 三种方式
if [ 条件 ]
then
    语句体
if

if [ 条件 ]
then
    语句体
else
    语句体
if

if [ 条件 ]
then
    语句体
elif [ 条件 ]
    语句体
else
    语句体
if


if [ $(ps -ef | grep -c &amp;#34;ssh&amp;#34;) -ge 1 ]
then
    echo &amp;#34;true&amp;#34;
fi


if [ $(ps -ef | grep -c &amp;#34;nonono&amp;#34;) -gt 2 ]
then
    echo &amp;#34;true&amp;#34;
else
    echo &amp;#34;flase&amp;#34;
fi


if [ $(ps -ef | grep -c &amp;#34;nonono&amp;#34;) -gt 2 ]
then
    echo &amp;#34;true&amp;#34;
elif [ $(ps -ef | grep -c &amp;#34;nonono&amp;#34;) -eq 1 ]
then
    echo &amp;#34;one&amp;#34;
else
    echo &amp;#34;flase&amp;#34;
fi
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-选择语句&#34;&gt;shell 选择语句&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;变量
case 变量 in
模式1 )
    语句体1
    ;;
模式2 )
    语句体2
    ;;
esac

#!/bin/zsh
# 注释
a=2
case &amp;#34;${a}&amp;#34; in
&amp;#34;1&amp;#34; )
    echo &amp;#39;1&amp;#39;
    ;;
&amp;#34;2&amp;#34; )
    echo &amp;#39;1&amp;#39;
    ;;
esac
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-循环语句&#34;&gt;shell 循环语句&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;for 变量 in 范围
do
    循环体
done


#!/bin/zsh
# 注释
for loop in 1 2 3 4 5
do
    echo $loop
done


while [ 条件 ]
do
    语句体
done


#!/bin/zsh
# 注释
a=1
while [ &amp;#34;${a}&amp;#34; -le 10 ]
do
    echo &amp;#34;${a}&amp;#34;
    ((a++))
done
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;shell-函数&#34;&gt;shell 函数&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;函数必须调用&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 无参无返回值
函数名(){
    函数体
}
函数名

#!/bin/zsh
# 注释
printhello(){
    echo &amp;#34;Hello&amp;#34;
}
printhello


# 有参无返回值
函数名(){
    echo $1
    echo $2
}

函数名 a b


printab(){
    echo $1
    echo $2
}

printab 10 20

# 有参有返回值
函数名(){
    echo $1
    return $(($1+$2))
}

函数名 10 20

printhe(){
    echo $1 + $2
    #return `expr $1 + $2` 这样写也可
    return $(($1+$2))
}

printhe 10 20
echo $?
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习&#34;&gt;练习&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;依次输入2个数, 打印合&lt;/li&gt;
&lt;li&gt;read 读取屏幕内容&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/bash
# 注释
getab(){
    echo &amp;#34;第1个数&amp;#34;
    read number1
    echo &amp;#34;第2个数&amp;#34;
    read number2
    return $(($number1+$number2))
}
getab
echo $?
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的反射 Li.049</title>
      <link>https://lizicai.com/p/java%E7%9A%84%E5%8F%8D%E5%B0%84-li.049/</link>
      <pubDate>Sun, 19 Sep 2021 22:18:30 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84%E5%8F%8D%E5%B0%84-li.049/</guid>
      <description>&lt;h2 id=&#34;反射&#34;&gt;反射&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;反射概述
&lt;ul&gt;
&lt;li&gt;Java的反射机制是在运行状态中, 对于任意一个类, 都能知道这个类的所有属性和方法&lt;/li&gt;
&lt;li&gt;对于任意一个对象, 都能够调用它的任意一个方法和属性&lt;/li&gt;
&lt;li&gt;这种动态获取信息以及动态调用对象的方法的功能称为Java语文的反射机制&lt;/li&gt;
&lt;li&gt;想要解剖一个类, 必需先要获取到该类的字节码文件对象&lt;/li&gt;
&lt;li&gt;而解剖使用的就是Class类中的方法, 所以先要获取到每一个字节码文件对应的Class类型的对象&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;反射的三种方式
&lt;ul&gt;
&lt;li&gt;Object烦的getClass()方法, 判断2个对象是否是同一个字节码文件&lt;/li&gt;
&lt;li&gt;静态属性class, 锁对象(Person.class)&lt;/li&gt;
&lt;li&gt;Class类中静态方法forName(), 读取配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Person;


public class Demo1_Reflect {
    public static void main(String[] args) throws ClassNotFoundException {
        Class clazz1 = Class.forName(&amp;#34;com.lizicai.bean.Person&amp;#34;);

        Class clazz2 = Person.class;

        Person p = new Person();
        Class clazz3 = p.getClass();

        System.out.println(clazz1 == clazz2);
        System.out.println(clazz2 == clazz3);

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;反射classforname读取配置文件举例&#34;&gt;反射(Class.forName()读取配置文件举例)&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo2_Reflect {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
//        nouseReflect();
        String str = null;
        BufferedReader br = new BufferedReader(new FileReader(&amp;#34;config.properties&amp;#34;));
        str = br.readLine();
        Class clazz = Class.forName(str);

        Fruit f = (Fruit) clazz.newInstance();
        Juier j = new Juier();
        j.run(f);

    }
    private static void nouseReflect() {
        Juier j = new Juier();
        Apple apple = new Apple();
        j.run(apple);
        j.run(new Orange());
    }
}
interface Fruit{
    public void squeeze();
}
class Apple implements Fruit {
    @Override
    public void squeeze(){
        System.out.println(&amp;#34;苹果汁&amp;#34;);
    }
}
class Orange implements Fruit{
    @Override
    public void squeeze(){
        System.out.println(&amp;#34;橙汁&amp;#34;);
    }
}
class Juier{
    public void run(Fruit fruit){
        fruit.squeeze();
    }
    public void run(Orange orange){
        orange.squeeze();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;com.lizicai.reflect.Orange
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;通过反射获取带参构造方法并使用&#34;&gt;通过反射获取带参构造方法并使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;构造函数必须public, 否则报NoSuchMethodException 异常.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo3_Reflect {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class clazz = Class.forName(&amp;#34;com.lizicai.bean.Person&amp;#34;);

//        Person p = (Person) clazz.newInstance();
        Constructor c = clazz.getConstructor(String.class, int.class);
        Person p = (Person) c.newInstance(&amp;#34;张三&amp;#34;,23);
        System.out.println(p);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Person {
    private String name;
    private int age;

    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public String toString() {
        return this.getName() + this.getAge();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;通过反射获取成员变量并使用&#34;&gt;通过反射获取成员变量并使用&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class Demo4_Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        Class clazz = Class.forName(&amp;#34;com.lizicai.bean.Person&amp;#34;);
        Constructor c = clazz.getConstructor(String.class, int.class);
        Person p = (Person) c.newInstance(&amp;#34;张三&amp;#34;,23);
//        Field f = clazz.getField(&amp;#34;name&amp;#34;);
        // 暴力反射
        Field f = clazz.getDeclaredField(&amp;#34;name&amp;#34;);
        // 去除私有权限
        f.setAccessible(true);
        f.set(p,&amp;#34;李四&amp;#34;);
        System.out.println(p);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;通过反射获取方法并使用&#34;&gt;通过反射获取方法并使用&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo5_Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, InvocationTargetException {
        Class clazz = Class.forName(&amp;#34;com.lizicai.bean.Person&amp;#34;);
        Constructor c = clazz.getConstructor(String.class, int.class);
        Person p = (Person) c.newInstance(&amp;#34;张三&amp;#34;,23);

        Method m = clazz.getMethod(&amp;#34;eat&amp;#34;);
        m.invoke(p);

        Method m2 = clazz.getMethod(&amp;#34;eat&amp;#34;, int.class);
        m2.invoke(p,10);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;通过反射越过泛型检查&#34;&gt;通过反射越过泛型检查&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;泛型编译时检查, 运行时没有检查&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ArrayList&amp;lt;Integer&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        list.add(1);
        list.add(2);

        Class clazz = Class.forName(&amp;#34;java.util.ArrayList&amp;#34;);
        Method m = clazz.getMethod(&amp;#34;add&amp;#34;,Object.class);
        m.invoke(list,&amp;#34;test&amp;#34;);
        System.out.println(list);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;通过反射写一个通用的设置某个对象的某个属性为指定的值&#34;&gt;通过反射写一个通用的设置某个对象的某个属性为指定的值&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Person对象仍然是上面的&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.lang.reflect.Field;

public class Tool {
    public void setProperty(Object obj, String propertyName, Object value) throws NoSuchFieldException, IllegalAccessException {
        Class clazz = obj.getClass();
        Field f = clazz.getDeclaredField(propertyName);
        f.setAccessible(true);
        f.set(obj,value);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Person;

public class Test2 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Person p = new Person(&amp;#34;小明&amp;#34;,23);
        System.out.println(p);

        Tool t = new Tool();
        t.setProperty(p,&amp;#34;name&amp;#34;,&amp;#34;小红&amp;#34;);
        System.out.println(p);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习&#34;&gt;练习&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {

        File file = new File(&amp;#34;demo.properties&amp;#34;);
        BufferedReader br = new BufferedReader(new FileReader(file));
        String clazzName = br.readLine();
        br.close();

        Class clazz = Class.forName(clazzName);

        DemoClass dc = (DemoClass) clazz.newInstance();

        Method m = clazz.getMethod(&amp;#34;run&amp;#34;);
        m.invoke(dc);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class DemoClass {
    public void run(){
        System.out.println(&amp;#34;大王叫我来巡山&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;com.lizicai.test.DemoClass
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;动态代理的概述和实现&#34;&gt;动态代理的概述和实现&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;写好了代理, 就能在所有类前后进行一些处理&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public interface User {
    public void add();
    public void delete();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class UserImp implements User{
    @Override
    public void add() {
//        System.out.println(&amp;#34;权限校验&amp;#34;);
        System.out.println(&amp;#34;添加&amp;#34;);
//        System.out.println(&amp;#34;日志记录&amp;#34;);
    }

    @Override
    public void delete() {
//        System.out.println(&amp;#34;权限校验&amp;#34;);
        System.out.println(&amp;#34;删除&amp;#34;);
//        System.out.println(&amp;#34;日志记录&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {
    private Object target;
    public MyInvocationHandler(Object target){
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(&amp;#34;权限检验&amp;#34;);
        method.invoke(target,args);
        System.out.println(&amp;#34;日志记录&amp;#34;);
        return null;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        User ui = new UserImp();
        ui.add();
        ui.delete();
        MyInvocationHandler m = new MyInvocationHandler(ui);
        User u = (User) Proxy.newProxyInstance(ui.getClass().getClassLoader(), ui.getClass().getInterfaces(),m);

        u.add();
        u.delete();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;模版template设计模式概述和使用&#34;&gt;模版(Template)设计模式概述和使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;模版设计模式概述
&lt;ul&gt;
&lt;li&gt;模版方法模式就是定义一个算法模版, 而将具体的算法延迟到子类中实现&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;优点 缺点
&lt;ul&gt;
&lt;li&gt;使用模版方法模式, 在定义骨架的同时, 可以很灵活实现具体的方法, 满足用户灵活多变的需求&lt;/li&gt;
&lt;li&gt;如果算法有修改, 则需要修改抽象类&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Template extends TestTime{
    public static void main(String[] args) {
        Demo1_Template d = new Demo1_Template();
        System.out.println(d.getTime());
    }
    @Override
    public void code() {
        for(int i=0;i&amp;lt;100000;i++){
            System.out.println(i);
        }
    }
}

abstract class TestTime{
    final public long getTime(){
        long start = System.currentTimeMillis();
        code();
        long end = System.currentTimeMillis();
        return end - start;
    }
    public abstract void code();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;自己实现枚举类&#34;&gt;自己实现枚举类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;概述
&lt;ul&gt;
&lt;li&gt;是指将变量的值一一列举出来, 变量的值仅限于列举出来的值的范围内&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;单例模式, 只有一个实例
&lt;ul&gt;
&lt;li&gt;多例类就是一个类有多个实例, 但不是无限多个实例, 是有限个数的实例, 这才是枚举类.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;枚举类有下例3种形式&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Week {
    final static Week MON = new Week();
    final static Week TUE = new Week();
    final static Week WED = new Week();
    private Week(){}
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Week2 {
    final static Week2 MON = new Week2(&amp;#34;星期一&amp;#34;);
    final static Week2 TUE = new Week2(&amp;#34;星期二&amp;#34;);
    final static Week2 WED = new Week2(&amp;#34;星期三&amp;#34;);
    String name;
    private Week2(String name){
        this.name = name;
    }

    @Override
    public String toString() {
        return this.name;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public abstract class Week3 {
    final static Week3 MON = new Week3(&amp;#34;星期一&amp;#34;){
        @Override
        public void show() {
            System.out.println(&amp;#34;星期一&amp;#34;);
        }
    };
    final static Week3 TUE = new Week3(&amp;#34;星期二&amp;#34;){
        @Override
        public void show() {
            System.out.println(&amp;#34;星期二&amp;#34;);
        }
    };
    final static Week3 WED = new Week3(&amp;#34;星期三&amp;#34;) {
        @Override
        public void show() {
            System.out.println(&amp;#34;星期三&amp;#34;);
        }
    };
    String name;
    private Week3(String name){
        this.name = name;
    }

    @Override
    public String toString() {
        return this.name;
    }

    public abstract void show();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Enum {
    public static void main(String[] args) {
        Week mon = Week.MON;
        System.out.println(mon);


        Week2 Mon = Week2.MON;
        Week2 Tue = Week2.TUE;
        Week2 Wed = Week2.WED;
        System.out.println(Mon);
        System.out.println(Tue);
        System.out.println(Wed);

        Week3 MON = Week3.MON;
        Week3 TUE = Week3.TUE;
        Week3 WED = Week3.WED;
        MON.show();
        TUE.show();
        WED.show();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;通过enum实现枚举类&#34;&gt;通过enum实现枚举类&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public enum Week {
    MON,TUE,WED;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public enum Week2 {
    MON(&amp;#34;星期一&amp;#34;),TUE(&amp;#34;星期二&amp;#34;),WED(&amp;#34;星期三&amp;#34;);
    private String name ;
    Week2(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public enum Week3 {
    MON(&amp;#34;星期一&amp;#34;){
        @Override
        public void show() {
            System.out.println(&amp;#34;星期一&amp;#34;);
        }
    },TUE(&amp;#34;星期二&amp;#34;){
        @Override
        public void show() {
            System.out.println(&amp;#34;星期二&amp;#34;);
        }
    },WED(&amp;#34;星期三&amp;#34;){
        @Override
        public void show() {
            System.out.println(&amp;#34;星期三&amp;#34;);
        }
    };
    private String name ;
    Week3(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public abstract void show();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Enum {
    public static void main(String[] args) {
        Week mon = Week.MON;
        Week tue = Week.TUE;
        System.out.println(mon);
        System.out.println(tue);

        Week2 Mon = Week2.MON;
        Week2 Tue = Week2.TUE;
        System.out.println(Mon);
        System.out.println(Tue.getName());

        Week3 MON = Week3.MON;
        Week3 TUE = Week3.TUE;
        Week3 WED = Week3.WED;
        System.out.println(MON);
        System.out.println(TUE.getName());
        System.out.println(WED.getName());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;switch-使用枚举&#34;&gt;switch 使用枚举&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public static void demo1(){
    Week2 MON = Week2.TUE;
    switch (MON){
        case MON:
            System.out.println(&amp;#34;星期一&amp;#34;);
            break;
        case TUE:
            System.out.println(&amp;#34;星期二&amp;#34;);
            break;
        case WED:
            System.out.println(&amp;#34;星期三&amp;#34;);
            break;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;常用的枚举方法&#34;&gt;常用的枚举方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;public final int ordinal() 获取枚举的位置&lt;/li&gt;
&lt;li&gt;public final int compareTo(E o) 比较枚举位置, 返回差&lt;/li&gt;
&lt;li&gt;public final String name() 获取枚举实例的名字&lt;/li&gt;
&lt;li&gt;public static &amp;lt;T extends Enum&lt;T&gt;&amp;gt; T valueOf(Class&lt;T&gt; enumType, String name) 字节码对象获取枚举项&lt;/li&gt;
&lt;li&gt;values 获取枚举的数组&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_Enum {
    public static void main(String[] args) {
        Week2 mon = Week2.MON;
        Week2 tue = Week2.TUE;
        Week2 wed = Week2.WED;

        System.out.println(mon.ordinal());
        System.out.println(tue.ordinal());
        System.out.println(wed.ordinal());

        System.out.println(mon.compareTo(tue));
        System.out.println(mon.compareTo(wed));

        System.out.println(mon.name());
        System.out.println(tue.name());

        System.out.println(mon);
        System.out.println(tue.toString());
        // 字节码对象获取枚举项
        Week2 TUE = Week2.valueOf(Week2.class,&amp;#34;TUE&amp;#34;);
        System.out.println(TUE);

        Week2[] arr = Week2.values();
        for(Week2 w:arr){
            System.out.println(w);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jdk-17-新增内容&#34;&gt;JDK 1.7 新增内容&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;switch支持字符串&lt;/li&gt;
&lt;li&gt;异常catch多个异常, 用|隔开&lt;/li&gt;
&lt;li&gt;try-whith-resources 自动关流&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Demo3_AutoClose {
    public static void main(String[] args) {
    File file = new File(&amp;#34;config.properties&amp;#34;);
    //资源放在try()中, 会自动关闭资源, 不用在finally 中关闭了
        try ( FileInputStream fis = new FileInputStream(file)){
            int b;
            while ( ( b = fis.read() ) != -1){
                System.out.println(b);
            }
        } catch (IOException e){
            System.out.println(e.getMessage());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;jdk-18-新增内容&#34;&gt;JDK 1.8 新增内容&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;接口可以支持default修饰, 有方法体&lt;/li&gt;
&lt;li&gt;接口也可以有静态方法了&lt;/li&gt;
&lt;li&gt;内部类可访问的变量默认是final修饰&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_JKD18 {
    // JDK1.8新特性
    public static void main(String[] args) {
        Demo d = new Demo();
        d.show();
        Inter.test();

        d.run();
    }
}

interface Inter{
    public default void show(){
        System.out.println(&amp;#34;显示&amp;#34;);
    }

    public static void test(){
        System.out.println(&amp;#34;测试&amp;#34;);
    }
}
class Demo implements Inter{

    public void run(){
        // num 默认是final
        int num = 20;
        class Inner{
            public void fun(){
                System.out.println(&amp;#34;fun&amp;#34;);
            }
        }
        Inner i = new Inner();
        i.fun();
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的网络编程 Li.048</title>
      <link>https://lizicai.com/p/java%E7%9A%84%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B-li.048/</link>
      <pubDate>Fri, 17 Sep 2021 10:27:11 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B-li.048/</guid>
      <description>&lt;h2 id=&#34;网络通信&#34;&gt;网络通信&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ip 电脑地址&lt;/li&gt;
&lt;li&gt;UDP TCP&lt;/li&gt;
&lt;li&gt;端口号&lt;/li&gt;
&lt;li&gt;socket 插座, 数据流间的插座, 用来联通&lt;/li&gt;
&lt;li&gt;类似电脑是港口ip, socket是航线用来发货, 端口号是港口停放船的泊位, UDP TCP是小船还是大船来运送数据箱子&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;datagramsocket-与-datagrampacket&#34;&gt;DatagramSocket 与 DatagramPacket&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;DatagramSocket 创建一条航线&lt;/li&gt;
&lt;li&gt;DatagramPacket 指定电脑ip(港口), 端口号(泊位), 运送的数据(集装箱)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;

public class Demo1_Send {
    public static void main(String[] args) throws IOException {
        String msg = &amp;#34;中午一起吃饭&amp;#34;;
        DatagramSocket datagramSocket = new DatagramSocket();
        DatagramPacket datagramPacket = new DatagramPacket
                (msg.getBytes(StandardCharsets.UTF_8),msg.getBytes().length, InetAddress.getByName(&amp;#34;127.0.0.1&amp;#34;),2000);

        datagramSocket.send(datagramPacket);
        datagramSocket.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Demo2_Receive {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(2000);
        DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
        socket.receive(packet);
        byte[] arr = packet.getData();
        int len = packet.getLength();
        System.out.println(new String(arr,0,len));
        socket.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;能够不断录入的版本&#34;&gt;能够不断录入的版本&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class Demo3_Send {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        DatagramSocket datagramSocket = new DatagramSocket();
        while (true){
            String msgLine = sc.nextLine();
            if( &amp;#34;quit&amp;#34;.equals(msgLine)){
                break;
            }
            System.out.println(msgLine);
            DatagramPacket packet =
                    new DatagramPacket (msgLine.getBytes(StandardCharsets.UTF_8),
                            msgLine.getBytes().length,
                            InetAddress.getByName(&amp;#34;127.0.0.1&amp;#34;),
                            2000);

            datagramSocket.send(packet);
        }
        datagramSocket.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Demo3_Receive {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(2000);
        DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);

        while (true){
            socket.receive(packet);
            byte[] arr = packet.getData();
            int len = packet.getLength();
            System.out.println(&amp;#34;信息&amp;#34; + new String(arr,0,len));
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多线程发送和接收信息&#34;&gt;多线程发送和接收信息&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class Demo4_MoreThread {
    public static void main(String[] args) {
        MyReceive myReceive = new MyReceive();
        MySend mySend = new MySend();
        myReceive.start();
        mySend.start();
    }

}
class MyReceive extends Thread{
    @Override
    public void run() {
        try {
            DatagramSocket socket = null;
            socket = new DatagramSocket(2000);
            DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);

            while (true){
                socket.receive(packet);
                byte[] arr = packet.getData();
                int len = packet.getLength();
                System.out.println(&amp;#34;信息&amp;#34; + new String(arr,0,len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class MySend extends Thread{
    @Override
    public void run() {
        Scanner sc = new Scanner(System.in);
        DatagramSocket datagramSocket = null;
        try {
            datagramSocket = new DatagramSocket();
            while (true){
                String msgLine = sc.nextLine();
                if( &amp;#34;quit&amp;#34;.equals(msgLine)){
                    break;
                }
                DatagramPacket packet =
                        new DatagramPacket (msgLine.getBytes(StandardCharsets.UTF_8),
                                msgLine.getBytes().length,
                                InetAddress.getByName(&amp;#34;127.0.0.1&amp;#34;),
                                2000);

                datagramSocket.send(packet);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        datagramSocket.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;gui-聊天&#34;&gt;GUI 聊天&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo5_GUIChat extends Frame{
    private TextField textField;
    private TextArea viewText;
    private TextArea sendText;
    private Button send;
    private Button log;
    private Button clear;
    private Button shake;
    private DatagramSocket socket;
//    private BufferedReader br;
    private FileInputStream fis;
    private BufferedWriter bw;
    public Demo5_GUIChat() throws SocketException,IOException{
        init();
        southPanel();
        centerPanel();
        event();
        Receive r = new Receive();
        r.start();
        this.setVisible(true);

    }

    public void event() {
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                try {
                    bw.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                socket.close();
                System.exit(0);
            }
        });
        send.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    send();
                } catch (SocketException ex) {
                    ex.printStackTrace();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
        log.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    logFile();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });

        clear.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                viewText.setText(&amp;#34;&amp;#34;);
            }
        });

        shake.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
//                shake();
                try {
                    send(new byte[]{-1},textField.getText());
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });

        sendText.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_ENTER ){
                    try {
                        send();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
    }
    public void shake(){
        int x = this.getX();
        int y = this.getY();
        for(int i=0;i&amp;lt;20;i++){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(i % 2 == 0){
                this.setLocation(x+3,y+3);
            } else {
                this.setLocation(x,y);
            }
        }
    }
    public void logFile() throws IOException {

//        br = new BufferedReader(new InputStreamReader(new FileInputStream(&amp;#34;chat.log&amp;#34;)));
//        br = new BufferedReader(new FileReader(&amp;#34;chat.log&amp;#34;));
//        viewText.setText(&amp;#34;&amp;#34;);
//        int len ;
//        char [] arr = new char[1024];
//        while ( ( len =br.read(arr)) != -1){
//            viewText.append(new String(arr,0,len));
//        }
//        br.close();
        fis = new FileInputStream(&amp;#34;chat.log&amp;#34;);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int len;
        byte[] arr = new byte[8192];
        while ( (len = fis.read(arr)) != -1){
            bos.write(arr,0,len);
        }
        viewText.setText(bos.toString());
        bos.close();

    }
    public void send(byte[] arr,String ip) throws IOException {
        DatagramPacket packet = new DatagramPacket(arr,
                arr.length,
                InetAddress.getByName(ip),
                9999);
        socket.send(packet);
    }

    public void send() throws IOException {
        String msg = sendText.getText();
        if( &amp;#34;&amp;#34;.equals(msg.trim())  || null ==msg){
            return;
        } else {
            String ip = textField.getText();
            if( ip.equals(null) || ip.trim().equals(&amp;#34;&amp;#34;)){
                ip = &amp;#34;255.255.255.255&amp;#34;;
            }
            String time = getTime();
            send(msg.getBytes(StandardCharsets.UTF_8),ip);

            String chatlog = time+&amp;#34; &amp;#34;+&amp;#34;我对:&amp;#34;+(ip.equals(&amp;#34;255.255.255.255&amp;#34;)? &amp;#34;所有人&amp;#34;:ip)+&amp;#34;说:&amp;#34;+&amp;#34;\n&amp;#34;+ msg +&amp;#34;\n&amp;#34;+&amp;#34;\n&amp;#34;;
            viewText.append(chatlog);
            bw.write(chatlog);
            bw.flush();
            sendText.setText(&amp;#34;&amp;#34;);
        }

    }
    public String getTime(){
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(&amp;#34;yyyy年MM月dd日 HH:mm:ss&amp;#34;);
        return sdf.format(date);
    }


    public void centerPanel() {
        Panel center = new Panel();
        viewText = new TextArea();
        sendText = new TextArea(5,2);
        viewText.setEditable(false);
        viewText.setBackground(Color.WHITE);
        center.setLayout( new BorderLayout());
        center.add(sendText, BorderLayout.SOUTH);
        center.add(viewText, BorderLayout.CENTER);
        sendText.setFont(new Font(&amp;#34;xxx&amp;#34;, Font.PLAIN,20));
        viewText.setFont(new Font(&amp;#34;xxx&amp;#34;, Font.PLAIN,16));
        this.add(center, BorderLayout.CENTER);
    }

    public void southPanel() {
        Panel south = new Panel();
        textField = new TextField(15);
        textField.setText(&amp;#34;127.0.0.1&amp;#34;);
        send = new Button(&amp;#34;发送&amp;#34;);
        log = new Button(&amp;#34;记录&amp;#34;);
        clear = new Button(&amp;#34;清除&amp;#34;);
        shake = new Button(&amp;#34;振动&amp;#34;);
        south.add(textField);
        south.add(send);
        south.add(log);
        south.add(clear);
        south.add(shake);
        this.add(south, BorderLayout.SOUTH);
    }

    private void init() throws IOException {
        this.setLocation(500,10);
        this.setSize(500,800);
        socket = new DatagramSocket();
//        bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(&amp;#34;chat.log&amp;#34;,true)));
        bw = new BufferedWriter(new FileWriter(&amp;#34;chat.log&amp;#34;,true));
    }

    public static void main(String[] args) throws SocketException,IOException {
        Demo5_GUIChat guiChat = new Demo5_GUIChat();

    }
    private class Receive extends Thread{
        //发送 接收同时进行
        @Override
        public void run() {
            try {
                DatagramSocket socket = new DatagramSocket(9999);
                DatagramPacket packet = new DatagramPacket(new byte[8192], 8192);
                while (true){
                    socket.receive(packet);
                    byte[] arr = packet.getData();
                    int length = packet.getLength();
                    if( length == 1 &amp;amp;&amp;amp; arr[0] == -1){
                        shake();
                        continue;
                    }
                    String msg = new String(packet.getData(), 0, packet.getLength());
                    String chatlog = getTime()+&amp;#34; &amp;#34;+textField.getText()+&amp;#34; &amp;#34;+&amp;#34;对我说:&amp;#34;+&amp;#34;\n&amp;#34;+msg+&amp;#34;\n\n&amp;#34; ;
                    viewText.append(chatlog);
                    bw.write(chatlog);
                    bw.flush();
                }
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;tcp协议-重要&#34;&gt;TCP协议 (重要)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;TCP 三次握手&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class Demo2_Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(2000);
        Socket socket = server.accept();

        InputStream is = socket.getInputStream();
        OutputStream os = socket.getOutputStream();

        os.write(&amp;#34;明天还上班不&amp;#34;.getBytes(StandardCharsets.UTF_8));

        byte[] arr = new byte[8192];
        int len;
        len = is.read(arr);
        System.out.println(new String(arr,0,len));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class Demo1_Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(&amp;#34;127.0.01&amp;#34;,2000);
        InputStream is = socket.getInputStream();
        OutputStream os = socket.getOutputStream();
        byte[] arr = new byte[8192];
        int len = is.read(arr);

        os.write(&amp;#34;吃了&amp;#34;.getBytes(StandardCharsets.UTF_8));
        System.out.println(new String(arr,0,len));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;服务端-客户端tcp-优化&#34;&gt;服务端 客户端TCP 优化&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class Demo2_Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(2000);
        Socket socket = server.accept();

        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        OutputStream out;
        PrintStream ps = new PrintStream(socket.getOutputStream()) ;
        ps.println(&amp;#34;快乐, 放假了&amp;#34;);
        System.out.println(br.readLine());
        ps.println(&amp;#34;出来玩吧&amp;#34;);
        System.out.println(br.readLine());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.net.Socket;

public class Demo2_Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(&amp;#34;127.0.01&amp;#34;,2000);
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintStream ps = new PrintStream(socket.getOutputStream()) ;

        System.out.println( br.readLine());
        ps.println(&amp;#34;是的, 放假了&amp;#34;);
        System.out.println( br.readLine());
        ps.println(&amp;#34;起飞&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;服务增加多线程&#34;&gt;服务增加多线程&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo2_Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(2000);
        while (true){
            final Socket socket = server.accept();
            new Thread(){
                @Override
                public void run() {
                    try {
                        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        OutputStream out;
                        PrintStream ps = new PrintStream(socket.getOutputStream()) ;
                        ps.println(&amp;#34;快乐, 放假了&amp;#34;);
                        System.out.println(br.readLine());
                        ps.println(&amp;#34;出来玩吧&amp;#34;);
                        System.out.println(br.readLine());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;服务端反转字符并写给客户端&#34;&gt;服务端反转字符并写给客户端&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo3_Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(2000);
        while (true){
            final Socket socket = server.accept();
            new Thread(){
                @Override
                public void run() {
                    while (true){
                        try {
                            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                            PrintStream ps = new PrintStream(socket.getOutputStream()) ;
                            StringBuilder sb = new StringBuilder( br.readLine());
                            ps.println(sb.reverse());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class Demo3_Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(&amp;#34;127.0.01&amp;#34;,2000);
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintStream ps = new PrintStream(socket.getOutputStream()) ;

        Scanner sc = new Scanner(System.in);
        String s = null;
        while (true){
            s = sc.nextLine();
            ps.println(s);
            System.out.println( br.readLine());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;上传文件到服务端&#34;&gt;上传文件到服务端&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo4_Server_SaveFiles {
    public static void main(String[] args) throws IOException{
        ServerSocket server = new ServerSocket(2000);
        while (true){
            final Socket socket = server.accept();
            new Thread(){
                @Override
                public void run() {
                    while (true){
                        try {
                            InputStream is = socket.getInputStream();
                            BufferedReader br = new BufferedReader(new InputStreamReader(is));
                            PrintStream ps = new PrintStream(socket.getOutputStream()) ;


                            File dir = new File(&amp;#34;update&amp;#34;);
                            if(!dir.exists()){
                                dir.mkdir();
                            }
                            String fileName = br.readLine();
                            System.out.println(fileName);
                            File file = new File(dir, fileName);
                            if( file.exists()){
                                ps.println(&amp;#34;已存在&amp;#34;);
                                return;
                            }else {
                                ps.println(&amp;#34;不存在&amp;#34;);
                            }

                            byte[] arr = new byte[8192];
                            int len;
                            FileOutputStream fos = new FileOutputStream(file);
                            while ( ( len = is.read(arr)) != -1){
                                fos.write(arr,0,len);
                            }
                            fos.close();
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Demo4_Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(&amp;#34;127.0.01&amp;#34;,2000);
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        PrintStream ps = new PrintStream(socket.getOutputStream()) ;

        Scanner sc = new Scanner(System.in);
        String s = null;
        int len;
        byte[] arr = new byte[8192];
        while (true){
            s = sc.nextLine();

            File file = new File(s);
            if( !file.exists()){
                System.out.println(&amp;#34;文件不存在&amp;#34;);
            } else if( file.isDirectory()){
                System.out.println(&amp;#34;文件夹, 请重新输入文件&amp;#34;);
            } else if (file.isFile()){
                ps.println(s);
                String flag = br.readLine();
                if( &amp;#34;已存在&amp;#34;.equals(flag)){
                    System.out.println(flag);
                    return;
                } else {
                    InputStream inputStream = new FileInputStream(file);
                    while ( (len = inputStream.read(arr)) != -1){
                        ps.write(arr,0,len);
                    }
                    ps.flush();
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的多线程二 Li.047</title>
      <link>https://lizicai.com/p/java%E7%9A%84%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%BA%8C-li.047/</link>
      <pubDate>Sun, 12 Sep 2021 22:36:28 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%BA%8C-li.047/</guid>
      <description>&lt;h2 id=&#34;单例设计模式重要&#34;&gt;单例设计模式(重要)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;保证类在内存中只有一个对象&lt;/li&gt;
&lt;li&gt;饿汉式, 空间换时间, 类创建的时候就创建对象, 线程安全的&lt;/li&gt;
&lt;li&gt;懒汉式, 双叫单例加载模式, 使用的时候才创建对象, 存在线程安全问题&lt;/li&gt;
&lt;li&gt;区别, 饿汉式空间换时间, 懒汉式时间换空间, 多线程访问时, 饿汉式不会创建多个对象, 懒汉式可能创建多个对象&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Singleton {

    public static void main(String[] args) {
        Singleton s1 = Singleton.getInstance();

        Singleton s2 = Singleton.getInstance();

        System.out.println(s1);
        System.out.println(s2 == s1);
    }
}

class Singleton{
    // 1. 私有化构造函数, 就不能随意实例类了
    private Singleton (){}

    // 2. 创建实例
    private static Singleton s = new Singleton();



    // 3. 饿汉式
    public static Singleton getInstance() {
        return s;
    }

}

class SingletonLazy{
    private SingletonLazy (){}

    private static SingletonLazy s ;

    public static SingletonLazy getInstance() {
        if(s == null){
            s = new SingletonLazy();
        }
        return s;
    }
}

class SingletonFinal{
    private SingletonFinal(){}
    public static final SingletonFinal s = new SingletonFinal();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;runtime-类&#34;&gt;Runtime 类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Process exec(String command) throws IOException 执行命令&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;

public class Demo2_Runtime {
    public static void main(String[] args) throws IOException {
        Runtime runtime = Runtime.getRuntime();
        runtime.exec(&amp;#34;ls&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;timer--可以被scheduledexecutorservice取代-&#34;&gt;Timer ( 可以被ScheduledExecutorService取代 )&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;一种工具, 线程用其安排以后在后台线程中执行的任务, 可安排任务执行一次, 或者定期重复执行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private static void demo1() {
    Timer t = new Timer();
//  t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01);  // 定时 执行
    // 循环执行, 每3秒执行一次
    t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01),3000);
    while (true){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(new Date());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;scheduledexecutorservice&#34;&gt;ScheduledExecutorService&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Time的缺陷, 单线程多个任务排队, 一个任务执行时间长了, 后面任务受影响, 一个任务挂了, 后面的任务无法执行, 强依赖系统时间, 系统时间更改则会更改&lt;/li&gt;
&lt;li&gt;ScheduledExecutorService 多线程, 则没有上述问题&lt;/li&gt;
&lt;li&gt;ScheduledFuture&lt;?&gt; scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 延时initialDelay, 开始周期delay执行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Demo3_Timer {
    public static void main(String[] args) throws InterruptedException {
        // 一个任务出现 异常, 不影响其他任务
        ScheduledExecutorService ses = Executors.newScheduledThreadPool(2);
        ses.scheduleAtFixedRate(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println(&amp;#34;===&amp;#34; + Thread.currentThread().getName() + &amp;#34;===&amp;#34;);
                    }
                }
                , 0, 3, TimeUnit.SECONDS);


        ses.scheduleAtFixedRate(
                new Runnable() {
                    @Override
                    public void run() {
                        int i = 1/0;
                        System.out.println(&amp;#34;***&amp;#34; + Thread.currentThread().getName() + &amp;#34;***&amp;#34;);
                    }
                }
                , 0, 3, TimeUnit.SECONDS);

    }
    private static void demo2(){
        // 一个任务执行时间长了, 也不会任务其他任务
        ScheduledExecutorService ses = Executors.newScheduledThreadPool(2);
        ses.scheduleAtFixedRate(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println(&amp;#34;===&amp;#34; + Thread.currentThread().getName() + &amp;#34;===&amp;#34;);
                        try {
                            TimeUnit.SECONDS.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                , 0, 3, TimeUnit.SECONDS);


        ses.scheduleAtFixedRate(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println(&amp;#34;***&amp;#34; + Thread.currentThread().getName() + &amp;#34;***&amp;#34;);
                    }
                }
                , 0, 3, TimeUnit.SECONDS);
    }

    private static void demo1() {
        Timer t = new Timer();
//        t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01);  // 定时 执行
        // 循环执行, 每3秒执行一次
        t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01),3000);
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(new Date());
        }
    }
}
class MyTimerTask extends TimerTask{
    @Override
    public void run() {
        System.out.println(&amp;#34;起来上班&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多个线程的通信重要&#34;&gt;多个线程的通信(重要)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;this.notify() 随机唤醒单个等待线程&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Notify {
    public static void main(String[] args) {
        Printer p = new Printer();
        new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        p.method1();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        p.method2();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
}

class Printer{
    private int flag = 1;
    public void method1() throws InterruptedException {
        synchronized (this){
            if(flag != 1){
                this.wait();
            }
            System.out.println(&amp;#34;aaaa&amp;#34;);
            flag = 2;
            this.notify();
        }
    }
    public void method2() throws InterruptedException {
        synchronized (this){
            if(flag != 2){
                this.wait();
            }
            System.out.println(&amp;#34;bbbbbbbb&amp;#34;);
            flag = 1;
            this.notify();
        }
    }

}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;三个或三个以上间的线程通信&#34;&gt;三个或三个以上间的线程通信&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_Notify3 {
    public static void main(String[] args) {
        Printer2 p = new Printer2();
        new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        p.method1();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        p.method2();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        p.method3();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
}

class Printer2{
    private int flag = 1;
    public void method1() throws InterruptedException {
        synchronized (this){
            while (flag != 1){
                this.wait();
            }
            System.out.println(&amp;#34;aaaa&amp;#34;);
            flag = 2;
            this.notifyAll();
        }
    }
    public void method2() throws InterruptedException {
        synchronized (this){
            while (flag != 2){
                this.wait();
            }
            System.out.println(&amp;#34;bbbbbbbb&amp;#34;);
            flag = 3;
            this.notifyAll();
        }
    }
    public void method3() throws InterruptedException {
        synchronized (this){
            while (flag != 3){
                this.wait();
            }
            System.out.println(&amp;#34;cccccccccccccc&amp;#34;);
            flag = 1;
            this.notifyAll();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;线程间通信注意的问题&#34;&gt;线程间通信注意的问题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1.在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法&lt;/li&gt;
&lt;li&gt;2.为什么wait方法和notify方法定义在Object这类中?
&lt;ul&gt;
&lt;li&gt;因为锁对象可以是任意对象,Object是所有的类的基类,所以wait方法和notify方法需要定义在Object这个类中&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.sleep方法和wait方法的区别?
&lt;ul&gt;
&lt;li&gt;a,sleep方法必须传入参数,参数就是时间,时间到了自动醒来&lt;/li&gt;
&lt;li&gt;wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待&lt;/li&gt;
&lt;li&gt;b,sleep方法在同步函数或同步代码块中,不释放锁,睡着了也抱着锁睡&lt;/li&gt;
&lt;li&gt;wait方法在同步函数或者同步代码块中,释放锁&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;互斥锁重要-reentrantlock-condition&#34;&gt;互斥锁(重要) ReentrantLock Condition&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Demo3_ReentrantLock {
    public static void main(String[] args) {
        Printer3  p = new Printer3();
        new Thread(){
            @Override
            public void run() {
                while (true) {
                    try {
                        p.method1();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                while (true) {
                    try {
                        p.method2();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                while (true) {
                    try {
                        p.method3();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

    }
}
class Printer3{
    private int flag = 1;
    private ReentrantLock r = new ReentrantLock();
    Condition c1 = r.newCondition();
    Condition c2 = r.newCondition();
    Condition c3 = r.newCondition();
    public void method1() throws InterruptedException {
        r.lock();
            if (flag != 1){
                c1.await();
            }
            System.out.println(&amp;#34;aaaa&amp;#34;);
            flag = 2;
            c2.signal();
        r.unlock();
    }
    public void method2() throws InterruptedException {
        r.lock();
        if (flag != 2){
                c2.await();
            }
            System.out.println(&amp;#34;bbbbbbbb&amp;#34;);
            flag = 3;
            c3.signal();
        r.unlock();
    }
    public void method3() throws InterruptedException {
        r.lock();
            if(flag != 3){
                c3.await();
            }
            System.out.println(&amp;#34;cccccccccccccc&amp;#34;);
            flag = 1;
            c1.signal();
        r.unlock();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;线程组&#34;&gt;线程组&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_ThreadGroup {
    public static void main(String[] args) {
//        demo1();
        ThreadGroup threadGroup = new ThreadGroup(&amp;#34;自造线程组&amp;#34;);
        Mythread mythread = new Mythread();
        Runnable target;
        Thread t1 = new Thread(threadGroup, mythread);
        Thread t2 = new Thread(threadGroup,mythread,&amp;#34;线程1&amp;#34;);
        Thread t3 = new Thread(threadGroup,mythread,&amp;#34;线程2&amp;#34;);

        System.out.println(t1.getName());
        System.out.println(t2.getName());
        System.out.println(t3.getName());

        System.out.println(t1.getThreadGroup().getName());
        System.out.println(t2.getThreadGroup().getName());
        System.out.println(t3.getThreadGroup().getName());

        System.out.println(t1.getThreadGroup().getParent().getName());
    }

    private static void demo1() {
        Mythread mythread = new Mythread();
        Thread t1 = new Thread(mythread);
        Thread t2 = new Thread(mythread);

        ThreadGroup tg1 = t1.getThreadGroup();
        ThreadGroup tg2 = t2.getThreadGroup();
        System.out.println(tg1.getName());
        System.out.println(tg2.getName());
    }
}

class Mythread implements Runnable{
    @Override
    public void run() {

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;线程的5种状态&#34;&gt;线程的5种状态&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;新建线程.start() -&amp;gt; 线程就绪状态, 有执行权-&amp;gt;抢到CPU执行权限执行-&amp;gt;死亡状态, run执行完了&lt;/li&gt;
&lt;li&gt;抢到CPU执行权限执行-&amp;gt;wait或sleep线程阻塞-&amp;gt;叫醒线,程线程就绪状态, 有执行权&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;线程池&#34;&gt;线程池&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;程序创建一个线程成本比较高, 为了方便使用线程池, 使用后再返给JVM&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo5_Executors {
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(2);
        pool.submit(new Mythread());
        pool.submit(new Mythread());

        pool.shutdown();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;实现callable的线程&#34;&gt;实现Callable的线程&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.concurrent.*;

public class Demo6_Callable {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService pool = Executors.newFixedThreadPool(2);
        Future&amp;lt;Integer&amp;gt; f1 =  pool.submit(new MyCallable(10));
        Future&amp;lt;Integer&amp;gt; f2 =  pool.submit(new MyCallable(20));
        System.out.println(f1.get());
        System.out.println(f2.get());

        pool.shutdown();
    }

}
class MyCallable implements Callable&amp;lt;Integer&amp;gt;{
    private int num;
    public MyCallable(int num){
        this.num = num;
    }
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for(int i=1;i&amp;lt;num;i++){
            sum = sum + i;
        }
        return sum;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;简单工厂模式&#34;&gt;简单工厂模式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;概述 静态工厂方法模式, 它定义一个具体的工厂类负责创建一些类的实例&lt;/li&gt;
&lt;li&gt;优点 客户端不负责对象的创建, 从而明确各类的职责&lt;/li&gt;
&lt;li&gt;缺点 静态工厂负责所有类的创建, 如果有新的对象或者新对象创建方式不同, 就需要不断修改工厂类, 不利于后期维护.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public abstract class Animal {
    public void eat(){};
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class AnimalFactory {
    public static Dog createDog(){
        return new Dog();
    }
    public static Cat createCat(){
        return new Cat();
    }
    public static Animal createAnimal(String animal){
        if( &amp;#34;dog&amp;#34;.equals(animal)){
            return new Dog();
        } else if( &amp;#34;cat&amp;#34;.equals(animal)){
            return new Cat();
        }
        return null;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println(&amp;#34;猫吃鱼&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println(&amp;#34;单身狗儿吃狗粮&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;``&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Test {
    public static void main(String[] args) {
        Dog dog = AnimalFactory.createDog();
        System.out.println(dog);

        Dog d = (Dog) AnimalFactory.createAnimal(&amp;#34;dog&amp;#34;);
        d.eat();

        Cat c = (Cat) AnimalFactory.createAnimal(&amp;#34;cat&amp;#34;);
        c.eat();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;工厂方法模式&#34;&gt;工厂方法模式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;工厂方法模式中看网易工厂类负责定义创建对象的接口, 具体对象的创建工作由继承工厂的具体类实现&lt;/li&gt;
&lt;li&gt;做点
&lt;ul&gt;
&lt;li&gt;客户端不需要在负责对象的创建, 从而明确了各个类的职责, 如果有新的对象增加, 只需要增加一个具体的类和&lt;/li&gt;
&lt;li&gt;俱体的工厂类即可, 不影响已有的代码, 后期维护容易, 增强了系统扩展性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;缺点 需要额外编写代码, 增加工作量&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public abstract class Animal {
    public void eat(){};
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println(&amp;#34;猫吃鱼&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println(&amp;#34;单身狗儿吃狗粮&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public interface Factory {
    public Animal createAnimal();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class CatFactory implements Factory{
    @Override
    public Animal createAnimal() {
        return new Cat();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class DogFactory implements Factory{
    @Override
    public Animal createAnimal() {
        return new Dog();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Test {
    public static void main(String[] args) {
        DogFactory dogFactory = new DogFactory();
        Dog d = (Dog) dogFactory.createAnimal();
        d.eat();

        CatFactory catFactory = new CatFactory();
        Cat c = (Cat) catFactory.createAnimal();
        c.eat();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;gui-了解-暂用不到&#34;&gt;Gui 了解, 暂用不到&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.awt.*;

public class Demo1_Frame {
    public static void main(String[] args) {
        Frame f = new Frame();

        f.setTitle(&amp;#34;我的窗口&amp;#34;);
        f.setLocation(500,400);
        f.setSize(400,300);
        f.setIconImage(Toolkit.getDefaultToolkit().createImage(&amp;#34;favicon.png&amp;#34;));
        f.setVisible(true);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;布局和按钮&#34;&gt;布局和按钮&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.awt.*;

public class Demo1_Frame {
    public static void main(String[] args) {
        Frame f = new Frame();

        f.setTitle(&amp;#34;我的窗口&amp;#34;);
        f.setLocation(500,400);
        f.setSize(400,300);
        f.setIconImage(Toolkit.getDefaultToolkit().createImage(&amp;#34;favicon.png&amp;#34;));
        f.setLayout(new FlowLayout());
        Button button = new Button(&amp;#34;按钮&amp;#34;);
        Button button2 = new Button(&amp;#34;按钮&amp;#34;);
        f.add(button);
        f.add(button2);

        f.setVisible(true);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;监听的3种方式&#34;&gt;监听的3种方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;类实现WindowListener接口&lt;/li&gt;
&lt;li&gt;类继承WindowAdapter&lt;/li&gt;
&lt;li&gt;匿名内部类 new WindowAdapter()&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class Demo1_Frame {
    public static void main(String[] args) {
        Frame f = new Frame();

        f.setTitle(&amp;#34;我的窗口&amp;#34;);
        f.setLocation(500,400);
        f.setSize(400,300);
        f.setLayout(new FlowLayout());
        Button button = new Button(&amp;#34;按钮&amp;#34;);
//        MyWindow myWindow = new MyWindow();
//        f.addWindowListener(myWindow);
//        MyAdapter myAdapter = new MyAdapter();
//        f.addWindowListener(myAdapter);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.add(button);

        f.setVisible(true);
    }
}

class MyAdapter extends WindowAdapter{
    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
}

class MyWindow implements WindowListener{
    @Override
    public void windowOpened(WindowEvent e) {
    }

    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }

    @Override
    public void windowClosed(WindowEvent e) {
        System.out.println(&amp;#34;Colosed&amp;#34;);
    }

    @Override
    public void windowIconified(WindowEvent e) {
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }
    @Override
    public void windowActivated(WindowEvent e) {

    }
    @Override
    public void windowDeactivated(WindowEvent e) {
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;鼠标监听&#34;&gt;鼠标监听&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;同样有3种方式&lt;/li&gt;
&lt;li&gt;实现MouseListener 接口&lt;/li&gt;
&lt;li&gt;继承MouseAdapter抽象类&lt;/li&gt;
&lt;li&gt;匿名内部类new MouseAdapter&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.awt.*;
import java.awt.event.*;

public class Demo1_Frame {
    public static void main(String[] args) {
        Frame f = new Frame();

        f.setTitle(&amp;#34;我的窗口&amp;#34;);
        f.setLocation(500,400);
        f.setSize(400,300);
        f.setLayout(new FlowLayout());
        Button button = new Button(&amp;#34;按钮&amp;#34;);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.add(button);
        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                System.exit(0);
            }
        });

        f.setVisible(true);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;键盘监听和键盘事件&#34;&gt;键盘监听和键盘事件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;实现KeyListener 接口&lt;/li&gt;
&lt;li&gt;继承 KeyAdapter  抽象类&lt;/li&gt;
&lt;li&gt;匿名内部类new KeyAdapter()&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.awt.*;
import java.awt.event.*;

public class Demo1_Frame {
    public static void main(String[] args) {
        Frame f = new Frame();

        f.setTitle(&amp;#34;我的窗口&amp;#34;);
        f.setLocation(500,400);
        f.setSize(400,300);
        f.setLayout(new FlowLayout());
        Button button = new Button(&amp;#34;按钮&amp;#34;);
//        MyWindow myWindow = new MyWindow();
//        f.addWindowListener(myWindow);
//        MyAdapter myAdapter = new MyAdapter();
//        f.addWindowListener(myAdapter);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.add(button);
        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                System.exit(0);
            }
        });
        button.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_SPACE){
                    System.exit(0);
                }
            }
        });

        f.setVisible(true);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;动作监听&#34;&gt;动作监听&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;实现ActionListener 接口&lt;/li&gt;
&lt;li&gt;匿名内部类 new ActionListener()类&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.awt.*;
import java.awt.event.*;

public class Demo1_Frame {
    public static void main(String[] args) {
        Frame f = new Frame();

        f.setTitle(&amp;#34;我的窗口&amp;#34;);
        f.setLocation(500,400);
        f.setSize(400,300);
        f.setLayout(new FlowLayout());
        Button button = new Button(&amp;#34;按钮&amp;#34;);
        Button button2 = new Button(&amp;#34;按钮二&amp;#34;);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.add(button);
        f.add(button2);
        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                System.exit(0);
            }
        });
        button.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_SPACE){
                    System.exit(0);
                }
            }
        });
        button2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        f.setVisible(true);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;设计模式-适配器模式&#34;&gt;设计模式-适配器模式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;什么是适配器
&lt;ul&gt;
&lt;li&gt;在使用监听器的时候, 需要定义一个事件监听器的接口&lt;/li&gt;
&lt;li&gt;通常接口中有多个方法, 而程序中不一定所有的都用到, 但又必须重写, 这很繁琐&lt;/li&gt;
&lt;li&gt;我在楼下器简化了这些操作, 我们定义监听器时只要继承我在楼下器, 然后重写需要的方法即可&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;适配器原理
&lt;ul&gt;
&lt;li&gt;适配器就是一个类, 实现了监听器接口, 所有抽象方法都重写了, 但是方法全是空的&lt;/li&gt;
&lt;li&gt;我在楼下器类需要定义成抽象的, 因为创建类对象, 调用空方法是没有意义的&lt;/li&gt;
&lt;li&gt;目的就是为了简化程序员的操作, 定义监听时继承适配器, 中重写需要的方法就可以了&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;gui需要知道的&#34;&gt;GUI(需要知道的)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;事件处理
&lt;ul&gt;
&lt;li&gt;事件: 用户的一个操作&lt;/li&gt;
&lt;li&gt;事件源: 被操作的组件&lt;/li&gt;
&lt;li&gt;监听器: 一个自定义类的对象, 实现了监听器接口, 包含事件处理方法, 监听器添加在事件源上, 当事件发生的时候虚拟机就会自动调用监听器中的事件处理方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Java的多线程一 Li.046</title>
      <link>https://lizicai.com/p/java%E7%9A%84%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%B8%80-li.046/</link>
      <pubDate>Fri, 10 Sep 2021 11:20:14 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%B8%80-li.046/</guid>
      <description>&lt;h2 id=&#34;多线程增加效率&#34;&gt;多线程增加效率&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;并行, 就是多个任务同时进行, 多核cpu同时执行&lt;/li&gt;
&lt;li&gt;并发, 多个任务轮流进行, cpu一个一个的执行&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;证明 JVM 是多线程的&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;垃圾回收和main线程间隔执行&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Thread {
    public static void main(String[] args) {
        for(int i=0; i &amp;lt; 10000000 ;i++){
            new Demo();
        }
        for(int i=0; i &amp;lt; 10000 ; i++){
            System.out.println(&amp;#34;主线程&amp;#34;);
        }
    }
}
class Demo{
    @Override
    protected void finalize() throws Throwable {
        System.out.println(&amp;#34;垃圾被回收了&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;继承thread-开启一个线程&#34;&gt;继承Thread 开启一个线程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;实际run() 方法&lt;/li&gt;
&lt;li&gt;start() 开启线程&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_ExtendsThread {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
//        mt.run();
        mt.start();
        for (int i=0; i &amp;lt;10000 ; i++){
            System.out.println(i+&amp;#34;bbbbbbbbbbbbb&amp;#34;);
        }
    }
}

class MyThread extends Thread{
    @Override
    public void run() {
        for(int i=0; i &amp;lt; 10000 ;i++){
            System.out.println(i+&amp;#34;aaaaaaaaaaaaaaa&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;实际-runnable-接口的类&#34;&gt;实际 Runnable 接口的类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;实际Runnable类, 类作为参数传递给线程, start() 开启线程&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo3_Runnable {
    public static void main(String[] args) {
        MyRunnable d =  new MyRunnable();
        Thread t = new Thread(d);
        t.start();
        for(int i=0; i &amp;lt; 10000 ;i++){
            System.out.println(i+&amp;#34;bbbbbbbbbbbbbbb&amp;#34;);
        }

    }
}
class MyRunnable implements Runnable{
    @Override
    public void run() {
        for(int i=0; i &amp;lt; 10000 ;i++){
            System.out.println(i+&amp;#34;aaa&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多线程的2种区别&#34;&gt;多线程的2种区别&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;继承 Thread: 由于子类重写了Thread类的run()方法, 当调用start()时, 直接找子类的run()方法&lt;/li&gt;
&lt;li&gt;实际 Runnable: 构造函数中传入了Runnable的引用, 成员变量记住了它, start()调用run() 方法时内部判断成员变量Runnable的引用是否为空,&lt;br&gt;
不为空看的Runnable的run(), 运行时是子类的run()方法.&lt;/li&gt;
&lt;li&gt;继承Thread实现简单, 方便使用, 有父类则不能使用这种方法&lt;/li&gt;
&lt;li&gt;有父类时可以实际Runnable 接口实现多线程, 对继承Thread的补充, 使用时必须获取线程对象, 使用复杂&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;匿名内类实现多线程的方法&#34;&gt;匿名内类实现多线程的方法&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_NoNameThread {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                for(int i=0; i&amp;lt;100000 ;i++){
                    System.out.println(&amp;#34;aaaaaa&amp;#34;);
                }
            }
        }.start();
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i&amp;lt;10000;i++){
                    System.out.println(&amp;#34;bbbbbbbbbbbbbbbbbbb&amp;#34;);
                }
            }
        });
        t.start();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;匿名内部类设置线程名字&#34;&gt;匿名内部类设置线程名字&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo5_ThreadName {
    public static void main(String[] args) {
//        demo1();
        Thread t =  new Thread(){
            @Override
            public void run() {
//                this.setName(&amp;#34;小明&amp;#34;);
                System.out.println(this.getName()+&amp;#34;aaaaa&amp;#34;);
            }
        };
        t.setName(&amp;#34;李明&amp;#34;);
        t.start();
        new Thread(){
            @Override
            public void run() {
                this.setName(&amp;#34;小明&amp;#34;);
                System.out.println(this.getName()+&amp;#34;aaaaa&amp;#34;);
            }
        }.start();
    }

    private static void demo1() {
        new Thread(&amp;#34;小明&amp;#34;){
            @Override
            public void run() {
                System.out.println(this.getName()+ &amp;#34;aaaaa&amp;#34;);
            }
        }.start();
        new Thread(&amp;#34;小红&amp;#34;){
            @Override
            public void run() {
                System.out.println(this.getName()+ &amp;#34;bbbbbb&amp;#34;);
            }
        }.start();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;也可调用setName更改名称&lt;/strong&gt;
&lt;strong&gt;获取本类的引用Thread.currentThread()&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo6_GetName {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());
        Thread.currentThread().setName(&amp;#34;主线程&amp;#34;);
        System.out.println(Thread.currentThread().getName());
        new Thread( new Runnable() {

            @Override
            public void run() {
                System.out.println(&amp;#34;dkf&amp;#34;+Thread.currentThread().getName());
            }
        }).start();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;休眠线程&#34;&gt;休眠线程&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo7_ThreadSleep {
    public static void main(String[] args) throws InterruptedException {
//        demo1();
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i&amp;lt;10;i++) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName()+&amp;#34;a&amp;#34;);
                }
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                for (int i=0;i&amp;lt;10;i++) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName()+&amp;#34;bbbb&amp;#34;);
                }
            }
        }.start();
    }

    private static void demo1() throws InterruptedException {
        for (int i=0; i&amp;lt;100;i++){
            Thread.sleep(1000);
            System.out.println(i);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;守护线程&#34;&gt;守护线程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;守护线程不会单独执行, 其他线程执行完了, 自动结束守护线程&lt;/li&gt;
&lt;li&gt;final void setDaemon(boolean on)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo8_GudarThread {
    public static void main(String[] args) {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i =0;i&amp;lt;2;i++){
                    System.out.println(getName()+i);
                }
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i =0;i&amp;lt;50;i++){
                    System.out.println(getName()+&amp;#34;aaaaaaaaaaa&amp;#34;);
                }
            }
        };
        t2.setDaemon(true);
        t1.start();
        t2.start();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;加入线程&#34;&gt;加入线程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;final void join() throws InterruptedException 插队执行线程&lt;/li&gt;
&lt;li&gt;final void join(long millis) throws InterruptedException 插队执行m毫秒后, 再交其他线程&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo9_ThreadJoin {
    public static void main(String[] args) {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i =0;i&amp;lt;100;i++){
                    System.out.println(getName()+i);
                }
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i =0;i&amp;lt;100;i++){
                    if(i == 2) {
                        try {
                            t1.join();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(getName()+&amp;#34;aaaaaaaaaaa&amp;#34;);
                }
            }
        };
        t1.start();
        t2.start();

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;礼让线程-了解即可&#34;&gt;礼让线程, 了解即可&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo10_Yield {
    public static void main(String[] args) {
        new MyThread2().start();
        new MyThread2().start();

    }
}

class MyThread2 extends Thread{
    @Override
    public void run() {
        for (int i=0;i&amp;lt;1000;i++) {
            if(0 == i%10){
                Thread.yield();
            }
            System.out.println(getName()+&amp;#34; &amp;#34;+i);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;线程优先级&#34;&gt;线程优先级&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;final void setPriority(int newPriority) 设置线程的优先级, 小范围1-10&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo11_Priority {
    public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                for (int i=0;i&amp;lt;100;i++){
                    System.out.println(getName()+&amp;#34;aaa&amp;#34;);
                }
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i=0;i&amp;lt;100;i++){
                    System.out.println(getName()+&amp;#34;bbb&amp;#34;);
                }
            }
        };
        t2.setPriority(Thread.MIN_PRIORITY);
        t.setPriority(Thread.MAX_PRIORITY);
        t.start();
        t2.start();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;线程同步&#34;&gt;线程同步&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;当多线程执行到一段代码块时, 不希望线程切换其他线程&lt;/li&gt;
&lt;li&gt;synchronized 关键字锁对象到定义一段代码块, 同步代码块&lt;/li&gt;
&lt;li&gt;锁对象是任意的, 锁对象不能是匿名对象&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Synchronized {
    public static void main(String[] args) {
        Printer p = new Printer();
        new Thread(){
            @Override
            public void run() {
                while (true) {
                    p.eatApple();
                }
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                while (true) {
                    p.eatMeet();
                }
            }
        }.start();
    }
}

class Printer{
    Demo d = new Demo();
    public  void eatApple(){
        synchronized (d) {
            System.out.print(&amp;#34;a&amp;#34;);
            System.out.print(&amp;#34;a&amp;#34;);
            System.out.print(&amp;#34;a&amp;#34;);
            System.out.print(&amp;#34;a&amp;#34;);
            System.out.print(&amp;#34;a&amp;#34;);
            System.out.print(&amp;#34;a&amp;#34;);
            System.out.println();
        }
    }
    public  void eatMeet(){
        synchronized (d) {
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.println();
        }
    }
}
class Demo{}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;同步方法&#34;&gt;同步方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;非静态方法的锁对象是this&lt;/li&gt;
&lt;li&gt;静态方法的锁对象是字节码对象&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.sync;

public class Demo2_Syn {
    public static void main(String[] args) {
        Printer2 p = new Printer2();
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    p.eatApple();
                }
            }
        }.start();

        new Thread() {
            @Override
            public void run() {
                while (true) {
                    p.eatMeet();
                }
            }
        }.start();
    }
}
class Printer2{
    Demo d = new Demo();
    synchronized public  void eatApple(){
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.println();
    }

    public  void eatMeet(){
        synchronized (this) {
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.println();
        }
    }
}
class Demo2{
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo3_SynStaticMethod {
    public static void main(String[] args) {
        Printer3 p = new Printer3();
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    Printer3.eatApple();
                }
            }
        }.start();

        new Thread() {
            @Override
            public void run() {
                while (true) {
                    Printer3.eatMeet();
                }
            }
        }.start();
    }
}
class Printer3{
    Demo d = new Demo();
    synchronized public static void eatApple(){
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.print(&amp;#34;a&amp;#34;);
        System.out.println();
    }

    public static void eatMeet(){
        synchronized (Printer3.class) {
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.print(&amp;#34;b&amp;#34;);
            System.out.println();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;模拟卖票&#34;&gt;模拟卖票&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用唯一对象字节对象作为锁&lt;/li&gt;
&lt;li&gt;或者使用静态的对象作为锁&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_SynSoldTicket {
    public static void main(String[] args) {
        new Ticket().start();
        new Ticket().start();
        new Ticket().start();
        new Ticket().start();

    }
}
class Ticket extends Thread{
    private static int tickets = 100;
    private static Object obj = new Object();

    @Override
    public void run() {
        while (true){
//            synchronized (obj){
            synchronized (Ticket.class) {
                if( tickets &amp;lt;= 0){
                    break;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(getName()+&amp;#34;-Ticket&amp;#34;+tickets--);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;火车站卖票-runnable接口方式&#34;&gt;火车站卖票 Runnable接口方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;多次启动start()非法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo5_SynSoldTicket {
    public static void main(String[] args) {
        Ticket2 tc = new Ticket2();
        new Thread(tc).start();
        new Thread(tc).start();
        new Thread(tc).start();
        new Thread(tc).start();
    }
}
class Ticket2 implements Runnable{

    private int tickets = 100;
    @Override
    public void run() {
        while (true) {
            // Ticket2.class 也可
//            synchronized (Ticket2.class) {
            synchronized (this) {
                if( tickets &amp;lt;= 0){
                    break;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+&amp;#34;-Ticket&amp;#34;+tickets--);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;多线程死锁&#34;&gt;多线程死锁&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;避免同步代码块嵌套, 容易造成死锁&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo6_SynDead {
    private static String s1 = &amp;#34;筷子左&amp;#34;;
    private static String s2 = &amp;#34;筷子右&amp;#34;;
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                while (true){
                    synchronized (s1){
                        System.out.println(getName()+&amp;#34;...&amp;#34;+s1+&amp;#34;等待&amp;#34;+s2);
                        synchronized (s2){
                            System.out.println(getName()+&amp;#34;...拿到&amp;#34;+s1+s2+&amp;#34;开饭&amp;#34;);
                        }
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                while (true){
                    synchronized (s2){
                        System.out.println(getName()+&amp;#34;...&amp;#34;+s2+&amp;#34;等待&amp;#34;+s1);
                        synchronized (s1){
                            System.out.println(getName()+&amp;#34;...拿到&amp;#34;+s2+s1+&amp;#34;开饭&amp;#34;);
                        }
                    }
                }
            }
        }.start();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;线程安全的类&#34;&gt;线程安全的类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Vector 线程安全的, ArrayList线程不安全&lt;/li&gt;
&lt;li&gt;StringBuffer 线程安全的, StringBuilder 线程不安全的&lt;/li&gt;
&lt;li&gt;Hashtable 线程安全的, HashMap 线程不安全的&lt;/li&gt;
&lt;li&gt;Connections 中有synchronizedList 等方法返回线程安全的列表ArrayList&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Java的递归 Li.045</title>
      <link>https://lizicai.com/p/java%E7%9A%84%E9%80%92%E5%BD%92-li.045/</link>
      <pubDate>Wed, 08 Sep 2021 23:06:35 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84%E9%80%92%E5%BD%92-li.045/</guid>
      <description>&lt;h2 id=&#34;递归练习-计算文件夹大小&#34;&gt;递归练习, 计算文件夹大小&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;
import java.util.Scanner;

public class Demo1_FolderSize {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String strFolder = null;
        long size = 0;
        while (true){
            if( sc.hasNext()){
                strFolder = sc.nextLine();
                break;
            }
        }
        if( strFolder.equals(null)){
            System.out.println(&amp;#34;不能为空&amp;#34;);
        } else {
            File folder = new File(strFolder);
            if(folder.isFile()){
                size = folder.length();
            } else if(folder.isDirectory()){
                size = getSize(folder);
            } else if(! folder.exists()){
                System.out.println(&amp;#34;文件夹不存在&amp;#34;);

            }
        }
        System.out.println(size);
    }
    public static long getSize(File folder){
        long len = 0;
        File [] files = folder.listFiles();
        for(File subFile:files){
            if(subFile.isFile()){
                len = len + subFile.length();
            } else{
                len = len + getSize(subFile);
            }
        }
        return len;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;递归删除文件夹&#34;&gt;递归删除文件夹&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;删除文件内的文件&lt;/li&gt;
&lt;li&gt;删除文件夹本身&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;
import java.util.Scanner;

public class Demo2_DeleteFolder {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String strFolder = null;
        strFolder = getDir(sc);

        if( strFolder.equals(null)){
            System.out.println(&amp;#34;不能为空&amp;#34;);
        } else {
            File folder = new File(strFolder);
            if(folder.isFile()){
                folder.delete();
            } else if(folder.isDirectory()){
                deleteFolder(folder);
            } else if(! folder.exists()){
                System.out.println(&amp;#34;文件夹不存在&amp;#34;);
            }
        }
    }
    private static void deleteFolder(File folder) {
        File[] files = folder.listFiles();
        for (File f : files){
            if(f.isFile()){
                f.delete();
            } else if(f.isDirectory()){
                deleteFolder(f);
                f.delete();
            }
        }
        folder.delete();
    }

    public static String getDir(Scanner sc) {
        String strFolder;
        while (true){
            if( sc.hasNext()){
                strFolder = sc.nextLine();
                break;
            }
        }
        return strFolder;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;复制文件到指定文件夹下&#34;&gt;复制文件到指定文件夹下&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;源文件夹, 目标文件夹&lt;/li&gt;
&lt;li&gt;在目标文件夹中创建源文件夹&lt;/li&gt;
&lt;li&gt;遍历源文件夹, 文件则调用stream 复制到目标文件夹/源文件夹, 文件夹则递归调用&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo3_MvFolder {
    public static void main(String[] args) throws IOException {
        File folderSrc = new File(&amp;#34;test&amp;#34;);
        File folderDes = new File(&amp;#34;des&amp;#34;);
        copyFile3(folderSrc, folderDes);
    }
    public static void copyFile3(File folderSrc, File folderDes) throws IOException {
        if(! folderDes.isDirectory()){
            System.out.println(&amp;#34;请复制到文件夹中&amp;#34;);
            return;
        }
        File newFolder = new File(folderDes, folderSrc.getName());
        newFolder.mkdir();
        for(File f : folderSrc.listFiles()){
            if( f.isFile()){
                fileStream(f.getAbsolutePath(), newFolder.getAbsolutePath()+&amp;#34;/&amp;#34;+f.getName());
            } else{
                copyFile3(f, newFolder);
            }
        }
    }
    public static void copyFile2(File folderSrc, File folderDes) throws IOException{
        if(! folderDes.isDirectory()){
            System.out.println(&amp;#34;请复制到文件夹中&amp;#34;);
            return;
        }
        File tempFolder = new File(folderDes.getAbsolutePath()+&amp;#34;/&amp;#34;+folderSrc.getName());
        if( folderSrc.isDirectory()){
            tempFolder.mkdir();
        }

        for( File f : folderSrc.listFiles()){
            if( f.isFile()){
                fileStream(f.getAbsolutePath(), tempFolder.getAbsolutePath()+&amp;#34;/&amp;#34;+f.getName());
            } else {
                copyFile2(f, tempFolder);
            }
        }
    }

    public static void copyFile(File folderSrc, File folderDes) throws IOException {
        if(! folderDes.isDirectory()){
            System.out.println(&amp;#34;请复制到文件夹中&amp;#34;);
            return;
        }
        if( folderSrc.isDirectory()){
            new File(folderDes.getAbsolutePath()+&amp;#34;/&amp;#34;+folderSrc).mkdir();
        }
        for(File f: folderSrc.listFiles()){
            if ( f.isFile()){
                fileStream(f.getAbsolutePath(), (folderDes.getAbsolutePath()+&amp;#34;/&amp;#34;+f.getPath()));
            } else if( f.isDirectory()){
                copyFile(f, folderDes);
            }
        }
    }

    public static void fileStream(String src, String desc) throws IOException{
        FileInputStream fis = new FileInputStream(src);
        int len;
        byte[] arr = new byte[1024*100];

        FileOutputStream fos = new FileOutputStream(desc);
        while ( (len = fis.read(arr)) != -1){
            fos.write(arr,0,len);
        }
        fis.close();
        fos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;打印文件夹的内文件-保持层级&#34;&gt;打印文件夹的内文件, 保持层级&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;

public class Demo4_PrintFolder {
    public static void main(String[] args) {
        File folder = new File(&amp;#34;test&amp;#34;);
        int lev = 0;
        printFolder(folder, lev);
    }
    public static void printFolder(File folder , int lev){
        System.out.println(folder.getPath());
        for ( File f : folder.listFiles()){
            for (int i=0;i&amp;lt;=lev;i++){
                System.out.print(&amp;#34;\t&amp;#34;);
            }
            if(f.isFile()){
                System.out.println(f.getPath());
            } else {
            // lev不能用lev++或++lev, 改变了lev值
                printFolder(f, lev+1);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;斐波那契数列&#34;&gt;斐波那契数列&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo5_TwoZi {
    public static void main(String[] args) {
        System.out.println(twoZi(6));
    }
    public static int twoZi(int month){
        int sum = 0;
        if(month &amp;gt; 2){
            sum = twoZi(month-1) + twoZi(month-2);
        } else if(month == 2){
            sum = 1;
        } else if(1 == month){
            sum = 1;
        }
        return sum;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;1000的阶乘-其中所有0和尾部0的个数&#34;&gt;1000的阶乘, 其中所有0和尾部0的个数&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.math.BigInteger;

public class Demo6_1000JieChen {
    public static void main(String[] args) {
        BigInteger bi = new BigInteger(&amp;#34;1&amp;#34;);
        for(int i=1;i&amp;lt;=1000;i++) {
            BigInteger tmepBi = new BigInteger(i + &amp;#34;&amp;#34;);
            bi = bi.multiply(tmepBi);
        }
        int sum = 0;
        String str = String.valueOf(bi);
        for(int i=0;i&amp;lt;str.length();i++){
            if(&amp;#39;0&amp;#39;== (str.charAt(i))){
                sum++;
            }
        }
        int num = 0;
        for(int j=str.length()-1;j&amp;gt;=0;j--){
            if( &amp;#39;0&amp;#39; == str.charAt(j)){
                num++;
            } else {
                break;
            }
        }
        System.out.println(sum);
        System.out.println(num);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;约瑟夫环&#34;&gt;约瑟夫环&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Iterator;

public class Demo7_LuckYue {
    public static void main(String[] args) {
        int num = 8;
        System.out.println(getLuck(num));
        System.out.println(getLuck2(num));
    }
    public static int getLuck2(int num) {
        ArrayList&amp;lt;Integer&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        for(int i=1;i&amp;lt;= num;i++){
            arrayList.add(i);
        }
        int sum = 1;
        for(int i=0; arrayList.size()!=1;i++){
            if( i == arrayList.size() ){
                i = 0;
            }
            if(0 == sum % 3){
                arrayList.remove(i--);
            }
            sum ++;
        }
        return arrayList.get(0);
    }
    public static int getLuck(int num){
        ArrayList&amp;lt;Integer&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        for(int i=1;i&amp;lt;= num;i++){
            arrayList.add(i);
        }
        int sum = 0;
        while (arrayList.size() &amp;gt; 1){
            Iterator&amp;lt;Integer&amp;gt; iterator = arrayList.iterator() ;
            while (iterator.hasNext()){
                Integer i = iterator.next();
                // next()和remove方法依赖关系
                sum++;
                if(0 == sum % 3){
                    iterator.remove();
                }
            }
        }
        return arrayList.get(0);
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的IO其他流(及Properties) Li.044</title>
      <link>https://lizicai.com/p/java%E7%9A%84io%E5%85%B6%E4%BB%96%E6%B5%81%E5%8F%8Aproperties-li.044/</link>
      <pubDate>Mon, 06 Sep 2021 16:17:32 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84io%E5%85%B6%E4%BB%96%E6%B5%81%E5%8F%8Aproperties-li.044/</guid>
      <description>&lt;h2 id=&#34;序列流&#34;&gt;序列流&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SequenceInputStream 关闭时会关闭所有流&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Stream {
    public static void main(String[] args) throws IOException {
        FileInputStream fr1 = new FileInputStream(&amp;#34;read1.md&amp;#34;);
        FileInputStream fr2 = new FileInputStream(&amp;#34;read2.md&amp;#34;);
        SequenceInputStream sis = new SequenceInputStream(fr1,fr2);
        FileOutputStream fos = new FileOutputStream(&amp;#34;read3.md&amp;#34;);
        int b ;
        while ( ( b = sis.read()) != -1){
            fos.write(b);
        }
        sis.close();
        fos.close();
    }
    public static void demo1() throws IOException {
        FileInputStream fr1 = new FileInputStream(&amp;#34;read1.md&amp;#34;);
        FileOutputStream fos = new FileOutputStream(&amp;#34;read3.md&amp;#34;);
        int b;
        while ((b = fr1.read()) != -1) {
            fos.write(b);
        }
        fr1.close();
        FileInputStream fr2 = new FileInputStream(&amp;#34;read2.md&amp;#34;);
        while ((b = fr2.read()) != -1) {
            fos.write(b);
        }
        fr2.close();
        fos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;io-流整合多个&#34;&gt;IO 流整合多个&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Stream {
    public static void main(String[] args) throws IOException {
        Vector&amp;lt;FileInputStream&amp;gt; v = new Vector&amp;lt;&amp;gt;();
        FileInputStream fr1 = new FileInputStream(&amp;#34;read1.md&amp;#34;);
        FileInputStream fr2 = new FileInputStream(&amp;#34;read2.md&amp;#34;);
        v.add(fr1);
        v.add(fr2);
        Enumeration&amp;lt;FileInputStream&amp;gt; en = v.elements();
        SequenceInputStream sis = new SequenceInputStream(en);
        FileOutputStream fos = new FileOutputStream(&amp;#34;read3.md&amp;#34;);
        int b ;
        while ( (b = sis.read()) != -1){
            fos.write(b);
        }
        sis.close();
        fos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;bytearrayoutputstream-获取数据&#34;&gt;ByteArrayOutputStream 获取数据&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ByteArrayOutputStream 的 toString 可直接转为默认或指定的字符&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Deom2_ByteArrayOutputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fi = new FileInputStream(&amp;#34;read1.md&amp;#34;);
        ByteArrayOutputStream baos  = new ByteArrayOutputStream();
        int b ;
        while ( (b = fi.read()) != -1){
            baos.write(b);
        }
        fi.close();
        System.out.println(baos.toString());
        System.out.println(baos.toString(&amp;#34;utf-8&amp;#34;));
    }

    private static void Demo1() throws IOException {
        FileInputStream fi = new FileInputStream(&amp;#34;read1.md&amp;#34;);
        byte[] arr = new byte[3];
        int len;
        while ( ( len = fi.read(arr)) != -1){
            System.out.println(new String(arr,0,len));
        }
        fi.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;内存输出&#34;&gt;内存输出&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Demo3_Test {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream(&amp;#34;read1.md&amp;#34;);
        byte[] arr = new byte[5];
        int len;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        while ( (len = fis.read(arr)) != -1){
            bos.write(arr,0,len);
        }
        fis.close();
        System.out.println(bos.toString());
        bos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;随机读和存-randomaccessfile&#34;&gt;随机读和存 RandomAccessFile&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.IOException;
import java.io.RandomAccessFile;

public class Demo4_RandomAccessFile {
    public static void main(String[] args) throws IOException {
//        Demo1();
        Demo2();
    }
    public static void Demo2() throws IOException{
        RandomAccessFile raf = new RandomAccessFile(&amp;#34;random.txt&amp;#34;,&amp;#34;rw&amp;#34;);
        int b;
        while ( (b = raf.read()) != -1){
            System.out.println(b);
        }
        raf.close();
    }

    private static void Demo1() throws IOException {
        RandomAccessFile raf = new RandomAccessFile(&amp;#34;random.txt&amp;#34;,&amp;#34;rw&amp;#34;);
        raf.write(97);
        raf.seek(10);
        raf.write(98);
        raf.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;对象操作流-objecoutputstream&#34;&gt;对象操作流 ObjecOutputStream&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;输出对象流, 序列化&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Person;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Demo5_ObjectOutputStream {
    public static void main(String[] args) throws IOException {
        Person p1 = new Person(&amp;#34;小明&amp;#34;, 23);
        Person p2 = new Person(&amp;#34;小红&amp;#34;, 23);

        ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(&amp;#34;person.txt&amp;#34;));
        oos.writeObject(p1);
        oos.writeObject(p2);
        oos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;读取对象流&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Person;

import java.io.*;

public class Deom6_ObjectInputStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream oos = new ObjectInputStream(new FileInputStream(&amp;#34;person.txt&amp;#34;));
        Person p1 = (Person) oos.readObject();
        System.out.println(p1.getName()+p1.getAge());
        Person p2 = (Person) oos.readObject();
        System.out.println(p2.getName()+p2.getAge());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;对象操作优化&#34;&gt;对象操作优化&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;对象放入集合中, 集合输出到流&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Person;

import java.io.*;
import java.util.ArrayList;

public class Demo7_OptimeObjectStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(&amp;#34;hashSetPerson.txt&amp;#34;));
        ArrayList&amp;lt;Person&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        arrayList.add(new Person(&amp;#34;小明&amp;#34;,25));
        arrayList.add(new Person(&amp;#34;小红&amp;#34;,23));
        arrayList.add(new Person(&amp;#34;小王&amp;#34;,26));
        oos.writeObject(arrayList);
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(&amp;#34;hashSetPerson.txt&amp;#34;));
        ArrayList&amp;lt;Person&amp;gt; personArrayList = ( ArrayList&amp;lt;Person&amp;gt; ) ois.readObject();
        for(Person p : personArrayList){
            System.out.println(p.getName() + p.getAge());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;io-流增加-id-号&#34;&gt;IO 流增加 id 号&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;更改Person属性时更改serialVersionUID 可以准备知道原来Persion和现在Persion属性区别&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.Serializable;

public class Person implements Serializable {

    private static final long serialVersionUID= 1L;

    private String name;
    private int age;

    public Person(){}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;io-基本数据流-datainputstream-dataoutputstream&#34;&gt;IO 基本数据流, DataInputStream DataOutputStream&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo8_DataInputStream {
    public static void main(String[] args) throws IOException {
        Demo1();
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(&amp;#34;outData.txt&amp;#34;));
        dos.writeInt(997);
        dos.writeInt(998);
        dos.writeInt(999);
        dos.close();
        DataInputStream dis = new DataInputStream(new FileInputStream(&amp;#34;outData.txt&amp;#34;));
        int x = dis.readInt();
        int y = dis.readInt();
        int z = dis.readInt();
        System.out.println(x);
        System.out.println(y);
        System.out.println(z);
        dis.close();


    }

    private static void Demo1() throws IOException {
        FileOutputStream fos = new FileOutputStream(&amp;#34;output.txt&amp;#34;);
        fos.write(997);
        fos.close();
    }
    private static void Demo2() throws IOException {
        FileInputStream fis = new FileInputStream(&amp;#34;output.txt&amp;#34;);
        int b = fis.read();
        fis.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;打印流的概述和特点&#34;&gt;打印流的概述和特点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PrintStream 和 PrintWriter 分别是打印的字节流和字符流&lt;/li&gt;
&lt;li&gt;只操作数据目的&lt;/li&gt;
&lt;li&gt;自动刷出作用不大&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo9_PrintStream {
    public static void main(String[] args) throws IOException {
//        Demo2();
        PrintWriter pw = new PrintWriter(new FileOutputStream(&amp;#34;printWriter.txt&amp;#34;), true);
        pw.println(97);
    }

    private static void Demo2() throws FileNotFoundException {
        PrintWriter pw = new PrintWriter(&amp;#34;printWriter.txt&amp;#34;);
        pw.println(97);
        pw.write(97);
        pw.flush();
        pw.close();
    }

    private static void demo1() {
        PrintStream p = System.out;
        p.println(&amp;#34;Hello World!&amp;#34;);
        p.write(97);
        p.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;标准输入输出流概述和输出语句&#34;&gt;标准输入输出流概述和输出语句&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;标准输入只有1个, 未关联到文件, 不用关闭, 关闭后无法打开了&lt;/li&gt;
&lt;li&gt;标准输出流未关联文件, 也不用关闭&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;

public class Demo10_SystemInOut {
    public static void main(String[] args) throws IOException {
//        demo1();
        System.setIn(new FileInputStream(&amp;#34;systemin.txt&amp;#34;));
        System.setOut(new PrintStream(&amp;#34;systemout.txt&amp;#34;));
        InputStream is = System.in;
        PrintStream ps = System.out;
        int b;
        while ( ( b = is.read()) != -1){
            ps.write(b);
        }
        is.close();
        ps.close();

    }

    private static void demo1() throws IOException {
        InputStream is = System.in;
        int x = is.read();
        System.out.println(x);
        is.close();

        InputStream is2 = System.in;
        int y = is2.read();
        System.out.println(y);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;练习, 复制文件, 增加使用数组, 增加复制速度&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo11_SystemInOutTest {
    public static void main(String[] args) throws IOException {
        System.setIn(new FileInputStream(&amp;#34;systemin.txt&amp;#34;));
        System.setOut(new PrintStream(&amp;#34;systemout.txt&amp;#34;));
        InputStream is = System.in;
        PrintStream ps = System.out;
        byte [] arr = new byte[1024];
        int len;
        while ( ( len = is.read(arr)) != -1){
            ps.write(arr,0,len);
        }
        is.close();
        ps.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;2种键盘录入方式&#34;&gt;2种键盘录入方式&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Scanner;

public class Demo12_SystemIn {
    public static void main(String[] args) throws IOException {
//        demo1();
        Scanner sc = new Scanner(System.in);
        String s = null;
        if(sc.hasNext()){
            s = sc.nextLine();
        }
        System.out.println(s);
    }

    private static void demo1() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = br.readLine();
        System.out.println(line);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;properties的概述和作为map集合的使用&#34;&gt;Properties的概述和作为Map集合的使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Object setProperty(String key, String value) 添加键值对&lt;/li&gt;
&lt;li&gt;Enumeration&lt;?&gt; propertyNames() 获取 key值枚举&lt;/li&gt;
&lt;li&gt;String getProperty(String key) 根据key 值获取 value&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Enumeration;
import java.util.Properties;

public class Demo13_Properties {
    public static void main(String[] args) {
//        demo1();
        Properties pp = new Properties();
        pp.setProperty(&amp;#34;name&amp;#34;, &amp;#34;小明&amp;#34;);
        pp.setProperty(&amp;#34;tel&amp;#34;, &amp;#34;12310001000&amp;#34;);
        System.out.println(pp);
        Enumeration &amp;lt;String&amp;gt; en = (Enumeration&amp;lt;String&amp;gt;) pp.propertyNames();
        while ( en.hasMoreElements()){
            String key = en.nextElement();
            System.out.println(key+pp.getProperty(key));
        }

    }

    private static void demo1() {
        Properties p = new Properties();
        p.put(&amp;#34;intA&amp;#34;, 12);
        System.out.println(p);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;properties-读和存&#34;&gt;Properties 读和存&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;void load(InputStream inStream) throws IOException 读取文件&lt;/li&gt;
&lt;li&gt;void store(OutputStream out, String comments) throws IOException 写到文件, comments 加入注释&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;

public class Demo13_Properties {
    public static void main(String[] args) throws IOException {
        Properties pp = new Properties();
        System.out.println(pp);
        pp.load(new FileInputStream(&amp;#34;config.properties&amp;#34;));
        System.out.println(pp);
        pp.setProperty(&amp;#34;qq&amp;#34;,&amp;#34;123&amp;#34;);
        System.out.println(pp);
        pp.store(new FileOutputStream(&amp;#34;config.properties&amp;#34;), &amp;#34;utf-8&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的Reader和Writer类 Li.043</title>
      <link>https://lizicai.com/p/java%E7%9A%84reader%E5%92%8Cwriter%E7%B1%BB-li.043/</link>
      <pubDate>Thu, 02 Sep 2021 16:43:49 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84reader%E5%92%8Cwriter%E7%B1%BB-li.043/</guid>
      <description>&lt;h2 id=&#34;filereader-读取文件&#34;&gt;FileReader 读取文件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileReader;
import java.io.IOException;

public class Demo1_FileReader {
    public static void main(String[] args) throws IOException {
//        Demo1();
        FileReader fr = new FileReader(&amp;#34;m.txt&amp;#34;);
        int b ;
        while ( (b = fr.read()) != -1){
            System.out.println((char)b);
        }
        fr.close();
    }

    private static void Demo1() throws IOException {
        FileReader fr = new FileReader(&amp;#34;m.txt&amp;#34;);
        int x = fr.read();
        System.out.println(x);
        System.out.println((char)x);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;filewriter-字符写入文件&#34;&gt;FileWriter 字符写入文件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileWriter;
import java.io.IOException;

public class Demo2_FileWriter {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter(&amp;#34;output.txt&amp;#34;);
        String s = &amp;#34;这只羊叫Leon&amp;#34;;
        fw.write(s);
        fw.flush();
        fw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;字符复制&#34;&gt;字符复制&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo3_ReaderWriter {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader(&amp;#34;input.txt&amp;#34;);
        FileWriter fw = new FileWriter(&amp;#34;output.txt&amp;#34;);

        int b ;
        while ( (b = fr.read()) != -1){
            fw.write(b);
        }
        fr.close();
        fw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;什么情况使用使用字符流&#34;&gt;什么情况使用使用字符流&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;字符流也能复制文件, 但不推荐, 字节-&amp;gt;字符, 字符-&amp;gt;字节 多一步转换&lt;/li&gt;
&lt;li&gt;程序需要读取一段文本, 或都需要写入一段文本的时候可以使用字符流&lt;/li&gt;
&lt;li&gt;读取的时候按字符读出, 不会出现半个中文&lt;/li&gt;
&lt;li&gt;写出时可直接字符串写出, 不用转换为字节数组&lt;/li&gt;
&lt;li&gt;图片类文件不能使用字符流复制, 丢失数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;自定义数组复制&#34;&gt;自定义数组复制&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo4_ReaderWriter {

    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader(&amp;#34;input.txt&amp;#34;);
        FileWriter fw = new FileWriter(&amp;#34;output.txt&amp;#34;);

        char[] arr = new char[1024];
        int len;
        while ( (len = fr.read(arr)) != -1){
            fw.write(arr, 0 , len);
        }
        fr.close();
        fw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;bufferedreader-和-bufferedwriter-读取写入字符&#34;&gt;BufferedReader 和 BufferedWriter 读取写入字符&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo5_BufferedReader {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(&amp;#34;input.txt&amp;#34;));
        BufferedWriter bw = new BufferedWriter(new FileWriter(&amp;#34;output.txt&amp;#34;));
        int b ;
        while ( (b=br.read()) != -1){
            bw.write(b);
        }
        br.close();
        bw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;bufferedreader-readline方法-bufferedwriter-的newline方法&#34;&gt;BufferedReader readLine()方法, BufferedWriter 的newLine方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;newLine 没有放在write(line)后, 并写在循环内, 这样写多写一个空行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo6_ReadLine {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(&amp;#34;input.txt&amp;#34;));
        BufferedWriter bw = new BufferedWriter(new FileWriter(&amp;#34;output.txt&amp;#34;));
        String line ;
        if( (line = br.readLine() ) != null ){
            bw.write(line);
        }
        while (  (line = br.readLine()) != null){
            bw.newLine();
            bw.write(line);
        }
        br.close();
        bw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-读取行-并行数反向输出&#34;&gt;练习, 读取行, 并行数反向输出&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;流, 最好晚开早关&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.util.ArrayList;

public class Demo7_ReverseLine {
    public static void main(String[] args) throws IOException {

        ArrayList&amp;lt;String&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        String str ;
        BufferedReader br = new BufferedReader(new FileReader(&amp;#34;input.txt&amp;#34;));
        while( ( str=br.readLine()) != null){
            arrayList.add(str);
        }
        br.close();

        BufferedWriter bw = new BufferedWriter(new FileWriter(&amp;#34;output.txt&amp;#34;));
        for(int i= arrayList.size()-1;i&amp;gt;=0 ;i--){
            bw.write(arrayList.get(i));
            if( i == 0 ){
                break;
            }
            bw.newLine();
        }
        bw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;linenumberreader&#34;&gt;LineNumberReader&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

public class Demo8_LineNumberReader {
    public static void main(String[] args) throws IOException {
        LineNumberReader lnr = new LineNumberReader(new FileReader(&amp;#34;input.txt&amp;#34;));
        String line;

        lnr.setLineNumber(3);
        while ( (line = lnr.readLine()) != null){
            System.out.println(lnr.getLineNumber() + &amp;#34; &amp;#34;+line);
        }
        lnr.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;装饰设计模式&#34;&gt;装饰设计模式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用被装饰的类, 对类中方法升级增加内容&lt;/li&gt;
&lt;li&gt;好处
&lt;ul&gt;
&lt;li&gt;耦合性不强, 被装饰类的变化与装饰类的变化无关&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo9_Wrap {
    public static void main(String[] args) {
        JiuCai j = new JiuCai(new Student());
        j.code();
    }
}
class Student {
    private String name;
    private int age;
    public void code(){
        System.out.println(&amp;#34;C&amp;#34;);
        System.out.println(&amp;#34;Java&amp;#34;);
    }
}
interface Coder{
    public void code();
}

class JiuCai implements Coder{
    JiuCai (Student stu){
        this.stu = stu;
    }
    private Student stu;
    @Override
    public void code() {
        stu.code();
        System.out.println(&amp;#34;JavaEE&amp;#34;);
        System.out.println(&amp;#34;SprintBoot&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;使用指定被码表读写字符&#34;&gt;使用指定被码表读写字符&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;utf8格式写到gbk中, 乱码&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo10_UTF8 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader(&amp;#34;utf8.txt&amp;#34;);
        FileWriter fw = new FileWriter(&amp;#34;gbk.txt&amp;#34;);
        int b ;
        while (( b=fr.read()) != -1){
            fw.write(b);
        }
        fr.close();
        fw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private static void Demo2() throws IOException {
    InputStreamReader isr = new InputStreamReader(new FileInputStream(&amp;#34;utf-8.txt&amp;#34;),&amp;#34;utf-8&amp;#34;);
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(&amp;#34;gbk.txt&amp;#34;), &amp;#34;gbk&amp;#34;);
    int b ;
    while ( ( b=isr.read()) != -1 ){
        osw.write(b);
    }
    isr.close();
    osw.close();
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader
        (new InputStreamReader(new FileInputStream(&amp;#34;utf-8.txt&amp;#34;),&amp;#34;utf-8&amp;#34;));
    BufferedWriter bw = new BufferedWriter
        (new OutputStreamWriter(new FileOutputStream(&amp;#34;gbk.txt&amp;#34;),&amp;#34;gbk&amp;#34;));
    int b ;
    while ( (b=br.read()) != -1){
        bw.write(b);
    }
    br.close();
    bw.close();

}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-统计字符-并输出到一个文件中&#34;&gt;练习, 统计字符, 并输出到一个文件中&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.util.Map;
import java.util.TreeMap;

public class Demo11_CalculatorChar {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader (new FileReader(&amp;#34;utf-8.txt&amp;#34;));
        TreeMap&amp;lt;String,Integer&amp;gt; treeMap = new TreeMap&amp;lt;&amp;gt;();

        int b ;
        while ( (b=br.read()) != -1){
            if( treeMap.containsKey(String.valueOf((char)b))){
                treeMap.put(String.valueOf((char)b),treeMap.get(String.valueOf((char)b))+1);
            } else {
                treeMap.put(String.valueOf((char)b), 1);
            }
        }
        br.close();
        BufferedWriter bw = new BufferedWriter(new FileWriter(&amp;#34;times.txt&amp;#34;));
        for(Map.Entry&amp;lt;String,Integer&amp;gt; stringIntegerEntry : treeMap.entrySet()){
            if( &amp;#34;\n&amp;#34;.equals(stringIntegerEntry.getKey())){
                bw.write(stringIntegerEntry.getValue()+&amp;#34;=&amp;#34;+&amp;#34;\\n&amp;#34;);
            } else if( &amp;#34; &amp;#34;.equals(stringIntegerEntry.getKey()) ){
                bw.write(stringIntegerEntry.getValue()+&amp;#34;=&amp;#34;+&amp;#34;space&amp;#34;);
            } else {
                bw.write(stringIntegerEntry.getValue()+&amp;#34;=&amp;#34;+stringIntegerEntry.getKey());
            }
            bw.newLine();
        }
        bw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;模拟软件剩余使用次数&#34;&gt;模拟软件剩余使用次数&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo12_CalculatorTimes {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(&amp;#34;license.txt&amp;#34;));
        String str;
        str = br.readLine();
        br.close();
        int times = Integer.parseInt(str);
        if( times &amp;lt;= 0){
            System.out.println(&amp;#34;试用结束, 请购买正版&amp;#34;);
        } else if( times &amp;gt; 0){
            System.out.println(&amp;#34;还可以使用&amp;#34;+times+&amp;#34;次&amp;#34;);
            times = times - 1;
        }
        BufferedWriter bw = new BufferedWriter(new FileWriter(&amp;#34;license.txt&amp;#34;));
        bw.write(String.valueOf(times));
        bw.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;递归&#34;&gt;递归&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public static int demo1(int nu){
    if(nu &amp;gt; 1){
        nu = nu * demo1(nu - 1);
    }
    return nu;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;递归找.java结尾的文件&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;
import java.util.Scanner;

public class Demo14_DiGui2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str;
        while (true){
            if( sc.hasNext()){
                str=sc.nextLine();
                break;
            }
        }
        File file = new File(str);
        if(file.exists()){
            printJavaFile(file);
        } else{
            System.out.println(&amp;#34;文件夹不存在&amp;#34;);
        }
    }

    private static void printJavaFile(File file) {
        File[] arrayList ;
        arrayList = file.listFiles();
        for(File f : arrayList) {
            if (f.isDirectory()) {
                printJavaFile(f);
            } else if (f.isFile() &amp;amp;&amp;amp; f.getName().endsWith(&amp;#34;.java&amp;#34;)) {
                System.out.println(f.getAbsoluteFile());
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的IO流 Li.042</title>
      <link>https://lizicai.com/p/java%E7%9A%84io%E6%B5%81-li.042/</link>
      <pubDate>Mon, 30 Aug 2021 17:04:54 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84io%E6%B5%81-li.042/</guid>
      <description>&lt;h2 id=&#34;java-的-io-流&#34;&gt;Java 的 IO 流&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;字节流, 字节流可以操作任何数据, 计算机中存储是字节流
&lt;ul&gt;
&lt;li&gt;InputStream&lt;/li&gt;
&lt;li&gt;OutputStream&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;字符流, 只能操作纯字符数据, 比较方便
&lt;ul&gt;
&lt;li&gt;Reader&lt;/li&gt;
&lt;li&gt;Writer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;使用IO流要导入包, 使用时要进行异常处理, 使用后要释放资源&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;fileinputstream-读取一个文件&#34;&gt;FileInputStream 读取一个文件&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileInputStream;
import java.io.IOException;

public class Demo1_FileInputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fps = new FileInputStream(&amp;#34;test.txt&amp;#34;);
        int x;
        while ((x = fps.read() ) != -1){
            System.out.println(x);
        }
        fps.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;read-为什么接收的int类型&#34;&gt;read() 为什么接收的int类型&lt;/h2&gt;
&lt;p&gt;因为字节输入流可以操作任意类型的文件,比如图片音频等,
这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte,
有可能在读到中间的时候遇到111111111,那么这11111111是byte类型的-1,
我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收,
如果11111111会在其前面补上24个0凑足4个字节,那么byte类型的-1就变成int类型的255了这样可以保证整个数据读完,
&lt;strong&gt;而结束标记的-1就是int类型&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;字节输出流-write&#34;&gt;字节输出流 write()&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;void write(int b) throws IOException 在输出时int 去掉前3个byte字节, 写入第4个byte到文件中, 这个写是覆盖&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileOutputStream;
import java.io.IOException;

public class Deom2_FileOutputStream {
    public static void main(String[] args) throws IOException {
        FileOutputStream fps = new FileOutputStream(&amp;#34;test.txt&amp;#34;);
        fps.write(100);
        fps.write(101);
        fps.write(102);
        fps.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;字节输出流-追加&#34;&gt;字节输出流 追加&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FileOutputStream(File file, boolean append) throws FileNotFoundException 输出字节流是否选择追加&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileOutputStream;
import java.io.IOException;

public class Demo3_FileOutputStream {
    public static void main(String[] args) throws IOException {
        FileOutputStream fps = new FileOutputStream(&amp;#34;test.txt&amp;#34;, true);
        fps.write(100);
        fps.write(101);
        fps.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;复制文件&#34;&gt;复制文件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;byte字节读取, byte复制&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo4_FileInOutStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream(&amp;#34;test.txt&amp;#34;);
        FileOutputStream fos = new FileOutputStream(&amp;#34;copy.txt&amp;#34;);
        int b = 0;
        while ( (b = fis.read() )!= -1){
            fos.write(b);
        }
        fis.close();
        fos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;fileinputstream-的-available方法&#34;&gt;FileInputStream 的 available方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;int available() throws IOException 返回输入流的长度&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo5_FileInOutStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream(&amp;#34;test.txt&amp;#34;);
        FileOutputStream fos = new FileOutputStream(&amp;#34;copy.txt&amp;#34;);

        int len = fis.available();
        byte[] arr = new byte[fis.available()];
        fis.read(arr);
        fos.write(arr);
        fis.close();
        fos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;通过数组-byte-读取写入&#34;&gt;通过数组 byte[] 读取写入&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo6_FileInOutStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream(&amp;#34;test.txt&amp;#34;);
        FileOutputStream fos = new FileOutputStream(&amp;#34;copy.txt&amp;#34;);

        byte[] arr = new byte[1024 * 1024];
        int b = 0;
        while ( (b =fis.read(arr)) != -1 ){
            fos.write(arr,0,b);
        }
        fis.close();
        fos.close();
    }

    private static void errSimple() throws IOException {
        FileInputStream fis = new FileInputStream(&amp;#34;test.txt&amp;#34;);
        FileOutputStream fos = new FileOutputStream(&amp;#34;copy.txt&amp;#34;);

        byte[] arr = new byte[3];
        int b = 0;
        while ( (b =fis.read(arr)) != -1 ){
            fos.write(arr);
        }
        fis.close();
        fos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;bufferedinputstream-bufferedoutputstream&#34;&gt;BufferedInputStream BufferedOutputStream&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;原码先读取1024*8个字节到内存, 复制给 BufferedOutputStream 1024*8 然后才写入文件&lt;/li&gt;
&lt;li&gt;只需要关闭BufferedInputStream BufferedOutputStream 就能关闭所有流&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo7_BufferInputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream(&amp;#34;test.txt&amp;#34;);
        FileOutputStream fos = new FileOutputStream(&amp;#34;copy.txt&amp;#34;);

        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        int b ;
        while( ( b = bis.read() ) != -1){
            bos.write(b);
        }
        // 只需关闭 BufferedInputStream BufferedOutputStream
        bis.close();
        bos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;flush和close方法的区别&#34;&gt;flush和close方法的区别&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;flush 刷新缓冲区, 缓冲区写到文件中, 刷完可以继续写.&lt;/li&gt;
&lt;li&gt;close 关闭前 就会刷新缓冲区 将缓冲区内容存到文件中&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;

public class Demo8_FlushClose {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream(&amp;#34;test.txt&amp;#34;);
        FileOutputStream fos = new FileOutputStream(&amp;#34;copy.txt&amp;#34;);

        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        int b ;
        while ( (b = bis.read()) != -1 ){
            bos.write(b);
            bos.flush();
        }
        bis.close();
        bos.close();
    }

}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;字节流读取中文有乱码&#34;&gt;字节流读取中文有乱码&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;UTF-8中英文1个字节, 中文3个字节, 按字节读取都会读出乱码&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class Demo9_CharIO {
    public static void main(String[] args) throws IOException {
//        Demo1();
        FileOutputStream fos = new FileOutputStream(&amp;#34;chinese.txt&amp;#34;);
        fos.write(&amp;#34;你好啊, 世界!&amp;#34;.getBytes(StandardCharsets.UTF_8));
        fos.write(&amp;#34;\r&amp;#34;.getBytes(StandardCharsets.UTF_8));
        fos.close();
    }

    private static void Demo1() throws IOException {
        FileInputStream fis = new FileInputStream(&amp;#34;chinese.txt&amp;#34;);
        byte[] arr = new byte[3];
        String s;
        int len ;
        while ( ( len=fis.read(arr) ) != -1){
            System.out.println(new String(arr,0,len));
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;异常处理&#34;&gt;异常处理&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;流初始化null&lt;/li&gt;
&lt;li&gt;try 关闭流&lt;/li&gt;
&lt;li&gt;能关闭一个就关闭一个&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo10_IOException {
    public static void main(String[] args) throws IOException{
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(&amp;#34;test.txt&amp;#34;);
            fos = new FileOutputStream(&amp;#34;copy.txt&amp;#34;);
        }
        finally {
            try{
                if(null != fis){
                    fis.close();
                }
            } finally {
                if(null != fos){
                    fos.close();
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;图片加密解密&#34;&gt;图片加密解密&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;加密把输出的字节异或一个数, 解密时再异或这个数&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
public class Demo12_Encrypt {
    public static void main(String[] args)  throws IOException {
        String src = &amp;#34;beauty.png&amp;#34;;
        String dest = &amp;#34;copy.png&amp;#34;;
        String dest2 = &amp;#34;copy1.png&amp;#34;;
//        extracted(src, dest);
        extracted(dest, dest2);
    }

    private static void extracted( String src, String dest) throws IOException {
        BufferedInputStream fis = new BufferedInputStream(new FileInputStream(src));
        BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(dest));
        int b ;
        while ( (b = fis.read()) != -1){
            fos.write(b ^ 123 );
        }
        fis.close();
        fos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;输入文件复制到当前路径下&#34;&gt;输入文件复制到当前路径下&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.*;
import java.util.Scanner;

public class Demo13_CopyFile {
    public static void main(String[] args) throws IOException {

        Scanner sc = new Scanner(System.in);
        String src = null;
        if(sc.hasNext()){
            src = sc.nextLine();
        }
        BufferedInputStream fis =null;
        int b ;
        BufferedOutputStream fos = null;
        if(src != null){
            File file = new File(src);
            fis = new BufferedInputStream(new FileInputStream(src));
            fos = new BufferedOutputStream(new FileOutputStream(&amp;#34;./&amp;#34;+file.getName()));
            if( file.isFile()){
                 while ( (b = fis.read()) != -1){
                     fos.write(b);
                 }
            } else if( file.isDirectory()){
                System.out.println(&amp;#34;文件夹无法复制&amp;#34;);
            }
        }
        fis.close();
        fos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-录入输入字符到文件中&#34;&gt;练习, 录入输入字符到文件中&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class Demo14_InputKey {
    public static void main(String[] args) throws IOException {
        Scanner sc  = new Scanner(System.in);
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(&amp;#34;test.txt&amp;#34;, true));
        String input = null;
        while ( sc.hasNext()){
            input = sc.nextLine();
            if( &amp;#34;quit&amp;#34;.equals(input)){
                break;
            } else{
                bos.write(input.getBytes(StandardCharsets.UTF_8));
                bos.write(&amp;#34;\n&amp;#34;.getBytes(StandardCharsets.UTF_8));
            }
        }
        bos.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的File类 Li.041</title>
      <link>https://lizicai.com/p/java%E7%9A%84file%E7%B1%BB-li.041/</link>
      <pubDate>Sun, 29 Aug 2021 21:34:53 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84file%E7%B1%BB-li.041/</guid>
      <description>&lt;h2 id=&#34;file&#34;&gt;File&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;相对路径文件或目录&lt;/li&gt;
&lt;li&gt;绝对路径文件或目录&lt;/li&gt;
&lt;li&gt;File(String pathname) 文件路径或目录&lt;/li&gt;
&lt;li&gt;File(String parent, String child) 父文件路径, 和子文件名&lt;/li&gt;
&lt;li&gt;File(File parent, String child) 父文件路径file, 和子文件名&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;

public class Demo1_File {
    public static void main(String[] args) {
//        Demo1();
//        Demo2();
        File parentFile = new File(&amp;#34;/usr/local/etc/nginx/&amp;#34;);
        String child = &amp;#34;nginx.conf&amp;#34;;
        File file = new File(parentFile, child);
    }

    private static void Demo2() {
        String parent = &amp;#34;/usr/local/etc/nginx/&amp;#34;;
        String child = &amp;#34;nginx.conf&amp;#34;;
        File file = new File(parent,child);
        System.out.println(file.exists());
    }
    // a.c 与 src 在同级目录下
    private static void Demo1() {
        File file = new File(&amp;#34;/usr/local/etc/nginx/nginx.conf&amp;#34;);
        System.out.println(file.exists());
        File file2 = new File(&amp;#34;a.c&amp;#34;);
        System.out.println(file2.exists());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;file-的方法&#34;&gt;File 的方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;boolean createNewFile() throws IOException 如果没有则创建true, 有则不创建false.&lt;/li&gt;
&lt;li&gt;boolean mkdir() 无则创建文件夹, 有则不创建false&lt;/li&gt;
&lt;li&gt;boolean mkdirs() 无则创建多级文件夹, 有则不创建false&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;
import java.io.IOException;

public class Demo2_FileMethod {
    public static void main(String[] args) throws IOException {
        File file = new File(&amp;#34;aaa.c&amp;#34;);
        System.out.println(file.createNewFile());

        File file2 = new File(&amp;#34;test&amp;#34;);
        System.out.println(file2.mkdir());

        File file3 = new File(&amp;#34;test/aaa&amp;#34;);
        System.out.println(file3.mkdirs());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;boolean renameTo(File dest) 就是mv命令&lt;/li&gt;
&lt;li&gt;boolean delete() 删除文件或删除空文件夹, 文件夹内有文件或文件夹(空的也算)则删除不了&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;
import java.io.IOException;

public class Demo3_FileMethod {
    public static void main(String[] args) throws IOException {
        File file1 = new File(&amp;#34;aaa.c&amp;#34;);
        File file2 = new File(&amp;#34;bbb.c&amp;#34;);
        System.out.println(file1.renameTo(file2));
        System.out.println(file2.delete());

        File file3 = new File(&amp;#34;test/aaa&amp;#34;);
        System.out.println(file3.delete());

        File file4 = new File(&amp;#34;test/ccc&amp;#34;);
        System.out.println(file4.mkdirs());
        file4.delete();
        File file5 = new File(  &amp;#34;test&amp;#34;);
        System.out.println(file5.delete());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;boolean isDirectory() 判断是否文件夹&lt;/li&gt;
&lt;li&gt;boolean isFile() 判断是否文件&lt;/li&gt;
&lt;li&gt;boolean exists() 判断是否存在&lt;/li&gt;
&lt;li&gt;boolean canRead() 判断是否可读权限&lt;/li&gt;
&lt;li&gt;boolean canWrite() 判断是否可写权限&lt;/li&gt;
&lt;li&gt;boolean isHidden() 判断是否隐藏&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;
import java.io.IOException;

public class Demo4_FileMethod {
    public static void main(String[] args) throws IOException {
        File file1 = new File(&amp;#34;test&amp;#34;);
        System.out.println(file1.isDirectory());

        File file2 = new File(&amp;#34;test.c&amp;#34;);
        System.out.println(file1.isFile());
        System.out.println(file2.isFile());

        File file3 = new File(&amp;#34;aaa.c&amp;#34;);
        System.out.println(file3.exists());
        System.out.println(file3.createNewFile());
        System.out.println(file3.exists());

        File file4 = new File(&amp;#34;ccc.c&amp;#34;);
        System.out.println(file4.createNewFile());
        System.out.println(file4.canRead());

        File file5 = new File(&amp;#34;ddd.c&amp;#34;);
        System.out.println(file5.createNewFile());
        System.out.println(file5.canWrite());

        File file6 = new File(&amp;#34;root.c&amp;#34;);
        System.out.println(file6.setReadable(false));
        System.out.println(file6.canRead());
        System.out.println(file6.canWrite());

        File file7 = new File(&amp;#34;test.c&amp;#34;);
        System.out.println(file7.isHidden());

        File file8 = new File(&amp;#34;.idea&amp;#34;);
        System.out.println(file8.isHidden());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;String getAbsolutePath()&lt;/li&gt;
&lt;li&gt;String getPath()&lt;/li&gt;
&lt;li&gt;String getName()&lt;/li&gt;
&lt;li&gt;long length()&lt;/li&gt;
&lt;li&gt;long lastModified()&lt;/li&gt;
&lt;li&gt;String[] list()&lt;/li&gt;
&lt;li&gt;File[] listFiles()&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo5_FileMethod {
    public static void main(String[] args) {
        File file = new File(&amp;#34;aaa.c&amp;#34;);
        File file2 = new File(&amp;#34;/Users/test/IdeaProjects/day19/&amp;#34;);
        System.out.println(file.getAbsoluteFile());
        System.out.println(file2.getAbsoluteFile());


        System.out.println(file.getPath());
        System.out.println(file2.getPath());

        System.out.println(file.getName());
        System.out.println(file2.getName());

        System.out.println(file.length());
        System.out.println(file2.length());

        System.out.println(file.lastModified());
        System.out.println(file2.lastModified());
        Date date = new Date(file.lastModified());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;);
        System.out.println(simpleDateFormat.format(date));


        String [] arr = file.list();
//        for(String s: arr){
//            System.out.println(s);
//        }
        String [] arr2 = file2.list();
        for(String s: arr2){
            System.out.println(s);
        }

        File[] list1 = file.listFiles();
//        for(File f : list1){
//            System.out.println(f);
//        }
        File[] list2 = file2.listFiles();
        for(File f : list2){
            System.out.println(f);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习---查找文件夹下所有的c结尾的文件&#34;&gt;练习   查找文件夹下所有的.c结尾的文件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;遍历所有的文件, 碰到文件夹则进入遍历&lt;/li&gt;
&lt;li&gt;文件名字正则匹配, 匹配输出&lt;/li&gt;
&lt;li&gt;或使用String endsWith 匹配&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;

public class Demo6_FileTest {
    public static void main(String[] args) {
        File file = new File(&amp;#34;/Users/test/workplace/test&amp;#34;);
        File file2 = new File(&amp;#34;/Users/test/workplace/test&amp;#34;);
        File[] arrFile = file.listFiles();
        File[] arrFile2 = file2.listFiles();
        String regex = &amp;#34;.*[\\.][c]$&amp;#34;;
        String strEnd = &amp;#34;.c&amp;#34;;
        fileFind(arrFile, strEnd);
        fileFindRegex(arrFile2, regex);

    }
    public static void fileFind(File[] file, String strEnd){
        for(File f : file){
            if(f.isDirectory()){
                fileFind(f.listFiles(), strEnd);
            } else{
                if( f.getName().endsWith(strEnd) ){
                    System.out.println(f.getName());
                }
            }
        }
        return ;
    }
    public static void fileFindRegex(File[] file, String regex){
        for(File f : file){
            if(f.isDirectory()){
                fileFindRegex(f.listFiles(), regex);
            } else{
                if( f.getName().matches(regex) ){
                    System.out.println(f.getName());
                }
            }
        }
        return ;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-listfilenamefilter-filter-实现filenamefilter-接口-返回匹配的数组&#34;&gt;String[] list(FilenameFilter filter) 实现FilenameFilter 接口, 返回匹配的数组&lt;/h2&gt;
&lt;p&gt;原码&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public String[] list(FilenameFilter filter) {
    String names[] = list();
    if ((names == null) || (filter == null)) {
        return names;
    }
    List&amp;lt;String&amp;gt; v = new ArrayList&amp;lt;&amp;gt;();
    for (int i = 0 ; i &amp;lt; names.length ; i++) {
        if (filter.accept(this, names[i])) {
            v.add(names[i]);
        }
    }
    return v.toArray(new String[v.size()]);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;练习, test下.c结尾的文件, 仅有一级目录&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.io.File;
import java.io.FilenameFilter;

public class Demo7_FileMethod {
    public static void main(String[] args) {
        File dir = new File(&amp;#34;/Users/test/workplace/test&amp;#34;);
        String [] arr = dir.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                File file = new File(dir, name);
                return file.isFile() &amp;amp;&amp;amp; file.getName().endsWith(&amp;#34;.c&amp;#34;);
            }
        });

        for (String str : arr){
            System.out.println(dir+&amp;#34;/&amp;#34; + str);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的异常类 Li.040</title>
      <link>https://lizicai.com/p/java%E7%9A%84%E5%BC%82%E5%B8%B8%E7%B1%BB-li.040/</link>
      <pubDate>Fri, 27 Aug 2021 17:14:29 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84%E5%BC%82%E5%B8%B8%E7%B1%BB-li.040/</guid>
      <description>&lt;h2 id=&#34;java-的异常类&#34;&gt;Java 的异常类&lt;/h2&gt;
&lt;h3 id=&#34;异常的体系&#34;&gt;异常的体系&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Throwable
&lt;ul&gt;
&lt;li&gt;Error&lt;/li&gt;
&lt;li&gt;Exception
&lt;ul&gt;
&lt;li&gt;RuntimeException&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;如果程序没有处理异常, JVM 自行处理, 把异常的名称和信息, 打印在控制台上.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;异常的2种处理方式&#34;&gt;异常的2种处理方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;try catch finally
&lt;ul&gt;
&lt;li&gt;try catch&lt;/li&gt;
&lt;li&gt;try catch finally&lt;/li&gt;
&lt;li&gt;try finally&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;throws&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Exception {
    public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        int x;
        try{
            x = demo1.div(10,0);
        } catch (ArithmeticException e){
            System.out.println(e.getClass());
            System.out.println(&amp;#34;test&amp;#34;);
        }finally {
            System.out.println(&amp;#34;最后执行了吗&amp;#34;);
        }
    }
}
class Demo1 {
    public int div (int a, int b){
        return a/b;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_Exception {
    public static void main(String[] args) {
        int a = 0;
        int b = 10;
        int[] arr = {1, 2, 3};
        int x ;
        arr = null;
        try {
//            x = b / a;
            System.out.println(arr[10]);
        } catch (ArithmeticException e){
            System.out.println(e.getClass());
        } catch (IndexOutOfBoundsException e){
            System.out.println(e.getClass());
        } catch (Exception e){
            System.out.println(&amp;#34;有异常&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo3_Exception {
    public static void main(String[] args) {
        try {
            System.out.println(10/0);
        } catch (ArithmeticException | IndexOutOfBoundsException  e){
            System.out.println(&amp;#34;Exception&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;异常throwable-的方法&#34;&gt;异常throwable 的方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;String getMessage() 获取异常信息&lt;/li&gt;
&lt;li&gt;String toString() 获取异常类和异常信息&lt;/li&gt;
&lt;li&gt;void printStackTrace() 获取异常类和异常信息, 异常在程序出现的位置&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo3_Exception {
    public static void main(String[] args) {
        try {
            System.out.println(10/0);
        } catch (ArithmeticException | IndexOutOfBoundsException  e){
            System.out.println(e.getMessage());
            System.out.println(e.toString());
            e.printStackTrace();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;方法上的2种异常&#34;&gt;方法上的2种异常&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RuntimeException 运行时异常, 不需要在方法向上抛出, 使用的时候也不需要在使用的方法上向上抛出&lt;/li&gt;
&lt;li&gt;非RuntimeException 的异常, 必须在方法上向上抛出, 使用方法时也必须向上抛出异常&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.Getter;
import lombok.Setter;

public class Person {
    public Person(){}
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Getter
    @Setter
    private String name;
    @Getter
    private int age;

    public void setAge(int age)  {
        if(age &amp;lt; 1 || age &amp;gt; 150){
            throw new RuntimeException (&amp;#34;年龄非法&amp;#34;);
        }
        this.age = age;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.Getter;
import lombok.Setter;

public class Person {
    public Person(){}
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Getter
    @Setter
    private String name;
    @Getter
    private int age;

    public void setAge(int age)  throws Exception{
        if(age &amp;lt; 1 || age &amp;gt; 150){
            throw new Exception (&amp;#34;年龄非法&amp;#34;);
        }
        this.age = age;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_Exception {
    public static void main(String[] args) throws Exception{
        Person p = new Person();
        p.setAge(-12);
        System.out.println(&amp;#34;MM&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;throws-和-throw-区别&#34;&gt;throws 和 throw 区别&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;throws
&lt;ul&gt;
&lt;li&gt;用在方法声明后, 跟的是异常类名&lt;/li&gt;
&lt;li&gt;跟以跟多个类名, 用逗号隔开&lt;/li&gt;
&lt;li&gt;表示抛出异常, 由该方法的调用者处理&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;throw
&lt;ul&gt;
&lt;li&gt;用在方法内, 跟的是异常对象名&lt;/li&gt;
&lt;li&gt;只能抛出一个异常对象名&lt;/li&gt;
&lt;li&gt;表示抛出异常, 由方法体内的语句处理&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;finally&#34;&gt;finally&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;finally 的特点
&lt;ul&gt;
&lt;li&gt;被finally 控制的语句一定会执行&lt;/li&gt;
&lt;li&gt;特殊情况: 在执行finally 前 JVM 退出了(如System.exit(0))&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;finally 的作用
&lt;ul&gt;
&lt;li&gt;用于释放资源, 在IO 操作和数据库操作中会见到&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;return 的区别
return 执行后, 如果有finally 则执行finally 类&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo5_Exception {
    public static void main(String[] args) {
        try {
            System.out.println(1/0);
        } catch (Exception e){
            System.out.println(&amp;#34;异常&amp;#34;);
        } finally {
            System.out.println(&amp;#34;最后一定执行&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;final-finally-finalize-区别&#34;&gt;final finally finalize 区别&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;final
&lt;ul&gt;
&lt;li&gt;final 可以修饰类, 但不能被继承&lt;/li&gt;
&lt;li&gt;修饰方法不能被重写&lt;/li&gt;
&lt;li&gt;修饰变量只能赋值一次&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;finally
&lt;ul&gt;
&lt;li&gt;try catch finally 体系中的一个语句, 不能单独使用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;finalize
&lt;ul&gt;
&lt;li&gt;当垃圾回收器确定不存在该对象的更多引用时, 对象回收器则调用此方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo6_Exception {
    public static void main(String[] args) {
        System.out.println(demo1());
    }
    public static int demo1(){
        int x = 10;
        try {
            x = 20;
            System.out.println(1/0);
            return x;
        } catch (Exception e){
            x = 30;
            return x;
        } finally {
            x = 40;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;x 会返回30, return 把x=30装箱返回回去&lt;/p&gt;
&lt;h2 id=&#34;自定义异常&#34;&gt;自定义异常&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;为什么需要定义异常类
&lt;ul&gt;
&lt;li&gt;可通过异常类名字即可知道错误在哪&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;异常使用
&lt;ul&gt;
&lt;li&gt;自定义异常类, 继承Exception&lt;/li&gt;
&lt;li&gt;在方法中使用异常类&lt;/li&gt;
&lt;li&gt;调用方法时处理异常类(try catch finally)或直接抛出&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class OutOfAgeException extends Exception {
    public OutOfAgeException() {
        super();
    }

    public OutOfAgeException(String message) {
        super(message);
    }

    public OutOfAgeException(String message, Throwable cause) {
        super(message, cause);
    }

    public OutOfAgeException(Throwable cause) {
        super(cause);
    }

    protected OutOfAgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.exception.OutOfAgeException;
import lombok.Getter;
import lombok.Setter;

public class Person {
    public Person(){}
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Getter
    @Setter
    private String name;
    @Getter
    private int age;

    public void setAge(int age)  throws Exception{
        if(age &amp;lt; 1 || age &amp;gt; 150){
            throw new OutOfAgeException(&amp;#34;年龄异常&amp;#34;);
        }
        this.age = age;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo7_Exception {
    public static void main(String[] args) throws Exception {
        Person p = new Person();
        p.setAge(-10);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;异常&#34;&gt;异常&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;子类重写父类方法时, 子类的方法必须抛出相同的异常或父类异常的子类( 子类不能比父类坏的更多 )&lt;/li&gt;
&lt;li&gt;如果父类抛出多个异常, 子类重写父类时, 只能抛出相同的异常或异常的子类, 子类不能抛出父类没有的异常&lt;/li&gt;
&lt;li&gt;如果重写方法没有异常抛出, 那么子类的方法绝对不可以抛出异常, 如果子类方法内有异常发生, 那么子类能try catch,不能throws&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;练习&#34;&gt;练习&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;输入一个整数&lt;/li&gt;
&lt;li&gt;超出整数范围则提示过大, 重新输入整数&lt;/li&gt;
&lt;li&gt;输入小数则提示小数, 重新输入整数&lt;/li&gt;
&lt;li&gt;输入字符等, 则提示非法字符, 请重新输入整数&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;

public class Demo8_Exception {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = null;
        BigInteger bigInteger = null;
        BigDecimal bigDecimal = null;
        int scInt = 0;
        System.out.println(&amp;#34;请输入一个整数:&amp;#34;);
        while (sc.hasNext()){
            str = sc.nextLine();
            try {
                scInt = Integer.parseInt(str);
                System.out.println(Integer.toBinaryString(scInt));
                break;
            } catch (Exception e){
                try {
                    bigInteger = new BigInteger(str);
                    System.out.println(&amp;#34;过大的整数, 请重新输入整数&amp;#34;);
                } catch (NumberFormatException e2){
                    try{
                        bigDecimal =  new BigDecimal(str);
                        System.out.println(&amp;#34;输入的小数, 请重新输入整数&amp;#34;);
                    } catch (Exception e3){
                        System.out.println(&amp;#34;输入的非法字符, 请重新输入整数&amp;#34;);
                    }
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的Map类 Li.039</title>
      <link>https://lizicai.com/p/java%E7%9A%84map%E7%B1%BB-li.039/</link>
      <pubDate>Tue, 24 Aug 2021 23:16:13 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84map%E7%B1%BB-li.039/</guid>
      <description>&lt;h2 id=&#34;map&#34;&gt;Map&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;将键映射到值的对象&lt;/li&gt;
&lt;li&gt;一个映射不能包含重复的键&lt;/li&gt;
&lt;li&gt;每个键最多只能映射到一个值&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;map-与-collection-接口的不同&#34;&gt;Map 与 Collection 接口的不同&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Map 是双列的, Collection 是单列的&lt;/li&gt;
&lt;li&gt;Map 是键唯一, Collection 的子体系Set是唯一的&lt;/li&gt;
&lt;li&gt;Map 集合的数据结构值针对键有效, 跟值无关; Collection集合的数据结构是针对元素有效&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;map-方法&#34;&gt;Map 方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;V put(K key, V value) 添加键和值, 成功返回null, 覆盖重复key值, 则返回被覆盖的Value值&lt;/li&gt;
&lt;li&gt;V remove(Object key) 通过key删除元素, 删除成功则返回Value值&lt;/li&gt;
&lt;li&gt;boolean containsKey(Object key) Map 中是否包含Key值&lt;/li&gt;
&lt;li&gt;boolean containsValue(Object value) Map 中是否包含Value值&lt;/li&gt;
&lt;li&gt;boolean isEmpty() Map 是否为空&lt;/li&gt;
&lt;li&gt;clear() 清空Map&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class Demo1_Map {
    public static void main(String[] args) {
//        Demo1();
        Map&amp;lt;String, Integer&amp;gt; hashMap = new HashMap&amp;lt;&amp;gt;();
        hashMap.put(&amp;#34;小明&amp;#34;, 18);
        hashMap.put(&amp;#34;小红&amp;#34;, 19);
        hashMap.put(&amp;#34;小王&amp;#34;, 20);
        System.out.println(hashMap);
        Integer i =  hashMap.remove(&amp;#34;小王&amp;#34;);
        System.out.println(i);
        System.out.println(hashMap);

        System.out.println(hashMap.containsKey(&amp;#34;小明&amp;#34;));
        System.out.println(hashMap.containsValue(19));
        System.out.println(hashMap.isEmpty());

        Collection&amp;lt;Integer&amp;gt; v = hashMap.values();
        System.out.println(v);
        hashMap.clear();
        System.out.println(hashMap.size());

    }

    private static void Demo1() {
        Map&amp;lt;String,Integer&amp;gt; map = new HashMap&amp;lt;&amp;gt;();
        Integer i1 = map.put(&amp;#34;s1&amp;#34;,12);
        Integer i2 = map.put(&amp;#34;s2&amp;#34;,22);
        Integer i3 = map.put(&amp;#34;s3&amp;#34;,33);
        Integer i4 = map.put(&amp;#34;s3&amp;#34;,34);
        Integer i5 = map.put(&amp;#34;s5&amp;#34;,35);
        Integer i6 = map.put(&amp;#34;s6&amp;#34;,35);
        System.out.println(map);
        System.out.println(i4);
        System.out.println(i5);
        System.out.println(i6);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;map-根据键获取值&#34;&gt;Map 根据键获取值&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.HashMap;

public class Demo2_Iterator {
    public static void main(String[] args) {
        HashMap&amp;lt;String, Integer&amp;gt; hashMap = new HashMap&amp;lt;&amp;gt;();

        hashMap.put(&amp;#34;a&amp;#34;, 100);
        hashMap.put(&amp;#34;b&amp;#34;,90);
        hashMap.put(&amp;#34;c&amp;#34;,98);

        for(String s:hashMap.keySet()){
            System.out.println(s + &amp;#34;=&amp;#34;+ hashMap.get(s));
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;map-的键值对-来获取map中的key-与-value&#34;&gt;Map 的键值对, 来获取Map中的Key 与 Value&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.HashMap;
import java.util.Map;

public class Demo3_Iterator {
    public static void main(String[] args) {
        HashMap&amp;lt;String, Integer&amp;gt; hashMap = new HashMap&amp;lt;&amp;gt;();

        hashMap.put(&amp;#34;a&amp;#34;, 90);
        hashMap.put(&amp;#34;b&amp;#34;,95);
        hashMap.put(&amp;#34;c&amp;#34;,98);

        for(Map.Entry&amp;lt;String,Integer&amp;gt; single: hashMap.entrySet()){
            System.out.println(single.getKey() + &amp;#34; &amp;#34;+ single.getValue());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;hashmap-存入student类和string时-重写-hashcode-和-equals方法&#34;&gt;HashMap 存入Student类和String时, 重写 hashCode 和 equals方法&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.Getter;
import lombok.Setter;

import java.util.Objects;

public class Student {
    public Student(){}
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Getter
    @Setter
    private String name;

    @Getter
    @Setter
    private int age;

    @Override
    public String toString() {
        return &amp;#34;Student &amp;#34;+this.name+this.age;
    }

    @Override public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public boolean equals(Object obj) {
        Student s = (Student) obj;
        return this.name == s.name &amp;amp;&amp;amp; this.age == s.age;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Student;

import java.util.HashMap;

public class Demo4_HashMap {
    public static void main(String[] args) {
        HashMap&amp;lt;Student, String&amp;gt; hashMap = new HashMap&amp;lt;&amp;gt;();
        hashMap.put(new Student(&amp;#34;小明&amp;#34;,23), &amp;#34;上海&amp;#34;);
        hashMap.put(new Student(&amp;#34;小明&amp;#34;,23), &amp;#34;北京&amp;#34;);
        hashMap.put(new Student(&amp;#34;小王&amp;#34;,26), &amp;#34;北京&amp;#34;);
        hashMap.put(new Student(&amp;#34;莱昂纳多&amp;#34;,28), &amp;#34;美国&amp;#34;);
        System.out.println(hashMap);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;linkedhashmap&#34;&gt;LinkedHashMap&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.LinkedHashMap;

public class Demo5_LinkedHashMap {
    public static void main(String[] args) {
        LinkedHashMap&amp;lt;String,Integer&amp;gt; linkedHashMap = new LinkedHashMap&amp;lt;&amp;gt;();
        linkedHashMap.put(&amp;#34;a&amp;#34;, 20);
        linkedHashMap.put(&amp;#34;b&amp;#34;, 20);
        linkedHashMap.put(&amp;#34;c&amp;#34;, 20);
        System.out.println(linkedHashMap);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;treemap-必须实现-comparable-接口-2种方式&#34;&gt;TreeMap 必须实现 Comparable 接口, 2种方式&lt;/h2&gt;
&lt;h3 id=&#34;方式一在bean类中实现comparable-接口&#34;&gt;方式一在bean类中实现Comparable 接口&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.Getter;
import lombok.Setter;

import java.util.Objects;

public class Student implements Comparable&amp;lt;Student&amp;gt;{
    public Student(){}
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Getter
    @Setter
    private String name;

    @Getter
    @Setter
    private int age;

    @Override
    public String toString() {
        return &amp;#34;Student &amp;#34;+this.name+this.age;
    }

    @Override public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public boolean equals(Object obj) {
        Student s = (Student) obj;
        return this.name == s.name &amp;amp;&amp;amp; this.age == s.age;
    }

    @Override
    public int compareTo(Student o) {
        int numName = this.name.compareTo(o.name);
        int numAge = numName == 0 ? this.age-o.age : numName;
        return numAge;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo6_TreeMap {
    public static void main(String[] args) {
//        Demo1();
        TreeMap&amp;lt;Student, String&amp;gt; treeMap = new TreeMap&amp;lt;&amp;gt;();
        treeMap.put(new Student(&amp;#34;ab&amp;#34;,23), &amp;#34;上海&amp;#34;);
        treeMap.put(new Student(&amp;#34;ab&amp;#34;,23), &amp;#34;北京&amp;#34;);
        treeMap.put(new Student(&amp;#34;ac&amp;#34;,26), &amp;#34;北京&amp;#34;);
        treeMap.put(new Student(&amp;#34;abc&amp;#34;,28), &amp;#34;美国&amp;#34;);

        System.out.println(treeMap);

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;方式二-在创建treemap时实现-comparator-接口&#34;&gt;方式二, 在创建TreeMap时实现 Comparator 接口&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public static void main(String[] args) {
    TreeMap&amp;lt;Student, String&amp;gt; treeMap = new TreeMap&amp;lt;&amp;gt;(new Comparator&amp;lt;Student&amp;gt;() {
        @Override
        public int compare(Student o1, Student o2) {
            int numName = o1.getName().compareTo(o2.getName());
            int numAge = numName == 0 ? o1.getAge()-o2.getAge() : numName;
            return numAge;
        }
    });
    treeMap.put(new Student(&amp;#34;ab&amp;#34;,23), &amp;#34;上海&amp;#34;);
    treeMap.put(new Student(&amp;#34;ab&amp;#34;,23), &amp;#34;北京&amp;#34;);
    treeMap.put(new Student(&amp;#34;ac&amp;#34;,26), &amp;#34;北京&amp;#34;);
    treeMap.put(new Student(&amp;#34;abc&amp;#34;,28), &amp;#34;美国&amp;#34;);

    System.out.println(treeMap);

}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-字符串-aaabbbccccfgkj-统计字母出现次数&#34;&gt;练习, 字符串 aaabbbccccfgkj 统计字母出现次数&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;字母在Map里Key 没有, 由存入key,1, 有则存key, value+1&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.HashMap;
import java.util.Map;

public class Demo7_HashMap {
    public static void main(String[] args) {
        HashMap&amp;lt;Character, Integer&amp;gt; hashMap = new HashMap&amp;lt;&amp;gt;();
        String str = &amp;#34;aaabbbbccccd&amp;#34;;
        char[] cArray = str.toCharArray();
        for(char c : cArray){
            if( ! hashMap.containsKey(c)){
                hashMap.put(c,1);
            } else {
                hashMap.put(c, hashMap.get(c)+1);
            }
        }
        for(Map.Entry&amp;lt;Character,Integer&amp;gt; ci:hashMap.entrySet()){
            System.out.println(ci.getKey() + &amp;#34;=&amp;#34; + ci.getValue() );
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-hashmap-嵌套-hashmap&#34;&gt;练习 HashMap 嵌套 HashMap&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.Getter;
import lombok.Setter;

import java.util.Objects;

public class Student implements Comparable&amp;lt;Student&amp;gt;{
    public Student(){}
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Getter
    @Setter
    private String name;

    @Getter
    @Setter
    private int age;

    @Override
    public String toString() {
        return &amp;#34;Student &amp;#34;+this.name+this.age;
    }

    @Override public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public boolean equals(Object obj) {
        Student s = (Student) obj;
        return this.name == s.name &amp;amp;&amp;amp; this.age == s.age;
    }
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Student;

import java.util.HashMap;
import java.util.Map;

public class Demo8_HashMapHashMap {
    public static void main(String[] args) {
        HashMap&amp;lt;Student, String&amp;gt; hashMap1 = new HashMap&amp;lt;&amp;gt;();
        hashMap1.put(new Student(&amp;#34;小明&amp;#34;,23), &amp;#34;上海&amp;#34;);
        hashMap1.put(new Student(&amp;#34;小王&amp;#34;,26), &amp;#34;北京&amp;#34;);
        hashMap1.put(new Student(&amp;#34;莱昂纳多&amp;#34;,28), &amp;#34;美国&amp;#34;);
        HashMap&amp;lt;Student, String&amp;gt; hashMap2 = new HashMap&amp;lt;&amp;gt;();
        hashMap2.put(new Student(&amp;#34;小明&amp;#34;,23), &amp;#34;上海&amp;#34;);
        hashMap2.put(new Student(&amp;#34;小王&amp;#34;,26), &amp;#34;北京&amp;#34;);
        hashMap2.put(new Student(&amp;#34;莱昂纳多&amp;#34;,29), &amp;#34;美国&amp;#34;);
        HashMap&amp;lt;HashMap&amp;lt;Student,String&amp;gt;,String &amp;gt; hashMap = new HashMap&amp;lt;&amp;gt;();
        hashMap.put(hashMap1,&amp;#34;班级1&amp;#34;);
        hashMap.put(hashMap2,&amp;#34;班级2&amp;#34;);
        for(Map.Entry&amp;lt;HashMap&amp;lt;Student,String&amp;gt;, String&amp;gt; HH : hashMap.entrySet()){
            for(Map.Entry&amp;lt;Student,String&amp;gt; HHS : HH.getKey().entrySet()){
                System.out.println(HHS.getKey() + HHS.getValue()+HH.getValue());
            }
        }
        System.out.println(hashMap);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;hashmap-和-hashtable-区别&#34;&gt;HashMap 和 Hashtable 区别&lt;/h2&gt;
&lt;h3 id=&#34;共同点&#34;&gt;共同点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;都是双链集合&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;区别&#34;&gt;区别&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HashMap 是线程不安全的, 效率高JDK 1.2 版本&lt;/li&gt;
&lt;li&gt;Hashtable 是线程安全的, 效率低, JDK 1.0 版本&lt;/li&gt;
&lt;li&gt;HashMap 可以存储null 键 和 null 值&lt;/li&gt;
&lt;li&gt;Hashtable 不可以存储null 键 及 null 值&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.HashMap;
import java.util.Hashtable;

public class Demo9_HashMapHashtable {
    public static void main(String[] args) {
        HashMap&amp;lt;String, Integer&amp;gt; hashMap = new HashMap&amp;lt;&amp;gt;();
        hashMap.put(null, 10);
        hashMap.put(&amp;#34;a&amp;#34;, null);
        System.out.println(hashMap);

        Hashtable&amp;lt;String, Integer&amp;gt; hashtable = new Hashtable&amp;lt;&amp;gt;();
        hashtable.put(null, 10);
        hashtable.put(&amp;#34;a&amp;#34;, null);
        System.out.println(hashtable);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;collections-中的方法&#34;&gt;Collections 中的方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;static &amp;lt;T extends Comparable&amp;lt;? super T&amp;raquo; void sort(List&lt;T&gt; list) 排序&lt;/li&gt;
&lt;li&gt;static &lt;T&gt; int binarySearch(List&amp;lt;? extends Comparable&amp;lt;? super T&amp;raquo; list, T key) 二分查找&lt;/li&gt;
&lt;li&gt;static &amp;lt;T extends Object &amp;amp; Comparable&amp;lt;? super T&amp;raquo; T max(Collection&amp;lt;? extends T&amp;gt; coll) 返回最大值&lt;/li&gt;
&lt;li&gt;static void reverse(List&lt;?&gt; list) 反转列表&lt;/li&gt;
&lt;li&gt;static void shuffle(List&lt;?&gt; list) list 序列洗牌&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private static void Demo5() {
    ArrayList&amp;lt;String&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
    arrayList.add(&amp;#34;d&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;b&amp;#34;);
    arrayList.add(&amp;#34;c&amp;#34;);
    arrayList.add(&amp;#34;f&amp;#34;);
    System.out.println(arrayList);
    Collections.shuffle(arrayList);
    System.out.println(arrayList);
}

private static void Demo4() {
    ArrayList&amp;lt;String&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
    arrayList.add(&amp;#34;d&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;b&amp;#34;);
    arrayList.add(&amp;#34;c&amp;#34;);
    arrayList.add(&amp;#34;f&amp;#34;);
    System.out.println(arrayList);
    Collections.reverse(arrayList);
    System.out.println(arrayList);
}

private static void Demo3() {
    ArrayList&amp;lt;String&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
    arrayList.add(&amp;#34;d&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;b&amp;#34;);
    arrayList.add(&amp;#34;c&amp;#34;);
    arrayList.add(&amp;#34;f&amp;#34;);
    String max = Collections.max(arrayList);
    System.out.println(max);
}

private static void Demo2() {
    ArrayList&amp;lt;String&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
    arrayList.add(&amp;#34;d&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;b&amp;#34;);
    arrayList.add(&amp;#34;c&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    Collections.sort(arrayList);
    System.out.println(arrayList);
    int index = Collections.binarySearch(arrayList, &amp;#34;b&amp;#34;);
    System.out.println(index);
    System.out.println(Collections.binarySearch(arrayList,&amp;#34;o&amp;#34;));
}

private static void Demo1() {
    ArrayList&amp;lt;String&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
    arrayList.add(&amp;#34;d&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    arrayList.add(&amp;#34;b&amp;#34;);
    arrayList.add(&amp;#34;c&amp;#34;);
    arrayList.add(&amp;#34;a&amp;#34;);
    System.out.println(arrayList);
    Collections.sort(arrayList);
    System.out.println(arrayList);
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-54-张牌-每人17张-剩下3张-打印每个人牌和底牌&#34;&gt;练习, 54 张牌, 每人17张, 剩下3张, 打印每个人牌和底牌&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class Demo2_Collections {
    public static void main(String[] args) {
        String[] nu = {&amp;#34;2&amp;#34;, &amp;#34;3&amp;#34;, &amp;#34;4&amp;#34;, &amp;#34;5&amp;#34;, &amp;#34;6&amp;#34;, &amp;#34;7&amp;#34;, &amp;#34;8&amp;#34;, &amp;#34;9&amp;#34;, &amp;#34;10&amp;#34;, &amp;#34;J&amp;#34;, &amp;#34;Q&amp;#34;, &amp;#34;K&amp;#34;, &amp;#34;A&amp;#34;};
        String[] color = { &amp;#34;♠️&amp;#34;,  &amp;#34;♥️&amp;#34;, &amp;#34;♦️&amp;#34;,  &amp;#34;♣️&amp;#34;};
        ArrayList&amp;lt;String&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        for(String nuStr : nu){
            for(String  colorStr : color){
                arrayList.add(nuStr + colorStr);
            }
        }
        arrayList.add(&amp;#34;Big King&amp;#34;);
        arrayList.add(&amp;#34;Small King&amp;#34;);
        for(int i=0;i&amp;lt;3;i++){
            Collections.shuffle(arrayList);
        }
        System.out.println(arrayList);
        ArrayList&amp;lt;String&amp;gt; list1 = new ArrayList&amp;lt;&amp;gt;();
        ArrayList&amp;lt;String&amp;gt; list2 = new ArrayList&amp;lt;&amp;gt;();
        ArrayList&amp;lt;String&amp;gt; list3 = new ArrayList&amp;lt;&amp;gt;();
        ArrayList&amp;lt;String&amp;gt; list4 = new ArrayList&amp;lt;&amp;gt;();
        Scanner sc = new Scanner(System.in);
        for(int i=0;i&amp;lt;53;i++){
            if(i &amp;gt;= 50 ){
                list4.add(arrayList.get(i));
            }
            else if( i % 3 == 0){
                list1.add(arrayList.get(i));
            } else if( i % 3 == 1) {
                list2.add(arrayList.get(i));
            } else if( i % 3 ==2 ){
                list3.add(arrayList.get(i));
            }
        }
        System.out.println(list4);
        System.out.println(list1);
        System.out.println(list2);
        System.out.println(list3);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习使用-hashmap-模拟一副牌&#34;&gt;练习使用 HashMap 模拟一副牌&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;用HashMap 的 Key 生成arraylist来洗牌&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeMap;

public class Demo3_Collections {
    public static void main(String[] args) {
        HashMap&amp;lt;Integer, String&amp;gt; poker = new HashMap&amp;lt;&amp;gt;();
        String[] nu = { &amp;#34;3&amp;#34;, &amp;#34;4&amp;#34;, &amp;#34;5&amp;#34;, &amp;#34;6&amp;#34;, &amp;#34;7&amp;#34;, &amp;#34;8&amp;#34;, &amp;#34;9&amp;#34;, &amp;#34;10&amp;#34;, &amp;#34;J&amp;#34;, &amp;#34;Q&amp;#34;, &amp;#34;K&amp;#34;, &amp;#34;A&amp;#34;,&amp;#34;2&amp;#34;};
        String[] color = { &amp;#34;♠️&amp;#34;,  &amp;#34;♥️&amp;#34;, &amp;#34;♦️&amp;#34;,  &amp;#34;♣️&amp;#34;};
        int count = 0;
        ArrayList&amp;lt;Integer&amp;gt; pokerIndex = new ArrayList&amp;lt;&amp;gt;();
        for(String nuStr : nu){
            for(String  colorStr : color){
                poker.put(count, (colorStr + nuStr));
                pokerIndex.add(count);
                count++;
            }
        }
        poker.put(count, &amp;#34;Small King&amp;#34;);
        pokerIndex.add(count);
        count++;
        poker.put(count, &amp;#34;Big King&amp;#34;);
        pokerIndex.add(count);

        TreeMap&amp;lt;Integer, String&amp;gt; gaojin = new TreeMap&amp;lt;&amp;gt;();
        TreeMap&amp;lt;Integer, String&amp;gt; jp = new TreeMap&amp;lt;&amp;gt;();
        TreeMap&amp;lt;Integer, String&amp;gt; tiger = new TreeMap&amp;lt;&amp;gt;();
        TreeMap&amp;lt;Integer, String&amp;gt; dipai = new TreeMap&amp;lt;&amp;gt;();

        System.out.println(pokerIndex.size());
        Collections.shuffle(pokerIndex);
        System.out.println(pokerIndex);

        for(int i=0;i&amp;lt; pokerIndex.size(); i++){
            int index = pokerIndex.get(i);
            if(i &amp;gt; 50){
                dipai.put( index  , poker.get( index));
            } else if ( i % 3 == 0){
                gaojin.put( index, poker.get(index ));
            } else if (i % 3 == 1){
                jp.put( index , poker.get( index ));
            } else if (i % 3 == 2){
                tiger.put( index, poker.get( index ));
            }
        }
        System.out.println(gaojin);
        System.out.println(jp);
        System.out.println(tiger);
        System.out.println(dipai);

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;-super-e-情况&#34;&gt;? Super E 情况&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;TreeSet TreeMap 会调用&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.Getter;
import lombok.Setter;

import java.util.Objects;

public class Student implements Comparable&amp;lt;Student&amp;gt;{
    public Student(){}
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Getter
    @Setter
    private String name;

    @Getter
    @Setter
    private int age;

    @Override
    public String toString() {
        return &amp;#34;Student &amp;#34;+this.name+this.age;
    }

    @Override public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public boolean equals(Object obj) {
        Student s = (Student) obj;
        return this.name == s.name &amp;amp;&amp;amp; this.age == s.age;
    }

    @Override
    public int compareTo(Student o) {
        int numName = this.name.compareTo(o.name);
        int numAge = numName == 0 ? this.age-o.age : numName;
        return numAge;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class BaseStudent extends Student{
    public BaseStudent(){}
    public BaseStudent(String name, int age){
        super(name, age);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.BaseStudent;
import com.lizicai.bean.Student;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;

public class Demo4_Generic {
    public static void main(String[] args) {
//        Demo1();
        TreeSet&amp;lt;Student&amp;gt; treeSet = new TreeSet&amp;lt;&amp;gt;(new CompareByAge());
        treeSet.add(new Student(&amp;#34;小明&amp;#34;,22));
        treeSet.add(new Student(&amp;#34;小红&amp;#34;,22));
        treeSet.add(new Student(&amp;#34;小王&amp;#34;,22));
        System.out.println(treeSet);


        TreeSet&amp;lt;BaseStudent&amp;gt; treeSet2 = new TreeSet&amp;lt;&amp;gt;(new CompareByAge());
        treeSet2.add(new BaseStudent(&amp;#34;小明&amp;#34;,22));
        treeSet2.add(new BaseStudent(&amp;#34;小红&amp;#34;,22));
        treeSet2.add(new BaseStudent(&amp;#34;小王&amp;#34;,22));
        System.out.println(treeSet2);

    }

    private static void Demo1() {
        ArrayList&amp;lt;Student&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        arrayList.add(new Student(&amp;#34;小明&amp;#34;,22));
        arrayList.add(new Student(&amp;#34;小红&amp;#34;,22));
        arrayList.add(new Student(&amp;#34;小王&amp;#34;,22));

        ArrayList&amp;lt;BaseStudent&amp;gt; arrayList2 = new ArrayList&amp;lt;&amp;gt;();
        arrayList2.add(new BaseStudent(&amp;#34;小明&amp;#34;,22));
        arrayList2.add(new BaseStudent(&amp;#34;小红&amp;#34;,22));
        arrayList2.add(new BaseStudent(&amp;#34;小王&amp;#34;,22));

        arrayList.addAll(arrayList2);
        System.out.println(arrayList);
    }
}

class CompareByAge implements Comparator&amp;lt;Student&amp;gt; {
    @Override
    public int compare(Student o1, Student o2) {
        int num = o1.getAge() - o2.getAge();
        int numName = num == 0 ? o1.getName().compareTo(o2.getName()): num;
        return numName;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;collection&#34;&gt;Collection&lt;/h2&gt;
&lt;h3 id=&#34;list-存取有序-有索引-可重复&#34;&gt;List 存取有序, 有索引, 可重复&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ArrayList
&lt;ul&gt;
&lt;li&gt;底层数组实现的, 线程不安全, 查找修改快, 增删慢&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LinkedList
&lt;ul&gt;
&lt;li&gt;底层是链表实现的, 线程不安全, 查找慢, 增删快&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vetor
&lt;ul&gt;
&lt;li&gt;底层数组实现的, 线程安全, 查找修改增删都慢&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;如果查找修改多用ArrayList, 增和删多用LinkedList, 如果都多用ArrayList&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;set-存取无序-无索引-不可重复&#34;&gt;Set 存取无序, 无索引, 不可重复&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HashSet
&lt;ul&gt;
&lt;li&gt;底层哈希算法实现的&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LinkedHashSet
&lt;ul&gt;
&lt;li&gt;底层是链表, 但是也可以保证元素唯一, 和HashSet 原理一样&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TreeSet
&lt;ul&gt;
&lt;li&gt;底层是二叉树实现&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;开发的时候不需要对存储的元素排序, 大多用HashSet&lt;/strong&gt;
&lt;strong&gt;TreeSet 比较的2种方式要记住&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;map-存取&#34;&gt;Map 存取&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HashMap 底层哈希算法, 针对键的
&lt;ul&gt;
&lt;li&gt;LinkedHashMap 底层是链表&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TreeMap 底层是二叉树实现&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;双链集合优先考虑TreeMap&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Java的Set类 Li.038</title>
      <link>https://lizicai.com/p/java%E7%9A%84set%E7%B1%BB-li.038/</link>
      <pubDate>Sun, 22 Aug 2021 23:35:31 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84set%E7%B1%BB-li.038/</guid>
      <description>&lt;h2 id=&#34;set&#34;&gt;Set&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;无序&lt;/li&gt;
&lt;li&gt;不可重复&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.HashSet;

public class Demo1_HashSet {
    public static void main(String[] args) {
        HashSet&amp;lt;String&amp;gt; hs = new HashSet&amp;lt;&amp;gt;();

        boolean b1 = hs.add(&amp;#34;a&amp;#34;);
        boolean b2 = hs.add(&amp;#34;a&amp;#34;);
        System.out.println(hs);
        System.out.println(b1+&amp;#34;  &amp;#34;+b2);
        for(String s:hs){
            System.out.println(s);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;hashset-的重写hashcode-方法-hashcode值一致时-调用equals方法&#34;&gt;HashSet 的重写hashCode() 方法, hashCode值一致时, 调用equals方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用HashSet 存取元素时, 这个元素必须重写 hashCode 和 equals方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.Getter;
import lombok.Setter;

import java.util.Objects;

public class Person {
    public Person(){}
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Getter
    @Setter
    private String name;
    @Getter
    @Setter
    private int age;


    @Override
    public String toString(){
        return &amp;#34;Person&amp;#34; + this.getName() + this.getAge();
    }

    @Override
    public boolean equals(Object obj) {
        Person p = (Person) obj;
        return this.getName() == p.getName() &amp;amp;&amp;amp; this.getAge() == p.getAge();
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public static int hashCode(Object a[]) {
    if (a == null)
        return 0;

    int result = 1;

    for (Object element : a)
        result = 31 * result + (element == null ? 0 : element.hashCode());

    return result;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;linkedhashset&#34;&gt;LinkedHashSet&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;底层链表实现的&lt;/li&gt;
&lt;li&gt;是Set对象中唯一一个保证怎么存就怎么取的集合对象&lt;/li&gt;
&lt;li&gt;HashSet的子类, 也是保证元素是唯一的&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.LinkedHashSet;

public class Demo1_LinkedHashSet {
    public static void main(String[] args) {
        LinkedHashSet &amp;lt;String&amp;gt; linkedHashSet = new LinkedHashSet&amp;lt;&amp;gt;();

        linkedHashSet.add(&amp;#34;a&amp;#34;);
        linkedHashSet.add(&amp;#34;a&amp;#34;);
        linkedHashSet.add(&amp;#34;b&amp;#34;);
        linkedHashSet.add(&amp;#34;b&amp;#34;);
        linkedHashSet.add(&amp;#34;b&amp;#34;);
        linkedHashSet.add(&amp;#34;c&amp;#34;);

        System.out.println(linkedHashSet);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;hashset-练习-放入集合10个120的整数&#34;&gt;HashSet 练习, 放入集合10个[1,20]的整数&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.HashSet;
import java.util.Random;

public class Demo1_Test {
    public static void main(String[] args) {
        Random r = new Random();
        HashSet &amp;lt;Integer&amp;gt; hashSet = new HashSet&amp;lt;&amp;gt;();

        while(hashSet.size() &amp;lt; 10 ){
            Integer i = r.nextInt(20) + 1;
            hashSet.add(i);
        }
        System.out.println(hashSet);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;hashset-练习-输入一串字符串-去掉重复字符&#34;&gt;HashSet 练习, 输入一串字符串, 去掉重复字符&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.HashSet;
import java.util.Scanner;

public class Demo2_Test {
    public static void main(String[] args) {
        HashSet&amp;lt;Character&amp;gt; hs = new HashSet&amp;lt;&amp;gt;();
        Scanner sc = new Scanner(System.in);
        String s = null;
        if(sc.hasNext()){
            s = sc.nextLine();
        }
        char[] charArray= s.toCharArray();

//        for(Character c:charArray){
        for(char c:charArray){
            hs.add(c);
        }
        System.out.println(hs);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;hashset-练习-list-去重-并返回元素list&#34;&gt;HashSet 练习, list 去重, 并返回元素list&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;

public class Demo3_Test {
    public static void main(String[] args) {
        List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        list.add(&amp;#34;a&amp;#34;);
        list.add(&amp;#34;b&amp;#34;);
        list.add(&amp;#34;b&amp;#34;);
        list.add(&amp;#34;c&amp;#34;);
        list.add(&amp;#34;c&amp;#34;);
        list.add(&amp;#34;c&amp;#34;);

        HashSet &amp;lt;String&amp;gt; hs = new LinkedHashSet&amp;lt;&amp;gt;();
//        deleteCopyElement(list, hs);
        deleteCopyE(list);
//        System.out.println(hs);
        System.out.println(list);
    }
    public static void deleteCopyElement(List&amp;lt;String&amp;gt; list, HashSet&amp;lt;String&amp;gt; hashSet){
        hashSet.addAll(list);
        list.clear();
        list.addAll(hashSet);
    }
    public static void deleteCopyE(List&amp;lt;String&amp;gt; list){
        LinkedHashSet&amp;lt;String&amp;gt; hs = new LinkedHashSet&amp;lt;&amp;gt;();
        hs.addAll(list);
        list.clear();
        list.addAll(hs);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;treeset-集合-对集合进行排序的-元素唯一&#34;&gt;TreeSet 集合, 对集合进行排序的, 元素唯一&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;保证元素唯一&lt;/li&gt;
&lt;li&gt;集合排序&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.TreeSet;

public class Demo1_TreeSet {
    public static void main(String[] args) {
        TreeSet &amp;lt;Integer&amp;gt; ts = new TreeSet&amp;lt;&amp;gt;();

        ts.add(1);
        ts.add(1);
        ts.add(2);
        ts.add(2);
        ts.add(3);
        ts.add(3);
        System.out.println(ts);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;treeset--类实现comparable接口&#34;&gt;TreeSet , 类实现Comparable&lt;T&gt;接口&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;compareTo 方法返回0, 则集合中只用一个元素&lt;/li&gt;
&lt;li&gt;compareTo 方法返回正数, 集合怎么存怎么取&lt;/li&gt;
&lt;li&gt;compareTo 方法返回负数, 集合倒序存储&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.Getter;
import lombok.Setter;

import java.util.Objects;

public class Person implements Comparable &amp;lt;Person&amp;gt;{
    public Person(){}
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Getter
    @Setter
    private String name;
    @Getter
    @Setter
    private int age;


    @Override
    public String toString(){
        return &amp;#34;Person&amp;#34; + this.getName() + this.getAge();
    }



    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Person)) {
            return false;
        }
        Person person = (Person) o;
        return getAge() == person.getAge() &amp;amp;&amp;amp; Objects.equals(getName(), person.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public int compareTo(Person p) {
        int num = this.age - p.age;
        return num == 0 ? this.name.compareTo(p.name) : num;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_TreeSet {
    public static void main(String[] args) {
        TreeSet&amp;lt;Person&amp;gt; ts = new TreeSet&amp;lt;&amp;gt;();
        ts.add(new Person(&amp;#34;小明&amp;#34;, 20));
        ts.add(new Person(&amp;#34;小红&amp;#34;, 19));
        ts.add(new Person(&amp;#34;小张&amp;#34;, 21));
        ts.add(new Person(&amp;#34;小张&amp;#34;, 21));

        System.out.println(ts);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;treeset-如果使用person-的name排序-则需要实现compareable-接口-compareto方法&#34;&gt;TreeSet 如果使用Person 的name排序, 则需要实现Compareable&lt;T&gt; 接口, compareTo方法&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Override
public int compareTo(Person p) {
    int num = this.name.compareTo(p.name);
    return num == 0 ? this.age-p.age : num;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_TreeSet {
    public static void main(String[] args) {
        TreeSet&amp;lt;Person&amp;gt; ts = new TreeSet&amp;lt;&amp;gt;();
        ts.add(new Person(&amp;#34;a&amp;#34;, 20));
        ts.add(new Person(&amp;#34;a&amp;#34;, 19));
        ts.add(new Person(&amp;#34;ab&amp;#34;, 19));
        ts.add(new Person(&amp;#34;ba&amp;#34;, 21));
        ts.add(new Person(&amp;#34;ca&amp;#34;, 21));

        System.out.println(ts);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;treeset-使用person-的name长度比较&#34;&gt;TreeSet 使用Person 的name长度比较&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Override
public int compareTo(Person p){
    int length = this.name.length()- p.name.length();
    int num = length == 0 ? this.name.compareTo(p.name) : length;
    return num == 0 ? this.age - p.age : num;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;treeset-实现comparator接口-在创建treeset时调用&#34;&gt;TreeSet 实现Comparator接口, 在创建TreeSet时调用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自动定义String 长度作为比较&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class Compare implements Comparator&amp;lt;String&amp;gt;{
    @Override
    public int compare(String o1, String o2) {
        int length = o1.length() - o2.length();
        int num =  length == 0 ? o1.compareTo(o2) : length;
        return num;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_TreeSet {
    public static void main(String[] args) {
        TreeSet&amp;lt;String&amp;gt; ts = new TreeSet&amp;lt;&amp;gt;(new Compare());
        ts.add(&amp;#34;asdfsdf&amp;#34;);
        ts.add(&amp;#34;z&amp;#34;);
        System.out.println(ts);
    }

}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-arraylist-重复无序的数据-如何按字典排序-且不可去除重复数据&#34;&gt;练习, ArrayList 重复无序的数据, 如何按字典排序, 且不可去除重复数据&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;

public class Demo5_TreeSet {
    public static void main(String[] args) {
        ArrayList&amp;lt;String&amp;gt; aList = new ArrayList&amp;lt;&amp;gt;();
        aList.add(&amp;#34;aaa&amp;#34;);
        aList.add(&amp;#34;aaa&amp;#34;);
        aList.add(&amp;#34;aaa&amp;#34;);
        aList.add(&amp;#34;bbb&amp;#34;);
        aList.add(&amp;#34;bbb&amp;#34;);
        aList.add(&amp;#34;bbb&amp;#34;);
        aList.add(&amp;#34;bbb&amp;#34;);
        aList.add(&amp;#34;aaa&amp;#34;);
        aList.add(&amp;#34;aaa&amp;#34;);
        aList.add(&amp;#34;zzz&amp;#34;);
        aList.add(&amp;#34;zzz&amp;#34;);
        aList.add(&amp;#34;zzz&amp;#34;);
        sortArrayList(aList);
        System.out.println(aList);

    }
    public static void sortArrayList(ArrayList&amp;lt;String&amp;gt; list){
       // 实际Comparator
       // list添加到tree(new comparator)中
       // 清空list
       // list.addAll(TreeSet)
        TreeSet&amp;lt;String&amp;gt; ts = new TreeSet&amp;lt;&amp;gt;(new StrComparator());
        ts.addAll(list);
        list.clear();
        list.addAll(ts);
    }
}
class StrComparator implements Comparator&amp;lt;String&amp;gt; {
    @Override
    public int compare(String o1, String o2) {
        int num = o1.compareTo(o2);
        if(0 == num){
            num ++;
        }
        return num;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-输入字符hello-输出ehllo&#34;&gt;练习, 输入字符hello 输出ehllo&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class Demo6_TreeSet {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = null;
        if(sc.hasNext()){
            s = sc.nextLine();
        }
        char[] chaArray = s.toCharArray();
//        Arrays.sort(chaArray);
//        System.out.println(chaArray);
        TreeSet&amp;lt;Character&amp;gt; ts = new TreeSet&amp;lt;&amp;gt;(new Comparator&amp;lt;Character&amp;gt;() {
            @Override
            public int compare(Character o1, Character o2) {
                int num = o1.compareTo(o2);
                return num == 0? 1 :num;
            }
        });
        for(Character c:chaArray){
            ts.add(c);
        }
        for(Character c:ts){
            System.out.print(c);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-输入数字并倒序&#34;&gt;练习, 输入数字并倒序&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;输入quit 退出&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class Demo7_TreeSet {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        TreeSet&amp;lt;Integer&amp;gt; ts = new TreeSet&amp;lt;&amp;gt;(new Comparator&amp;lt;Integer&amp;gt;() {
            @Override
            public int compare(Integer o1, Integer o2) {
                int num = o2.compareTo(o1);
                return num == 0 ? 1 :num ;
            }
        });
        while (sc.hasNext()){
            String s = sc.next();
            if( &amp;#34;quit&amp;#34;.equals(s)){
                break;
            } else{
                ts.add(Integer.parseInt(s));
            }
        }
        for(Integer i:ts){
            System.out.print(i+&amp;#34; &amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习&#34;&gt;练习&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩) 按总成绩从高到低输入到控制台&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@AllArgsConstructor
@NoArgsConstructor
public class Student implements Comparable&amp;lt;Student&amp;gt;{
    @Getter
    @Setter
    private String name;
    @Getter
    @Setter
    private int motherTongue;
    @Getter
    @Setter
    private int math;
    @Getter
    @Setter
    private int english;

    @Override
    public int compareTo(Student o) {
        int num =  (o.motherTongue + o.math + o.english) - (this.motherTongue + this.math + this.english);
        int num2 = num == 0 ? o.motherTongue - this.motherTongue : num;
        int num3 = num2 == 0 ? o.math - this.math : num2;
        int num4 = num3 == 0 ? o.english - this.english : num3;
        int num5 = num4 == 0 ? o.name.compareTo(this.name) : num4 ;
        if (0 == num5){
            num5 = -1;
        }
        return num5;
    }

    @Override
    public String toString() {
        return &amp;#34;Student.&amp;#34;+this.name +&amp;#34;.语文&amp;#34;+this.motherTongue+&amp;#34;.数学&amp;#34;+this.math+&amp;#34;.英语&amp;#34; + this.english;

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Student;

import java.util.Scanner;
import java.util.TreeSet;

public class Demo8_TreeSet {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        TreeSet&amp;lt;Student&amp;gt; ts = new TreeSet&amp;lt;&amp;gt;();
        for(int i=0; i&amp;lt;5;i++){
            String str = null;
            if(sc.hasNext()){
                str = sc.nextLine();
            }
            String[] strArray = str.split(&amp;#34;,&amp;#34;);
            ts.add(new Student(strArray[0],
                    Integer.parseInt(strArray[1]),
                    Integer.parseInt(strArray[2]),
                    Integer.parseInt(strArray[3])));
        }
        System.out.println(ts);
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的List类 Li.037</title>
      <link>https://lizicai.com/p/java%E7%9A%84list%E7%B1%BB-li.037/</link>
      <pubDate>Fri, 20 Aug 2021 17:17:58 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84list%E7%B1%BB-li.037/</guid>
      <description>&lt;h2 id=&#34;list-练习person-集合去重&#34;&gt;List 练习Person 集合去重&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String name;
    private int age;

    @Override
    public boolean equals(Object obj) {
        Person p = (Person) obj;
        boolean d = false;
        if(this.getAge() == p.getAge() &amp;amp;&amp;amp; this.getName() == p.getName()){
            d = true;
        } else{
            d = false;
        }
        return d;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Demo2_ArrayList {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(new Person(&amp;#34;小明&amp;#34;, 23));
        list.add(new Person(&amp;#34;小明&amp;#34;, 23));
        list.add(new Person(&amp;#34;小红&amp;#34;, 22));
        list.add(new Person(&amp;#34;小王&amp;#34;, 25));

        List list2 = new ArrayList();
        deleteMu(list, list2);
        System.out.println(list2);

    }
    public static void deleteMu(List srcList, List destList){
        Iterator iTsrc = srcList.iterator();
        while (iTsrc.hasNext()){
            Person p = (Person) iTsrc.next();
            if( !destList.contains(p) ){

                destList.add(p);
            }
        }
        return ;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;linkedlist-方法&#34;&gt;LinkedList 方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;void addFirst(E e) void addLast(E e) 在头增加 或 在尾增加&lt;/li&gt;
&lt;li&gt;public E getFirst() public E getLast() 获取第1个 或 最后1个&lt;/li&gt;
&lt;li&gt;public E removeFirst() public E removeLast()  删除第1个或最后1个&lt;/li&gt;
&lt;li&gt;public E get(int index) 获取指定位置的元素&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.LinkedList;

public class Demo1_LinkedList {
    public static void main(String[] args) {
        LinkedList ll = new LinkedList();
        ll.add(&amp;#34;a&amp;#34;);
        ll.add(&amp;#34;b&amp;#34;);
        ll.add(&amp;#34;c&amp;#34;);
        ll.add(&amp;#34;d&amp;#34;);

        ll.addFirst(0);
        ll.addLast(10);
        System.out.println(ll);

        System.out.println(ll.getFirst());
        System.out.println(ll.getLast());

        ll.removeFirst();
        System.out.println(ll);
        ll.removeLast();
        System.out.println(ll);

        System.out.println(ll.get(0));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;linkedlist-模拟栈&#34;&gt;LinkedList 模拟栈&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import lombok.Data;

import java.util.LinkedList;

@Data
public class Stank {
    private LinkedList ll = new LinkedList();

    public  void in(Object obj){
        ll.addLast(obj);
    }
    public void out(){
        ll.removeLast();
    }
    public void outAll(){
        while (! ll.isEmpty()){
            ll.removeLast();
        }
    }
    public boolean isEmpty(){
        if(ll.isEmpty()){
            return true;
        }
        return false;
    }
}


import com.lizicai.bean.Stank;

public class Demo3_LinkedList {
    public static void main(String[] args) {
        Stank s = new Stank();
        s.in(&amp;#34;a&amp;#34;);
        s.in(&amp;#34;b&amp;#34;);
        s.in(&amp;#34;c&amp;#34;);
        s.out();
        System.out.println(s.getLl());
        s.outAll();
        System.out.println(s.getLl());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;泛型-generic&#34;&gt;泛型 generic&lt;/h2&gt;
&lt;h3 id=&#34;泛型的好处&#34;&gt;泛型的好处&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;提高安全性, 把运行的错误转移到编译时校验&lt;/li&gt;
&lt;li&gt;省去强转的麻烦&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;前后泛型一致, 或者后面泛型是前端泛型的子类&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Generic {
    public static void main(String[] args) {
        ArrayList &amp;lt;Person&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        list.add(new Person(&amp;#34;小红&amp;#34;, 23));
        list.add(new Person(&amp;#34;小明&amp;#34;, 23));

        ListIterator &amp;lt;Person&amp;gt; it = list.listIterator();
        while ( it.hasNext()){
            Person p = it.next();
            System.out.println(p.getName() + p.getAge());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;类的泛型&#34;&gt;类的泛型&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在类首行指定处理的引用数据类型&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class SePersion &amp;lt;E&amp;gt;{
    private E e;

    public E getP() {
        return e;
    }

    public void setP(E p) {
        this.e = p;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
import com.lizicai.bean.Person;
import com.lizicai.bean.SePersion;

public class Demo3_Generic {

    public static void main(String[] args) {
        SePersion&amp;lt;Person&amp;gt; s = new SePersion();
//        s.setP(&amp;#34;kdfj&amp;#34;);
        s.setP(new Person(&amp;#34;小明&amp;#34;, 23));
        System.out.println(s.getP());

        SePersion d = new SePersion();
        d.setP(&amp;#34;dk&amp;#34;);
        d.setP(new Person());
        System.out.println(d.getP());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;方法泛型&#34;&gt;方法泛型&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;方法泛型和类的泛型一至&lt;/li&gt;
&lt;li&gt;也可以不一致, 在使用方法时指定泛型&lt;/li&gt;
&lt;li&gt;静态方法必须申明自己的泛型&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class SePersion &amp;lt;E&amp;gt;{
    private E e;

    public E getP() {
        return e;
    }

    public void setP(E e) {
        this.e = e;
    }
    public &amp;lt;T&amp;gt; void show(T t){
        System.out.println(t);
    }
    public static&amp;lt;Q&amp;gt; void print(Q q){
        System.out.println(q);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;泛型高级之通配符&#34;&gt;泛型高级之通配符&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;泛型通配符&lt;?&gt;, 如果没有明确, 那么就是Object 及任意Java类&lt;/li&gt;
&lt;li&gt;? extends E  ?是E的子类, 向下限定&lt;strong&gt;示例是这个&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;? super E  ? 是E的父类, 向下限定&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Person {
    private String name;
    private int age;
    public  Person(){}
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        Person p = (Person) obj;
        boolean d = false;
        if(this.getAge() == p.getAge() &amp;amp;&amp;amp; this.getName() == p.getName()){
            d = true;
        } else{
            d = false;
        }
        return d;
    }
    @Override
    public String toString(){
        return this.getName() + this.getAge();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Student extends Person{
    private String name;
    private int age;
    public Student(){ }
    public Student(String name, int age){
        super(name,age);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo5_Generic {
    public static void main(String[] args) {
        ArrayList &amp;lt;Person&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        arrayList.add(new Person(&amp;#34;小明&amp;#34;, 23));
        arrayList.add(new Person(&amp;#34;小红&amp;#34;, 22));

        ArrayList &amp;lt;Student&amp;gt; arrayList2 = new ArrayList&amp;lt;&amp;gt;();
        arrayList2.add(new Student(&amp;#34;小张&amp;#34;, 25));
        arrayList2.add(new Student(&amp;#34;小美&amp;#34;, 26));

        arrayList.addAll(arrayList2);

        System.out.println(arrayList);

        Person p = new Student(&amp;#34;test&amp;#34;,20);
        System.out.println(p.toString());

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;增加for循环&#34;&gt;增加for循环&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;底层依赖 iterator 迭代器&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Person;

import java.util.ArrayList;

public class Demo6_Generic {
    public static void main(String[] args) {
        ArrayList &amp;lt;Person&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        arrayList.add(new Person(&amp;#34;小红&amp;#34;, 22));
        arrayList.add(new Person(&amp;#34;小明&amp;#34;, 23));
        arrayList.add(new Person(&amp;#34;小张&amp;#34;, 25));

        for(Person p:arrayList){
            System.out.println(p);
        }

        int [] arr = {1, 2, 3 ,4, 5};
        for(int i:arr){
            System.out.print(i);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;三种迭代&#34;&gt;三种迭代&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;普通for循环, 可以删除, 索引-1&lt;/li&gt;
&lt;li&gt;迭代器, 可以删除, 必须使用迭代器中的remove() 方法, 否则出现并发修改异常&lt;/li&gt;
&lt;li&gt;增加for循环, 不可删除&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.ListIterator;

public class Demo7_Generic {
    public static void main(String[] args) {
        ArrayList &amp;lt;String&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        arrayList.add(&amp;#34;a&amp;#34;);
        arrayList.add(&amp;#34;b&amp;#34;);
        arrayList.add(&amp;#34;b&amp;#34;);
        arrayList.add(&amp;#34;c&amp;#34;);
        for (int i = 0; i &amp;lt; arrayList.size(); i++) {
            if(&amp;#34;b&amp;#34;.equals(arrayList.get(i))){
                arrayList.remove(i);
                i--;
            }
        }

        ArrayList&amp;lt;String&amp;gt; arrayList2 = new ArrayList&amp;lt;&amp;gt;();
        arrayList2.add(&amp;#34;a&amp;#34;);
        arrayList2.add(&amp;#34;b&amp;#34;);
        arrayList2.add(&amp;#34;b&amp;#34;);
        arrayList2.add(&amp;#34;c&amp;#34;);
        ListIterator&amp;lt;String &amp;gt; it = arrayList2.listIterator();
        while (it.hasNext()){
            if( &amp;#34;b&amp;#34;.equals(it.next())){
//                arrayList2.remove(&amp;#34;b&amp;#34;);
                it.remove();
            }
        }
        System.out.println(arrayList);

        System.out.println(arrayList2);

        for (ListIterator&amp;lt;String&amp;gt; it2 = arrayList2.listIterator(); it2.hasNext();){

            System.out.println(it2.next());
        }

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;静态导入-一般不用&#34;&gt;静态导入, 一般不用&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Arrays.sort
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;可变参数&#34;&gt;可变参数&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;定义的时候不知道定义多少个&lt;/li&gt;
&lt;li&gt;可变参数其实是一个数组&lt;/li&gt;
&lt;li&gt;如果一个方法有多个参数, 可变参数必须是最后一个&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_ChangeableArgs {
    public static void main(String[] args) {
       int[] arr = {5, 2, 3, 4, 5};
//       print(arr);
//       print(1,2,3,4,5,6);

//        for(int i=0;i&amp;lt;arr.length;i++){
//            System.out.println(arr[i]);
//        }
        pp(arr);

    }
//    public static void print(int[] arr){
//        for(int i=0;i&amp;lt;arr.length;i++){
//            System.out.println(arr[i]);
//        }
//    }

    public static void print(int ... arr){
        for(int i=0;i&amp;lt;arr.length;i++){
            System.out.println(arr[i]);
        }
    }

    public static void pp(int [] arr){
        for(int i:arr){
            System.out.println(arr[i]);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;数组转集合&#34;&gt;数组转集合&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;基本数据类型数组转成集合, 只会把数组的地址作为元素转到集合中&lt;/li&gt;
&lt;li&gt;要想基本数据转成集合, 必须是引用类型 int -&amp;gt; Integer boolean Boolean&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Arrays;
import java.util.List;
public class Demo8_Generic {
    public static void main(String[] args) {
        String [] arr = {&amp;#34;a&amp;#34;, &amp;#34;b&amp;#34;, &amp;#34;c&amp;#34;};
        List&amp;lt;String&amp;gt; arrayList = Arrays.asList(arr);
//        arrayList.add(&amp;#34;d&amp;#34;);
        System.out.println(arrayList);

        Integer [] arr2 = {new Integer(1),new Integer(2),new Integer(3)};
        List a = Arrays.asList(arr2);
        System.out.println(a);

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;集合转数组&#34;&gt;集合转数组&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;如果集合size大于等于数组, 则转换后, 数组长度 = 集合长度&lt;/li&gt;
&lt;li&gt;集合size小于数组, 转换后, 数组长度还是原数组长度&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;

public class Demo9_Generic {
    public static void main(String[] args) {
        ArrayList&amp;lt;String&amp;gt;  arrayList = new ArrayList&amp;lt;&amp;gt;();
        arrayList.add(&amp;#34;a&amp;#34;);
        arrayList.add(&amp;#34;b&amp;#34;);
        arrayList.add(&amp;#34;c&amp;#34;);

        String[] arr = arrayList.toArray(new String[2]);
        String[] arr2 = arrayList.toArray(new String[4]);
        System.out.println(arr.length);
        System.out.println(arr2.length);
        for(String s:arr){
            System.out.print(s);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;集合嵌套之arraylist嵌套arraylist&#34;&gt;集合嵌套之ArrayList嵌套ArrayList&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;

public class Demo10_Generic {
    public static void main(String[] args) {
        ArrayList &amp;lt;ArrayList&amp;lt;Person&amp;gt;&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        ArrayList&amp;lt;Person&amp;gt; cls1 = new ArrayList&amp;lt;&amp;gt;();
        ArrayList&amp;lt;Person&amp;gt; cls2 = new ArrayList&amp;lt;&amp;gt;();

        cls1.add(new Person(&amp;#34;小明&amp;#34;, 20));
        cls1.add(new Person(&amp;#34;小红&amp;#34;, 19));
        cls1.add(new Person(&amp;#34;小张&amp;#34;, 21));

        cls2.add(new Person(&amp;#34;小丽&amp;#34;, 21));
        cls2.add(new Person(&amp;#34;小李&amp;#34;, 22));
        cls2.add(new Person(&amp;#34;小王&amp;#34;, 23));

        arrayList.add(cls1);
        arrayList.add(cls2);

        for(ArrayList&amp;lt;Person&amp;gt; s:arrayList){
            for(Person p:s){
                System.out.println(p);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的Collection集合一 Li.036</title>
      <link>https://lizicai.com/p/java%E7%9A%84collection%E9%9B%86%E5%90%88%E4%B8%80-li036/</link>
      <pubDate>Thu, 19 Aug 2021 16:41:04 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84collection%E9%9B%86%E5%90%88%E4%B8%80-li036/</guid>
      <description>&lt;h2 id=&#34;collection-和-数组区别&#34;&gt;Collection 和 数组区别&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;数组可以存储基本数据类型, 也可以存储引用数据类型&lt;/li&gt;
&lt;li&gt;集合可以存储引用数据类型, 也能存基本数据类型, 存储时会自动装箱&lt;/li&gt;
&lt;li&gt;数组的长度固定, 不可以自由增加&lt;/li&gt;
&lt;li&gt;集合长度可变, 可以自由增加&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;list-set-集合&#34;&gt;List Set 集合&lt;/h2&gt;
&lt;h3 id=&#34;list&#34;&gt;List&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;有序集合, 存取位置一致&lt;/li&gt;
&lt;li&gt;有索引&lt;/li&gt;
&lt;li&gt;可存储重复数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;set&#34;&gt;Set&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;无序集合, 存取位置不一致&lt;/li&gt;
&lt;li&gt;无索引&lt;/li&gt;
&lt;li&gt;不可存储重复数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;list-体系-arraylist-linkedlist-vector&#34;&gt;List 体系 ArrayList LinkedList Vector&lt;/h2&gt;
&lt;h3 id=&#34;arraylist&#34;&gt;ArrayList&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;底层是数组, 查询快, 增删慢&lt;/li&gt;
&lt;li&gt;线程不安全, 效率高&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;linkedlist&#34;&gt;LinkedList&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;链表实现, 查询慢, 增删快&lt;/li&gt;
&lt;li&gt;线程不安全, 效率高&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;vection&#34;&gt;Vection&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;数组实现, 查询快, 增删慢&lt;/li&gt;
&lt;li&gt;线程安全, 效率低&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;set-体系-hashset-treeset&#34;&gt;Set 体系 HashSet TreeSet&lt;/h2&gt;
&lt;h3 id=&#34;hashset&#34;&gt;HashSet&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;哈希算法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;treeset&#34;&gt;TreeSet&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;二叉树算法&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;arraylist-的&#34;&gt;ArrayList 的&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;boolean add(E e) 方法一直返回true, Set 集合存取重复元素时, 则返回false&lt;/li&gt;
&lt;li&gt;boolean remove(Object o) 一次删除一个对象&lt;/li&gt;
&lt;li&gt;int size() 打印集合对象数&lt;/li&gt;
&lt;li&gt;void clear() 清空集合&lt;/li&gt;
&lt;li&gt;boolean isEmpty() 判断集合是否为空&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_Collection {
    public static void main(String[] args) {
        Collection collection = new ArrayList();
        boolean b1 = collection.add(&amp;#34;abc&amp;#34;);
        boolean b2 = collection.add(true);
        boolean b3 = collection.add(100);
        boolean b4 = collection.add(new Student(&amp;#34;小红&amp;#34;,18));
        boolean b5 = collection.add(&amp;#34;abc&amp;#34;);
        System.out.println(b1);
        System.out.println(b2);
        System.out.println(b3);
        System.out.println(b4);
        System.out.println(b5);
        System.out.println(collection);

        System.out.println(collection.contains(&amp;#34;abc&amp;#34;));
        collection.remove(&amp;#34;abc&amp;#34;);
        System.out.println(collection);
        collection.remove(&amp;#34;abc&amp;#34;);
        System.out.println(collection.size());
        System.out.println(collection);
        System.out.println(collection.isEmpty());
        collection.clear();
        System.out.println(collection.isEmpty());
        System.out.println(collection);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Object[] toArray()  集合转换成数组&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Student;
import java.util.ArrayList;
import java.util.Collection;

public class Demo3_Collection {
    public static void main(String[] args) {
        Collection c = new ArrayList();
        c .add( new Student(&amp;#34;小明&amp;#34;, 24));
        c .add( new Student(&amp;#34;小红&amp;#34;, 22));
        c .add( new Student(&amp;#34;小张&amp;#34;, 30));
        Object [] oArray = c.toArray();
        for(Object o:oArray){
            if( o instanceof Student){
                Student s = (Student) o;
                System.out.println(s.getName()+s.getAge());
            } else{
                System.out.println(o);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;list-中带有all的方法&#34;&gt;List 中带有All的方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;boolean addAll(Collection&amp;lt;? extends E&amp;gt; c) 添加另一个集合&lt;/li&gt;
&lt;li&gt;boolean removeAll(Collection&lt;?&gt; c) 移除集合中所有与C集合一样的元素&lt;/li&gt;
&lt;li&gt;boolean containsAll(Collection&lt;?&gt; c) 返回结果c集合全部 是 调用集合内元素的判断结果&lt;/li&gt;
&lt;li&gt;boolean retainAll(Collection&lt;?&gt; c) 调用集合和c集合取交集, 调用集合改变则是true, 没改是false&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private static void Demo4() {
    Collection c = new ArrayList();
    c.add(&amp;#34;a&amp;#34;);
    c.add(&amp;#34;b&amp;#34;);
    c.add(&amp;#34;c&amp;#34;);
    Collection c2 = new ArrayList();
    c2.add(&amp;#34;a&amp;#34;);
    c2.add(&amp;#34;b&amp;#34;);
    System.out.println(c.retainAll(c2));
    System.out.println(c);
}

private static void Demo3() {
    Collection c = new ArrayList();
    c.add(&amp;#34;a&amp;#34;);
    c.add(&amp;#34;b&amp;#34;);
    c.add(&amp;#34;b&amp;#34;);
    c.add(&amp;#34;c&amp;#34;);
    Collection c2 = new ArrayList();
    c2.add(&amp;#34;a&amp;#34;);
    c2.add(&amp;#34;b&amp;#34;);
    c2.add(&amp;#34;c&amp;#34;);
    System.out.println(c.containsAll(c2));
    System.out.println(c);
    System.out.println(c2);
}

private static void Demo2() {
    Collection c = new ArrayList();
    c.add(&amp;#34;a&amp;#34;);
    c.add(&amp;#34;b&amp;#34;);
    c.add(&amp;#34;b&amp;#34;);
    c.add(&amp;#34;c&amp;#34;);
    Collection c2 = new ArrayList();
    c2.add(&amp;#34;a&amp;#34;);
    c2.add(&amp;#34;b&amp;#34;);
    c2.add(&amp;#34;cc&amp;#34;);
    c.removeAll(c2);
    System.out.println(c);
}

private static void Demo1() {
    Collection c = new ArrayList();
    c.add(&amp;#34;a&amp;#34;);
    c.add(&amp;#34;b&amp;#34;);
    c.add(&amp;#34;c&amp;#34;);
    Collection c2 = new ArrayList();
    c2.add(&amp;#34;aa&amp;#34;);
    c2.add(&amp;#34;bb&amp;#34;);
    c2.add(&amp;#34;cc&amp;#34;);

    c.addAll(c2);
    c2.add(c);
    System.out.println(c);
    System.out.println(c2);
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;集合的迭代器遍历&#34;&gt;集合的迭代器遍历&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.bean.Student;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo1_Iterator {
    public static void main(String[] args) {
        Collection c = new ArrayList();
        c.add(new Student(&amp;#34;小明&amp;#34;, 24));
        c.add(new Student(&amp;#34;小红&amp;#34;, 22));
        c.add(new Student(&amp;#34;小张&amp;#34;, 30));
        Iterator it = c.iterator();
        while (it.hasNext()){
            Object obj = it.next();
            if( obj instanceof Student){
                Student s = (Student)obj;
                System.out.println(s.getName()+s.getAge());
            } else {
                System.out.println(obj);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;list-集合&#34;&gt;List 集合&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;void add(int index, E element)&lt;/li&gt;
&lt;li&gt;E remove(int index)&lt;/li&gt;
&lt;li&gt;E get(int index)&lt;/li&gt;
&lt;li&gt;E set(int index, E element)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.List;

public class Demo1_List {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(&amp;#34;a&amp;#34;);
        list.add(&amp;#34;b&amp;#34;);
        list.add(&amp;#34;c&amp;#34;);
        list.add(0,&amp;#34;d&amp;#34;);
        System.out.println(list);

        list.remove(0);
        System.out.println(list);

        list.set(2,&amp;#34;w&amp;#34;);
        System.out.println(list);

        System.out.println(list.get(2));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;list-遍历的2种方式&#34;&gt;List 遍历的2种方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;for循环&lt;/li&gt;
&lt;li&gt;iterator迭代器&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_List {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(&amp;#34;a&amp;#34;);
        list.add(&amp;#34;b&amp;#34;);
        list.add(&amp;#34;c&amp;#34;);
        for(int i=0;i&amp;lt;list.size();i++){
            System.out.println(list.get(i));
        }
        Iterator it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;list-的-listiterator-可以在遍历的时候添加元素-list不能在遍历的时候添加元素&#34;&gt;List 的 ListIterator 可以在遍历的时候添加元素, List不能在遍历的时候添加元素&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Demo3_List {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(&amp;#34;a&amp;#34;);
        list.add(&amp;#34;ab&amp;#34;);
        list.add(&amp;#34;abc&amp;#34;);
        list.add(&amp;#34;Hello&amp;#34;);

//        Iterator li = list.iterator();
//        while (li.hasNext()){
//            String s = (String)li.next();
//            if(&amp;#34;Hello&amp;#34;.equals(s)){
//                list.add(&amp;#34;World&amp;#34;);
//            }
//            System.out.println(s);
//        }

        ListIterator li = list.listIterator();
        while (li.hasNext()){
            String s = (String)li.next();
            if(&amp;#34;Hello&amp;#34;.equals(s)){
                li.add(&amp;#34;World&amp;#34;);
            }
        }
        System.out.println(list);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;vector&#34;&gt;Vector&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Enumeration;
import java.util.Vector;
public class Demo1_Vector {
    public static void main(String[] args) {
        Vector v = new Vector();
        v.addElement(&amp;#34;a&amp;#34;);
        v.addElement(&amp;#34;b&amp;#34;);
        v.addElement(&amp;#34;c&amp;#34;);
        v.addElement(&amp;#34;d&amp;#34;);

        Enumeration en = v.elements();
        while (en.hasMoreElements()){
            System.out.println(en.nextElement());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的正则表达式 Li.035</title>
      <link>https://lizicai.com/p/java%E7%9A%84%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F-li.035/</link>
      <pubDate>Mon, 16 Aug 2021 16:45:01 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F-li.035/</guid>
      <description>&lt;h2 id=&#34;java-的正则表达式regex&#34;&gt;Java 的正则表达式Regex&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;java.util.regex.Pattern 有正则表达示例&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/*
[abc]	a, b, or c (simple class)   abc中任意一个字符
[^abc]	Any character except a, b, or c (negation)  非abc的一个字符
[a-zA-Z]	a through z or A through Z, inclusive (range)  匹配a-z A-Z 大小写字符
[a-d[m-p]]	a through d, or m through p: [a-dm-p] (union)  匹配a-d 和 匹配 m-p 字符, 匹配则true
[a-z&amp;amp;&amp;amp;[def]]	d, e, or f (intersection)  匹配def 与 a-z的并集是 def
[a-z&amp;amp;&amp;amp;[^bc]]	a through z, except for b and c: [ad-z] (subtraction), 非bc 和 a-z取并集(匹配a d-z字符)
[a-z&amp;amp;&amp;amp;[^m-p]]	a through z, and not m through p: [a-lq-z](subtraction), 非m-p字符与a-z取并集, 并集是a-l和q-z
 */

private static void Demo7() {
    String regex = &amp;#34;[a-z&amp;amp;&amp;amp;[^m-p]]&amp;#34;;
    System.out.println(&amp;#34;a&amp;#34;.matches(regex));
    System.out.println(&amp;#34;n&amp;#34;.matches(regex));
}

private static void Demo6() {
    String regex = &amp;#34;[a-z&amp;amp;&amp;amp;[^bc]]&amp;#34;;
    System.out.println(&amp;#34;a&amp;#34;.matches(regex));
    System.out.println(&amp;#34;b&amp;#34;.matches(regex));
}

private static void Demo5() {
    String regex = &amp;#34;[a-z&amp;amp;&amp;amp;[def]]&amp;#34;;
    System.out.println(&amp;#34;m&amp;#34;.matches(regex));
    System.out.println(&amp;#34;a&amp;#34;.matches(regex));
    System.out.println(&amp;#34;d&amp;#34;.matches(regex));
}

private static void Demo4() {
    String regex = &amp;#34;[a-d[x-z]]&amp;#34;;
    System.out.println(&amp;#34;m&amp;#34;.matches(regex));
    System.out.println(&amp;#34;a&amp;#34;.matches(regex));
    System.out.println(&amp;#34;x&amp;#34;.matches(regex));
}

private static void Demo3() {
    String regex = &amp;#34;[a-zA-Z]&amp;#34;;
    System.out.println(&amp;#34;a&amp;#34;.matches(regex));
    System.out.println(&amp;#34;*&amp;#34;.matches(regex));
}

private static void Demo2() {
    String regex = &amp;#34;[^abc]&amp;#34;;
    System.out.println(&amp;#34;a&amp;#34;.matches(regex));
    System.out.println(&amp;#34;d&amp;#34;.matches(regex));
    System.out.println(&amp;#34;10&amp;#34;.matches(regex));
}

private static void Demo1() {
    String regex = &amp;#34;[abc]&amp;#34;;
    System.out.println(&amp;#34;a&amp;#34;.matches(regex));
    System.out.println(&amp;#34;d&amp;#34;.matches(regex));
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;正则预先定义的字符&#34;&gt;正则预先定义的字符&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_Regex {
    public static void main(String[] args) {
       /*
         .	Any character (may or may not match line terminators)  匹配任何字符
        \d	A digit: [0-9]    0-9字符, 其他字符则false
        \D	A non-digit: [^0-9]  非 0-9 字符, 0-9字符则false
        \h	A horizontal whitespace character: [ \t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]  水平空白字符
        \H	A non-horizontal whitespace character: [^\h]   非水平空白字符
        \s	A whitespace character: [ \t\n\x0B\f\r]  空白字符
        \S	A non-whitespace character: [^\s]  非空白字符
        \v	A vertical whitespace character: [\n\x0B\f\r\x85\u2028\u2029]  垂直空白字符
        \V	A non-vertical whitespace character: [^\v]   非垂直空白字符
        \w	A word character: [a-zA-Z_0-9] 大小写 数字 下划线
        \W	A non-word character: [^\w]  除大小写 数字 下划线 以外字符
        */
    }

    private static void Demo5() {
        // 字符 \w a-zA-Z0-9_ \W, 除去a-zA-Z0-9_的字符
        String regex = &amp;#34;\\w&amp;#34;;
        System.out.println(&amp;#34;s&amp;#34;.matches(regex));
        System.out.println(&amp;#34;_&amp;#34;.matches(regex));
        System.out.println(&amp;#34;0&amp;#34;.matches(regex));
        System.out.println(&amp;#34;&amp;amp;&amp;#34;.matches(regex));

        String regex2 = &amp;#34;\\W&amp;#34;;
        System.out.println(&amp;#34;s&amp;#34;.matches(regex2));
        System.out.println(&amp;#34;_&amp;#34;.matches(regex2));
        System.out.println(&amp;#34;0&amp;#34;.matches(regex2));
        System.out.println(&amp;#34;&amp;amp;&amp;#34;.matches(regex2));
    }

    private static void Demo4() {
        String regex = &amp;#34;\\v&amp;#34;;
        System.out.println(&amp;#34; &amp;#34;.matches(regex));
        System.out.println(&amp;#34;\t&amp;#34;.matches(regex));
        System.out.println(&amp;#34;\n&amp;#34;.matches(regex));
        System.out.println(&amp;#34;a&amp;#34;.matches(regex));

        String regex2 = &amp;#34;\\V&amp;#34;;
        System.out.println(&amp;#34; &amp;#34;.matches(regex2));
        System.out.println(&amp;#34;\t&amp;#34;.matches(regex2));
        System.out.println(&amp;#34;\n&amp;#34;.matches(regex2));
        System.out.println(&amp;#34;a&amp;#34;.matches(regex2));
    }

    private static void Demo3() {
        String regex = &amp;#34;\\s&amp;#34;;
        System.out.println(&amp;#34; &amp;#34;.matches(regex));
        System.out.println(&amp;#34;\t&amp;#34;.matches(regex));
        System.out.println(&amp;#34;\n&amp;#34;.matches(regex));
        System.out.println(&amp;#34;a&amp;#34;.matches(regex));

        String regex2 = &amp;#34;\\S&amp;#34;;
        System.out.println(&amp;#34; &amp;#34;.matches(regex2));
        System.out.println(&amp;#34;\t&amp;#34;.matches(regex2));
        System.out.println(&amp;#34;\n&amp;#34;.matches(regex2));
        System.out.println(&amp;#34;a&amp;#34;.matches(regex2));
    }

    private static void Demo2() {
        String regex = &amp;#34;\\h&amp;#34;;
        String regex2 = &amp;#34;\\H&amp;#34;;
        System.out.println(&amp;#34;a&amp;#34;.matches(regex));
        System.out.println(&amp;#34; &amp;#34;.matches(regex));
        System.out.println(&amp;#34;\t&amp;#34;.matches(regex));
        System.out.println(&amp;#34;\n&amp;#34;.matches(regex));

        System.out.println(&amp;#34;a&amp;#34;.matches(regex2));
        System.out.println(&amp;#34; &amp;#34;.matches(regex2));
        System.out.println(&amp;#34;\t&amp;#34;.matches(regex2));
        System.out.println(&amp;#34;\n&amp;#34;.matches(regex2));
    }


    private static void Demo1() {
        String regex = &amp;#34;\\d&amp;#34;;
        System.out.println(&amp;#34;a&amp;#34;.matches(regex));
        System.out.println(&amp;#34;9&amp;#34;.matches(regex));

        String regex2 = &amp;#34;\\D&amp;#34;;
        System.out.println(&amp;#34;a&amp;#34;.matches(regex2));
        System.out.println(&amp;#34;9&amp;#34;.matches(regex2));
    }
    private static void Demo() {
        String regex = &amp;#34;.&amp;#34;;
        System.out.println(&amp;#34;a&amp;#34;.matches(regex));
        System.out.println(&amp;#34;%&amp;#34;.matches(regex));
        System.out.println(&amp;#34;9&amp;#34;.matches(regex));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;正则匹配-出现次数&#34;&gt;正则匹配 出现次数&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo5_Regex {
    public static void main(String[] args) {
        /*
        X?	X, once or not at all  X出现一次或一次也没有, 但是不能出现其他内容
        X*	X, zero or more times  X出现0次或&amp;gt;0次, 但是不能出现其它内容
        X+	X, one or more times   X出现1次或&amp;gt;1次, 但是不能出现其它内容
        X{n}	X, exactly n times X准确出现n次, 不多不少, 但是不能出现其它内容
        X{n,}	X, at least n times X出现次数至少n次, 但是不能出现其它内容
        X{n,m}	X, at least n but not more than m times  X出现次数 至少n次, 不超过m次, 记[n, m)次
        */
    }

    private static void Demo6() {
        String regex = &amp;#34;[abc]{2,4}&amp;#34;;
        System.out.println(&amp;#34;a&amp;#34;.matches(regex));
        System.out.println(&amp;#34;ab&amp;#34;.matches(regex));
        System.out.println(&amp;#34;aba&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abca&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abcabc&amp;#34;.matches(regex));
        System.out.println(&amp;#34; &amp;#34;.matches(regex));
    }

    private static void Demo5() {
        String regex = &amp;#34;[abc]{5,}&amp;#34;;
        System.out.println(&amp;#34;abca&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abcab&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abcabc&amp;#34;.matches(regex));
        System.out.println(&amp;#34;dkfjkf&amp;#34;.matches(regex));
    }

    private static void Demo4() {
        String regex = &amp;#34;[abc]{5}&amp;#34;;
        System.out.println(&amp;#34;abca&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abccc&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abcabc&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abccd&amp;#34;.matches(regex));
        System.out.println(&amp;#34;d&amp;#34;.matches(regex));
        System.out.println(&amp;#34; &amp;#34;.matches(regex));
    }

    private static void Demo3() {
        String regex = &amp;#34;[abc]+&amp;#34;;
        System.out.println(&amp;#34;a&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abc&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abcabccc&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abcd&amp;#34;.matches(regex));
        System.out.println(&amp;#34;&amp;#34;.matches(regex));
        System.out.println(&amp;#34;d&amp;#34;.matches(regex));
    }

    private static void Demo2() {
        String regex = &amp;#34;[abc]*&amp;#34;;
        System.out.println(&amp;#34;&amp;#34;.matches(regex));
        System.out.println(&amp;#34;a&amp;#34;.matches(regex));
        System.out.println(&amp;#34;b&amp;#34;.matches(regex));
        System.out.println(&amp;#34;bb&amp;#34;.matches(regex));
        System.out.println(&amp;#34;abc&amp;#34;.matches(regex));
        System.out.println(&amp;#34; &amp;#34;.matches(regex));
        System.out.println(&amp;#34;s&amp;#34;.matches(regex));
    }

    private static void Demo1() {
        String regex = &amp;#34;[abc]?&amp;#34;;
        System.out.println(&amp;#34;&amp;#34;.matches(regex));
        System.out.println(&amp;#34;a&amp;#34;.matches(regex));
        System.out.println(&amp;#34;b&amp;#34;.matches(regex));
        System.out.println(&amp;#34; &amp;#34;.matches(regex));
        System.out.println(&amp;#34;bb&amp;#34;.matches(regex));
        System.out.println(&amp;#34;s&amp;#34;.matches(regex));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-中的-split-方法&#34;&gt;String 中的 split 方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;String[] split(String regex) 匹配正则分隔成字符串数组&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// 空格或问号出现1次或以上, 分隔
public class Demo6_Regex {
    public static void main(String[] args) {
        String str = &amp;#34;What is a youth?&amp;#34;;
        String regex = &amp;#34;[\\s\\?]+&amp;#34;;
        String [] strArray = str.split(regex);
        for(String s:strArray){
            System.out.println(s);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;练习-字符串的数组-经过排序后-再转换成字符串&#34;&gt;练习 字符串的数组, 经过排序后, 再转换成字符串&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;字符串, 分隔成字符串组&lt;/li&gt;
&lt;li&gt;字符串组 转换为 数组&lt;/li&gt;
&lt;li&gt;数组排序&lt;/li&gt;
&lt;li&gt;数组重新转换为字符串&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Split {
    public static void main(String[] args) {
        String str = &amp;#34;1 10 2 30 100 40&amp;#34;;
        String regex = &amp;#34;[\\s]+&amp;#34;;
        String [] strArray = str.split(regex);
        int [] a = new int[strArray.length];
        for(int i=0;i&amp;lt;strArray.length;i++){
            a[i]  =  Integer.parseInt(strArray[i]);
        }
        StringBuffer sb = new StringBuffer();
        Arrays.sort(a);
        if(a.length &amp;lt;1){
            sb = sb.append(&amp;#34;{}&amp;#34;);
        } else{
            sb.append(&amp;#34;{&amp;#34;);
            for (int i=0;i&amp;lt;a.length;i++){
                if(i == a.length-1){
                    sb.append(a[i] + &amp;#34;}&amp;#34;);
                    break;
                }
                sb.append(a[i] + &amp;#34; &amp;#34;);
            }
        }
        System.out.println(sb);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;正则匹配-替换字符&#34;&gt;正则匹配, 替换字符&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_Replace {
    public static void main(String[] args) {
        String str = &amp;#34;What2is2a233youth?&amp;#34;;
        String regex = &amp;#34;[\\d]&amp;#34;;
        String res = str.replaceAll(regex,&amp;#34;&amp;#34;);
        System.out.println(res);

        String regex2 = &amp;#34;[\\d]&amp;#34;;
        String res2 = str.replaceAll(regex2,&amp;#34; &amp;#34;);
        System.out.println(res2);

        String regex3 = &amp;#34;[\\d]+&amp;#34;;
        String res3 = str.replaceAll(regex3,&amp;#34; &amp;#34;);
        System.out.println(res3);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;正则匹配-组-捕获&#34;&gt;正则匹配, 组 捕获&lt;/h2&gt;
&lt;h3 id=&#34;abc--组是以左括号为一组-所有共有-4-组&#34;&gt;((A)(B(C))) , 组是以左括号为一组, 所有共有 4 组&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;((A)(B(C)))&lt;/li&gt;
&lt;li&gt;(A)&lt;/li&gt;
&lt;li&gt;(B(C))&lt;/li&gt;
&lt;li&gt;(C)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;正则匹配-组的练习&#34;&gt;正则匹配, 组的练习&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_Replace {
    public static void main(String[] args) {
//        Demo1();
        String str = &amp;#34;我...我...我...我....想想........学编...编...程....程...程程..&amp;#34;;
        String regex = &amp;#34;[\\.]+&amp;#34;;
        String str2 = str.replaceAll(regex, &amp;#34;&amp;#34;);
        System.out.println(str2);

        String regex2 = &amp;#34;(.)\\1+&amp;#34;;
        String str3 = str2.replaceAll(regex2, &amp;#34;$1&amp;#34;);
        System.out.println(str3);
    }

    private static void Demo1() {
        String str = &amp;#34;abchhhhkdjflllljkklqqqq&amp;#34;;
        String regex = &amp;#34;(.)\\1+&amp;#34;;
        String[] strArray = str.split(regex);
        for(String s:strArray){
            System.out.println(s);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;正则匹配-pattern-和-matcher-练习获取手机号&#34;&gt;正则匹配, Pattern 和 Matcher, 练习获取手机号&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;考虑手机号第2位一直在增加, 以1开头11位即认为正确手机号&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public static void main(String[] args) {
    String str = &amp;#34;我用过的手机号12310001000, 上一个手机号是12310001001, 目前在用的12310001002&amp;#34;;
    String regex = &amp;#34;[1][\\d]{10}&amp;#34;;
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(str);
    while (m.find()){
        System.out.println(m.group());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;math-类&#34;&gt;Math 类&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Math {
    public static void main(String[] args) {
        System.out.println(Math.PI);
        System.out.println(Math.abs(-120));
        // 向上取整 (0,1]
        System.out.println(Math.ceil(23.8));
        System.out.println(Math.ceil(23.1));
        // 向下取整 [0,1)
        System.out.println(Math.floor(23.8));
        System.out.println(Math.floor(24.0));
        System.out.println(Math.max(23,30));
        System.out.println(Math.pow(3,3));
        // 包含 [0.0,1.0)
        System.out.println(Math.random());
        System.out.println(Math.sqrt(2));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;random-随机数&#34;&gt;Random 随机数&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Random 是伪随机数, 生成的随机数由随机因子决定的&lt;/li&gt;
&lt;li&gt;nextInt(100) 可以生成[0,100) 的随机整数&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Random;
public class Demo1_Random {
    public static void main(String[] args) {
        Random r = new Random();
        for(int i=0;i&amp;lt;10;i++){
            int a = r.nextInt(100);
            System.out.println(a);
        }

        Random r2 = new Random(1000);
        int a1 = r2.nextInt();
        int a2 = r2.nextInt();
        System.out.println(a1);
        System.out.println(a2);
        // 执行多少次 a1 和 a2 固定
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;system-类&#34;&gt;System 类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;System.in 输入流, Scanner 录收键盘&lt;/li&gt;
&lt;li&gt;System.out 输出控制台&lt;/li&gt;
&lt;li&gt;System.gc() 垃圾回收&lt;/li&gt;
&lt;li&gt;System.currentTimeMillis() 到1971年的毫秒, 2次时间差就能知道程序运行时间&lt;/li&gt;
&lt;li&gt;exit() 退出 0 正常终止, 非0 异常终止&lt;/li&gt;
&lt;li&gt;arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 数组复制, int str 对象等都可复制&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_System {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        System.out.println(&amp;#34;jkdjf&amp;#34;);
        System.out.println(System.currentTimeMillis());
        long start = System.currentTimeMillis();
        for(int i=0;i&amp;lt;10000000;i++){
            System.out.print(&amp;#34;&amp;#34;);
            StringBuffer sf = new StringBuffer();
        }
        long end = System.currentTimeMillis();

        System.out.println(end-start);
        for(int i=0;i&amp;lt;10;i++){
            new Test();
            System.gc();
        }
        int [] src = {1, 2, 3, 4, 5};
        int [] dest = new int[8];
        System.arraycopy(src, 0, dest,0,src.length);
        for(int i:dest){
            System.out.println(i);
        }
    }
}
class Test{
    Test(){}
    @Override
    public void finalize(){
        System.out.println(&amp;#34;垃圾回收&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;biginteger-类&#34;&gt;BigInteger 类&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.math.BigInteger;

public class Demo1_BigInteger {
    public static void main(String[] args) {
        BigInteger bi1 = new BigInteger(&amp;#34;100&amp;#34;);
        BigInteger bi2 = new BigInteger(&amp;#34;3&amp;#34;);
        System.out.println(bi1.add(bi2));
        System.out.println(bi1.subtract(bi2));
        System.out.println(bi1.multiply(bi2));
        System.out.println(bi1.divide(bi2));
        BigInteger [] bArray;
        bArray = bi1.divideAndRemainder(bi2);
        for(BigInteger b:bArray){
            System.out.println(b);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;bigdecimal-金融运算使用&#34;&gt;BigDecimal, 金融运算使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;static BigDecimal valueOf(double val) 由double 转为 BigDecimal&lt;/li&gt;
&lt;li&gt;构造函数时BigDecimal(String val), string 转为 BigDecimal&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_BigDecimal {
    public static void main(String[] args) {

        System.out.println(2.0 - 1.1 );

        BigDecimal bd1 = new BigDecimal(2.0);
        BigDecimal bd2 = new BigDecimal(1.1);
        System.out.println(bd1.subtract(bd2));

        BigDecimal bd3 = new BigDecimal(&amp;#34;2.0&amp;#34;);
        BigDecimal bd4 = new BigDecimal(&amp;#34;1.1&amp;#34;);
        System.out.println(bd3.subtract(bd4));

        BigDecimal bd5 = BigDecimal.valueOf(2.0);
        BigDecimal bd6 = BigDecimal.valueOf(1.1);
        System.out.println(bd5.subtract(bd6));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;date-类&#34;&gt;Date 类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;System.currentTimeMillis date.getTime() 都是与GMT 1970 01 01 00:00:00 的毫秒值&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Date {
    public static void main(String[] args) {
//        Demo1();
        Date date = new Date();
        System.out.println(date.getTime());
        System.out.println(System.currentTimeMillis());

        date.setTime(2000);
        System.out.println(date);
    }

    private static void Demo1() {
        Date date = new Date();
        System.out.println(date);
        Date date2 = new Date(0);
        System.out.println(date2);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;simpledateformat&#34;&gt;SimpleDateFormat&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Date 特定格式输出&lt;/li&gt;
&lt;li&gt;字符串转为Date&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo1_DateFormat {
    public static void main(String[] args) throws ParseException {
//        Demo1();
        SimpleDateFormat sdf = new SimpleDateFormat(&amp;#34;yyyy年MM月dd日 HH:mm:ss E&amp;#34;);
        String strDate = &amp;#34;2021年08月18日 23:44:59 星期三&amp;#34;;
        Date date = sdf.parse(strDate);
        System.out.println(date);
    }

    private static void Demo1() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(&amp;#34;yyyy年MM月dd日 HH:mm:ss E&amp;#34;);
        System.out.println(sdf.format(date));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;simpledateformat-练习-从生日到现在多少天了&#34;&gt;SimpleDateFormat 练习, 从生日到现在多少天了&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo2_DateFormat {
    public static void main(String[] args) throws ParseException {
        String strDate = &amp;#34;1991-01-01&amp;#34;;
        Date date = new Date();

        SimpleDateFormat sdf = new SimpleDateFormat(&amp;#34;yyyy-MM-dd&amp;#34;);
        Date birthday = sdf.parse(strDate);

        long days = date.getTime() - birthday.getTime();

        System.out.println(days/1000/3600/24);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;calendar-类&#34;&gt;Calendar 类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Calendar 的获取月份时的0对应1月,  7 对应8月&lt;/li&gt;
&lt;li&gt;Calendar 获取的1对应的是 星期天, DAY_OF_WEEK&lt;/li&gt;
&lt;li&gt;add(int field, int amount) 给年月日时分秒增减&lt;/li&gt;
&lt;li&gt;set(int field, int value) 给年月日时分秒设置数值&lt;/li&gt;
&lt;li&gt;set(int year, int month, int date) 设置年月日&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.text.SimpleDateFormat;
import java.util.Calendar;

public class Demo1_Calendar {
    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        String month = setTwoNu(cal.get(Calendar.MARCH) + 1);
        System.out.println(month);
        String week = getWeek(cal.get(Calendar.DAY_OF_WEEK));
        System.out.println(week);
        System.out.println(cal.get(Calendar.DAY_OF_MONTH));
        System.out.println(cal.getTime());
        SimpleDateFormat sdf = new SimpleDateFormat(&amp;#34;yyyy-MM-dd HH:mm:ss E&amp;#34;);
        System.out.println(sdf.format(cal.getTime()));
    }
    public static String getWeek(int week){
        String [] strArray = {&amp;#34;&amp;#34;, &amp;#34;星期日&amp;#34;, &amp;#34;星期一&amp;#34;,&amp;#34;星期二&amp;#34;,&amp;#34;星期三&amp;#34;,&amp;#34;星期四&amp;#34;,&amp;#34;星期五&amp;#34;,&amp;#34;星期六&amp;#34;};
        return strArray[week];
    }
    public static String setTwoNu(int nu){
        String s = String.valueOf(nu);
        if( nu &amp;lt;10 ){
            s = &amp;#34;0&amp;#34; + nu;
        }
        return s;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Calendar;

public class Demo2_Calendar {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, 10);
        System.out.println(calendar.get(Calendar.YEAR));
        System.out.println(calendar.get(Calendar.MONTH));

        calendar.set(Calendar.MONTH, 10);
        System.out.println(calendar.get(Calendar.MONTH));

        calendar.set(2021,9,01);
        System.out.println(calendar.get(Calendar.YEAR) +&amp;#34;&amp;#34;+ (calendar.get(Calendar.MONTH)+1) +&amp;#34;&amp;#34; +calendar.get(Calendar.DAY_OF_MONTH));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;calendar-平年-润年&#34;&gt;Calendar 平年 润年&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Calendar;

public class Demo3_Calendar {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        int year = 2020;
        calendar.set(year,2,1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
        if( 29 == calendar.get(Calendar.DAY_OF_MONTH)){
            System.out.println( year + &amp;#34;年是润年&amp;#34;);
        } else {
            System.out.println( year + &amp;#34;年是平年&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的StringBuffer类 Li.034</title>
      <link>https://lizicai.com/p/java%E7%9A%84stringbuffer%E7%B1%BB-li.034/</link>
      <pubDate>Thu, 12 Aug 2021 21:57:43 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84stringbuffer%E7%B1%BB-li.034/</guid>
      <description>&lt;h2 id=&#34;string-与-stringbuffer-区别&#34;&gt;String 与 StringBuffer 区别&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;StringBuffer 是线程安全的可变字符序列&lt;/li&gt;
&lt;li&gt;String 是一个不可变的字符序列&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;stringbuffer-的构造函数&#34;&gt;StringBuffer 的构造函数&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Sb {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        System.out.println(sb.length());
        System.out.println(sb.capacity());

        StringBuffer sb2 = new StringBuffer(10);
        System.out.println(sb2.length());
        System.out.println(sb2.capacity());

        StringBuffer sb3 = new StringBuffer(&amp;#34;hello&amp;#34;);
        System.out.println(sb3.length());
        System.out.println(sb3.capacity());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;stringbuffer-的append-和-insert-方法&#34;&gt;StringBuffer 的append 和 insert 方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;StringBuffer append() 支持int String StringBuffer boolean, 返回本身,&lt;/li&gt;
&lt;li&gt;StringBuffer insert(int , String) 在指定索引添加int String char等, 返回本身, 有可能会越界&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_Sb {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append(2);
        System.out.println(sb);
        sb.append(&amp;#34;haihai&amp;#34;);
        System.out.println(sb);
        sb.append(true);
        System.out.println(sb);
        sb.insert(1,&amp;#34;sss&amp;#34;);
        System.out.println(sb);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;stringbuffer-的deletecharat-delete方法&#34;&gt;StringBuffer 的deleteCharAt delete方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;StringBuffer deleteCharAt(int index) 删除指定索引的字符, 返回本身, 可能会越界&lt;/li&gt;
&lt;li&gt;StringBuffer delete(int start, int end) 删除从start到end, 返回本身, 可能会越界&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo3_Sb {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append(&amp;#34;Word hen da&amp;#34;);
        sb.deleteCharAt(10);
        System.out.println(sb);
        sb.delete(0,4);
        System.out.println(sb);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;stringbuffer-的-replace-reverse方法&#34;&gt;StringBuffer 的 replace reverse方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;StringBuffer replace(int start, int end, String str) 用户str替换从start到end, 返回本身, 可能越界&lt;/li&gt;
&lt;li&gt;StringBuffer reverse() 反转字符串, 返回本身&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_StringBuffer {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append(&amp;#34;Hello&amp;#34;);
        sb.replace(0,1,&amp;#34;Say&amp;#34;);
        System.out.println(sb);

        sb.reverse();
        System.out.println(sb);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;stringbuffer-的substring方法&#34;&gt;StringBuffer 的substring方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;String substring(int start) 从索引start开始向后截取, 返回新的String( 不再是StringBuffer本身了 )&lt;/li&gt;
&lt;li&gt;String substring(int start, int end) 从start到end(不包含end)截取, 返回新的String( 不再是StringBuffer本身了 )&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo5_StringBuffer {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append(&amp;#34;Hello&amp;#34;);
        String s = sb.substring(3);
        System.out.println(sb);
        System.out.println(s);

        String s2 = sb.substring(0,2);
        System.out.println(s2);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;stringbuffer-与-string-转换&#34;&gt;StringBuffer 与 String 转换&lt;/h2&gt;
&lt;h3 id=&#34;string---stringbuffer&#34;&gt;String -&amp;gt; StringBuffer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;构造方法&lt;/li&gt;
&lt;li&gt;通过append()方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;stringbuffer---string&#34;&gt;StringBuffer -&amp;gt; String&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;通过构造方法&lt;/li&gt;
&lt;li&gt;通过toString()&lt;/li&gt;
&lt;li&gt;通过substring(0,length);&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo6_StringBuffer {
    public static void main(String[] args) {
        //String -&amp;gt; StringBuffer
        StringBuffer sb = new StringBuffer(&amp;#34;See You Tomorrow&amp;#34;);

        StringBuffer sb2 = new StringBuffer();
        sb2.append(&amp;#34;HaHa&amp;#34;);

        // StringBuffer -&amp;gt; String

        StringBuffer sb3 = new StringBuffer(&amp;#34;F Word&amp;#34;);

        String s = new String(sb3);

        String s2 = sb3.toString();

        String s3 = sb3.substring(0,sb3.length());

    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;使用-stringbuffer-指定格式重新拼接成新的字符串char-c---123-转换成1-2-3&#34;&gt;使用 StringBuffer 指定格式重新拼接成新的字符串,char[] c =  {1,2,3}, 转换成[1, 2, 3]&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用 StringBuffer 中的方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo7_StringBuffer {
    public static void main(String[] args) {
        int [] arr = {1,2,3};
        StringBuffer sb = new StringBuffer();
        if( arr.length &amp;lt;= 1){
            sb = sb.append(&amp;#34;[&amp;#34;).append(sb).append(&amp;#34;]&amp;#34;);
        }else if ( arr.length &amp;gt; 1 ){
            for (int i=0; i&amp;lt;arr.length; i++) {
                if( 0 == i ){
                    sb = sb.append(&amp;#34;[&amp;#34;).append(arr[i]);
                } else if ( i &amp;gt; 0 &amp;amp;&amp;amp; i != (arr.length-1)){
                    sb = sb.append(&amp;#34;, &amp;#34;).append(arr[i]);
                } else if( i == arr.length-1) {
                    sb = sb.append(&amp;#34;, &amp;#34;).append(arr[i]).append(&amp;#34;]&amp;#34;);
                }
            }
        }
        System.out.println(sb);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;stringbuffer-作为参数传递-和-string-作为参数传递&#34;&gt;StringBuffer 作为参数传递 和 String 作为参数传递&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;基本数据类型传递, 不改变其值. 引用数据类型传递改变其值&lt;/li&gt;
&lt;li&gt;StringBuffer 作为参数传递&lt;/li&gt;
&lt;li&gt;String 作为参数传递&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo8_StringBuffer {
    public static void main(String[] args) {
        String s = &amp;#34;Hello&amp;#34;;
        System.out.println(s);
        change(s);
        System.out.println(s);

        StringBuffer sb = new StringBuffer(s);
        System.out.println(sb);
        change(sb);
        System.out.println(sb);
    }
    public static void change(String s){
        s = s + &amp;#34;hello&amp;#34;;
        return ;
    }
    public static void change(StringBuffer sb){
        sb.append(&amp;#34; Wrold!&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;冒泡排序&#34;&gt;冒泡排序&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo9_StringBuffer {
    public static void main(String[] args) {
        int []  arr = {1, 100, 200, 30, 1, 0};
        int temp = 0;
        sortArray(arr);
        printArray(arr);
    }
    public static int[] sortArray(int [] array){
        int temp = 0;
        for (int i=0;i&amp;lt;array.length-1;i++){
            for(int j=array.length-1;j &amp;gt; i;j--){
                if(array[j] &amp;lt; array[j-1]){
                    temp = array[j];
                    array[j] = array[j-1];
                    array[j - 1] = temp;
                }
            }
        }
        return array;
    }
    public static void printArray(int [] array){
        for (int i=0;i&amp;lt;array.length;i++){
            System.out.println(array[i]);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;选择冒泡排序&#34;&gt;选择冒泡排序&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_SortArray {
    public static void main(String[] args) {
        int [] arr = { 1,22, 30,3, 100};
        selectArray(arr);
        printArray(arr);
    }
    public static int[] selectArray(int []  arr){
        for (int i=0;i&amp;lt;arr.length;i++){
            for (int j=i;j&amp;lt;arr.length;j++){
                if(arr[i] &amp;gt; arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        return arr;
    }
    public static void printArray(int [] array){
        for (int i=0;i&amp;lt;array.length;i++){
            System.out.println(array[i]);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;二分查找&#34;&gt;二分查找&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public static int search(int [] arr, int t){
    int index = -1;
    int min = 0;
    int max = arr.length;
    int mid = arr.length/2;
    int count = 0;
    while ( count &amp;lt;= Math.log(arr.length)/Math.log(2)){
        if(arr[mid] == t){
            return mid;
        } else if (arr[mid] &amp;lt; t ){
            min = mid + 1;
            mid = (min + max)/2;
        } else if (arr[mid] &amp;gt; t){
            max = mid - 1;
            mid = (min + max)/2;
        }
        count ++;
    }
    return index;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;array-类的排序-和-二分查找&#34;&gt;Array 类的排序 和 二分查找&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;void sort(int[] a) 排序, 快速排序&lt;/li&gt;
&lt;li&gt;int binarySearch(int[] a, int key) 在数组中查找key, 找到返回索引位置, 没找到则返回插入-位置-1&lt;/li&gt;
&lt;li&gt;String toString(int[] a) 数组转成String 输出&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_SortArray {
    public static void main(String[] args) {
        int [] arr = { 15, 100, 1 , 2, 3, 15, 20, 30, 50};

        Arrays.sort(arr);

        System.out.println(Arrays.toString(arr));

        int k1 = Arrays.binarySearch(arr, 20);
        System.out.println(k1);
        int k2 = Arrays.binarySearch(arr, 200);
        System.out.println(k2);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;integer-parseint-方法&#34;&gt;Integer parseInt 方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;字符串和数字转换&lt;/li&gt;
&lt;li&gt;inter 最大值 最小值&lt;/li&gt;
&lt;li&gt;2 进制 8进制 16进制转换&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Integer {
    public static void main(String[] args) {
        int aInt = Integer.parseInt(&amp;#34;190&amp;#34;);
        System.out.println(Integer.toBinaryString(aInt));
        System.out.println(Integer.toHexString(aInt));
        System.out.println(Integer.toOctalString(aInt));

        Integer bInt = new Integer(&amp;#34;180&amp;#34;);
        System.out.println(bInt);
        System.out.println(bInt.toString());

        System.out.println(Integer.MAX_VALUE);
        System.out.println(Integer.MIN_VALUE);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;int-和-string-转换&#34;&gt;int 和 String 转换&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_Integer {
    public static void main(String[] args) {
        // int -&amp;gt; String
        int a =  160;
        String s1 = a + &amp;#34;&amp;#34;;

        String s2 = String.valueOf(a);

        Integer i3 = new Integer(a);
        String s3 = i3.toString();

        String s4 = Integer.toString(a);


        // String -&amp;gt; int
        String str = &amp;#34;200&amp;#34;;

        int a1 = Integer.parseInt(str);

        Integer ig2 = new Integer(str);
        int a2 = ig2.intValue();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;java-基本数据类型自动装箱-和-拆箱&#34;&gt;Java 基本数据类型自动装箱 和 拆箱&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;基本数据类型才可以自动装箱 拆箱&lt;/li&gt;
&lt;li&gt;Integer Boolean 自动装箱 拆箱时需要判断对象不为&lt;/li&gt;
&lt;li&gt;byte范围内-128到127内, 不会创建新的对象, 而是从常量池中获取.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo3_Integer {
    public static void main(String[] args) {
        Integer i = 200;
        System.out.println(i);

        int a = i + 100;
        System.out.println(a);

        Integer a2 = 127;
        Integer a3 = 127;
        Integer a4 = 128;
        Integer a5 = 128;

        System.out.println(a2 == a3);
        System.out.println(a4 == a5);

        System.out.println(a2.equals(a3));
        System.out.println(a4.equals(a5));

        Integer a7 = new Integer(127);
        Integer a8 = new Integer(127);
        System.out.println(a7 == a8);

        // 自动装箱用的Integer.valueOf方法
        Integer a9 = Integer.valueOf(127);
        Integer a10 = Integer.valueOf(127);
        System.out.println(a9 == a10);

        // Integer -&amp;gt; int
        Integer iObject = Integer.valueOf(3);
        int a11 = iObject.intValue();
        System.out.println(a11);
    }
}
// 200 300 T F T T F T 3
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java的String类 Li.033</title>
      <link>https://lizicai.com/p/java%E7%9A%84string%E7%B1%BB-li.033/</link>
      <pubDate>Tue, 10 Aug 2021 22:15:46 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E7%9A%84string%E7%B1%BB-li.033/</guid>
      <description>&lt;h2 id=&#34;scanner&#34;&gt;Scanner&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;hasNext() 表示判断下一个输入项是否是字符串, hasNextInt() 表示判断下一个输入项是否是int, 否则返回false&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;next()获取输入项的字符串, nextInt 获取项输入的int&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Scanner;

public class Demo1_Scanner {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        if( scanner.hasNextInt()) {
            int p = scanner.nextInt();
            System.out.println(p);
        } else {
            System.out.println(&amp;#34;输入内容不是int 数字&amp;#34;);
        }
        scanner.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;输入1个整数-1个数字串-输出数字和字符串-错误示例&#34;&gt;输入1个整数, 1个数字串, 输出数字和字符串, 错误示例&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Scanner;

public class Demo2_Scanner {
    public static void main(String[] args) {
        // 输入1个整数, 1个字符串的 错误示例
        Scanner sc = new Scanner(System.in);
        int i = sc.nextInt();
        String s = sc.nextLine();
        System.out.println(i+&amp;#34; &amp;#34;+s);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;输入1个整数-1个数字串-输出数字和字符串-正确示例-都当成一行字符串-后期string转成int类型&#34;&gt;输入1个整数, 1个数字串, 输出数字和字符串, 正确示例, 都当成一行字符串, 后期String转成int类型&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Scanner;
import java.lang.Integer;;
public class Demo2_Scanner {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s1 = sc.nextLine();
        int i = Integer.parseInt(s1);
        String s2 = sc.nextLine();
        System.out.println(s1+ s2);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-类&#34;&gt;String 类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;toString()方法, 没重写前显示包和类名@hashcode()&lt;/li&gt;
&lt;li&gt;常量池的string, 没有则创建, 有则使用现有的string&lt;/li&gt;
&lt;li&gt;使用new String()则会创建常量的副本&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_String {
    public static void main(String[] args) {
        String s1 = new String(&amp;#34;abc&amp;#34;);
        String s2 = &amp;#34;abc&amp;#34;;
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));
    }
}
//结果 false ture
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;使用+号连接的, 是在StringBuffer中连接后, 再把地址指给变量&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo2_String {
    public static void main(String[] args) {
        String s4 = &amp;#34;ab&amp;#34;;
        String s5 = s4 + &amp;#34;c&amp;#34;;
        System.out.println(s4 == s5);
    }
}
// false
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;string-其他方法&#34;&gt;String 其他方法&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;startWith endWith equalsIgnoreCase contains&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo3_String {
    public static void main(String[] args) {
        String sm = &amp;#34;123 sdf z&amp;#34;;
        String s1 = &amp;#34;123&amp;#34;;
        String s2 = &amp;#34;z&amp;#34;;
        String s3 = &amp;#34;123 SDF z&amp;#34;;
        String s4 = &amp;#34;sdf&amp;#34;;
        String s5 = &amp;#34;sDf&amp;#34;;
        System.out.println(sm.startsWith(s1));
        System.out.println(sm.endsWith(s2));
        System.out.println(sm.equalsIgnoreCase(s3));
        System.out.println(sm.contains(s4));
        System.out.println(sm.contains(s5));
        System.out.println(sm.toLowerCase().contains(s4.toLowerCase()));
    }
}
//  T T T T F T
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string练习-模拟用户登录&#34;&gt;String练习, 模拟用户登录&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Scanner;

public class Demo4_String {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String name = &amp;#34;&amp;#34;;
        String passwd = &amp;#34;&amp;#34;;
        for(int i=0;i&amp;lt;3;i++){
            System.out.println(&amp;#34;请输入用户名:&amp;#34;);
            if( sc.hasNextLine() ){
                name = sc.nextLine();
            }
            System.out.println(&amp;#34;请输入用户密码:&amp;#34;);
            if( sc.hasNextLine() ){
                passwd = sc.nextLine();
            }
            if( &amp;#34;admin&amp;#34;.equals(name) &amp;amp;&amp;amp; &amp;#34;admin&amp;#34;.equals(passwd) ){
                System.out.println(&amp;#34;欢迎&amp;#34;+ name + &amp;#34;登录!&amp;#34;);
                break;
            } else {
                if( (2-i)==0 ){
                    System.out.println(&amp;#34;请找回密码, 或过1小时后再重试 !&amp;#34;);
                } else{
                    System.out.println(&amp;#34;用户名或密码错误, 您还有&amp;#34; + (2-i) + &amp;#34;次机会!&amp;#34;);
                }
            }
            name = &amp;#34;&amp;#34;;
            passwd = &amp;#34;&amp;#34;;
        }
        sc.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-的方法&#34;&gt;String 的方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;char charAt(int index) 获取指定索引位置的字符&lt;/li&gt;
&lt;li&gt;int length() 获取字符串长度&lt;/li&gt;
&lt;li&gt;int indexOf(int ch) 获取字母在字符串第一次出现的索引&lt;/li&gt;
&lt;li&gt;int indexOf(String str) 获取字符串第一次出现的出现的索引位置&lt;/li&gt;
&lt;li&gt;int indexOf( int ch, int fromIndex ) 从指定索引位置向后, 字母ch 第一次出现的索引位置&lt;/li&gt;
&lt;li&gt;int indexOf( String str, int fromInex ) 从指定索引位置向后, str 第一次出现的索引位置&lt;/li&gt;
&lt;li&gt;int lastIndexOf(int ch) 最后一次出现字符的索引, 即从后向前找第1次出现字母的索引&lt;/li&gt;
&lt;li&gt;int lastIndexOf(int ch, int fromIndex) 从指定索引向前找, 字素ch 出现的索引&lt;/li&gt;
&lt;li&gt;int lastIndexOf(String str)&lt;/li&gt;
&lt;li&gt;int lastIndexOf(String str, int fromIndex)&lt;/li&gt;
&lt;li&gt;String substring(int beginIndex) 从索引位置开始到结尾截取字符串&lt;/li&gt;
&lt;li&gt;String substring(int beginIndex, int endIndex) 从开始索引 到 结束索引位置前(结束索引不包含) 截取字符串&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo5_String {
    public static void main(String[] args) {
        String sm = &amp;#34;Hello Wrold!&amp;#34;;
        System.out.println(sm.charAt(0));
        //System.out.println(sm.charAt(20));

        System.out.println(sm.length());

        System.out.println(sm.indexOf(&amp;#39;l&amp;#39;));
        System.out.println(sm.indexOf(&amp;#39;z&amp;#39;));

        System.out.println(sm.indexOf(&amp;#34;Wrold&amp;#34;));
        System.out.println(sm.indexOf(&amp;#34;Wrood&amp;#34;));

        System.out.println(sm.indexOf(&amp;#39;o&amp;#39;,5));

        System.out.println( sm.indexOf( &amp;#34;old&amp;#34;, 5 ) );
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo6_String {
    public static void main(String[] args) {
        String s = &amp;#34;ET drive UFO! So COOL&amp;#34;;

        System.out.println(s.lastIndexOf(&amp;#39;O&amp;#39;));

        System.out.println(s.lastIndexOf(&amp;#39;O&amp;#39;,17));

        System.out.println(s.lastIndexOf(&amp;#34;UFO&amp;#34;));

        System.out.println(s.lastIndexOf(&amp;#34;So&amp;#34;, 9));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo7_String {
    public static void main(String[] args) {
        String s = &amp;#34;PhpIsBest?&amp;#34;;
        System.out.println(s.substring(3));

        System.out.println(s.substring(0,3));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-练习-统计大写-小写-数字-其他字符个数&#34;&gt;String 练习, 统计大写, 小写, 数字, 其他字符个数&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo9_String {
    public static void main(String[] args) {
        String s = &amp;#34;C C++ C# Go Java Javascript Php Swift 2021&amp;#34;;
        int sumUp    = 0;
        int sumLow   = 0;
        int sumNu    = 0;
        int sumOther = 0;
        for(int i=0;i&amp;lt;s.length();i++){
            char tmpChar = s.charAt(i);
            if( tmpChar &amp;lt;= &amp;#39;z&amp;#39; &amp;amp;&amp;amp; tmpChar &amp;gt;= &amp;#39;a&amp;#39;){
                sumLow++;
            } else if( tmpChar &amp;lt;= &amp;#39;Z&amp;#39; &amp;amp;&amp;amp; tmpChar &amp;gt;= &amp;#39;A&amp;#39; ){
                sumUp++;
            } else if( tmpChar &amp;lt;= &amp;#39;9&amp;#39; &amp;amp;&amp;amp; tmpChar &amp;gt;= &amp;#39;0&amp;#39; ){
                sumNu++;
            } else if( &amp;#39; &amp;#39; == tmpChar ){

            } else {
                sumOther++;
            }
        }
        System.out.println(sumUp+&amp;#34;,&amp;#34; + sumLow + &amp;#34;,&amp;#34; + sumNu + &amp;#34;,&amp;#34; + sumOther);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-的方法-1&#34;&gt;String 的方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;byte[] getBytes() 字符串转换为字节数组&lt;/li&gt;
&lt;li&gt;char[] toCharArray() 字符串转换为字符数线&lt;/li&gt;
&lt;li&gt;String valueOf(char[] data) 字符数组转化为字符串&lt;/li&gt;
&lt;li&gt;String valueOf(int i) 把 int 转换为字符串, (valueOf 可以任意类型的数据转化为字符串)&lt;/li&gt;
&lt;li&gt;String toLowerCase() 字符串转换成小写&lt;/li&gt;
&lt;li&gt;String toUpperCase() 字符串转换大写&lt;/li&gt;
&lt;li&gt;concat(String str) 字符串拼接&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo10_String {
    public static void main(String[] args) {
        String s = &amp;#34;Hello&amp;#34;;
        byte [] b = s.getBytes();
        for(int i=0;i&amp;lt;b.length;i++){
            System.out.print(b[i]+&amp;#34; &amp;#34;);
        }
        System.out.println();

        char[] c = s.toCharArray();
        for(int i=0;i&amp;lt;c.length;i++){
            System.out.print(c[i] + &amp;#34; &amp;#34;);
        }
        System.out.println();

        String s2 = String.valueOf(c);
        System.out.println(s2);

        String s3 = String.valueOf(10);
        System.out.println(s3);

        System.out.println(s.toLowerCase());

        System.out.println(s.toUpperCase());

        System.out.println(s.concat(&amp;#34; Wrold!&amp;#34;));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-练习-首字母大写-其他小写&#34;&gt;String 练习, 首字母大写, 其他小写&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo11_String {
    // 字符串首写字母大写, 其他字母小写
    public static void main(String[] args) {
        String s = &amp;#34;what Is A Youth?&amp;#34;;
        if(s.length() &amp;gt; 0){
            System.out.println(s.substring(0,1).toUpperCase() + s.substring(1).toLowerCase());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-练习-int--arr--123-转换成指定格式-1-2-3的字符串&#34;&gt;String 练习, int [] arr = {1,2,3}; 转换成指定格式 {1, 2, 3}的字符串.&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo12_String {
    // int [] arr = {1,2,3}; 转换成指定格式 {1, 2, 3}的字符串.
    public static void main(String[] args) {
        int [] arr = {1,2,3,4,5};
        String s = &amp;#34;&amp;#34;;
        if( 1 == arr.length ){
            s = &amp;#34;{&amp;#34;+ arr[0]+&amp;#34;}&amp;#34;;
        }
        if( arr.length &amp;gt; 1 ){
            for (int i=0; i&amp;lt;arr.length; i++) {
                if ( 0 == i ){
                    s = &amp;#34;{&amp;#34; + arr[i] + &amp;#34;, &amp;#34;;
                }
                else if( i &amp;lt; arr.length - 1 ){
                    s = s + arr[i] + &amp;#34;, &amp;#34;;
                }
                else if( i == arr.length-1 ){
                    s = s + arr[i] + &amp;#34;}&amp;#34;;
                }
            }
        }
        System.out.println(s);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-中的方法&#34;&gt;String 中的方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;String replace(char oldChar, char newChar) 用新字符替换所有旧的字符&lt;/li&gt;
&lt;li&gt;String replace(CharSequence target, CharSequence replacement) 使用新字符串替换旧的字符串&lt;/li&gt;
&lt;li&gt;int compareTo(String anotherString) 比较2个字符串&lt;/li&gt;
&lt;li&gt;int compareToIgnoreCase(String str) 忽略大小写比较2个字符串&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo13_String {
    public static void main(String[] args) {
        String s = &amp;#34;Switch Mario&amp;#34;;

        String s2 = s.replace(&amp;#39;i&amp;#39;,&amp;#39;a&amp;#39;);
        System.out.println(s2);

        String s3 = s.replace(&amp;#34;Mario&amp;#34;, &amp;#34;Zelda&amp;#34;);
        System.out.println(s3);

        String s4 = &amp;#34;     switch one  &amp;#34;;
        System.out.println(&amp;#34;{&amp;#34;+s4.trim()+&amp;#34;}&amp;#34;);

        String s5 = &amp;#34;sEE&amp;#34;;
        String s6 = &amp;#34;see&amp;#34;;
        int sum = s5.compareTo(s6);
        System.out.println(sum);

        int sum2 = s5.compareToIgnoreCase(s6);
        System.out.println(sum2);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-练习反转字符串&#34;&gt;String 练习反转字符串&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import java.util.Scanner;
public class Demo14_String {
    //反转字符串
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = &amp;#34;&amp;#34;;
        String s2 = &amp;#34;&amp;#34;;
        if( sc.hasNextLine() ){
            s = sc.nextLine();
        }
        char [] cs = s.toCharArray();
        for (int i=0; i&amp;lt;(cs.length/2); i++) {
            char temp = cs[cs.length-1-i];
            cs[cs.length-1-i] = cs[i];
            cs[i] = temp;
        }
        System.out.println(new String(cs));

        char [] cs2 = s.toCharArray();
        for (int i=cs2.length-1; i&amp;gt;=0; i--) {
            s2 = s2 + cs2[i];
        }
        System.out.println(s2);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;string-练习-查找str在另一个str出现的次数&#34;&gt;String 练习, 查找str在另一个str出现的次数&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo15_String {
    public static void main(String[] args) {
        String sMax = &amp;#34;Whatever is worth doing is worth doing well.&amp;#34;;
        String sMin = &amp;#34;worth&amp;#34;;
        int sum   = 0;
        int j     = 0;
        int index = 0;
        while(index&amp;lt;sMax.length()){
            j = sMax.indexOf(sMin, index);
            if(-1 == j){
                break;
            } else{
                index = j + 1;
                sum++;
            }
        }
        System.out.println(sum);
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java重写equals方法 Li.032</title>
      <link>https://lizicai.com/p/java%E9%87%8D%E5%86%99equals%E6%96%B9%E6%B3%95-li.032/</link>
      <pubDate>Tue, 10 Aug 2021 21:49:52 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E9%87%8D%E5%86%99equals%E6%96%B9%E6%B3%95-li.032/</guid>
      <description>&lt;h2 id=&#34;未重写前equals是比较引用的地址-如比较2个对象-地址一定是不同的&#34;&gt;未重写前equals是比较引用的地址, 如比较2个对象, 地址一定是不同的&lt;/h2&gt;
&lt;h2 id=&#34;重写后-可以比较对象的属性相同-则认为对象相同&#34;&gt;重写后, 可以比较对象的属性相同, 则认为对象相同&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo1_Object {
    private int age;
    private String name;
    Demo1_Object(){}
    Demo1_Object(int age,String name){
        this.age  = age;
        this.name = name;
    }
    public static void main(String[] args) {
        Demo1_Object d  = new Demo1_Object(12, &amp;#34;xiaoming&amp;#34;);
        Demo1_Object d2 = new Demo1_Object(12, &amp;#34;xiaohong&amp;#34;);
        Demo1_Object d3 = new Demo1_Object(12, &amp;#34;xiaoming&amp;#34;);
        System.out.println(d.equals(d2));
        System.out.println(d.equals(d3));
    }
    public boolean equals(Object obj){
        // 重写Object 类中equals方法
        if( obj instanceof Demo1_Object ){
            Demo1_Object demo = (Demo1_Object)obj;
            return this.name.equals(demo.name) &amp;amp;&amp;amp; this.age == demo.age;
        }
        return false;
    }
    public boolean equals(Demo1_Object dobj){
        //这个不是重写, 是重载
        return this.name.equals(dobj.name) &amp;amp;&amp;amp; this.age == dobj.age;
    }
    public String toString(){
        return (age + name);
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Java面向对象 Li.031</title>
      <link>https://lizicai.com/p/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-li.031/</link>
      <pubDate>Fri, 06 Aug 2021 17:14:22 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-li.031/</guid>
      <description>&lt;h2 id=&#34;package&#34;&gt;Package&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;包只能类的首行 com.lizica.java&lt;/li&gt;
&lt;li&gt;默认编译是不会创建包的文件夹, 加入参数 -d .才会创建&lt;/li&gt;
&lt;li&gt;运行类的方式就变了, 必须带上包的路径才的运行类&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;javac -d . Demo1_Package.java
java com.lizicai.java.Demo1_Package
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package com.lizicai.java;
public class Demo1_Package {
    public static void main(String[] args) {
        System.out.println(&amp;#34;hello&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;引用时候3种方式, 推荐导入具体的类,第2种&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class Demo2_Package{
    public static void main(String[] args) {
        com.lizicai.java.Demo1_Package d = new com.lizicai.java.Demo1_Package();
        d.sprint();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.java.Demo1_Package;
class Demo2_Package{
    public static void main(String[] args) {
        Demo1_Package d = new Demo1_Package();
        d.sprint();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.lizicai.java.*;
class Demo2_Package{
    public static void main(String[] args) {
        Demo1_Package d = new Demo1_Package();
        d.sprint();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;不同类修饰符-和-包访问关系&#34;&gt;不同类修饰符 和 包访问关系&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;类修饰符&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;本类&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;同一个包下(子类和无关系)&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;不同包下(子类)&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;不同包下(无关系)&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;private&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;默认&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;protected&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;public&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;java-修饰符总结&#34;&gt;Java 修饰符总结&lt;/h2&gt;
&lt;h3 id=&#34;修饰符&#34;&gt;修饰符&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;权限修饰符：private，默认的，protected，public&lt;/li&gt;
&lt;li&gt;状态修饰符：static，final&lt;/li&gt;
&lt;li&gt;抽象修饰符：abstract&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;类的修饰符&#34;&gt;类的修饰符&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;权限修饰符：默认修饰符，public&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;状态修饰符：final&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;抽象修饰符：abstract&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用的最多的就是：public&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;成员变量的修饰符&#34;&gt;成员变量的修饰符&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;权限修饰符：private，默认的，protected，public&lt;/li&gt;
&lt;li&gt;状态修饰符：static，final&lt;/li&gt;
&lt;li&gt;用的最多的就是：private&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;构造方法的修饰符&#34;&gt;构造方法的修饰符&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;权限修饰符：private，默认的，protected，public&lt;/li&gt;
&lt;li&gt;用的最多的就是：public&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;成员方法&#34;&gt;成员方法&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;权限修饰符：private，默认的，protected，public&lt;/li&gt;
&lt;li&gt;状态修饰符：static，final&lt;/li&gt;
&lt;li&gt;抽象修饰符：abstract&lt;/li&gt;
&lt;li&gt;用的最多的就是：public&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;组合规则&#34;&gt;组合规则&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;成员变量：public static final&lt;/li&gt;
&lt;li&gt;成员方法：public static, public abstract, public final&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;内部类&#34;&gt;内部类&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo3_Iner {
    public static void main(String[] args) {
        Outer.Inner aa = new Outer().new Inner();
        aa.method();
    }
}
class Outer{
    class Inner{
        public void method(){
            System.out.println(&amp;#34;InerClass&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;静态内部类&#34;&gt;静态内部类&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo4_StaticInner {
    public static void main(String[] args) {
        Outer.Inner aa = new Outer.Inner();
        aa.method();
    }
}
class Outer{
    static class Inner{
        public void method(){
            System.out.println(&amp;#34;InerClass&amp;#34;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;内部类调用外部类成员&#34;&gt;内部类调用外部类成员&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo5_Inner {
    public static void main(String[] args) {
        Outer.Inner o = new Outer().new Inner();
        o.method();
    }
}
class Outer{
    private int num = 30;
    class Inner{
        private int num = 20;
        public void method(){
            int num = 10;
            System.out.println(num);
            System.out.println(this.num);
            System.out.println(Outer.this.num);
        }
        public int getNum() {
            return num;
        }
    }
    //外部类调用内部类成员
    public void test(){
        Inner n = new Inner();
        System.out.println(n.getNum());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo7_Inner {
    public static void main(String[] args) {
        Outer o = new Outer();
        o.printe();
    }
}
interface Inter1{
    public void method();
}
class Outer{
    class Inner implements Inter1{
        public void method(){
            System.out.println(&amp;#34;LLL&amp;#34;);
        }
    }
    public void printe(){
        Inner i = new Inner();
        i.method();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;匿名内部类-只能放在方法内-推荐只有一个方法的类才使用匿名内部类&#34;&gt;匿名内部类, 只能放在方法内, 推荐只有一个方法的类才使用匿名内部类.&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo8_Inner {
    public static void main(String[] args) {
        Outer o = new Outer();
        o.test();
    }
}
interface Inter2{
    public void method();
    public void method2();
}
class Outer{
    public void test(){
        new Inter2(){
            public void method(){
                System.out.println(&amp;#34;HHH&amp;#34;);
            }
            public void method2(){
                System.out.println(&amp;#34;KKK&amp;#34;);
            }
        }.method();
        new Inter2(){
            public void method(){
                System.out.println(&amp;#34;HHH&amp;#34;);
            }
            public void method2(){
                System.out.println(&amp;#34;KKK&amp;#34;);
            }
        }.method2();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo9_Inner {
    public static void main(String[] args) {
        Outer o = new Outer();
        o.test();
    }
}
interface Inter2{
    public void method();
    public void method2();
}
class Outer{
    public void test(){
        Inter2 i = new Inter2(){
            public void method(){
                System.out.println(&amp;#34;HHH&amp;#34;);
            }
            public void method2(){
                System.out.println(&amp;#34;KKK&amp;#34;);
            }
        };
        i.method();
        i.method2();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;匿名内部类当作参数使用&#34;&gt;匿名内部类当作参数使用&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo10_Inner {
    public static void main(String[] args) {
        Outer o = new Outer();
        o.method(new Inter(){
            public void method(){
                System.out.println(&amp;#34;NoName&amp;#34;);
            }
        });
    }
}
interface Inter{
    public void method();
}
class Outer {
    public void method(Inter i){
        i.method();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;匿名内部类当前返回类型使用&#34;&gt;匿名内部类当前返回类型使用&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class Demo11_Inner {
    public static void main(String[] args) {
        Outer.method().show();
    }
}
interface Inter{
    public void show();
}
class Outer {
    public static Inter method(){
        return new Inter(){
            public void show(){
                System.out.println(&amp;#34;HaHaHa...&amp;#34;);
            }
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;面向对象成员变量和局部变量的区别&#34;&gt;面向对象(成员变量和局部变量的区别)&lt;/h2&gt;
&lt;h3 id=&#34;在类中的位置不同&#34;&gt;在类中的位置不同&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;成员变量: 在类中方法外&lt;/li&gt;
&lt;li&gt;局部变量: 在方法宣言中或者方法声明上&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;在内存中位置不同&#34;&gt;在内存中位置不同&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;成员变量: 在堆内存(成员变量属于对象, 对象进堆内存)&lt;/li&gt;
&lt;li&gt;局部变量: 在栈内存(局部变量属于方法, 方法进栈内存)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;生命周期不同&#34;&gt;生命周期不同&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;成员变量: 随着对象的创建而存在, 随着对象的消失而消失&lt;/li&gt;
&lt;li&gt;局部变量: 随着方法的调用而存在, 随着方法的调用完毕而消失&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;初始化值不同&#34;&gt;初始化值不同&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;成员变量: 有默认初始化值&lt;/li&gt;
&lt;li&gt;局部变量: 没有默认初始化值, 必须定义, 赋值, 然后才能使用.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;注意事项&#34;&gt;注意事项&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;局部变量名称可以和成员变量名称一样, 在方法中使用的时候, 采用的是就近原则&lt;/li&gt;
&lt;li&gt;基本数据类型变量包括哪些: byte,short,int,long,float,double,boolean,char&lt;/li&gt;
&lt;li&gt;线上服务数据类型变量包括哪些: 数组, 类, 接口, 枚举&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;静态代码块-构造代码块-构造方法搜索顺序&#34;&gt;静态代码块 构造代码块 构造方法搜索顺序&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public class FuZi {
    public static void main(String[] args) {
        Fu f = new Zi();
    }
}
class Fu{
    static {
        System.out.println(&amp;#34;Fu static&amp;#34;);
    }

    {
        System.out.println(&amp;#34;Fu 构造代码块&amp;#34;);
    }

    Fu(){
        System.out.println(&amp;#34;Fu 构造方法&amp;#34;);
    }
}

class Zi extends Fu{
    static {
        System.out.println(&amp;#34;Zi static&amp;#34;);
    }

    {
        System.out.println(&amp;#34;Zi 构造代码块&amp;#34;);
    }

    Zi(){
        System.out.println(&amp;#34;Zi 构造方法&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Fu static
Zi static
Fu 构造代码块
Fu 构造方法
Zi 构造代码块
Zi 构造方法
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;面向对象-方法重写概述及其应用-&#34;&gt;面向对象( 方法重写概述及其应用 )&lt;/h2&gt;
&lt;h3 id=&#34;方法重写是什么&#34;&gt;方法重写是什么&lt;/h3&gt;
&lt;p&gt;子父类出现一模一样的方法( 注意: 值返回值类型可以是子父类)&lt;/p&gt;
&lt;h3 id=&#34;方法重写的应用&#34;&gt;方法重写的应用&lt;/h3&gt;
&lt;p&gt;当子类需要父类的功能, 而功能主体子类有自己的特有内容时, 可以重写父类中的方法&lt;/p&gt;
&lt;h3 id=&#34;方法重写注意事项&#34;&gt;方法重写注意事项&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;父类中私有方法不能被重写, 因为父类私有方法子类根本无法继承&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;子类重写父类方法时, 访问权限不能更低, 最好一致&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;父类静态方法, 子类也必须通过静态方法进行重写,( 其实是静态的覆盖 )&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;抽象类&#34;&gt;抽象类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;抽象类必须是abstract 修饰&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;抽象方法必须有abstract 修饰&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;抽象类不一定有抽象方法(可以全是非抽象方法), 有抽象方法的一定是抽象类或者接口&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;抽象类不能实例化, 可以由继承的子类实例化&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;抽象类的子类要么是抽象类要么实现全部接口的非抽象类&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;抽象类成员特点&#34;&gt;抽象类成员特点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;抽象类成员特点: 既可以是变量也可以是常量, abstract 不能修饰成员变量&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;构造方法: 有, 用于子类访问父类数据的初始化.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;成员方法, 既可以是抽象的, 也可以是非抽象的.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Java接口和类 Li.030</title>
      <link>https://lizicai.com/p/java%E6%8E%A5%E5%8F%A3%E5%92%8C%E7%B1%BB-li.030/</link>
      <pubDate>Thu, 05 Aug 2021 23:22:27 +0800</pubDate>
      <guid>https://lizicai.com/p/java%E6%8E%A5%E5%8F%A3%E5%92%8C%E7%B1%BB-li.030/</guid>
      <description>&lt;h2 id=&#34;java-类-和-接口&#34;&gt;Java 类 和 接口&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;类和类只能是继承, 类不能继承构造函数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;类与接口, 类可以实现多个接口, 不能继承接口&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;接口与接口, 接口可以继承多个接口, 不能实现接口&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;类 类 接口, 类只能继承一个类, 同时实现多个接口&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;抽象类-与-接口&#34;&gt;抽象类 与 接口&lt;/h2&gt;
&lt;h3 id=&#34;抽象类&#34;&gt;抽象类&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;成员变量: 常量 或者 变量&lt;/li&gt;
&lt;li&gt;构造方法: 有&lt;/li&gt;
&lt;li&gt;成员方法: 可以抽象, 也可以非抽象&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;接口&#34;&gt;接口&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;成员变量: 常量&lt;/li&gt;
&lt;li&gt;成员方法: 抽象方法, &lt;strong&gt;强制, 不写也会默认抽象&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;abstract class Demo1_Animal {
    public static void main (String[] args) {
        Cat c = new Cat(12, &amp;#34;美短&amp;#34;);
        c.eat();
        c.sleep();
        JumpCat jumpCat = new JumpCat(1, &amp;#34;跳高猫&amp;#34;);
        jumpCat.eat();
        jumpCat.sleep();
        jumpCat.jump();
    }
}

abstract class Animal{
    private int age;
    private String name;

    Animal(){ }
    Animal(int age, String name){
        this.age = age;
        this.name = name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getName() {
        return name;
    }
    abstract public void eat();
    abstract public void sleep();
}

class Cat extends Animal{
    private int age;
    private String name;
    Cat(){}
    Cat(int age, String name){
        super(age, name);
    }
    public void eat(){
        System.out.println(&amp;#34;Fish&amp;#34;);
    }
    public void sleep(){
        System.out.println(&amp;#34;sleep whit bowl&amp;#34;);
    }
}
interface Jump{
    public void jump();
}

class JumpCat extends Cat implements Jump{
    JumpCat(){}
    JumpCat(int age, String name){
        super(age,name);
    }
    public void jump(){
        System.out.println(&amp;#34;jump height&amp;#34;);
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>2021计划 Li.029</title>
      <link>https://lizicai.com/p/2021%E8%AE%A1%E5%88%92-li.029/</link>
      <pubDate>Thu, 05 Aug 2021 17:26:29 +0800</pubDate>
      <guid>https://lizicai.com/p/2021%E8%AE%A1%E5%88%92-li.029/</guid>
      <description>&lt;h2 id=&#34;计划&#34;&gt;计划&lt;/h2&gt;
&lt;p&gt;时间过的太快了&lt;/p&gt;
&lt;p&gt;俺30了&lt;/p&gt;
&lt;p&gt;说真的还没有什么能拿出手的技能&lt;/p&gt;
&lt;p&gt;感觉一线越来越难生存&lt;/p&gt;
&lt;p&gt;分分钟失业&lt;/p&gt;
&lt;p&gt;中年焦虑&lt;/p&gt;
&lt;p&gt;生活有点难&lt;/p&gt;
&lt;p&gt;之前估算的, 要想留在一线, 工资至少30K才行&lt;/p&gt;
&lt;p&gt;也没&lt;/p&gt;
&lt;p&gt;所以考虑回省会变成一迫切的问题了&lt;/p&gt;
&lt;p&gt;看了省会情况, 没啥重要技能难找工作的&lt;/p&gt;
&lt;p&gt;下一段时间, 计划学习Java&lt;/p&gt;
&lt;p&gt;至少能写个项目出来&lt;/p&gt;
&lt;p&gt;这样回省会不至于饿死&lt;/p&gt;
&lt;p&gt;就这样&lt;/p&gt;
&lt;p&gt;2021 年 08 月 05 日 周四&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hugo学习路线 Li.028</title>
      <link>https://lizicai.com/p/hugo%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF-li.028/</link>
      <pubDate>Wed, 04 Aug 2021 23:09:07 +0800</pubDate>
      <guid>https://lizicai.com/p/hugo%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF-li.028/</guid>
      <description>&lt;h2 id=&#34;1-hugo-学习路线&#34;&gt;1. Hugo 学习路线&lt;/h2&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/hugo-learn-mindnode.png&#34; alt=&#34;Hugo学习路线&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;Hugo学习路线&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;11-基础&#34;&gt;1.1 基础&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;了解Hugo, 使用Hugo命令和Github, 搭建起来静态博客&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%92%8cgithub-pages%e6%90%ad%e5%bb%ba%e9%9d%99%e6%80%81%e7%bd%91%e7%ab%99li.004/&#34; target=&#34;_blank&#34;&gt;Hugo和GitHub Pages搭建静态网站Li.004&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;了解一下常用hugo命令&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%b8%b8%e7%94%a8%e5%91%bd%e4%bb%a4li.023/&#34; target=&#34;_blank&#34;&gt;Hugo常用命令Li.023&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;Hugo使用Markdown标记语言, Markdown语法学习是必要的, 仅有十几个标签&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/markdown%e8%af%ad%e6%b3%95li.002/&#34; target=&#34;_blank&#34;&gt;Markdown语法Li.002&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;找一个顺手的Markdown编辑器, 用来写作&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/markdown%e7%bc%96%e8%be%91%e8%bd%af%e4%bb%b6li.003/&#34; target=&#34;_blank&#34;&gt;Markdown编辑软件Li.003&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;12-进阶&#34;&gt;1.2 进阶&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;解决Markdown图片存放问题&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e4%b8%admarkdown%e5%9b%be%e7%89%87%e8%b5%84%e6%ba%90%e5%ad%98%e6%94%be%e5%87%a0%e7%a7%8d%e6%96%b9%e5%bc%8fli.024/&#34; target=&#34;_blank&#34;&gt;Hugo中Markdown图片资源存放几种方式Li.024&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐存放在Github(2.1方式)上, 免费, 容易操作&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;13-难度&#34;&gt;1.3 难度&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;Hugo静态网站常用管理方式, 使用自有域名&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e9%9d%99%e6%80%81%e7%bd%91%e7%ab%99%e5%b8%b8%e7%94%a8%e7%ae%a1%e7%90%86%e6%96%b9%e5%bc%8fli.026/&#34; target=&#34;_blank&#34;&gt;Hugo静态网站常用管理方式Li.026&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐方式1.2使用Github, 配置自己的域名, 免费&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;Hugo的Shortcode模板片段,插入视频, 定制网页&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e7%9a%84shortcode%e6%94%af%e6%8c%81%e8%a7%86%e9%a2%91%e7%ad%89%e5%92%8c%e4%b8%bb%e9%a2%98%e4%bf%ae%e6%94%b9li.027/&#34; target=&#34;_blank&#34;&gt;Hugo的shortcode(支持视频等)和主题修改Li.027&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;插入bilibili和YouTube视频, Hugo完全可以作为自媒体平台了&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hugo的shortcode(支持视频等)和主题修改 Li.027</title>
      <link>https://lizicai.com/p/hugo%E7%9A%84shortcode%E6%94%AF%E6%8C%81%E8%A7%86%E9%A2%91%E7%AD%89%E5%92%8C%E4%B8%BB%E9%A2%98%E4%BF%AE%E6%94%B9-li.027/</link>
      <pubDate>Tue, 03 Aug 2021 22:32:56 +0800</pubDate>
      <guid>https://lizicai.com/p/hugo%E7%9A%84shortcode%E6%94%AF%E6%8C%81%E8%A7%86%E9%A2%91%E7%AD%89%E5%92%8C%E4%B8%BB%E9%A2%98%E4%BF%AE%E6%94%B9-li.027/</guid>
      <description>&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%ad%a6%e4%b9%a0%e8%b7%af%e7%ba%bfli.028/&#34; target=&#34;_blank&#34;&gt;本篇文章属于Hugo学习路线Li.028一部分&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;1-hugo的shortcodes是什么&#34;&gt;1. Hugo的Shortcodes是什么?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;shortcode 是一些可以直接插入内容文档中的助记符，在Hugo 生成网站时，会将这些助记符替换为相应的HTML 代码片段（严格来说是模板片段)&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;2-为什么需要shortcodes&#34;&gt;2. 为什么需要Shortcodes.&lt;/h2&gt;
&lt;h3 id=&#34;虽然markdown-支持html标签-写起来相当麻烦-碰到页面兼容性问题-就得修改所有写了html的markdown文件-想想都可怕&#34;&gt;虽然Markdown 支持html标签, 写起来相当麻烦, 碰到页面兼容性问题, 就得修改所有写了Html的Markdown文件, 想想都可怕&lt;/h3&gt;
&lt;h3 id=&#34;shortcode像如下-类似特殊markdown标记语言&#34;&gt;shortcode像如下, 类似特殊Markdown标记语言&lt;/h3&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/shortcode-nuimg.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;显示效果&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;步骤, shortcode示例&lt;/a&gt;
&lt;/div&gt;

&lt;h3 id=&#34;可在markdown中使用-如果出现问题-只需要修改模板片段即可&#34;&gt;可在Markdown中使用, 如果出现问题, 只需要修改模板片段即可.&lt;/h3&gt;
&lt;h2 id=&#34;3-shortcodes-可以用来做什么-嵌入视频之类-hugo静态博客也能是自媒体&#34;&gt;3. Shortcodes 可以用来做什么, 嵌入视频之类, Hugo静态博客也能是自媒体.&lt;/h2&gt;
&lt;h3 id=&#34;31-可在网页嵌入视频-常用网站bilibili-和-youtube&#34;&gt;3.1 可在网页嵌入视频, 常用网站Bilibili 和 Youtube.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;在hugo网站目录layouts/shortcodes中创建bilibili.html文件&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;文件名称bilibili, 引用的时候也是相同名称&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;style&amp;gt;
.meta-media {
  position: relative;
  margin-bottom: 30px;
  display: flex;
  width: 100%;
  height: 0;
  padding-bottom: 75%;
}
.video {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
}
&amp;lt;/style&amp;gt;
&amp;lt;div class=&amp;#34;meta-media&amp;#34;&amp;gt;
    &amp;lt;iframe src=&amp;#34;{{ .Get &amp;#34;src&amp;#34; }}&amp;amp;high_quality=1&amp;#34; frameborder=&amp;#34;no&amp;#34; scrolling=&amp;#34;yes&amp;#34; allowfullscreen=&amp;#34;allowfullscreen&amp;#34; high_quality=&amp;#34;1&amp;#34; framespacing=&amp;#34;1&amp;#34; class=&amp;#34;video&amp;#34; &amp;gt;
&amp;lt;/iframe&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;复制bilibili视频代码&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.bilibili.com/video/BV1144y167iZ&#34; target=&#34;_blank&#34;&gt;示例视频地址&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/shortcode-bilibili-copy-src.png&#34; alt=&#34;复制 嵌入代码&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;复制 嵌入代码&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;得到如下, 复制src双引号内容&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;iframe src=&amp;#34;//player.bilibili.com/player.html?aid=973574581&amp;amp;bvid=BV1144y167iZ&amp;amp;cid=352795710&amp;amp;page=1&amp;#34; scrolling=&amp;#34;no&amp;#34; border=&amp;#34;0&amp;#34; frameborder=&amp;#34;no&amp;#34; framespacing=&amp;#34;0&amp;#34; allowfullscreen=&amp;#34;true&amp;#34;&amp;gt; &amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;引用&lt;/a&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/shortcode-bilibili-mark.png&#34; alt=&#34;复制src到shortcode格式内&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;复制src到shortcode格式内&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;style&gt;
.meta-media {
  position: relative;
  margin-bottom: 30px;
  display: flex;
  width: 100%;
  height: 0;
  padding-bottom: 75%;
}
.video {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
}
&lt;/style&gt;

&lt;div class=&#34;meta-media&#34;&gt;
    &lt;iframe src=&#34;//player.bilibili.com/player.html?aid=973574581&amp;amp;bvid=BV1144y167iZ&amp;amp;cid=352795710&amp;amp;page=1&amp;high_quality=1&#34; frameborder=&#34;no&#34; scrolling=&#34;yes&#34; allowfullscreen=&#34;allowfullscreen&#34; high_quality=&#34;1&#34; framespacing=&#34;1&#34; class=&#34;video&#34; &gt;
&lt;/iframe&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;Youtube, 在layouts/shortcodes创建youtube.html&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;同名会覆盖Hugo原生的youtube shortcode&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;style&amp;gt;
.meta-media {
  position: relative;
  margin-bottom: 30px;
  display: flex;
  width: 100%;
  height: 0;
  padding-bottom: 75%;
}
.video {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
}
&amp;lt;/style&amp;gt;
&amp;lt;div class=&amp;#34;meta-media&amp;#34;&amp;gt;
&amp;lt;iframe src=&amp;#34;https://www.youtube.com/embed/{{ .Get &amp;#34;embed&amp;#34; }}&amp;#34; frameborder=&amp;#34;no&amp;#34; scrolling=&amp;#34;yes&amp;#34; allowfullscreen=&amp;#34;allowfullscreen&amp;#34; high_quality=&amp;#34;1&amp;#34; framespacing=&amp;#34;1&amp;#34; class=&amp;#34;video&amp;#34; &amp;gt;
&amp;lt;/iframe&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/shortcode-youtube.png&#34; alt=&#34;引用&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;引用&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;meta-media&#34;&gt;
&lt;iframe src=&#34;https://www.youtube.com/embed/zvwsYx9cMY0&#34; frameborder=&#34;no&#34; scrolling=&#34;yes&#34; allowfullscreen=&#34;allowfullscreen&#34; high_quality=&#34;1&#34; framespacing=&#34;1&#34; class=&#34;video&#34; &gt;
&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;静态博客嵌入视频完成, 完全可以作为自媒体平台&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;4-创建一个shortcode&#34;&gt;4. 创建一个shortcode&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;div style=&amp;#34;justify-content: center;text-align:center;color: var(--secondary);&amp;#34;&amp;gt;
&amp;lt;div &amp;gt;
    &amp;lt;img src=&amp;#34;{{ .Get &amp;#34;src&amp;#34; }}&amp;#34; alt=&amp;#34;{{ .Get &amp;#34;title&amp;#34; }}&amp;#34; style=&amp;#34;max-width: {{ .Get &amp;#34;max-width&amp;#34; }}px; max-height: {{ .Get &amp;#34;max-height&amp;#34; }}px;&amp;#34;&amp;gt;
    &amp;lt;p style=&amp;#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&amp;#34; &amp;gt;{{ .Get &amp;#34;title&amp;#34; }}&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;其中{{ .Get &amp;ldquo;title&amp;rdquo; }}是shortcode引用时使用的参数名称中引号内容title=&amp;quot;&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;src是图片链接&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其中{{ .Get &amp;ldquo;len&amp;rdquo; }}定义图片最大长度, 可以省略, 无限制&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/shortcode-imgtitle.png&#34; alt=&#34;标题在图片下面&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;标题在图片下面&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&#34;5-以-hahahugoshortcode22s14hbhb主题为例&#34;&gt;5. 以 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/adityatelange/hugo-PaperMod&#34; target=&#34;_blank&#34;&gt;hugo-PaperMod&lt;/a&gt; 

主题为例&lt;/h2&gt;
&lt;h3 id=&#34;51-papermodassetscsscoretheme-varscss中控制黑暗白天主题显示-更改就可看到效果&#34;&gt;5.1 papermod/assets/css/core/theme-vars.css中控制黑暗/白天主题显示, 更改就可看到效果&lt;/h3&gt;
&lt;h3 id=&#34;52-更改黑暗主题颜色-就能和hahahugoshortcode22s15hbhb黑暗主题一致&#34;&gt;5.2 更改黑暗主题颜色, 就能和
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com&#34; target=&#34;_blank&#34;&gt;Lizicai.com&lt;/a&gt; 

黑暗主题一致.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;单纯黑色对比太强烈了, 更改成灰蓝色了&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;.dark {
    /*--theme: #1d1e20;*/
    --theme: #3c4456;
    /*--entry: #2e2e33;*/
    --entry: #323442;
    --primary: rgba(255, 255, 255, 0.84);
    --secondary: rgba(255, 255, 255, 0.56);
    --tertiary: rgba(255, 255, 255, 0.16);
    --content: rgba(255, 255, 255, 0.74);
    --hljs-bg: #2e2e33;
    /*--code-bg: #37383e;*/
    --code-bg: #313742;
    --border: #333;
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Hugo静态网站常用管理方式 Li.026</title>
      <link>https://lizicai.com/p/hugo%E9%9D%99%E6%80%81%E7%BD%91%E7%AB%99%E5%B8%B8%E7%94%A8%E7%AE%A1%E7%90%86%E6%96%B9%E5%BC%8F-li.026/</link>
      <pubDate>Mon, 02 Aug 2021 23:59:19 +0800</pubDate>
      <guid>https://lizicai.com/p/hugo%E9%9D%99%E6%80%81%E7%BD%91%E7%AB%99%E5%B8%B8%E7%94%A8%E7%AE%A1%E7%90%86%E6%96%B9%E5%BC%8F-li.026/</guid>
      <description>&lt;h2 id=&#34;1-列表出全部方式&#34;&gt;1. 列表出全部方式&lt;/h2&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/hugo-manage-mindnode.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;11-本地文章hugo生成静态网站-上传github-github提供域名&#34;&gt;1.1 本地文章Hugo生成静态网站-&amp;gt;上传Github, Github提供域名&lt;/h3&gt;
&lt;h3 id=&#34;12-本地文章hugo生成静态网站-上传github-使用自有域名-配置域名cname&#34;&gt;1.2 本地文章Hugo生成静态网站-&amp;gt;上传Github, 使用自有域名, 配置域名CNAME&lt;/h3&gt;
&lt;h3 id=&#34;13-本地文章hugo生成静态网站-rsycn上传自己服务器上-使用自有域名&#34;&gt;1.3 本地文章Hugo生成静态网站-&amp;gt;(rsycn)上传自己服务器上, 使用自有域名&lt;/h3&gt;
&lt;h3 id=&#34;14-本地文章hugo生成静态网站-上传github-使用github-action在服务器上拉取github静态网站-使用自有域名&#34;&gt;1.4 本地文章Hugo生成静态网站-&amp;gt;上传Github-&amp;gt;(使用Github action)在服务器上拉取Github静态网站, 使用自有域名&lt;/h3&gt;
&lt;h3 id=&#34;15-本地文章hugo生成静态网站-上传github-使用crontab-定时任务在服务器上拉取github静态网站-使用自有域名&#34;&gt;1.5 本地文章Hugo生成静态网站-&amp;gt;上传Github-&amp;gt;(使用crontab 定时任务)在服务器上拉取Github静态网站, 使用自有域名&lt;/h3&gt;
&lt;h3 id=&#34;16-本地文章-上传服务器-服务器hugo生成静态网站-使用自有域名&#34;&gt;1.6 本地文章-&amp;gt;上传服务器-&amp;gt;服务器Hugo生成静态网站, 使用自有域名&lt;/h3&gt;
&lt;h3 id=&#34;17-服务器文章-服务器hugo生成静态网站-使用自有域名&#34;&gt;1.7 服务器文章-&amp;gt;服务器Hugo生成静态网站, 使用自有域名&lt;/h3&gt;
&lt;h2 id=&#34;2-方式比较&#34;&gt;2. 方式比较&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;方式&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;是否推荐&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;是否免费&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;更新及时&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;是否使用自有域名&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;难易程度(1最容易)&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.1方式&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29&#34; width=&#34;29&#34;
alt=&#34;1&#34; src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.2方式&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29&#34; width=&#34;29&#34;
alt=&#34;2&#34; src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.3方式&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29&#34; width=&#34;29&#34;
alt=&#34;2&#34; src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.4方式&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29&#34; width=&#34;29&#34;
alt=&#34;3&#34; src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.5方式&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29&#34; width=&#34;29&#34;
alt=&#34;2&#34; src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.6方式&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29&#34; width=&#34;29&#34;
alt=&#34;2&#34; src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.7方式&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29&#34; width=&#34;29&#34;
alt=&#34;1&#34; src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;11方式推荐-免费-更新及时-会使用hugo-git-markdown即可-最简单的方式&#34;&gt;1.1方式(推荐), 免费, 更新及时, 会使用Hugo Git Markdown即可, 最简单的方式.&lt;/h3&gt;
&lt;h3 id=&#34;12方式推荐-除了11有的内容-可使用自己域名&#34;&gt;1.2方式(推荐), 除了1.1有的内容, 可使用自己域名.&lt;/h3&gt;
&lt;h3 id=&#34;13方式推荐-方式简单-更新及时会使用hugo-markdown-rsycn-配置ssh-key即可&#34;&gt;1.3方式(推荐), 方式简单, 更新及时,会使用Hugo Markdown rsycn 配置ssh key即可&lt;/h3&gt;
&lt;h3 id=&#34;14方式推荐-自动化程序最高-只需要上传到github就可触发-更新及时-难度也稍微高点-除会使用hugo-git-markdown-还需要使用github-action-ssh-key配置&#34;&gt;1.4方式(推荐), 自动化程序最高, 只需要上传到Github就可触发, 更新及时, 难度也稍微高点. 除会使用Hugo Git Markdown, 还需要使用Github action, SSH KEY配置.&lt;/h3&gt;
&lt;h3 id=&#34;15方式-如半小时拉一次github-则有延时&#34;&gt;1.5方式, 如半小时拉一次Github, 则有延时&lt;/h3&gt;
&lt;h3 id=&#34;16-17-更新同样及时-不够自动化-需要手动登录服务器执行&#34;&gt;1.6 1.7 更新同样及时, 不够自动化, 需要手动登录服务器执行.&lt;/h3&gt;
&lt;h2 id=&#34;3-推荐方式使用-11-12-13-14-方式&#34;&gt;3. 推荐方式使用, 1.1, 1.2, 1.3, 1.4 方式.&lt;/h2&gt;
&lt;h3 id=&#34;31-方式-11-使用&#34;&gt;3.1 (方式 1.1 使用)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%92%8cgithub-pages%e6%90%ad%e5%bb%ba%e9%9d%99%e6%80%81%e7%bd%91%e7%ab%99li.004/&#34; target=&#34;_blank&#34;&gt;1.1方式使用参考&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;32-方式-12-使用&#34;&gt;3.2 (方式 1.2 使用)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%92%8cgithub-pages%e6%90%ad%e5%bb%ba%e9%9d%99%e6%80%81%e7%bd%91%e7%ab%99li.004/&#34; target=&#34;_blank&#34;&gt;完成1.1方式&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;购买域名, 设置设置CNAME记录&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;设置CNAME记录mywebsite.lizicai.com leezicai.github.io&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;在Github Pages设置域名, 会在Github项目中生成一个文件&lt;/a&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/hugo-manage-github-mywebsite.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;~/mywebsite/mywebsite拉取Github静态网站, 获取步骤2的文件&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:red;&#34;&gt;这一步必须执行&lt;/a&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;重新设置baseUrl, 因为域名更改了&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;直接访问http://mywebsite.lizicai.com, 显示错误&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/hugo-manage-github-wrong.png&#34; alt=&#34;页面显示错误&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;页面显示错误&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~/mywebsite
hugo --theme=papermod --baseUrl=&amp;#34;https://mywebsite.lizicai.com/&amp;#34; --destination=mywebsite

cd mywebsite
# 远程仓库名称github, 在方式1.1重命名过, 注意, 未重命名则是orign
git add  .
git commit -m  &amp;#34;test&amp;#34;
git push orign master
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;5&#34;
    src=&#34;https://s.lizicai.com/icon/number/5.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;检查&lt;/a&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/hugo-manage-github-right.png&#34; alt=&#34;正确显示内容&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;正确显示内容&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;33-方式-13-使用-hahahugoshortcode23s47hbhb&#34;&gt;3.3 (方式 1.3 使用), 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/rsycn%e5%90%8c%e6%ad%a5%e5%9b%be%e7%89%87%e6%88%96%e5%85%b6%e4%bb%96%e8%b5%84%e6%ba%90%e5%88%b0%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8ali.025/&#34; target=&#34;_blank&#34;&gt;rsycn用法&lt;/a&gt; 

&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;设置SSH Key&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ssh-keygen -t ed25519
ssh-copy-id -i ~/.ssh/test.pub root@192.168.1.100  -p 22

# vim ~/.ssh/config,存入以下内容
Host myhost
 User root
 Port 22
 HostName 192.168.1.100
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/test
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;以lizicai.com网站为例&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;upli(){
    LOCAL_PATH=&amp;#34;${HOME}/lizicai/lizicai.com/&amp;#34;
    SERVER_PATH=&amp;#34;lizicai.com/&amp;#34;
    echo &amp;#34;\033[42;30m Begin rsync ${LOCAL_PATH} myhost:${SERVER_PATH}...  \033[0m&amp;#34;
    rsync -aut --delete --exclude &amp;#39;.DS_Store&amp;#39; ${LOCAL_PATH} myhost:${SERVER_PATH}
    echo &amp;#34;\033[42;30m Finash.  \033[0m&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;34-方式-14-使用-github-action-事件驱动的意味着您可以在指定事件发生后运行一系列命令-比如push后就登录服务器拉取github代码&#34;&gt;3.4 (方式 1.4 使用), Github Action 事件驱动的，意味着您可以在指定事件发生后运行一系列命令. 比如push后就登录服务器拉取Github代码.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;设置SSH Key&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ssh-keygen -t ed25519
# test.pub复制到服务器root@192.168.1.100上.
ssh-copy-id -i ~/.ssh/test.pub root@192.168.1.100  -p 22

# vim ~/.ssh/config,存入以下内容
Host myhost
 User root
 Port 22
 HostName 192.168.1.100
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/test
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/rsycn-ssh-test.gif&#34; alt=&#34;生成密钥&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;生成密钥&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/rsycn-ssh-ls.gif&#34; alt=&#34;ls查看生成的密钥&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;ls查看生成的密钥&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;配置Github SSH keys&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/settings/keys&#34; target=&#34;_blank&#34;&gt;https://github.com/settings/keys&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;将test.pub内容复制上去即可&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;服务器上设置Github SSH keys&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 使用scp将~/.ssh/test复制到服务器上
scp ~/.ssh/test myhost:.ssh/

# 登录服务, 配置
ssh myhost
# vim ~/.ssh/config添加如下内容
Host github.com
 User git
 HostName github.com
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/test
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;服务器上拉取Github静态网站内容&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ssh myhost

cd ~

git clone git@github.com:leezicai/lizicai.com.git
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;5&#34;
    src=&#34;https://s.lizicai.com/icon/number/5.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;Nginx配置, 供参考&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;server{
    listen 80;
    server_name lizicai.com;
    return 301 https://lizicai.com$request_uri;
}
server {
    listen       443 ssl;
    server_name  lizicai.com;
    charset utf-8;
    ssl_certificate /root/cert/lizicai.com/fullchain.pem;
    ssl_certificate_key /root/cert/lizicai.com/private.key;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /root/lizicai.com/;
        index  index.html index.htm;
    }
    error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /root/lizicai.com/;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;6&#34;
    src=&#34;https://s.lizicai.com/icon/number/6.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;配置Github Action的Secrets&lt;/a&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/hugo-manage-github-action.png&#34; alt=&#34;设置Github Action&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;设置Github Action&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;使用步骤1 SSH Key内容, 配置如下参数&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;HOST 192.168.1.100
PORT 22
USERNAME root
KEY 复制~/.ssh/test中的内容
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;7&#34;
    src=&#34;https://s.lizicai.com/icon/number/7.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;在https://github.com/leezicai/lizicai.com项目添加Github Action&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 这里是github静态网站目录
cd ~/lizicai/lizicai.com
# 创建文件夹
mkdir -p .github/workflows
# vim git-pull-lizicai-com.yml, 添加如下内容

name: Git Pull Lizicai.com

on:
  push:
    branches:
      - master

jobs:
  ssh-job:
    name: git pull lizicai.com  job
    runs-on: ubuntu-latest
    steps:
      - name: ssh git pull
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.KEY }}
          port: ${{ secrets.PORT }}
          script: |
            cd ${HOME}/lizicai.com
            git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;8&#34;
    src=&#34;https://s.lizicai.com/icon/number/8.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;上传Github Action文件到github就会自动执行了&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~/lizicai/lizicai.com
git add .
git commit -m &amp;#34;Github action&amp;#34;
# 远程仓库origin已改名为github
git push github master
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;9&#34;
    src=&#34;https://s.lizicai.com/icon/number/9.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;查看Github Action执行情况&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;每次推送时就会触发, 在服务器上登录, 拉取Github代码&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/hugo-manage-github-action-view.gif&#34; alt=&#34;执行成功&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;执行成功&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>rsycn同步图片或其他资源到服务器上 Li.025</title>
      <link>https://lizicai.com/p/rsycn%E5%90%8C%E6%AD%A5%E5%9B%BE%E7%89%87%E6%88%96%E5%85%B6%E4%BB%96%E8%B5%84%E6%BA%90%E5%88%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A-li.025/</link>
      <pubDate>Mon, 02 Aug 2021 17:39:14 +0800</pubDate>
      <guid>https://lizicai.com/p/rsycn%E5%90%8C%E6%AD%A5%E5%9B%BE%E7%89%87%E6%88%96%E5%85%B6%E4%BB%96%E8%B5%84%E6%BA%90%E5%88%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A-li.025/</guid>
      <description>&lt;h2 id=&#34;1-rsycn-是什么&#34;&gt;1. rsycn 是什么&lt;/h2&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/rsycn-logo.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;rsycn最大特点是可以检查本地和远程的文件差异-只上传变动的文件-sftp-是全量上传&#34;&gt;rsycn最大特点是可以检查本地和远程的文件差异, 只上传变动的文件. sftp 是全量上传.&lt;/h3&gt;
&lt;h3 id=&#34;rsycn-会用在上传图片到nginx服务器上-作为图床使用&#34;&gt;rsycn 会用在上传图片到Nginx服务器上, 作为图床使用&lt;/h3&gt;
&lt;h2 id=&#34;2-rsycn安装&#34;&gt;2. rsycn安装&lt;/h2&gt;
&lt;h3 id=&#34;mac&#34;&gt;Mac&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew install rsycn
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;linux&#34;&gt;Linux&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;yum install rsycn
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;windows&#34;&gt;Windows&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;choco install rsycn
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-rsycn-命令&#34;&gt;3. rsycn 命令&lt;/h2&gt;
&lt;h3 id=&#34;-r-参数-递归同步-同步文件夹时使用&#34;&gt;-r 参数, 递归同步, 同步文件夹时使用&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rsycn -r source destination
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;-a-参数-除了可以递归同步以外还可以同步元信息比如修改时间权限等&#34;&gt;-a 参数, 除了可以递归同步以外，还可以同步元信息（比如修改时间、权限等）.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rsycn -a source destination
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;-u-跳过目标目录比源目录修改时间新的文件-不同步这些文件&#34;&gt;-u 跳过目标目录比源目录修改时间新的文件, 不同步这些文件&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rsycn -ru source destination
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;-t-保留文件的修改时间&#34;&gt;-t 保留文件的修改时间&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rsycn -aut source destination
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;exclude-排除某些文件&#34;&gt;&amp;ndash;exclude 排除某些文件&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rsycn -aur --exclude &amp;#39;.DS_Store&amp;#39; source destination
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;include-与exclude连用&#34;&gt;&amp;ndash;include 与&amp;ndash;exclude连用&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rsycn -aur --exclude &amp;#39;*&amp;#39; --include &amp;#34;readme.md&amp;#34; source destination
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;delete-删除目标目录中与源目录不一致文件&#34;&gt;&amp;ndash;delete 删除目标目录中与源目录不一致文件&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rsync -aut --delete --exclude &amp;#39;.DS_Store&amp;#39; source destination
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;4-与ssh-key连用-上传到服务器上&#34;&gt;4. 与ssh key连用, 上传到服务器上&lt;/h2&gt;
&lt;h3 id=&#34;41-配置ssh-key&#34;&gt;4.1 配置ssh key&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;使用ssh命令生成密钥&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ssh-keygen -t ed25519
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/rsycn-ssh-test.gif&#34; alt=&#34;生成密钥&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;生成密钥&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/rsycn-ssh-ls.gif&#34; alt=&#34;ls查看生成的密钥&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;ls查看生成的密钥&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;ssh命令把公钥复制copy到服务器上&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 输入对应root用户密码即可完成
ssh-copy-id -i ~/.ssh/test.pub root@192.168.1.100  -p 22
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;配置~/.ssh/config&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;添加如下配置, 用户名 端口 ip与上面一致, 私钥则是test&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Host myhost
 User root
 Port 22
 HostName 192.168.1.100
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/test
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;设置上传的脚本&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;如下内容放到~/.zshrc或~/.bashrc中&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;把本地~/Pictures/s.lizicai.com/下子文件文件夹上传到myhost的root用户根目录s.lizicai.com/目录中&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;myhost名称是步骤3中的Host名称&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;upli(){
    LOCAL_PATH=&amp;#34;${HOME}/Pictures/s.lizicai.com/&amp;#34;
    SERVER_PATH=&amp;#34;s.lizicai.com/&amp;#34;
    echo &amp;#34;\033[42;30m Begin rsync ${LOCAL_PATH} myhost:${SERVER_PATH}...  \033[0m&amp;#34;
    rsync -aut --delete --exclude &amp;#39;.DS_Store&amp;#39; ${LOCAL_PATH} myhost:${SERVER_PATH}
    echo &amp;#34;\033[42;30m Finash.  \033[0m&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;5&#34;
    src=&#34;https://s.lizicai.com/icon/number/5.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;重新生效&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;source ~/.zshrc
# 或source ~/.bashrc, 取决使用哪种shell
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;6&#34;
    src=&#34;https://s.lizicai.com/icon/number/6.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;命令行上传&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;upli
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/rsycn-ssh-upli.png&#34; alt=&#34;上传图片或资源&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;上传图片或资源&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>Hugo中Markdown图片资源存放几种方式 Li.024</title>
      <link>https://lizicai.com/p/hugo%E4%B8%ADmarkdown%E5%9B%BE%E7%89%87%E8%B5%84%E6%BA%90%E5%AD%98%E6%94%BE%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F-li.024/</link>
      <pubDate>Sun, 01 Aug 2021 23:14:57 +0800</pubDate>
      <guid>https://lizicai.com/p/hugo%E4%B8%ADmarkdown%E5%9B%BE%E7%89%87%E8%B5%84%E6%BA%90%E5%AD%98%E6%94%BE%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F-li.024/</guid>
      <description>&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%ad%a6%e4%b9%a0%e8%b7%af%e7%ba%bfli.028/&#34; target=&#34;_blank&#34;&gt;本篇文章属于Hugo学习路线Li.028一部分&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;1-hugo中markdown图片资源放在哪-一直是个问题&#34;&gt;1. Hugo中Markdown图片资源放在哪? 一直是个问题&lt;/h2&gt;
&lt;h3 id=&#34;引用其他资源担心其他网站改动路径-就没了-建立自己的网络图片资源库就显得很重要了&#34;&gt;引用其他资源担心其他网站改动路径, 就没了, 建立自己的网络图片资源库就显得很重要了.&lt;/h3&gt;
&lt;h3 id=&#34;存放hugo的静态网站中-引用起来不方便-而且更新图片时必须更新网站-强依赖&#34;&gt;存放Hugo的静态网站中, 引用起来不方便, 而且更新图片时必须更新网站, 强依赖.&lt;/h3&gt;
&lt;h3 id=&#34;所以一个独立的图片库就显示有必要了&#34;&gt;所以一个独立的图片库就显示有必要了.&lt;/h3&gt;
&lt;h3 id=&#34;图片压缩也少不了&#34;&gt;图片压缩也少不了.&lt;/h3&gt;
&lt;h2 id=&#34;2-常用几种存放图片资源方式-github-使用nginx做为静态资源-自建私有云-自建图床-使用云存储服务&#34;&gt;2. 常用几种存放图片资源方式. Github 使用Nginx做为静态资源 自建私有云 自建图床 使用云存储服务.&lt;/h2&gt;
&lt;h3 id=&#34;21-github或gitee国内理论理论速度更快-公共项目存放图片资源-这种方式只需要更新图片即可-不需要更新静态博客-管理更方便-免费&#34;&gt;2.1 Github或Gitee(国内理论理论速度更快) 公共项目存放图片资源. 这种方式只需要更新图片即可, 不需要更新静态博客, 管理更方便. 免费.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;免费, 会使用git就可以. 也可使用图形界面PicGo上传图片到Github&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;示例, 复制文件下载链接即可在markdown使用&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/hugo/hugo-github-img.png&#34; alt=&#34;复制文件下载链接即可在markdown使用&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;复制文件下载链接即可在markdown使用&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;![number1](https://github.com/leezicai/share/raw/master/icon/number/1.png)
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://github.com/leezicai/share/raw/master/icon/number/1.png&#34; alt=&#34;&#34; style=&#34;max-width: 100px; max-height: 100px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;22-静态博客存放在github-图片也存放在同一项目下-免费&#34;&gt;2.2 静态博客存放在Github, 图片也存放在同一项目下. 免费.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;免费, 会使用Git&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果存放在Hugo文件夹中static中, 虽然文件生成在项目根目录下, 但在Github上地址从baseUrl开始的&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 图片存放在static文件夹下

&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/adityatelange/hugo-PaperMod/tree/exampleSite/static&#34; target=&#34;_blank&#34;&gt;https://github.com/adityatelange/hugo-PaperMod/tree/exampleSite/static&lt;/a&gt; 



# 图片地址起始https://adityatelange.github.io/hugo-PaperMod/
![papermod-cover.png](https://adityatelange.github.io/hugo-PaperMod/papermod-cover.png)
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://adityatelange.github.io/hugo-PaperMod/papermod-cover.png&#34; alt=&#34;单个图片,如果有文件夹则添加&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;单个图片,如果有文件夹则添加&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;23-使用nginx或其他服务器做静态资源hahahugoshortcode18s5hbhb-付费-需要服务器&#34;&gt;2.3 使用Nginx或其他服务器做静态资源.
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/%e5%ae%89%e8%a3%85nginx%e5%8f%af%e7%94%a8%e6%9c%8d%e5%8a%a1li.012/&#34; target=&#34;_blank&#34;&gt;Nginx安装参考地址&lt;/a&gt; 

, 付费, 需要服务器.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Nginx default.conf配置&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用sftp上传图片到服务器的s.lizicai.com文件夹下即可&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;server {
    listen       80;
    server_name  s.lizicai.com;
    return 301 https://s.lizicai.com$request_uri;
}
server {
    listen       443 ssl;
    server_name  s.lizicai.com;
    charset utf-8;
    ssl_certificate /root/cert/s.lizicai.com/fullchain.pem;
    ssl_certificate_key /root/cert/s.lizicai.com/private.key;
    location / {
        root   /root/s.lizicai.com/;
        index  index.html index.htm;
        autoindex on;
        autoindex_localtime on;
        autoindex_exact_size off;
    }
    error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /root/s.lizicai.com/;
        autoindex_localtime on;
        autoindex_exact_size off;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;示例地址
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://s.lizicai.com/icon/tags/&#34; target=&#34;_blank&#34;&gt;https://s.lizicai.com/icon/tags/&lt;/a&gt; 

, 右键复制blue.png的链接&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;![tagblue](https://s.lizicai.com/icon/tags/blue.png)
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/icon/tags/blue.png&#34; alt=&#34;&#34; style=&#34;max-width: 100px; max-height: 100px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;24-搭建私有云盘-图片和视频资源-hugo中想使用个人视频服务的推荐-付费-需要服务器&#34;&gt;2.4 搭建私有云盘, 图片和视频资源. Hugo中想使用个人视频服务的推荐, 付费, 需要服务器.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/nextcloud/docker&#34; target=&#34;_blank&#34;&gt;如NextCloud&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;25-部署一个图片服务-开源图床服务imgurl-付费-需要服务器&#34;&gt;2.5 部署一个图片服务, 开源图床服务ImgURL, 付费, 需要服务器.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.yuque.com/helloz/imgurl/install&#34; target=&#34;_blank&#34;&gt;官方安装文档地址&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;26-使用阿里腾讯云存储平台-付费&#34;&gt;2.6 使用阿里腾讯云存储平台, 付费.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://zhuanlan.zhihu.com/p/104152479&#34; target=&#34;_blank&#34;&gt;阿里云参考&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;3-上传前的图片压缩软件&#34;&gt;3. 上传前的图片压缩软件.&lt;/h2&gt;
&lt;h3 id=&#34;hahahugoshortcode18s11hbhb--支持mac&#34;&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://imageoptim.com/versions.html&#34; target=&#34;_blank&#34;&gt;ImageOptim&lt;/a&gt; 

  支持Mac&lt;/h3&gt;
&lt;h3 id=&#34;hahahugoshortcode18s12hbhb-支持mac-windows&#34;&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://tuya.xinxiao.tech/&#34; target=&#34;_blank&#34;&gt;图压&lt;/a&gt; 

 支持Mac Windows&lt;/h3&gt;
&lt;h3 id=&#34;hahahugoshortcode18s13hbhb-chrome-浏览器应用-支持mac-windows-linux&#34;&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://squoosh.app/&#34; target=&#34;_blank&#34;&gt;squoosh.app&lt;/a&gt; 

 Chrome 浏览器应用 支持Mac Windows Linux&lt;/h3&gt;
&lt;h3 id=&#34;hahahugoshortcode18s14hbhb-支持windows&#34;&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/leezicai/share/raw/master/pinga/pinga-win64.zip&#34; target=&#34;_blank&#34;&gt;pinga&lt;/a&gt; 

 支持Windows&lt;/h3&gt;
</description>
    </item>
    
    <item>
      <title>Hugo常用命令 Li.023</title>
      <link>https://lizicai.com/p/hugo%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4-li.023/</link>
      <pubDate>Sat, 31 Jul 2021 17:00:14 +0800</pubDate>
      <guid>https://lizicai.com/p/hugo%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4-li.023/</guid>
      <description>&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%ad%a6%e4%b9%a0%e8%b7%af%e7%ba%bfli.028/&#34; target=&#34;_blank&#34;&gt;本篇文章属于Hugo学习路线Li.028一部分&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;hugo-常用命令-hahahugoshortcode21s1hbhb&#34;&gt;Hugo 常用命令. 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.gohugo.org/doc/commands/&#34; target=&#34;_blank&#34;&gt;官网参考地址&lt;/a&gt; 

&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询所有命令
hugo -h

# 创建Hugo 静态网站
hugo new site mywebsite

# 创建文章, 当前必须mywebsite下才可创建文章
# 创建的文章存放在 mywebsite/content/p/test.md下
# 使用命令创建的hogo可以监控到, 实时显示到预览上
hugo new p/test.md

# 启动服务, 必须在mywebsite文件夹下启动
hugo server

# 草稿也预览, -D 参数, 必须在mywebsite文件夹下启动
hugo -D server

# 指定预览的主题, 必须在mywebsite文件夹下启动
# papermod是在themes文件夹下的主题名称
hugo -D server --theme=papermod

# 指定预览的端口
hugo -D server  --port=1313

# 指定服务绑定在哪个端口, 比如你想在手机预览, 电脑手机同一局域网时
# 电脑ip 192.168.1.20, 手机访问192.168.1.20就能看到预览
hugo -D server --bind=&amp;#34;192.168.1.20&amp;#34; --port=80

# 指定预览的默认地址, http://192.168.1.20:1313

&lt;a style=&#34;color:red;&#34;&gt;错误示例&lt;/a&gt;

hugo -D server --baseUrl=&amp;#34;http://192.168.1.20/&amp;#34; --port=1313
# 访问不到, 没有绑定ip, 访问http://192.168.1.20:1313失败, 访问localhost:1313则显示
# 访问任意链接被定位到http://192.168.1.20:1313上


&lt;a style=&#34;color:green;&#34;&gt;正确做法,绑定当前ip,提醒baseUrl最后结尾必须是&amp;#39;/&amp;#39;&lt;/a&gt;

hugo -D server --baseUrl=&amp;#34;http://192.168.1.20/&amp;#34; --port=1313 --bind=&amp;#34;192.168.1.20&amp;#34;

# 指定配置文件
hugo -D server --config=config.yml

# 指定输出静态博客网站的目录lizicai.com, 再次提醒baseUrl最后一位是/
hugo --theme=papermod --baseUrl=&amp;#34;https://lizicai.com/&amp;#34; --destination=&amp;#34;lizicai.com&amp;#34; --config=config.yml
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>RSS和一些RSS订阅网站 Li.022</title>
      <link>https://lizicai.com/p/rss%E5%92%8C%E4%B8%80%E4%BA%9Brss%E8%AE%A2%E9%98%85%E7%BD%91%E7%AB%99-li.022/</link>
      <pubDate>Thu, 29 Jul 2021 23:57:14 +0800</pubDate>
      <guid>https://lizicai.com/p/rss%E5%92%8C%E4%B8%80%E4%BA%9Brss%E8%AE%A2%E9%98%85%E7%BD%91%E7%AB%99-li.022/</guid>
      <description>&lt;h2 id=&#34;1-rss是什么&#34;&gt;1. RSS是什么&lt;/h2&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/icon/rss/rss.png&#34; alt=&#34;RSS&#34; style=&#34;max-width: 120px; max-height: 120px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;RSS&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;全称是really-simple-syndication-简易信息聚合-在一个软件中可以看到所有订阅网址更新内容&#34;&gt;全称是Really Simple Syndication 简易信息聚合, 在一个软件中可以看到所有订阅网址更新内容.&lt;/h3&gt;
&lt;h2 id=&#34;2-为什么会有rss&#34;&gt;2. 为什么会有RSS&lt;/h2&gt;
&lt;h3 id=&#34;没有rss-如果你要a-b-c-d网站信息-需要一个个上去看看有没有更新-这样无疑很费时&#34;&gt;没有RSS, 如果你要A B C D网站信息, 需要一个个上去看看有没有更新, 这样无疑很费时&lt;/h3&gt;
&lt;h3 id=&#34;如果有软件能订阅你感兴趣的a-b-c-d网站-只用在一个软件查看就看到4个网站的更新内容-这就是rss重要作用了&#34;&gt;如果有软件能订阅你感兴趣的A B C D网站, 只用在一个软件查看就看到4个网站的更新内容, 这就是RSS重要作用了&lt;/h3&gt;
&lt;h2 id=&#34;3-苹果iphone-和-安卓android-rss-应用&#34;&gt;3. 苹果iPhone 和 安卓Android RSS 应用.&lt;/h2&gt;
&lt;h3 id=&#34;iphone&#34;&gt;iPhone&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Netnewswire&lt;/strong&gt; (不需要的默认订阅可以删除)&lt;/p&gt;
&lt;h3 id=&#34;android&#34;&gt;Android&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Read&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;4-一些rss订阅网站-写独立博客人变少了&#34;&gt;4. 一些RSS订阅网站, 写独立博客人变少了&amp;hellip;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;阮一峰 &lt;a href=&#34;https://www.ruanyifeng.com/blog/&#34;&gt;https://www.ruanyifeng.com/blog/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://feeds.feedburner.com/ruanyifeng&#34;&gt;https://feeds.feedburner.com/ruanyifeng&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;陈浩 coolshell.cn&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://coolshell.cn/feed&#34;&gt;https://coolshell.cn/feed&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;少数派 sspai.com&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://sspai.com/feed&#34;&gt;https://sspai.com/feed&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Dash Mac下最好的开发文档 Li.021</title>
      <link>https://lizicai.com/p/dash-mac%E4%B8%8B%E6%9C%80%E5%A5%BD%E7%9A%84%E5%BC%80%E5%8F%91%E6%96%87%E6%A1%A3-li.021/</link>
      <pubDate>Thu, 29 Jul 2021 21:59:53 +0800</pubDate>
      <guid>https://lizicai.com/p/dash-mac%E4%B8%8B%E6%9C%80%E5%A5%BD%E7%9A%84%E5%BC%80%E5%8F%91%E6%96%87%E6%A1%A3-li.021/</guid>
      <description>&lt;h2 id=&#34;1-dash-是什么&#34;&gt;1. Dash 是什么&lt;/h2&gt;
&lt;h3 id=&#34;dash-是mac开发文档集合-从前端react到后端java-能想到的语言文档这里都有&#34;&gt;Dash 是Mac开发文档集合, 从前端React到后端Java, 能想到的语言文档这里都有&lt;/h3&gt;
&lt;h3 id=&#34;dash-支持多种插件-在开发工具内就可以直接搜索开发文档&#34;&gt;Dash 支持多种插件, 在开发工具内就可以直接搜索开发文档&lt;/h3&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/dash/dash-extension.png&#34; alt=&#34;Dash插件支持编辑器&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;Dash插件支持编辑器&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;hahahugoshortcode14s1hbhb-或使用homebrew命令安装&#34;&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://kapeli.com/dash&#34; target=&#34;_blank&#34;&gt;官网下载&lt;/a&gt; 

, 或使用Homebrew命令安装&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew install dash
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;hahahugoshortcode14s2hbhb&#34;&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://s.lizicai.com/dash/dash-shop.PNG&#34; target=&#34;_blank&#34;&gt;购买-微信小店&lt;/a&gt; 

&lt;/h3&gt;
&lt;h2 id=&#34;2-常用软件示例&#34;&gt;2. 常用软件示例&lt;/h2&gt;
&lt;h3 id=&#34;21-alfred&#34;&gt;2.1 Alfred&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;不用打开Dash软件, 使用Alfred直接搜索开发文档&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/leezicai/share/raw/master/alfred/workflow/Dash.alfredworkflow&#34; target=&#34;_blank&#34;&gt;Dash Wrokflow下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/workflow-dash.gif&#34; alt=&#34;搜索Dash软件java开发文档&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;搜索Dash软件java开发文档&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;22-intellij-idea&#34;&gt;2.2 Intellij IDEA&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;使用⌘ + shift + h搜索选中内容&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Intellij 插件应用市场就可以下载&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/dash/dash-idea.gif&#34; alt=&#34;⌘ &amp;#43; shift &amp;#43; h 搜索选中内容&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;⌘ &amp;#43; shift &amp;#43; h 搜索选中内容&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;23-visual-studio-code&#34;&gt;2.3 Visual Studio Code&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Dash插件可以Visual Studio Code扩展市场搜索下载&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;option + h 指定搜索文档&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/dash/dash-vscode.gif&#34; alt=&#34;option &amp;#43; h,指定搜索html: a标签&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;option &amp;#43; h,指定搜索html: a标签&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;指定开发文档名称在Dash中可查询, 也可以自行修改&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/dash/dash-shortcut.png&#34; alt=&#34;指定开发文档名称在Dash中可查询, 也可以自行修改&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;指定开发文档名称在Dash中可查询, 也可以自行修改&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&#34;3-hahahugoshortcode14s8hbhb-在线版的-同样好用&#34;&gt;3. 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://devdocs.io/&#34; target=&#34;_blank&#34;&gt;devdocs.io&lt;/a&gt; 

 在线版的, 同样好用&lt;/h2&gt;
</description>
    </item>
    
    <item>
      <title>Alfred Mac效率神器 Li.020</title>
      <link>https://lizicai.com/p/alfred-mac%E6%95%88%E7%8E%87%E7%A5%9E%E5%99%A8-li.020/</link>
      <pubDate>Wed, 28 Jul 2021 00:45:21 +0800</pubDate>
      <guid>https://lizicai.com/p/alfred-mac%E6%95%88%E7%8E%87%E7%A5%9E%E5%99%A8-li.020/</guid>
      <description>&lt;h2 id=&#34;1-alfred-是什么&#34;&gt;1. Alfred 是什么.&lt;/h2&gt;
&lt;h3 id=&#34;alfred是mac上一款效率软件-有着剪切板历史记录快速复制之前的记录&#34;&gt;Alfred是Mac上一款效率软件, 有着剪切板历史记录,快速复制之前的记录&lt;/h3&gt;
&lt;h3 id=&#34;可以快捷搜索文件-快速打开应用或文件&#34;&gt;可以快捷搜索文件, 快速打开应用或文件.&lt;/h3&gt;
&lt;h3 id=&#34;有着snippet片段-可以记录代码或常用的信息&#34;&gt;有着Snippet片段, 可以记录代码或常用的信息.&lt;/h3&gt;
&lt;h3 id=&#34;可以开发定制工作流-完成更多复杂内容&#34;&gt;可以开发定制工作流, 完成更多复杂内容.&lt;/h3&gt;
&lt;h3 id=&#34;alfred-安装-hahahugoshortcode11s0hbhb-或使用-hahahugoshortcode11s1hbhb安装hahahugoshortcode11s2hbhb&#34;&gt;Alfred 安装, 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.alfredapp.com/&#34; target=&#34;_blank&#34;&gt;官网下载&lt;/a&gt; 

, 或使用 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/homebrew-mac%e4%b8%8b%e6%9c%80%e5%a5%bd%e7%94%a8%e7%9a%84%e8%bd%af%e4%bb%b6%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7li.008/&#34; target=&#34;_blank&#34;&gt;Homebrew&lt;/a&gt; 

安装.
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://s.lizicai.com/alfred/alfred-shop.PNG&#34; target=&#34;_blank&#34;&gt;代购-微信小店&lt;/a&gt; 

.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew install alfred
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:red;&#34;&gt;Alfred 还需要Mac OS系统中文件夹等权限&lt;/a&gt;
&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/grant.png&#34; alt=&#34;授予Alfred权限&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;授予Alfred权限&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&#34;2-alfred-mac效率神器&#34;&gt;2. Alfred Mac效率神器.&lt;/h2&gt;
&lt;h3 id=&#34;21-剪粘板历史记录&#34;&gt;2.1 剪粘板历史记录.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;快速粘贴历史复制记录, 支持图片, 最长记录3个月时间.&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/clipboardhistory-set.png&#34; alt=&#34;快捷键⌘ &amp;#43; .触发, 保存最长3个月记录&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;快捷键⌘ &amp;#43; .触发, 保存最长3个月记录&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/clipboardhistory-txt.gif&#34; alt=&#34;⌘&amp;#43;.触发,搜索&amp;#39;复制&amp;#39;,⌘&amp;#43;6 可直接粘贴历史记录到输入框&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;⌘&amp;#43;.触发,搜索&amp;#39;复制&amp;#39;,⌘&amp;#43;6 可直接粘贴历史记录到输入框&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/clipboardhistory-img.gif&#34; alt=&#34;⌘&amp;#43;.触发,可以预览已复制图片,回车可粘贴到输入框&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;⌘&amp;#43;.触发,可以预览已复制图片,回车可粘贴到输入框&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;22-snippets代码片段&#34;&gt;2.2 Snippets代码片段.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;记录代码片段, 常用邮箱链接等&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;记录代码块, 关键字就触发粘贴, ⌘ &amp;#43; .或 shift &amp;#43; ⌘ &amp;#43; . 也可搜索&lt;/a&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/snippets-set.png&#34; alt=&#34;片段Snippets设置&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;片段Snippets设置&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;html5设置参数&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/snippets-html5.png&#34; alt=&#34;html5设置&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;html5设置&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Name:
html5

Keyword:
#html5

Snippet:
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta charset=&amp;#34;utf-8&amp;#34;&amp;gt;
        &amp;lt;meta name=&amp;#34;viewport&amp;#34; content=&amp;#34;width=device-width&amp;#34;&amp;gt;
        &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;
        link
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        body
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/snippets-html5.gif&#34; alt=&#34;关键字 ⌘ &amp;#43; .或 shift &amp;#43; ⌘ &amp;#43; . 也可搜索&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;关键字 ⌘ &amp;#43; .或 shift &amp;#43; ⌘ &amp;#43; . 也可搜索&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;常用邮箱等&lt;/a&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/snippets-txt.png&#34; alt=&#34;常用邮箱配置&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;常用邮箱配置&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/snippets-txt.gif&#34; alt=&#34;打出testmail自动替换为mail@lizicai.com&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;打出testmail自动替换为mail@lizicai.com&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;23-计算器&#34;&gt;2.3 计算器&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;直接进行各种计算&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/calculator.gif&#34; alt=&#34;计算器 计算结果复制到剪切板上&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;计算器 计算结果复制到剪切板上&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;24-工作流workflows&#34;&gt;2.4 工作流Workflows&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;开发强大的工作流, 更快速处理信息&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;分享几个常用的Alfred Workflows&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/leezicai/share/raw/master/alfred/workflow/all.zip&#34; target=&#34;_blank&#34;&gt;全部Wrokfows下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;Github Workflow&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;快速跳到自己的Github项目, 或在Github中搜索. 使用前需要授权&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/gharlan/alfred-github-workflow/releases/download/v1.6.2/github.alfredworkflow&#34; target=&#34;_blank&#34;&gt;Github Workflow下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/workflow-github.gif&#34; alt=&#34;快速跳到自己的Github项目, 或在Github中搜索&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;快速跳到自己的Github项目, 或在Github中搜索&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;链接地址编码转换Encode Decode&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;分享出去链接有中文通常是%AF%这样, Decode后就会显示与浏览一样的地址&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://raw.github.com/willfarrell/alfred-encode-decode-workflow/master/encode-decode.alfredworkflow&#34; target=&#34;_blank&#34;&gt;Alfred Encode Decode Workflow下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/workflow-encode-decode.gif&#34; alt=&#34;dc解密编码 ec加密编码&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;dc解密编码 ec加密编码&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;Dash Wrokflow&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;不用打开Dash软件, 使用Alfred直接搜索开发文档&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在Dash软件设置里可以添加Dash Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/workflow-dash.gif&#34; alt=&#34;搜索Dash软件java开发文档&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;搜索Dash软件java开发文档&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;指定搜索引擎&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;搜索引擎 百度 谷歌 必应 搜狗 360搜索&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/leezicai/share/raw/master/alfred/workflow/search.alfredworkflow&#34; target=&#34;_blank&#34;&gt;Search Wrokflow 下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/workflow-search.gif&#34; alt=&#34;百度, 搜索, 最下面一行关键词b&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;百度, 搜索, 最下面一行关键词b&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;5&#34;
    src=&#34;https://s.lizicai.com/icon/number/5.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;购物网站搜索&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;京东 淘宝 天猫 亚马逊 日亚 美亚 当当 搜索&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/leezicai/share/raw/master/alfred/workflow/search-goods.alfredworkflow&#34; target=&#34;_blank&#34;&gt;Search-goods Wrokflow下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/workflow-search-goods.gif&#34; alt=&#34;jd 关键字跳转京东搜索&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;jd 关键字跳转京东搜索&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;6&#34;
    src=&#34;https://s.lizicai.com/icon/number/6.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;TerminalFinder Workflow&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;复制访达Finder路径在终端打开, 使用达打开终端当前路径&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ft: 复制访达Finder当前路径 在终端Terminal打开
tf: 复制终端Terminal当前路径 在访达Finder中打开
fi: 复制访达Finder当前路径 在终端iTerm2打开
if: 复制终端iTerm2当前路径 在访达Finder中打开
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/LeEnno/alfred-terminalfinder/raw/master/TerminalFinder.alfredworkflow&#34; target=&#34;_blank&#34;&gt;TerminalFinder Workflow 下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/workflow-terminalFinder.gif&#34; alt=&#34;tf 打开terminal文件夹 在访达Finder中&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;tf 打开terminal文件夹 在访达Finder中&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;7&#34;
    src=&#34;https://s.lizicai.com/icon/number/7.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;exchange rate 汇率&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;设置本币为人民币, 就可以计算汇率了&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/jeppestaerk/alfred-currency-conversion/releases/download/v0.2.0/alfred-currency-conversion.alfredworkflow&#34; target=&#34;_blank&#34;&gt;Alfred-currency-conversion Workflow下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;  &lt;strong&gt;
&lt;a style=&#34;color:red;&#34;&gt;需要安装node&lt;/a&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew install node
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/workflow-exchage.gif&#34; alt=&#34;设置本币, curcon关键字可以计算转换汇率后金额&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;设置本币, curcon关键字可以计算转换汇率后金额&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;8&#34;
    src=&#34;https://s.lizicai.com/icon/number/8.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;Translate Workflow&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;打开百度翻译中英文 谷歌翻译&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/leezicai/share/raw/master/alfred/workflow/translate.alfredworkflow&#34; target=&#34;_blank&#34;&gt;Translate Workflow 下载&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/workflow-translate.gif&#34; alt=&#34;fanyi关键词 使用百度翻译&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;fanyi关键词 使用百度翻译&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;25-文件-文件夹搜索&#34;&gt;2.5 文件 文件夹搜索&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;关键词&amp;rsquo; 空格 open, 搜索文件与文件夹并打开&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/open-file.gif&#34; alt=&#34;搜索并打开文件&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;搜索并打开文件&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/open-folder.gif&#34; alt=&#34;搜索并进入文件夹&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;搜索并进入文件夹&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;26-控制mac-os系统快捷命令&#34;&gt;2.6 控制Mac OS系统快捷命令&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 退出应用
quit
# 退出全部应用
quitall
# 隐藏应用
hide
# 清空垃圾桶
emptytrash
# 锁屏
lock
# 关机
shutdown
# 重启
restart
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/system-command.gif&#34; alt=&#34;清空垃圾桶 退出(可使用⌘&amp;#43;5快速退出) 强制退出&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;清空垃圾桶 退出(可使用⌘&amp;#43;5快速退出) 强制退出&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;27-使用mac-os-字典&#34;&gt;2.7 使用Mac OS 字典&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;中文英文意思查询&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/dictionary.gif&#34; alt=&#34;dt查询&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;dt查询&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;28-快捷运行终端terminal命令&#34;&gt;2.8 快捷运行终端terminal命令&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;关键词 &amp;gt; 触发&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/alfred/terminal.gif&#34; alt=&#34;&amp;gt;运行终端Terminal命令&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&amp;gt;运行终端Terminal命令&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>ZV-E10索尼2021年7月27日22点发布的新机 Li.019</title>
      <link>https://lizicai.com/p/zv-e10%E7%B4%A2%E5%B0%BC2021%E5%B9%B47%E6%9C%8827%E6%97%A522%E7%82%B9%E5%8F%91%E5%B8%83%E7%9A%84%E6%96%B0%E6%9C%BA-li.019/</link>
      <pubDate>Tue, 27 Jul 2021 22:26:42 +0800</pubDate>
      <guid>https://lizicai.com/p/zv-e10%E7%B4%A2%E5%B0%BC2021%E5%B9%B47%E6%9C%8827%E6%97%A522%E7%82%B9%E5%8F%91%E5%B8%83%E7%9A%84%E6%96%B0%E6%9C%BA-li.019/</guid>
      <description>
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/sony/camera/ZVE10.png&#34; alt=&#34;SONY ZV-E10&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;SONY ZV-E10&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;1-zv-e10-使用aps-c传感器-作为对比zv-1使用1英寸传感器&#34;&gt;1. ZV-E10 使用APS-C传感器, 作为对比ZV 1使用1英寸传感器.&lt;/h3&gt;
&lt;p&gt;尺寸大了3倍, APS-C(23.6mm*15.6mm)/1英寸(13.2mm*8.8mm)=3.17&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/sony/camera/ZVE10-sensor.png&#34; alt=&#34;ZV-E10 对比 ZV 1传感器尺寸&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;ZV-E10 对比 ZV 1传感器尺寸&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;2-zv-e10镜头使用e卡口-意味超过60组原厂镜头可用-副厂也有适马腾龙&#34;&gt;2. ZV-E10镜头使用E卡口, 意味超过60组原厂镜头可用, 副厂也有适马腾龙&lt;/h3&gt;
&lt;h3 id=&#34;3-zv-e10使用与全画幅一样的数字音频热靴mi接口-直接使用ecm-w2bt麦克风&#34;&gt;3. ZV-E10使用与全画幅一样的数字音频热靴Mi接口, 直接使用ECM-W2BT麦克风&lt;/h3&gt;
&lt;h3 id=&#34;4-zv-e10支持s-log3&#34;&gt;4. ZV-E10支持S-Log3&lt;/h3&gt;
&lt;h3 id=&#34;5-可以用作视频会议-支持usb-type-c接口&#34;&gt;5. 可以用作视频会议, 支持USB type c接口.&lt;/h3&gt;
&lt;h3 id=&#34;6-其他改进&#34;&gt;6. 其他改进&lt;/h3&gt;
&lt;p&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;更好的肤色表现&lt;/a&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;更好的麦克风, 防风性能更好&lt;/a&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;改进的产品展示功&lt;/a&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;表现更好的电子视频防抖&lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>acme.sh命令 Li.018</title>
      <link>https://lizicai.com/p/acme.sh%E5%91%BD%E4%BB%A4-li.018/</link>
      <pubDate>Tue, 27 Jul 2021 14:16:36 +0800</pubDate>
      <guid>https://lizicai.com/p/acme.sh%E5%91%BD%E4%BB%A4-li.018/</guid>
      <description>&lt;h2 id=&#34;1-acmesh-常见命令&#34;&gt;1. acme.sh 常见命令&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 查询所有命令
acme.sh -h

# acme.sh更改申请证书机构
acme.sh --set-default-ca  --server  letsencrypt

# http方式申请证书, lizicai.com域名, --webroot指定访问文件夹
acme.sh  --issue  -d lizicai.com --webroot /root/test/

# 手动dns申请证书
acme.sh --issue --dns -d lizicai.com

# 使用dns提供接口, 自动dns申请证书, 以阿里云为例
export Ali_Key=&amp;#34;Ali_Key&amp;#34;
export Ali_Secret=&amp;#34;Ali_Secret&amp;#34;
acme.sh --issue --dns dns_ali -d lizicai.com

# Cloudflare 为例
export CF_Key=&amp;#34;你的Global API Key&amp;#34;
export CF_Email=&amp;#34;注册Cloudflare邮箱&amp;#34;
acme.sh --issue --dns dns_cf -d \*.lizicai.com


# 检查并更新所有证书
acme.sh --cron

# 设置更新证书通知, 以钉钉 dingtalk通知为例
export DINGTALK_WEBHOOK=&amp;#39;复制的Webhook&amp;#39;
export DINGTALK_KEYWORD=acme
acme.sh  --set-notify  --notify-hook dingtalk

# 设置通知级别
#  --notify-level &amp;lt;0|1|2|3&amp;gt;
# Set the notification level:  Default value is 2.
# 0: disabled, no notification will be sent. 没有通知
# 1: send notifications only when there is an error. 有错误时才通知
# 2: send notifications when a cert is successfully renewed, or there is an error. 证书更新成功或错误才通知.
# 3: send notifications when a cert is skipped, renewed, or error. 跳过证书, 更新证书, 错误都有通知.
export NOTIFY_LEVEL=&amp;#39;3&amp;#39;

# 设置acme.sh 自动升级
acme.sh --upgrade --auto-upgrade 1

# 卸载acme.sh, 并删除所有acme.sh添加crontab任务.
acme.sh --uninstall

# 证书key和fullchain另存, 在获取证书时一起使用
--key-file /root/cert/lizicai.com/private.key
--fullchain-file  /root/cert/lizicai.com/fullchain.pem

# 获取证书时使用, 可执行的一些命令
--reloadcmd     &amp;#34;/usr/sbin/nginx -s reload&amp;#34;

# 重新获取证书, 获取证书时使用
-r, --renew

# 强制
-f
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;2-具体使用可-hahahugoshortcode5s0hbhb&#34;&gt;2. 具体使用可 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/acme.sh%e8%8e%b7%e5%8f%96%e8%af%81%e4%b9%a6-%e8%ae%be%e7%bd%aecrontab%e5%ae%9a%e6%97%b6%e6%a3%80%e6%9f%a5%e6%9b%b4%e6%96%b0%e5%8f%8a%e6%9b%b4%e6%96%b0%e9%80%9a%e7%9f%a5li.017/&#34; target=&#34;_blank&#34;&gt;参考acme.sh获取证书crontab更新及更新通知&lt;/a&gt; 

&lt;/h2&gt;
</description>
    </item>
    
    <item>
      <title>acme.sh获取证书 设置crontab定时检查更新及更新通知 Li.017</title>
      <link>https://lizicai.com/p/acme.sh%E8%8E%B7%E5%8F%96%E8%AF%81%E4%B9%A6-%E8%AE%BE%E7%BD%AEcrontab%E5%AE%9A%E6%97%B6%E6%A3%80%E6%9F%A5%E6%9B%B4%E6%96%B0%E5%8F%8A%E6%9B%B4%E6%96%B0%E9%80%9A%E7%9F%A5-li.017/</link>
      <pubDate>Mon, 26 Jul 2021 20:59:57 +0800</pubDate>
      <guid>https://lizicai.com/p/acme.sh%E8%8E%B7%E5%8F%96%E8%AF%81%E4%B9%A6-%E8%AE%BE%E7%BD%AEcrontab%E5%AE%9A%E6%97%B6%E6%A3%80%E6%9F%A5%E6%9B%B4%E6%96%B0%E5%8F%8A%E6%9B%B4%E6%96%B0%E9%80%9A%E7%9F%A5-li.017/</guid>
      <description>&lt;h2 id=&#34;1-acmesh-是什么&#34;&gt;1. acme.sh 是什么&lt;/h2&gt;
&lt;h4 id=&#34;11-一个纯粹用shellunix-shell语言编写的acme协议客户端-支持shell就能安装&#34;&gt;1.1 一个纯粹用Shell（Unix shell）语言编写的ACME协议客户端. 支持shell就能安装.&lt;/h4&gt;
&lt;h4 id=&#34;12-支持非盈利证书颁发机构hahahugoshortcode9s0hbhb-可以自由获取免费证书&#34;&gt;1.2 支持非盈利证书颁发机构
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://letsencrypt.org/&#34; target=&#34;_blank&#34;&gt;letsencrypt.org&lt;/a&gt; 

, 可以自由获取免费证书.&lt;/h4&gt;
&lt;h4 id=&#34;13-可以自动更新证书&#34;&gt;1.3 可以自动更新证书.&lt;/h4&gt;
&lt;h4 id=&#34;14-支持主流的dns服务商dnspodcn腾讯旗下-阿里云-cloudflare-godaddy-amazon-可申请通配符的证书-hahahugoshortcode9s1hbhb&#34;&gt;1.4 支持主流的DNS服务商(DNSPod.cn(腾讯旗下) 阿里云 Cloudflare GoDaddy Amazon), 可申请通配符的证书. 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/acmesh-official/acme.sh/wiki/dnsapi&#34; target=&#34;_blank&#34;&gt;全部DNS服务商支持列表&lt;/a&gt; 

&lt;/h4&gt;
&lt;h4 id=&#34;15-支持每次更新证书时发送通知-支持主流qq-dingtalk钉钉-telegram-email-slack-hahahugoshortcode9s2hbhb&#34;&gt;1.5 支持每次更新证书时发送通知, 支持主流QQ Dingtalk钉钉 Telegram Email Slack, 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/acmesh-official/acme.sh/wiki/notify&#34; target=&#34;_blank&#34;&gt;完整支持列表&lt;/a&gt; 

&lt;/h4&gt;
&lt;h2 id=&#34;2-安装acmesh-设置默认证书分发机构为letsencryptorg&#34;&gt;2. 安装acme.sh, 设置默认证书分发机构为letsencrypt.org.&lt;/h2&gt;
&lt;h3 id=&#34;21-安装acmesh&#34;&gt;2.1 安装acme.sh&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;curl https://get.acme.sh | sh -s email=my@example.com
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;22-设置默认证书分发机构为letsencryptorg-原因非盈利机构letsencrypt目前为止比较安全-zerossl则是商业机构-hahahugoshortcode9s3hbhb&#34;&gt;2.2 设置默认证书分发机构为letsencrypt.org, 原因非盈利机构letsencrypt目前为止比较安全. ZeroSSL则是商业机构. 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/acme.sh%e8%a2%ab%e6%94%b6%e8%b4%ad-%e6%9b%b4%e6%8d%a2%e9%bb%98%e8%ae%a4%e8%af%81%e4%b9%a6%e9%a2%81%e5%8f%91%e6%9c%ba%e6%9e%84%e4%b8%bazerossl-%e8%bf%98%e5%ae%89%e5%85%a8%e5%90%97li.005/&#34; target=&#34;_blank&#34;&gt;更多解释&lt;/a&gt; 

.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;acme.sh --set-default-ca  --server  letsencrypt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-申请证书常用方式-http和dns方式&#34;&gt;3. 申请证书常用方式. http和dns方式.&lt;/h2&gt;
&lt;h3 id=&#34;31-http方式-特点简单易操作&#34;&gt;3.1 http方式, 特点简单易操作.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;以Nginx为例, 配置的文件夹/root/test/&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;在default.conf增加配置&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;server{
    listen 80;
    server_name lizicai.com;
    location / {
        root   /root/test/;
        index  index.html index.htm;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;确认lizicai.com 解析a记录指向服务器ip&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;在域名服务商或DNS服务商增加lizicai.com指向服务ip的a记录.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;检查&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ping lizicai.com
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;预期显示服务器ip&lt;/strong&gt;&lt;/p&gt;

&lt;a style=&#34;color:red;&#34;&gt;如未显示, DNS服务商生效a记录需要时间5分钟~3小时&lt;/a&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;以http方式申请lizicai.com证书&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 与前面nginx创建的文件夹目录一致
acme.sh  --issue  -d lizicai.com --webroot /root/test/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;申请证书成功则存放在 ~/.acme.sh/lizicai.com 目录下.&lt;/p&gt;
&lt;h3 id=&#34;32-dns自动获取证书-需要转移域名到支持自动获取的api的dns服务商-dnspod-阿里-cloudflare已支持&#34;&gt;3.2 dns自动获取证书, 需要转移域名到支持自动获取的api的dns服务商, dnspod 阿里 Cloudflare已支持.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;阿里云&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;登录阿里云, 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://ak-console.aliyun.com/#/accesskey&#34; target=&#34;_blank&#34;&gt;获取key和secret&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;export Ali_Key=&amp;#34;Ali_Key&amp;#34;
export Ali_Secret=&amp;#34;Ali_Secret&amp;#34;

acme.sh --issue --dns dns_ali -d lizicai.com
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;以dnspod为例&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;你需要先登录到DNSPod账号, 更改域名dns服务为DNSPod, 然后生成你的api id和api key, 完全免费&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;export DP_Id=&amp;#34;1234&amp;#34;
export DP_Key=&amp;#34;sADDsdasdgdsf&amp;#34;

# 可以一次申请2个
acme.sh   --issue   --dns dns_dp   -d lizicai.com  -d www.lizicai.com
# 也可以申请通配域名, * 需要转译
acme.sh   --issue   --dns dns_dp   -d \*.lizicai.com
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;以Cloudflare为例&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;注册Cloudflare, 更改dns服务为Cloudflare, 我的个人资料-&amp;gt;API令牌-&amp;gt;查看Global API Key&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;export CF_Key=&amp;#34;你的Global API Key&amp;#34;
export CF_Email=&amp;#34;注册Cloudflare邮箱&amp;#34;

acme.sh --issue --dns dns_cf -d \*.lizicai.com
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;33-手动dns-不需要转移dns服务商-但是需要手机添加txt记录&#34;&gt;3.3 手动dns, 不需要转移dns服务商, 但是需要手机添加txt记录.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 根据提示添加记录即可
acme.sh --issue --dns -d lizicai.com
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;4-设置crontab定期更新证书&#34;&gt;4. 设置crontab定期更新证书&lt;/h2&gt;
&lt;h3 id=&#34;41-创建crontab的任务&#34;&gt;4.1 创建crontab的任务.&lt;/h3&gt;
&lt;p&gt;Crontab用法, 更多请参考 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/crontab%e5%ae%9a%e6%97%b6%e4%bb%bb%e5%8a%a1%e4%bd%bf%e7%94%a8li.010/&#34; target=&#34;_blank&#34;&gt;Crontab使用&lt;/a&gt; 

&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/crontab/crontab.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;添加如下内容, 每月1,15号12点1分钟检验证书,如距离过期&amp;lt;30天, 则自动申请新证书. ${HOME}安装acme.sh的home目录&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;vim test.cron&lt;/strong&gt; 添加如下内容&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1 12 1,15 * *  ${HOME}/.acme.sh/acme.sh --cron
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;42-任务添加到任务中&#34;&gt;4.2 任务添加到任务中.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;crontab -uroot test.cron

# 检查是否添加成功
crontab -uroot -l
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;5-每次更新证书获取更新通知-了解域名更新成功或失败情况-有问题及时处理&#34;&gt;5. 每次更新证书获取更新通知, 了解域名更新成功或失败情况, 有问题及时处理.&lt;/h2&gt;
&lt;h3 id=&#34;网站如果使用hsts策略-证书过期巨大影响-有必要第一时间获知解证书更新情况&#34;&gt;网站如果使用HSTS策略, 证书过期巨大影响, 有必要第一时间获知解证书更新情况.&lt;/h3&gt;
&lt;h3 id=&#34;51-以dingtalk钉钉为例-创建钉钉test群&#34;&gt;5.1 以Dingtalk钉钉为例. 创建钉钉test群.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;钉钉Dingtalk设置&lt;/a&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/dingtalk1.png&#34; alt=&#34;创建群test,并点击设置&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;创建群test,并点击设置&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/dingtalk2.png&#34; alt=&#34;选择智能群助手&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;选择智能群助手&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/dingtalk3.png&#34; alt=&#34;添加机器人&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;添加机器人&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/dingtalk4.png&#34; alt=&#34;选择 自定义&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;选择 自定义&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/dingtalk5.png&#34; alt=&#34;添加&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;添加&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/dingtalk6.png&#34; alt=&#34;自定义关键词 . 或 acme 都可&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;自定义关键词 . 或 acme 都可&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/dingtalk7.png&#34; alt=&#34;复制Webhook&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;复制Webhook&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;在acme.sh设置参数&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;export NOTIFY_LEVEL=&amp;#39;3&amp;#39;
export DINGTALK_WEBHOOK=&amp;#39;上面复制的Webhook&amp;#39;
export DINGTALK_KEYWORD=acme
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;设置通知为钉钉Dingtalk&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;acme.sh  --set-notify  --notify-hook dingtalk
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/dingtalk8.png&#34; alt=&#34;设置成功后通知&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;设置成功后通知&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;更新证书时就有通知了&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;acme.sh --cron
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/dingtalk9.png&#34; alt=&#34;更新证书时的通知&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;更新证书时的通知&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&#34;52-telegram通知&#34;&gt;5.2 telegram通知.&lt;/h3&gt;
&lt;p&gt;@BotFather 申请机器人, /newbot 可获取TELEGRAM_BOT_APITOKEN&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/telegram1.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;@userinfobot 输入 /start 可获取 TELEGRAM_BOT_CHATID&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/acme.sh/telegram2.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;export NOTIFY_LEVEL=&amp;#39;3&amp;#39;
export TELEGRAM_BOT_APITOKEN=&amp;#34;...&amp;#34;
export TELEGRAM_BOT_CHATID=&amp;#34;...&amp;#34;

acme.sh --set-notify --notify-hook telegram
# 测试
acme.sh --cron
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>SQL基本用法二 Li.016</title>
      <link>https://lizicai.com/p/sql%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95%E4%BA%8C-li.016/</link>
      <pubDate>Mon, 26 Jul 2021 00:10:53 +0800</pubDate>
      <guid>https://lizicai.com/p/sql%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95%E4%BA%8C-li.016/</guid>
      <description>&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/sql/sql-logo.png&#34; alt=&#34;SQL&#34;  /&gt;
&lt;/p&gt;
&lt;h2 id=&#34;1-创建表&#34;&gt;1. 创建表&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table if not exists usrinfo(
id INT(11),
number INT(11),
name VARCHAR(255),
 birthday DATE
  );
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;2-查询表结构&#34;&gt;2. 查询表结构&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;show full columns from usrinfo;

desc usrinfo;

describe usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-查询创建表的语句&#34;&gt;3. 查询创建表的语句&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;show create table usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;4-插入数据&#34;&gt;4. 插入数据&lt;/h2&gt;
&lt;h3 id=&#34;41-插入单选数据&#34;&gt;4.1 插入单选数据&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;insert into usrinfo values (12123123,&amp;#34;hello&amp;#34;,&amp;#34;1990-02-15&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;42-插入多行数据&#34;&gt;4.2 插入多行数据&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;insert into usrinfo values (12123123,&amp;#34;hello&amp;#34;,&amp;#34;1990-02-15&amp;#34;),
(12123123,&amp;#34;cc&amp;#34;,&amp;#34;1991-03-01&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;43-插入某些列&#34;&gt;4.3 插入某些列&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;insert into usrinfo(number,name) values (121234123,&amp;#34;eefef&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;44-插入某些列多行&#34;&gt;4.4 插入某些列多行&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;insert into usrinfo(number,name) values (121234123,&amp;#34;eefef&amp;#34;),
(121234123,&amp;#34;eefef&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;5-查询某一列不重复的值&#34;&gt;5. 查询某一列不重复的值&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select distinct number from usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;6-增加新的列&#34;&gt;6. 增加新的列&lt;/h2&gt;
&lt;h3 id=&#34;61-增加新列&#34;&gt;6.1 增加新列&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table usrinfo add id int(11);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;62-并给修改新列的属性&#34;&gt;6.2 并给修改新列的属性&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table usrinfo change id id int not null auto_increment primary key;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;63-更改新加列的排序&#34;&gt;6.3 更改新加列的排序:&lt;/h3&gt;
&lt;p&gt;把id这列,放到第1列&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table usrinfo modify id int(11) first;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;64-把birthday这列放在number后面&#34;&gt;6.4 把birthday这列放在number后面&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table usrinfo modify birthday date after number;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;7-重命名表-和-列名&#34;&gt;7. 重命名表 和 列名.&lt;/h2&gt;
&lt;h3 id=&#34;71-更改表名&#34;&gt;7.1 更改表名&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table &amp;lt;old_name&amp;gt;  rename &amp;lt;new_name&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;72-更改列名后面必须有属性值才能修改成功&#34;&gt;7.2 更改列名,后面必须有属性值,才能修改成功&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table usrinfo change id new_id int(10) ;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;73-更改列名-属性由int-转换为varchar&#34;&gt;7.3 更改列名+ 属性,由int 转换为varchar&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table usrinfo change id new_id varchar(11);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;8-删除列&#34;&gt;8. 删除列.&lt;/h2&gt;
&lt;h3 id=&#34;81-提前新建一个列-alter-table-usrinfo-add-dd-varchar11&#34;&gt;8.1 提前新建一个列 alter table usrinfo add dd varchar(11);&lt;/h3&gt;
&lt;p&gt;mysql适用于下面的语句, 别的数据库未知.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table usrinfo drop dd;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;9-删除某个列中某行为null的数据注意是is-null-不是null&#34;&gt;9. 删除某个列中某行为null的数据,注意是is null 不是=null&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;delete from usrinfo where birthday is null;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;10删除一个表&#34;&gt;10.删除一个表&lt;/h2&gt;
&lt;h3 id=&#34;为了删除我先创建一个表create-table-delid-int11-not-null-primary-key-auto_incrementname-varchar255phone-int11&#34;&gt;为了删除我先创建一个表create table del(id int(11) not null primary key auto_increment,name varchar(255),phone int(11));&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;drop table del;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;11-返回唯一不同的值&#34;&gt;11. 返回唯一不同的值&lt;/h2&gt;
&lt;h3 id=&#34;111-查询单行的唯一不同的值&#34;&gt;11.1 查询单行的唯一不同的值&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select DISTINCT birthday from usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;112-查询多行唯一不同的值组合起来是唯一不同的值&#34;&gt;11.2 查询多行唯一不同的值,组合起来是唯一不同的值&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select DISTINCT number,birthday from usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;12-where的简单查询语句&#34;&gt;12. where的简单查询语句&lt;/h2&gt;
&lt;h3 id=&#34;121-in-和-like&#34;&gt;12.1 In 和 like&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * from usrinfo where name in (&amp;#34;Hello&amp;#34;);

select * from usrinfo where name like &amp;#39;%ello&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;%表示多个字符,_ 下划线表示一个字母,like不区分大小写的&lt;/p&gt;
&lt;h3 id=&#34;122-binary-区分大小写&#34;&gt;12.2 binary 区分大小写&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * from usrinfo where name like binary &amp;#39;Hello&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;13-and和or&#34;&gt;13. and和or&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * from usrinfo where name=&amp;#39;hello&amp;#39; and number=&amp;#39;1233&amp;#39;;
select * from usrinfo where name=&amp;#39;hello&amp;#39; or name=&amp;#39;Hello&amp;#39;;
select * from usrinfo where name=&amp;#39;hello&amp;#39; or number=1233;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;14-order-by&#34;&gt;14. order by&lt;/h2&gt;
&lt;h3 id=&#34;141-升序默认方式也是这种&#34;&gt;14.1 升序,默认方式也是这种&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * from usrinfo order by number asc;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;142-降序&#34;&gt;14.2 降序&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * from usrinfo order by number desc;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;15-update&#34;&gt;15. update&lt;/h2&gt;
&lt;h3 id=&#34;151-update-记录&#34;&gt;15.1 update 记录&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;update usrinfo set number=999 where id=18;
update usrinfo set number=999 wehre id in(18,19);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:red;&#34;&gt;更新必须带where,否则会更新所有数据&lt;/a&gt;
&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;16-limit&#34;&gt;16. limit&lt;/h2&gt;
&lt;h3 id=&#34;161-查询数据库中从2行到后n行的数据&#34;&gt;16.1 查询数据库中从2行到后n行的数据&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * from usrinfo limit 2,n;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;162-查询起始后n行数据如顶部的5行数据&#34;&gt;16.2 查询起始后n行数据,如顶部的5行数据.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * from usrinfo limit 5;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;17-min-和-max&#34;&gt;17. Min 和 Max&lt;/h2&gt;
&lt;h3 id=&#34;171-查询某列的最小值并赋值给参数&#34;&gt;17.1 查询某列的最小值并赋值给参数&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select min(id) as small_id from usrinfo;
select max(id) as max_id from usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;18-count计算搜索得到的行数-sum求合-avg求平均值&#34;&gt;18. count计算搜索得到的行数, sum求合 avg求平均值&lt;/h2&gt;
&lt;h3 id=&#34;181-sum-和-avg-仅针对所有int数据&#34;&gt;18.1 sum 和 avg 仅针对所有int数据&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select count(id) from usrinfo;

select avc(number) from usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;19-alias-重命名&#34;&gt;19. alias 重命名&lt;/h2&gt;
&lt;h3 id=&#34;191-mysql中语句&#34;&gt;19.1 MySQL中语句&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select id,CONCAT(name,&amp;#39; , &amp;#39;,address) as cc from usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;192-其它数据库写法&#34;&gt;19.2 其它数据库写法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select id,name,&amp;#39; , &amp;#39;, address as cc from usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;20-inner-join-left-join-rigth-join-full-join&#34;&gt;20. inner join, left join, rigth join, full join&lt;/h2&gt;
&lt;h3 id=&#34;201-mysql-not-have-fulljush-left-join-union-right-join&#34;&gt;20.1 Mysql not have full,jush left join union right join.&lt;/h3&gt;
&lt;h3 id=&#34;默认为join为inner-join两个表的交集-left-join-取左边表的集合包括交集但不包含右表没有交集的部分&#34;&gt;默认为join为inner join两个表的交集, left join 取左边表的集合包括交集但不包含右表没有交集的部分,&lt;/h3&gt;
&lt;h3 id=&#34;右连接与左连接相反全连接是左右表的并集&#34;&gt;右连接与左连接相反,全连接是左右表的并集.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select o.id,o.name,c.id,c.number from order as o (inner) join customers as c on o.id = c.id;
select o.id,o.name,c.id,c.number from order as o left join customers as c on o.id = c.id;
select o.id,o.name,c.id,c.number from order as o right join customers as c on o.id = c.id;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;202-全连接&#34;&gt;20.2 全连接&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select o.id,o.name,c.id,c.number from order as o right join customers as c on o.id = c.id
union
select o.id,o.name,c.id,c.number from order as o left join customers as c on o.id = c.id;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;203-三个表inner-join&#34;&gt;20.3 三个表inner join&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select o.orderId,o.customerID,cu.costomerID,cu.costomerName,cp.CustomerID,cp.phone1 from
(orders as o join customers as cu on where o.CustomerID = cu.CustomerID)
join cphone as cp on o.CustomerID = cp.CustomerID;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;21-self-join&#34;&gt;21. self join&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select A.CustomerName as CustomerName1,B.CustomerName as CustomerName2,A.Country
from customers A, customers B
where A.CustomerID &amp;lt;&amp;gt; B.CustomerID and A.Country= B.Country
order by A.Country;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;22-union&#34;&gt;22. union&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select CustomerID from orders
union
select CustomerID from customers;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;23-group-by-把查询到的结果分组&#34;&gt;23. group by 把查询到的结果分组&lt;/h2&gt;
&lt;h3 id=&#34;231-以国家为组统计有多少个id&#34;&gt;23.1 以国家为组统计有多少个id&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select count(c.CustomerID),c.Country
from orders as o join customers as c on o.customerID = c.CustomerID group by c.Country;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;232-以国家为组统计有多少个id并按照id个数排序从小到大&#34;&gt;23.2 以国家为组统计有多少个id,并按照id个数排序,从小到大&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select count(c.CustomerID),c.Country
from orders as o join customers as c on o.customerID = c.CustomerID group by c.Country order by count(c.CustomerID);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;24-having-having是分组group-by后的筛选条件分组后的数据组内再筛选where则是在分组前筛选&#34;&gt;24. having, having是分组(group by)后的筛选条件,分组后的数据组内再筛选,where则是在分组前筛选.&lt;/h2&gt;
&lt;h3 id=&#34;241-以country分组然后找个数超过1的&#34;&gt;24.1 以country分组,然后找个数超过1的.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select count(CustomerID) as number,Country from customers where CustomerID&amp;gt;1 group by Country having count(CustomerID) &amp;gt; 1;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;25-select-into-复制表或表结构的时候-只得到一个外壳-clone一个躯体-原表的主键外键约束触发器索引都不会被复制过来&#34;&gt;25. select into, 复制表或表结构的时候, 只得到一个&amp;quot;外壳&amp;quot;, clone一个躯体, 原表的主键,外键,约束,触发器,索引都不会被复制过来.&lt;/h2&gt;
&lt;h3 id=&#34;251-非mysql用法&#34;&gt;25.1 非mysql用法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * into orders_back from orders;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;252-mysql用法&#34;&gt;25.2 mysql用法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table orders_back (select * from orders);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;253-复制部分列&#34;&gt;25.3 复制部分列&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table order_b1(select orderId,orderDate from orders);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;254-可以增加where语句&#34;&gt;25.4 可以增加where语句&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table order_b2(select orderId,orderDate from orders where orderId &amp;gt; 123);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;255-只复制表&#34;&gt;25.5 只复制表&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table orders_back3 (select * from orders where 1=2)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;26-insert-into-select-从一个表拿数据插入另一个表中&#34;&gt;26. Insert into select, 从一个表拿数据插入另一个表中,&lt;/h2&gt;
&lt;h3 id=&#34;261-复制某些字段到另一个表中&#34;&gt;26.1 复制某些字段到另一个表中&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;insert into orders_back(orderId,customerID,orderDate) select orderId,customerID,orderDate from orders;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;262-复制整个表到另一个表中两张表的结构属性是一样的&#34;&gt;26.2 复制整个表到另一个表中,两张表的结构属性是一样的&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;insert into orders_back select * from orders;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;263-也可以后面跟where语句进入-筛选要复制的列&#34;&gt;26.3 也可以后面跟where语句进入, 筛选要复制的列&lt;/h3&gt;
&lt;p&gt;insert into orders_back select * from orders where orderId &amp;gt; 1;&lt;/p&gt;
&lt;h2 id=&#34;27-创建一个数据库-删除一个数据&#34;&gt;27. 创建一个数据库, 删除一个数据&lt;/h2&gt;
&lt;h3 id=&#34;271-你必须有创建或者删除数据库的权限&#34;&gt;27.1 你必须有创建或者删除数据库的权限&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create database mydata;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;272-删除数据&#34;&gt;27.2 删除数据&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;drop database mydata;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;28-创建一个表时列的属性的限定&#34;&gt;28. 创建一个表时,列的属性的限定&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NOT NULL
UNIQUE
PRIMARY KEY
FOREIGN KEY
CHECK
DEFAULT
INDEX
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;281-check&#34;&gt;28.1 check&lt;/h3&gt;
&lt;h3 id=&#34;mysql-用法&#34;&gt;Mysql 用法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table person(
    id int(11) primary key,
    Age int(11),
    CHECK (Age &amp;gt; = 18)
);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;282-oracle-sql-server用法&#34;&gt;28.2 Oracle SQL server用法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table person(
    id int(11) primary key,
    Age int CHECK (Age&amp;gt;=18)
        );
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;283-多个check条件-能用mysql-oracle都可用&#34;&gt;28.3 多个check条件, 能用mysql, oracle都可用&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create tables person(
    id int primary key,
    Age int(11),
    City varchar(255),
    CONSTRAINT CHK_person check (Age&amp;gt;=18 and City=&amp;#39;Shanghai&amp;#39;)
);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;284-增加一个check条件&#34;&gt;28.4 增加一个check条件&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table person add CHECK (Age&amp;gt;=18);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;285-增加多个check条件-mysql-oracle都可用&#34;&gt;28.5 增加多个check条件, mysql oracle都可用&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table person add CONSTRAINT CHK_personAge CHECK (Age&amp;gt;=18 and city=&amp;#39;Shanghai&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;286-删除表中一个check条件&#34;&gt;28.6 删除表中一个check条件&lt;/h3&gt;
&lt;h3 id=&#34;mysql用法&#34;&gt;Mysql用法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table person drop CHECK CHK_personAge;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;287-oracesql-server用法&#34;&gt;28.7 orace/SQL server用法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table person drop CONSTRAINT CHK_personAge;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;29-default-用法&#34;&gt;29. Default 用法&lt;/h2&gt;
&lt;h3 id=&#34;291-创建表的时间&#34;&gt;29.1 创建表的时间&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table person(
    id int(11) primary key,
    Age int,
    City varchar(255) DEFAULT &amp;#39;Shanghai&amp;#39;
);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;292-增加表的属性时&#34;&gt;29.2 增加表的属性时&lt;/h3&gt;
&lt;h4 id=&#34;mysql用法-1&#34;&gt;Mysql用法&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table person alter City set DEFAULT &amp;#39;Shanghai&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;oracle用法&#34;&gt;oracle用法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table person modify City DEFAULT &amp;#39;Shanghai&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;293-删除默认&#34;&gt;29.3 删除默认&lt;/h3&gt;
&lt;h4 id=&#34;mysql-用法-1&#34;&gt;Mysql 用法&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table person alter City drop default;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;oracle-sql-server-用法&#34;&gt;Oracle SQL server 用法&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table person alter COLUMN City drop default;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;30-index-索引-聚集索引一个表最多有一个&#34;&gt;30. Index 索引, 聚集索引一个表最多有一个&lt;/h2&gt;
&lt;h3 id=&#34;301-创建一个索引和创建多个索引&#34;&gt;30.1 创建一个索引和创建多个索引&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create index ind_orderId on orders(orderId);
create index ind_orderid on orders(orderId, orderDate);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;302-删除一个索引&#34;&gt;30.2 删除一个索引&lt;/h3&gt;
&lt;h4 id=&#34;mysql格式是alter-table-table_name-drop-index-index_name&#34;&gt;mysql,格式是alter table table_name drop INDEX index_name;&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alter table orders drop INDEX ind_orderId;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;oracle-db2&#34;&gt;Oracle DB2&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;drop index index_name;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;sql-server&#34;&gt;SQL server&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;drop index table_name.index_name;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;31-auto_increment-自动增加值&#34;&gt;31. Auto_INCREMENT 自动增加值&lt;/h2&gt;
&lt;h3 id=&#34;311-mysql&#34;&gt;31.1 Mysql&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table person(
    id int(11) auto_increment primary key,
    age int(3)
);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;312-sql-server&#34;&gt;31.2 SQL server&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create table person(
    id int(11) IDENTITY(1,1) primary key,
    Age int(11)
);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;313-oracle-未知待更新&#34;&gt;31.3 Oracle 未知待更新&lt;/h3&gt;
&lt;h2 id=&#34;32-view-视图是原表某些列的影分身-更改视图也就是更改原表的数据&#34;&gt;32. View 视图是原表某些列的影分身, 更改视图也就是更改原表的数据.&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create VIEW view_orders_list as select orderId,orderDate from orders;

update view_orders_list set orderId=222 where orderId=22;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;321-更新一个视图-可以更新列的直接在下面语句中增加就可以了&#34;&gt;32.1 更新一个视图, 可以更新列的,直接在下面语句中增加就可以了.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;create or replace view view_list
as
select orderId,orderDate,customerID
from orders ;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;322-删除一个视图&#34;&gt;32.2 删除一个视图&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;drop view view_list;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;33-null-functions&#34;&gt;33. Null Functions&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select productName, unitPrice\*(unitInstock+IFNULL(unitOrder,0)) from products;
select productName, unitPrice\*(unitInstock+COALESCE(unitOrder,0)) from products;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;34-cross-join-是两个表笛卡尔集&#34;&gt;34. Cross join 是两个表笛卡尔集&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select * from orders cross join usrinfo;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;35-update-与-inner-join连用&#34;&gt;35. update 与 inner join连用&lt;/h2&gt;
&lt;h3 id=&#34;351-oracle-中用法&#34;&gt;35.1 oracle 中用法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;update orders set orderDate=&amp;#34;1991-02-09&amp;#34; where orders.customerID in(
    select customers.CustomerID from orders join customers on
    orders.customerID = customers.CustomerID;
    );
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;352-mysql用法&#34;&gt;35.2 Mysql用法&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;update orders  as o join
(select c.customerID from orders as o join customers as c on o.customerID = c.CustomerID)
c on o.customerID = c.customerID
set o.orderDate=&amp;#34;1990-09-08&amp;#34;;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;36-date日期查询特定year-month-day的人&#34;&gt;36. date日期查询特定year month day的人&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; student &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;year&lt;/span&gt;(birthday)&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1990&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;month&lt;/span&gt;(birthday)&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;02&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;day&lt;/span&gt;(birthday)&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>SQL基本用法一 Li.015</title>
      <link>https://lizicai.com/p/sql%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95%E4%B8%80-li.015/</link>
      <pubDate>Mon, 26 Jul 2021 00:05:35 +0800</pubDate>
      <guid>https://lizicai.com/p/sql%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95%E4%B8%80-li.015/</guid>
      <description>&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/sql/sql-logo.png&#34; alt=&#34;SQL&#34;  /&gt;
&lt;/p&gt;
&lt;h2 id=&#34;1-建立表-4个表关系&#34;&gt;1. 建立表 4个表关系&lt;/h2&gt;
&lt;p&gt;1.学生表&lt;/p&gt;
&lt;p&gt;Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别&lt;/p&gt;
&lt;p&gt;2.课程表&lt;/p&gt;
&lt;p&gt;Course(c_id,c_name,t_id) – –课程编号, 课程名称, 教师编号&lt;/p&gt;
&lt;p&gt;3.教师表&lt;/p&gt;
&lt;p&gt;Teacher(t_id,t_name) –教师编号,教师姓名&lt;/p&gt;
&lt;p&gt;4.成绩表&lt;/p&gt;
&lt;p&gt;Score(s_id,c_id,s_s_score) –学生编号,课程编号,分数&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-- 学生表
CREATE TABLE Student(
s_id VARCHAR(20),
s_name VARCHAR(20) NOT NULL DEFAULT &amp;#39;&amp;#39;,
s_birth VARCHAR(20) NOT NULL DEFAULT &amp;#39;&amp;#39;,
s_sex VARCHAR(10) NOT NULL DEFAULT &amp;#39;&amp;#39;,
PRIMARY KEY(s_id)
);

-- 课程表
CREATE TABLE Course(
c_id VARCHAR(20),
c_name VARCHAR(20) NOT NULL DEFAULT &amp;#39;&amp;#39;,
t_id VARCHAR(20) NOT NULL,
PRIMARY KEY(c_id)
);

-- 教师表
CREATE TABLE Teacher(
t_id VARCHAR(20),
t_name VARCHAR(20) NOT NULL DEFAULT &amp;#39;&amp;#39;,
PRIMARY KEY(t_id)
);

-- 成绩表
CREATE TABLE `Score`(
s_id VARCHAR(20),
c_id VARCHAR(20),
s_score INT(3),
PRIMARY KEY(s_id,c_id)
);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;11-插入对应的数据&#34;&gt;1.1 插入对应的数据&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 插入学生表测试数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;赵雷&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1990-01-01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;男&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;钱电&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1990-12-21&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;男&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;孙风&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1990-05-20&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;男&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;04&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;李云&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1990-08-06&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;男&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;05&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;周梅&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1991-12-01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;女&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;06&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;吴兰&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1992-03-01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;女&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;07&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;郑竹&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1989-07-01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;女&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;08&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;王菊&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1990-01-20&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;女&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;09&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;如花&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1991-02-15&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;女&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 课程表测试数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Course &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;语文&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Course &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;数学&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Course &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;英语&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Course &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;04&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;体育&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 教师表测试数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;张三&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;李四&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;王五&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 成绩表测试数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;90&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;99&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;70&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;04&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;50&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;04&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;04&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;05&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;76&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;05&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;87&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;06&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;31&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;06&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;34&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;07&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;89&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;07&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt; , &lt;span style=&#34;color:#ae81ff&#34;&gt;98&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;09&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;50&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;09&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;02&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;09&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;03&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;90&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;insert&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;into&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;values&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;09&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;04&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;99&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;2-sql练习&#34;&gt;2. SQL练习&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;查询姓&amp;quot;张&amp;quot;老师的个数&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(t_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_name &lt;span style=&#34;color:#66d9ef&#34;&gt;like&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;张%&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询1990年出生的学生名单&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;year&lt;/span&gt;(s_birth)&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1990&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询课程编号为&amp;quot;02&amp;quot;的总成绩&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id,&lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;总成绩&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;02&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询选了课程的学生人数
思路学生唯一, 然后再计算总数&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;distinct&lt;/span&gt; s_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;选课人数&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询各科成绩最高和最低的分: 以如下的形式显示: 课程ID, 最高分, 最低分&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;课程&lt;/span&gt;ID, &lt;span style=&#34;color:#66d9ef&#34;&gt;max&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;最高分&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;min&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;最低分&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询每门课程被选修的学生数&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id, &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(s_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询男生,女生人数&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_sex &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;性别&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(s_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;人数&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_sex;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询平均成绩大于60分的学生的学号和平均成绩&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;学号与平均成绩都在Score表中可以获取到&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;学号&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;平均成绩&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询至少选修两门课程的学生学号
学生学号与学生选修课程数都在Score表中&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;学号&lt;/span&gt;,&lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;选修课程数&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询两门以上不及格课程的同学的学号及其平均成绩&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;21-这种做法是错误的-只计算不及格课程的平均成绩-如果还有其他课程及格就未计算在内了&#34;&gt;2.1 这种做法是错误的, 只计算不及格课程的平均成绩, 如果还有其他课程及格就未计算在内了&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;学号&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score)&lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;平均成绩&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;22-学生学号-学生不及格课程总数-平均成绩都在score表中-但是一条语句无法查询出来不及格条件后的平均成绩是不正确即是不及格课程的平均成绩不是总成绩包含及格与不及格课程成绩&#34;&gt;2.2 学生学号, 学生不及格课程总数, 平均成绩都在Score表中, 但是一条语句无法查询出来,不及格条件后的平均成绩是不正确(即是不及格课程的平均成绩),不是总成绩(包含及格与不及格课程成绩).&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询到不及格课程总断&amp;gt;2的学生
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询学生的总成绩计算的平均成绩
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id,&lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; avg_score &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 将2表内连接起来
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s1.s_id, s2.avg_score
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id,&lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; avg_score &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; s1.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;s2.s_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;23-这次查询不及格课程数1的学生学号平均成绩09号有3门课程三门成绩405090360-错误做法只计算不及格成绩4050245&#34;&gt;2.3 这次查询不及格课程数&amp;gt;1的学生,学号,平均成绩.(&amp;ldquo;09号有3门课程,三门成绩(40+50+90)/3=60&amp;rdquo;, 错误做法只计算不及格成绩(40+50)/2=45)&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 错误做法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;学号&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score)&lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;平均成绩&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 正确做法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s1.s_id, s2.avg_score
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id,&lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; avg_score &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; s1.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;s2.s_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询名字完全一致的学生, 统计同名人数&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 名字, 同名人数都在表Student中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_name, &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(s_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;同名人数&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(s_id)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询每门课程的平均成绩，结果按平均成绩升序排序，平均成绩相同时，按课程号降序排列&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id, &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;平均成绩&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;order&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;ASC&lt;/span&gt;, c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询不及格课程号和学生号, 课程号从大到小排列&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 这些不及格课程号与学生号数据都在Score表中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, c_id, s_score &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;检索课程编号为“03”且分数小于60的学生学号，结果按按分数降序排列&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, s_score &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;03&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;统计每门课程的学生选修人数(超过5人的课程才统计), 要求输出课程号和选修人数，查询结果按人数降序排序，若人数相同，按课程号升序排序&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id, &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(s_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(s_id)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;order&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(s_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt;, c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;ASC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询所有课程成绩小于60分的学生的学号、姓名.
学生成绩在表Score中, 学生姓名在表Student, 内连接2个表&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 小于60分的学生号
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, s_score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 学生姓名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 通过s_id内连接2个表, 2个成绩&amp;lt;60分会有2条数据, 可用group by去重
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; sco.s_id,s.s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s &lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; sco.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;s.s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 还可以这么写
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id,s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询没有学全所有课的学生的学号、姓名&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;24-全部课程数在course中-学生所选课程在score中-学生姓名在student中隐藏条件学生所学课程一定属于全部课程中的一种&#34;&gt;2.4 全部课程数在Course中, 学生所选课程在Score中, 学生姓名在Student中.(隐藏条件学生所学课程一定属于全部课程中的一种)&lt;/h3&gt;
&lt;h3 id=&#34;理解是学没有学全所有课程的所有学号与学生姓名注意是所有学生&#34;&gt;理解是学没有学全所有课程的所有学号与学生姓名(注意是所有学生)&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询全部课程数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Course;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询学生学号与课程数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; count_cid &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询学生学号与学生姓名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 左连Student与Score表, 为什么左连接, 因为是没有学无所有课程的学生, 学生一定会有, 学生不一定有选修的课程成绩.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s.s_id, s.s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Student &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;left&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; sco.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;s.s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s.s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Course);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询出只选修了两门课程的全部学生的学号和姓名&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;25-学生选修课程数在score表中-学生姓名在表student中&#34;&gt;2.5 学生选修课程数在Score表中, 学生姓名在表Student中&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询学生选择课程数为2的学生
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id,&lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询学生姓名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 左连接2个表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s.s_id, s.s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Student &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;left&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; s.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;sco.s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s.s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询课程编号为03且课程成绩在80分以上的学生的学号和姓名&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;26-学生选修课程与成绩在score表中-学生姓名在表student中&#34;&gt;2.6 学生选修课程与成绩在Score表中, 学生姓名在表Student中&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询课程03,&amp;gt;80的学生成绩
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, s_score, c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;03&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询学生姓名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 内连接2个表, 注意不是左右连接,有对应成绩的才检索,否则不检索
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s.s_id, s.s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Student &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; s.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;sco.s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; sco.s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; sco.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;03&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 其他写法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id, s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;03&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号
内连接 s1同学.s_id=s2同学.s_id, s1.c_id=&amp;ldquo;01&amp;rdquo;, s2.c_id=&amp;ldquo;02&amp;rdquo;, s1.s_score&amp;gt;s2.s_score, 最后去重&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s1.s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score s1,Score s2 &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s1.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;s2.s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; s1.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;01&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; s2.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;02&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; s1.s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;s2.s_score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s1.s_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;按平均成绩从高到低，按如下形式显示: 学生ID, 有效课程数, 有效平均分&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;学生ID&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id) &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;有效课程数&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;有效平均分&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;使用分段[100-85],[85-70],[70-60],[&amp;lt;60]来统计各科成绩，分别统计各分数段人数: 课程ID和课程名称&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;.c_id, &lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;.c_name, &lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;when&lt;/span&gt; sco.s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;85&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; sco.s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;[100-85]&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;when&lt;/span&gt; sco.s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;70&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; sco.s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;85&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;[85-70]&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;when&lt;/span&gt; sco.s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; sco.s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;70&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;[70-60]&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;when&lt;/span&gt; sco.s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;[&amp;lt;60]&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Course &lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;  Score sco &lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; sco.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;.c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;.c_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询出每门课程的及格人数和不及格人数&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;when&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;及格人数&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;when&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;不及格人数&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询出每门课程的及格百分数&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id, sco.&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;及格人数&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;(sco.&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;及格人数&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;sco.&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;不及格人数&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;及格百分比&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;when&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;及格人数&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;when&lt;/span&gt; s_score&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;不及格人数&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询至少有一门课与学号为“01”的学生所学课程相同的学生的学号和姓名&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;27-注意是其他学生-应该去除自己s_id01的情况&#34;&gt;2.7 注意是其他学生, 应该去除自己s_id=&amp;ldquo;01&amp;quot;的情况&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id,s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;02&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 内连接
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s.s_id, s.s_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Student s &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt; Score sco &lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; s.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;sco.s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; sco.c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;01&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; sco.s_id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s.s_id;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询和“01”号同学所学课程完全相同的其他同学的学号&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;28-注意是其他学生-应该去除自己s_id01的情况&#34;&gt;2.8 注意是其他学生, 应该去除自己s_id=&amp;ldquo;01&amp;quot;的情况&lt;/h3&gt;
&lt;h4 id=&#34;属于的01学生的课程数-应该与01学生的总课程数一致才算完全一致&#34;&gt;属于的&amp;quot;01&amp;quot;学生的课程数, 应该与&amp;quot;01&amp;quot;学生的总课程数一致才算完全一致.&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 计算&amp;#34;01&amp;#34;号学生的课程数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;01&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 计算其他学生属于&amp;#34;01&amp;#34;课程的课程数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;01&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; s_id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;01&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;把“SCORE”表中“张三”老师教的课的成绩都更改为此课程的平均成绩&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询&amp;#34;张三老师名字和id&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t_id, t_name &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询张三老师的课程
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t_id, c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Course &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 课程分组的平均成绩
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; avg_score,c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 张三老师课程与课程分组平均成绩内连接
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t.t_id, t.c_id, sco.avg_score &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t_id, c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Course &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;)) t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; avg_score,c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id) sco
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; t.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;sco.c_id;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 内连接得到老师和学生课程成绩和每科的平均成绩
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; ss1 &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; sco.c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco_cid,sco.avg_score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco_avg_socre &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t_id, c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Course &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;)) t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; avg_score,c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id) sco
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; t.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;sco.c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; ss2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; ss1.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;ss2.sco_cid;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 更新上面的内连接表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;update&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; ss1 &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; sco.c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco_cid,sco.avg_score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco_avg_socre &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t_id, c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Course &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; t_name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;张三&amp;#34;&lt;/span&gt;)) t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; avg_score,c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id) sco
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; t.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;sco.c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; ss2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; ss1.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;ss2.sco_cid
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; ss1.s_score&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;ss2.sco_avg_socre;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;按各科平均成绩从低到高和及格率的百分数从高到低排列，以如下形式显示: 课程号，课程名平均成绩，及格百分数&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 查询课程号与课程平均成绩
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; c_id, &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; avg_score &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 及格百分数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s1.c_id, jige&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;all_chenji, s2.avg_score
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;when&lt;/span&gt; s_score &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; jige,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(s_id)all_chenji,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; avg_score,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;c_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; c_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; s1.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;s2.c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s1.c_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;order&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s2.avg_score &lt;span style=&#34;color:#66d9ef&#34;&gt;ASC&lt;/span&gt;, jige&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;all_chenji &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询不同老师所教不同课程平均分从高到低显示&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; t.t_name, &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Teacher &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Course &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; t.t_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;.t_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;.c_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;sco.c_id &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; sco.c_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;order&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询学生平均成绩及其名次&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id,&lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score),&lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;curRank:&lt;span style=&#34;color:#f92672&#34;&gt;=@&lt;/span&gt;curRank &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score s1,(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;curRank:&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) q &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询各科成绩前三名的记录（不考虑成绩并列情况）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;待解决&#34;&gt;待解决&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;查询所有学生的学号、姓名、选课数、总成绩&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;29-所有学生-用左连接-查到所有学生&#34;&gt;2.9 所有学生, 用左连接, 查到所有学生&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 学号,姓名在Student表中, 学号,选课数,总成绩在Score表中, 左连接起来
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s.s_id, s.s_name,&lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id),&lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;left&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; s.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;sco.s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询平均成绩大于85的所有学生的学号、姓名和平均成绩&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 学号,姓名在Student表中, 平均成绩,选课数在Score表中, 左连接起来
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s.s_id, s.s_name,&lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;left&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; sco
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; s.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;sco.s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;(s_score)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;85&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询有2门不同课程成绩相同的学生的学号、课程号、学生成绩&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s1.s_id,s1.c_id,s1.s_score &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score s1,Score s2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s1.s_id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;s2.s_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; s1.s_score&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;s2.s_score
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; s1.c_id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;s2.c_id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s1.s_id,s1.c_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;查询选修了全部课程的学生信息&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Student &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Score &lt;span style=&#34;color:#66d9ef&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; s_id &lt;span style=&#34;color:#66d9ef&#34;&gt;having&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id)&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;count&lt;/span&gt;(c_id) &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; Course));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>MariaDB MySQL连接的2种常见错误 Li.014</title>
      <link>https://lizicai.com/p/mariadb-mysql%E8%BF%9E%E6%8E%A5%E7%9A%842%E7%A7%8D%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF-li.014/</link>
      <pubDate>Sun, 25 Jul 2021 23:55:39 +0800</pubDate>
      <guid>https://lizicai.com/p/mariadb-mysql%E8%BF%9E%E6%8E%A5%E7%9A%842%E7%A7%8D%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF-li.014/</guid>
      <description>&lt;h2 id=&#34;1-常见mysql-mariadb连接的2种错误&#34;&gt;1. 常见MySQL Mariadb连接的2种错误&lt;/h2&gt;
&lt;h3 id=&#34;11-错误一&#34;&gt;1.1 错误一&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ERROR 1045 (28000): Access denied
for user &amp;#39;usera&amp;#39;@&amp;#39;localhost&amp;#39; (using password:YES)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;12-错误二&#34;&gt;1.2 错误二&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ERROR 1045 (28000): Access denied
for user &amp;#39;usera&amp;#39;@&amp;#39;localhost&amp;#39; (using password:NO).
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;2-错误一-常见错误是密码错误&#34;&gt;2. 错误一 常见错误是密码错误&lt;/h2&gt;
&lt;h3 id=&#34;重置密码即可&#34;&gt;重置密码即可&lt;/h3&gt;
&lt;h2 id=&#34;3-错误二-输入账号密码时没有输入密码&#34;&gt;3. 错误二 输入账号密码时没有输入密码.&lt;/h2&gt;
&lt;h3 id=&#34;31-命令行中没有-p进行无密码登录&#34;&gt;3.1 命令行中没有-p进行无密码登录&lt;/h3&gt;
&lt;h4 id=&#34;32-如果是ide中的yaml文件确定password的缩进正确&#34;&gt;3.2 如果是IDE中的yaml文件确定password的缩进正确&lt;/h4&gt;
&lt;p&gt;cat application.yaml&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;spring:
  datasource:
    driver-class-name: org.mariadb.jdbc.Driver
    url: jdbc:mariadb://localhost:3306/admin
    username: admin
password: 123456
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;上面的password缩进错误-就会提示using-passwordno&#34;&gt;上面的password缩进错误, 就会提示(using password:No)&lt;/h4&gt;
&lt;h4 id=&#34;正确的是&#34;&gt;正确的是&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;spring:
  datasource:
    driver-class-name: org.mariadb.jdbc.Driver
    url: jdbc:mariadb://localhost:3306/admin
    username: admin
    password: 123456
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>编译安装Nginx支持tls1.3 Li.013</title>
      <link>https://lizicai.com/p/%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85nginx%E6%94%AF%E6%8C%81tls1.3-li.013/</link>
      <pubDate>Sun, 25 Jul 2021 20:29:58 +0800</pubDate>
      <guid>https://lizicai.com/p/%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85nginx%E6%94%AF%E6%8C%81tls1.3-li.013/</guid>
      <description>&lt;h2 id=&#34;1-直接脚本安装-分别安装openss-111k和nginx&#34;&gt;1. 直接脚本安装, 分别安装openss 1.1.1k和Nginx.&lt;/h2&gt;
&lt;h3 id=&#34;步骤2-3分步安装是脚本的解释-步骤4是配置和验证&#34;&gt;步骤2 3分步安装是脚本的解释. 步骤4是配置和验证.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;curl -O https://raw.githubusercontent.com/leezicai/share/master/nginx/yum_install_openssl.sh
sh yum_install_openssl.sh

curl -O https://raw.githubusercontent.com/leezicai/share/master/nginx/yum_install_openssl_nginx.sh
sh yum_install_openssl_nginx.sh
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;2-分步安装-安装opentssl-tls13需要openssl-111以上版本-默认centos中openssl版本111以下-不支持&#34;&gt;2. 分步安装, 安装Opentssl, tls1.3需要openssl 1.1.1以上版本, 默认CentOS中openssl版本1.1.1以下, 不支持.&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://raw.githubusercontent.com/leezicai/share/master/nginx/yum_install_openssl.sh&#34; target=&#34;_blank&#34;&gt;install_openssl.sh&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
# 安装需要编译的软件
yum install -y gcc gcc-c++ pcre-devel zlib-devel make unzip gd-devel perl-ExtUtils-Embed libxslt-devel openssl-devel perl-Test-Simple

yum groupinstall -y &amp;#39;Development Tools&amp;#39;

cd /usr/src

wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz

tar xvf openssl-1.1.1k.tar.gz

cp -r openssl-1.1.1k openssl

cd openssl

./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl --libdir=/lib64 shared zlib-dynamic

make -j4

make test

make install

mv /usr/bin/openssl /usr/bin/openssl-backup

ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-分步安装-编译安装nginx-hahahugoshortcode80s1hbhb&#34;&gt;3. 分步安装, 编译安装Nginx, &lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://raw.githubusercontent.com/leezicai/share/master/nginx/yum_install_openssl_nginx.sh&#34; target=&#34;_blank&#34;&gt;编译安装nginx脚本&lt;/a&gt; 

&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id=&#34;31-编译安装nginx-需要指定openssl的路径&#34;&gt;3.1 编译安装Nginx, 需要指定openssl的路径.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 编译安装nginx
cd /usr/src

wget http://nginx.org/download/nginx-1.21.1.tar.gz

tar xvf nginx-1.21.1.tar.gz

cd nginx-1.21.1

# 使用命令nginx -V查看编译参数, 和官方源保持一致, 仅用添加--with-openssl=/usr/src/openssl即可.
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt=&amp;#39;-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC&amp;#39; --with-ld-opt=&amp;#39;-Wl,-z,relro -Wl,-z,now -pie&amp;#39; --with-openssl=/usr/src/openssl

make -j4

make install
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;32-创建nginx服务-hahahugoshortcode80s2hbhb&#34;&gt;3.2 创建Nginx服务, 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.nginx.com/resources/wiki/start/topics/examples/systemd/&#34; target=&#34;_blank&#34;&gt;参考官方&lt;/a&gt; 

&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 创建nginx服务
vi /lib/systemd/system/nginx.service

# 输入以下内容
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;33-启动nginx服务-已经支持tls13&#34;&gt;3.3 启动nginx服务, 已经支持tls1.3.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# nginx.service生效
systemctl daemon-reload

systemctl enable nginx

systemctl start nginx
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;4-配置和验证tls13&#34;&gt;4. 配置和验证tls1.3&lt;/h2&gt;
&lt;h3 id=&#34;41-配置支持tls13&#34;&gt;4.1 配置支持tls1.3&lt;/h3&gt;
&lt;p&gt;在https服务中服务以下参数即可.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ssl_protocols    TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers    on;
ssl_ciphers                 TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;

配置后重启nginx
systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;42-浏览器中查看tls版本&#34;&gt;4.2 浏览器中查看tls版本.&lt;/h3&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/nginx/nginx-tls1.3.png&#34; alt=&#34;Google Chrome浏览器添加Security即可查看&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;Google Chrome浏览器添加Security即可查看&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>安装Nginx可用服务 Li.012</title>
      <link>https://lizicai.com/p/%E5%AE%89%E8%A3%85nginx%E5%8F%AF%E7%94%A8%E6%9C%8D%E5%8A%A1-li.012/</link>
      <pubDate>Sun, 25 Jul 2021 17:08:50 +0800</pubDate>
      <guid>https://lizicai.com/p/%E5%AE%89%E8%A3%85nginx%E5%8F%AF%E7%94%A8%E6%9C%8D%E5%8A%A1-li.012/</guid>
      <description>&lt;h2 id=&#34;1-nginx-简介-本篇主要nginx安装&#34;&gt;1. Nginx 简介, 本篇主要Nginx安装.&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Nginx是免费的开源软件，根据类BSD许可证的条款发布。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Nginx是异步框架的网页服务器，也可以用作反向代理、负载平衡器和HTTP缓存。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;根据W3Techs的数据，前100万个网站中的37.7%，前10万个网站中的49.7%，以及前10000个网站中的57.0%被使用.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;2-nginx-安装&#34;&gt;2. Nginx 安装.&lt;/h2&gt;
&lt;h3 id=&#34;21-centos-使用默认源安装&#34;&gt;2.1 CentOS 使用默认源安装&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;yum install nginx
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;22-centos-使用nginx官方源安装--hahahugoshortcode78s0hbhb&#34;&gt;2.2 CentOS 使用Nginx官方源安装,  
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/leezicai/share/blob/master/nginx/yum_install_nginx.sh&#34; target=&#34;_blank&#34;&gt;安装脚本地址&lt;/a&gt; 

.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;创建Nginx官方源&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;vim /etc/yum.repos.d/nginx.repo

# 存入写下面数据

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;使用yum安装nginx&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 默认安装 最新稳定版本nginx.
yum install nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;检查安装成功&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;nginx -version
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;23-如需编译安装可参考-hahahugoshortcode78s4hbhb&#34;&gt;2.3 如需编译安装可参考, 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/%e7%bc%96%e8%af%91%e5%ae%89%e8%a3%85nginx%e6%94%af%e6%8c%81tls1.3li.013/&#34; target=&#34;_blank&#34;&gt;编译安装Nginx地址&lt;/a&gt; 

.&lt;/h3&gt;
&lt;h2 id=&#34;3-创建nginx可访问的服务-开通端口-仅安装nginx外部仍然是无法访问的-需要解决如下问题&#34;&gt;3. 创建Nginx可访问的服务, 开通端口. 仅安装Nginx外部仍然是无法访问的, 需要解决如下问题.&lt;/h2&gt;
&lt;h3 id=&#34;31-云服务器开启安全组-对外网开放可以访问的端口和协议-以腾讯云为例添加nginx的80和443端口&#34;&gt;3.1 云服务器开启安全组, 对外网开放可以访问的端口和协议. 以腾讯云为例添加Nginx的80和443端口.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;云服务商有无安全组, 蓝色有, 灰色标记无&lt;/a&gt;
&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;类型&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;腾讯云&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;阿里云&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;亚马逊云&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;谷歌云&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;搬瓦工&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;有无安全组&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34; alt=&#34;blue&#34; src=&#34;https://s.lizicai.com/icon/tags/blue.png&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34; alt=&#34;blue&#34; src=&#34;https://s.lizicai.com/icon/tags/blue.png&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34; alt=&#34;blue&#34; src=&#34;https://s.lizicai.com/icon/tags/blue.png&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34; alt=&#34;blue&#34; src=&#34;https://s.lizicai.com/icon/tags/blue.png&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34; alt=&#34;white&#34; src=&#34;https://s.lizicai.com/icon/tags/white.png&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;以腾讯为例如何开通安全组中 80 和 443 端口.&lt;/a&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/nginx/tencent-vpc1.png&#34; alt=&#34;点击对应的云服务&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;点击对应的云服务&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/nginx/tencent-vpc2.png&#34; alt=&#34;云服务中查看安全组名称, 及有无80和443端口&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;云服务中查看安全组名称, 及有无80和443端口&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/nginx/tencent-vpc3.png&#34; alt=&#34;选择服务器使用的安全组, 修改规则&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;选择服务器使用的安全组, 修改规则&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;自定义 0.0.0.0/0 TCP:80,443 允许 ok&lt;/strong&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/nginx/tencent-vpc4.png&#34; alt=&#34;增加80和443商品&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;增加80和443商品&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h3 id=&#34;32-关闭selinux&#34;&gt;3.2 关闭SElinux.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;为何关闭SELinux&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;SELinux有着变态的限制系统服务，文件权限，网络端口访问, 哪怕root用户也不行.&lt;/p&gt;
&lt;p&gt;除资深Linux 安全用户, 否则不建议开启.&lt;/p&gt;
&lt;p&gt;CentOS 发行版有安装SELinux, Ubuntu是未安装SELinux, 真的必须的吗?&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;永久关闭SELinux&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;vi /etc/selinux/config

# 更改为 disabled
SELINUX=&amp;#34;disabled&amp;#34;
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;重启电脑&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;检查SELinux状态&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;getenforce
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;输出预期是disabled.&lt;/p&gt;
&lt;h3 id=&#34;32-开启防火墙80和443端口-以centos为例&#34;&gt;3.2 开启防火墙80和443端口, 以CentOS为例.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 启动防火墙
systemctl start firewalld
# 添加80 和 443 端口
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --zone=public --add-port=80/tcp --permanent
# 重启防火墙, 生效添加的端口.
systemctl restart firewalld
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;补充查询占用80或443端口-如占用-可关闭占用程序&#34;&gt;补充查询占用80或443端口, 如占用, 可关闭占用程序.&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;netstat -tunlp | grep 80
netstat -tunlp | grep 443
kill -9 5970
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/nginx/kill-80443port.png&#34; alt=&#34;关闭占用的端口&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;关闭占用的端口&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&#34;4-启动nginx服务-浏览器访问&#34;&gt;4. 启动Nginx服务, 浏览器访问.&lt;/h2&gt;
&lt;h3 id=&#34;41-启动nginx服务-并设置开机启动&#34;&gt;4.1 启动Nginx服务, 并设置开机启动.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 启动
systemctl start nginx
# 设置开机自启动
systemctl enabled nginx
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;42-浏览器访问ip-检查nginx启动成功&#34;&gt;4.2 浏览器访问ip, 检查Nginx启动成功.&lt;/h3&gt;
&lt;p&gt;访问服务器所在的ip即可.&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/nginx/welcome-to-nginx.png&#34; alt=&#34;出现类似这样的页面表示Nginx服务已可用&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;出现类似这样的页面表示Nginx服务已可用&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>安装MariaDB和设置utf-8mb4字符集 Li.011</title>
      <link>https://lizicai.com/p/%E5%AE%89%E8%A3%85mariadb%E5%92%8C%E8%AE%BE%E7%BD%AEutf-8mb4%E5%AD%97%E7%AC%A6%E9%9B%86-li.011/</link>
      <pubDate>Wed, 21 Jul 2021 01:01:19 +0800</pubDate>
      <guid>https://lizicai.com/p/%E5%AE%89%E8%A3%85mariadb%E5%92%8C%E8%AE%BE%E7%BD%AEutf-8mb4%E5%AD%97%E7%AC%A6%E9%9B%86-li.011/</guid>
      <description>&lt;h2 id=&#34;1-安装mariadb-二种方式-使用默认源和自建官方源&#34;&gt;1. 安装MariaDB. 二种方式, 使用默认源和自建官方源.&lt;/h2&gt;
&lt;h3 id=&#34;11-使用默认源&#34;&gt;1.1 使用默认源&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;yum -y install mariadb-server mariadb-client
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;安装后执行, mysql_secure_installation是初始化&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;systemctl enable mariadb
systemctl start mariadb
mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;12-使用自建官方源-可安装mariadb-105稳定版-hahahugoshortcode76s0hbhb&#34;&gt;1.2 使用自建官方源, 可安装MariaDB 10.5稳定版. 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://downloads.mariadb.org/mariadb/repositories/#distro=CentOS&amp;amp;distro_release=centos7-amd64--centos7&amp;amp;mirror=ustc-hefei&amp;amp;version=10.5&#34; target=&#34;_blank&#34;&gt;官方文档地址&lt;/a&gt; 

&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;创建MariaDB.repo&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;vim /etc/yum.repos.d/MariaDB.repo&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# MariaDB 10.7 CentOS repository list - created 2022-02-16 06:02 UTC
# https://mariadb.org/download/
[mariadb]
name = MariaDB
baseurl = https://tw1.mirror.blendbyte.net/mariadb/yum/10.7/centos7-amd64
gpgkey=https://tw1.mirror.blendbyte.net/mariadb/yum/RPM-GPG-KEY-MariaDB
gpgcheck=1
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;px&#34; width=&#34;px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;再执行安装命令即可, 并初始化&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;yum install -y mariadb-server mariadb-client
systemctl enable mariadb
systemctl start mariadb
# 初始化
mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;2-设置mariadb字符集-需要设置1个文件mycnf-即可&#34;&gt;2. 设置MariaDB字符集. 需要设置1个文件my.cnf 即可&lt;/h2&gt;
&lt;h3 id=&#34;21-vim-etcmycnf-增加以下内容&#34;&gt;2.1 vim /etc/my.cnf 增加以下内容&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-client-handshake = FALSE
init_connect=&amp;#39;SET NAMES utf8mb4&amp;#39;
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

!includedir /etc/my.cnf.d
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;character-set-client-handshake=FALSE 可以影响collation_connection的结果为utf8mb4_unicode_ci，而不是utf8mb4_general_ci。当然，使用SET collation_connection = utf8mb4_unicode_ci或collation_connection = utf8mb4_unicode_ci也可以。&lt;/li&gt;
&lt;li&gt;SET NAMES 指示客户端连接使用的字符集，即向服务器发送 SQL 语句的字符集。 character-set-server 设置服务器字符集。要正确使用 utf8mb4，需要确保客户端、服务器和连接都设置为 utf8mb4。&lt;/li&gt;
&lt;li&gt;init_connect等所有其他有关字符集的默认设置都会继承自character-set-server，也即单独指定init-connect、character_set_client, character_set_results,character_set_connection等都是不必须的。因此，上面设置中的init_connect可以省略&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;3-重启mariadb-连接数据库检查字符集&#34;&gt;3. 重启MariaDB, 连接数据库,检查字符集.&lt;/h2&gt;
&lt;h3 id=&#34;31-重启mariadb&#34;&gt;3.1 重启MariaDB&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;systemctl restart mariadb
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;32-连接数据库&#34;&gt;3.2 连接数据库.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 回车输入密码即可
mysql -uroot -hlocalhost -P3306 -p
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;33-检查字符集&#34;&gt;3.3 检查字符集&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;show variables like &amp;#39;%character%&amp;#39;;
show variables like &amp;#39;%collation%&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/mariadb/utf-8mb4.png&#34; alt=&#34;utf8mb4&#34;  /&gt;
&lt;/p&gt;
&lt;h2 id=&#34;4-补充utf8mb4_unicode_ci和utf8mb4_general_ci区别-mysql可以使用utf8mb4_0900_ai_ci-character_set_system是固定utf8不可更改&#34;&gt;4. 补充utf8mb4_unicode_ci和utf8mb4_general_ci区别, MySQL可以使用utf8mb4_0900_ai_ci, character_set_system是固定utf8不可更改.&lt;/h2&gt;
&lt;h3 id=&#34;41-utf8mb4_unicode_ci和utf8mb4_general_ci区别&#34;&gt;4.1 utf8mb4_unicode_ci和utf8mb4_general_ci区别&lt;/h3&gt;
&lt;p&gt;utf8mb4_unicode_ci: 基于标准的Unicode来排序和比较，能够在各种语言之间精确排序，在特殊情况下，Unicode排序规则为了能够处理特殊字符的情况，实现了略微复杂的排序算法，所以兼容度比较高，但是性能不高。&lt;/p&gt;
&lt;p&gt;utf8mb4_general_ci: 没有实现Unicode排序规则，在遇到某些特殊语言或者字符集，排序结果可能不一致，但是在比较和排序的时候速度更快。&lt;/p&gt;
&lt;h3 id=&#34;42-mysql可以使用utf8mb4_0900_ai_ci-对应位置替换show-variables-like-character与mariadb一致show-variables-like-collation&#34;&gt;4.2 MySQL可以使用utf8mb4_0900_ai_ci, 对应位置替换,show variables like &amp;lsquo;%character%&amp;rsquo;;与MariaDB一致,show variables like &amp;lsquo;%collation%&amp;rsquo;;&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;collation_connection          utf8mb4_0900_ai_ci
collation_database            utf8mb4_general_ci
collation_server              utf8mb4_0900_ai_ci
default_collation_for_utf8mb4 utf8mb4_0900_ai_ci
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;查询结果&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/mariadb/msqlutf8mb4.png&#34; alt=&#34;msqlutf8mb4&#34;  /&gt;
&lt;/p&gt;
&lt;p&gt;character_set_system固定utf8格式, 不可更改.&lt;/p&gt;
&lt;p&gt;参考
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://mariadb.com/kb/en/supported-character-sets-and-collations/&#34; target=&#34;_blank&#34;&gt;MariaDB官方支持字符集&lt;/a&gt; 

&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;创建用户和授权, 远程访问%&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE DATABASE testdatabase;
CREATE USER &amp;#39;testuser&amp;#39;@&amp;#39;%&amp;#39; IDENTIFIED BY &amp;#39;password&amp;#39;;
# mariadb mysql.user view
SET Password FOR root@&amp;#39;localhost&amp;#39; = password(&amp;#39;password&amp;#39;);
GRANT ALL ON testdatabase.* TO &amp;#39;testuser&amp;#39;@&amp;#39;%&amp;#39;;
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;5-修复优化所有数据库中所有表&#34;&gt;5. 修复优化所有数据库中所有表&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mysqlcheck -u root -p --auto-repair --optimize --all-databases
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Crontab定时任务使用 Li.010</title>
      <link>https://lizicai.com/p/crontab%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1%E4%BD%BF%E7%94%A8-li.010/</link>
      <pubDate>Wed, 21 Jul 2021 00:48:32 +0800</pubDate>
      <guid>https://lizicai.com/p/crontab%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1%E4%BD%BF%E7%94%A8-li.010/</guid>
      <description>&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/command/crontab.png&#34; alt=&#34;crontab&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;1-使用crontab的原因&#34;&gt;1. 使用Crontab的原因.&lt;/h3&gt;
&lt;h4 id=&#34;每次更新博客都要登录服务器ssh延迟容易中断手动去拉取代码-不方便-故设置成自动获取最新代码&#34;&gt;每次更新博客都要登录服务器(ssh延迟容易中断)手动去拉取代码, 不方便. 故设置成自动获取最新代码.&lt;/h4&gt;
&lt;h3 id=&#34;2-选择crontab定时&#34;&gt;2. 选择crontab定时&lt;/h3&gt;
&lt;h4 id=&#34;查看下资源-觉得crontab简单可行-直接来用就好了&#34;&gt;查看下资源, 觉得crontab简单可行, 直接来用就好了.&lt;/h4&gt;
&lt;h3 id=&#34;3-定时任务需需要做事情&#34;&gt;3. 定时任务需需要做事情.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;特定目录执行git pul的shell脚本. 这里配置ssh key&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;vim git_pull.sh&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
#!/bin/bash

# 进入目录中

cd ~/nginx-hugoBlog/lizicai.com/

# 拉取github中的代码

git pull
&lt;/code&gt;&lt;/pre&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;添加crontab任务文件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;vim git_pull.cron&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设置5分钟拉取一次代码&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;*/5 * * * * cd /root &amp;amp;&amp;amp; ./git_pull.sh
&lt;/code&gt;&lt;/pre&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;把定时任务文件内容加到crontab中&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 添加root账户中

crontab -uroot git_pull.cron

# 查询当前任务, root是账户, 添加的定时任务会放到这个目录中
crontab -uroot -l
cat /var/spool/cron/root


# 删除root用户的定时任务

crontab -uroot -r
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;日志的地址-相当重要&#34;&gt;日志的地址, 相当重要.&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 日志文件 /var/spool/mail/root
# 查看日志
# 可以把时间设置1分钟, 可以很快看到执行情况, 方便调试.

tail -f /var/spool/mail/root
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;4-crontab-时间配置&#34;&gt;4. crontab 时间配置&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 格式是
# 分 时 月份中第日 月份 星期中第几天 运行的命令

# 每分钟执行一次,
*/1 * * * * 命令

# 每小时第20, 30分钟执行一次

20,30 * * * * 命令

# 8-20时, 每小时第20, 30分执行一次

20,30 8-20 * * * 命令

# 每2天执行一次命令
0 0 */2 * * 命令

# 周六周日执行命令
0 0 0 0 6,0  命令

# 每月初一, 十五去执行

0 0 1,15 * *  命令
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Ag Fasd Fzf终端模糊搜索神器 Li.009</title>
      <link>https://lizicai.com/p/ag-fasd-fzf%E7%BB%88%E7%AB%AF%E6%A8%A1%E7%B3%8A%E6%90%9C%E7%B4%A2%E7%A5%9E%E5%99%A8-li.009/</link>
      <pubDate>Tue, 20 Jul 2021 23:00:24 +0800</pubDate>
      <guid>https://lizicai.com/p/ag-fasd-fzf%E7%BB%88%E7%AB%AF%E6%A8%A1%E7%B3%8A%E6%90%9C%E7%B4%A2%E7%A5%9E%E5%99%A8-li.009/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;ag比grep快速的速度, 同时打印出搜索词的行数.&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Fasd 时空机, 瞬间跳到去过的目录, 或定位打开过的文件.&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Fzf 模糊搜索工具.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;1-安装ag-fasd-fzf&#34;&gt;1. 安装ag fasd fzf&lt;/h2&gt;
&lt;h3 id=&#34;11-mac安装ag-fasd-fzf&#34;&gt;1.1 Mac安装ag fasd fzf.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew install the_silver_searcher fzf fasd

# 以下内容添加到~/.zshrc或~/.bashrc中
eval &amp;#34;$(fasd --init auto)&amp;#34;

# 重新生效
source ~/.zshrc 或 source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;12-linux安装ag-fasd-fzf&#34;&gt;1.2 Linux安装ag fasd fzf.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;yum install the_silver_searcher fasd

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf

~/.fzf/install
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/fzf-install.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&#34;2-别名&#34;&gt;2. 别名&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alias jan=&amp;#39;fasd -a&amp;#39;        # any
alias js=&amp;#39;fasd -si&amp;#39;       # show / search / select
alias jd=&amp;#39;fasd -d&amp;#39;        # directory
alias jf=&amp;#39;fasd -f&amp;#39;        # file
alias jsd=&amp;#39;fasd -sid&amp;#39;     # interactive directory selection
alias jsf=&amp;#39;fasd -sif&amp;#39;     # interactive file selection
alias j=&amp;#39;fasd_cd -d&amp;#39;     # cd, same functionality as j in autojump
alias jz=&amp;#39;fasd_cd -d -i&amp;#39; # cd with interactive selection
alias jdd=&amp;#39;fasd -D&amp;#39; # 删除一个路径

alias v=&amp;#39;jf -e vim&amp;#39;
alias nv=&amp;#39;jf -e nvim&amp;#39;
alias catf=&amp;#39;jf -e cat&amp;#39;
alias py3f=&amp;#34;jf -e python3&amp;#34;
alias lsf=&amp;#34;jd -e ls&amp;#34;
alias shf=&amp;#39;jf -e sh&amp;#39;
alias commandf=&amp;#39;jf -e command&amp;#39;

# preview file
alias ffp=&amp;#39;fzf --preview &amp;#39;&amp;#34;&amp;#39;&amp;#34;&amp;#39;[[ $(file --mime {}) =~ binary ]] &amp;amp;&amp;amp; echo {} is a binary file || (rougify {}  || highlight -O ansi -l {} || coderay {} || cat {}) 2&amp;gt; /dev/null | head -500&amp;#39;&amp;#34;&amp;#39;&amp;#34;

# 跳到最近匹配的目录中
jj() {
    [ $# -gt 0 ] &amp;amp;&amp;amp; fasd_cd -d &amp;#34;$*&amp;#34; &amp;amp;&amp;amp; return
    local dir
    dir=&amp;#34;$(fasd -Rdl &amp;#34;$1&amp;#34; | fzf -1 -0 --no-sort +m)&amp;#34; &amp;amp;&amp;amp; cd &amp;#34;${dir}&amp;#34; || return 1
}

jje() {
    [ $# -gt 0 ] &amp;amp;&amp;amp; fasd_cd -d &amp;#34;$*&amp;#34; &amp;amp;&amp;amp; return
    local dir
    dir=&amp;#34;$(fasd -Rdl &amp;#34;$1&amp;#34; | fzf -e -1 -0 --no-sort +m)&amp;#34; &amp;amp;&amp;amp; cd &amp;#34;${dir}&amp;#34; || return 1
}

# 从当前路径搜索并跳转
jcd() {
  local dir
  dir=$(find ${1:-.} -path &amp;#39;*/\.*&amp;#39; -prune \
                  -o -type d -print 2&amp;gt; /dev/null | fzf +m) &amp;amp;&amp;amp;
  cd &amp;#34;$dir&amp;#34;
}
jcde() {
  local dir
  dir=$(find ${1:-.} -path &amp;#39;*/\.*&amp;#39; -prune \
                  -o -type d -print 2&amp;gt; /dev/null | fzf -e +m) &amp;amp;&amp;amp;
  cd &amp;#34;$dir&amp;#34;
}

alias ffall=&amp;#34;find / -type f | fzf | pbcopy&amp;#34;
alias ffm=&amp;#34;find ~/ -type f | fzf | pbcopy&amp;#34;
alias ffd=&amp;#34;find . -type f | fzf | pbcopy&amp;#34;
alias ffec=&amp;#34;find ~/ -type f | fzf -e | pbcopy&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-使用效果&#34;&gt;3. 使用效果&lt;/h2&gt;
&lt;h3 id=&#34;31-ag-ag与fasd联用&#34;&gt;3.1 ag, ag与fasd联用.&lt;/h3&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/command/ag.gif&#34; alt=&#34;ag&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;32-fasd使用&#34;&gt;3.2 fasd使用&lt;/h3&gt;
&lt;p&gt;单个文件夹&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/command/fasd.gif&#34; alt=&#34;ag&#34;  /&gt;
&lt;/p&gt;
&lt;p&gt;多个目录关键词也能识别出来&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/command/fasd-folder.gif&#34; alt=&#34;fasd-folder&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;33-fzf-搜索命令行历史记录-模糊搜索并跳转-预览文件内容&#34;&gt;3.3 fzf 搜索命令行历史记录 模糊搜索并跳转, 预览文件内容&lt;/h3&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/fzf-search-history.gif&#34; alt=&#34;Control &amp;#43; R 搜索命令行历史记录&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;Control &amp;#43; R 搜索命令行历史记录&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/fzf-fasd.gif&#34; alt=&#34;模糊搜索并跳转&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;模糊搜索并跳转&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/command/fzf-preview.gif&#34; alt=&#34;快速预览文件内容&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;快速预览文件内容&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>Homebrew Mac下最好用的软件管理工具 Li.008</title>
      <link>https://lizicai.com/p/homebrew-mac%E4%B8%8B%E6%9C%80%E5%A5%BD%E7%94%A8%E7%9A%84%E8%BD%AF%E4%BB%B6%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7-li.008/</link>
      <pubDate>Mon, 19 Jul 2021 22:50:18 +0800</pubDate>
      <guid>https://lizicai.com/p/homebrew-mac%E4%B8%8B%E6%9C%80%E5%A5%BD%E7%94%A8%E7%9A%84%E8%BD%AF%E4%BB%B6%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7-li.008/</guid>
      <description>&lt;h2 id=&#34;1-homebrew是什么-homebrew能做什么&#34;&gt;1. Homebrew是什么? Homebrew能做什么?&lt;/h2&gt;
&lt;h4 id=&#34;homebrew是mac下神一样的软件管理工具&#34;&gt;Homebrew是Mac下神一样的软件管理工具.&lt;/h4&gt;
&lt;h4 id=&#34;homebrew几乎安装任何你想到的开源软件没有界面gui的-有界面的&#34;&gt;Homebrew几乎安装任何你想到的开源软件(没有界面Gui的, 有界面的)&lt;/h4&gt;
&lt;h4 id=&#34;homebrew同样支持相当多的商业应用安装-像jetbrains-idea全家桶-网易云音乐-qq也都支持&#34;&gt;Homebrew同样支持相当多的商业应用安装, 像jetbrains IDEA全家桶, 网易云音乐 QQ也都支持.&lt;/h4&gt;
&lt;h2 id=&#34;2-homebrew-安装&#34;&gt;2. Homebrew 安装&lt;/h2&gt;
&lt;h3 id=&#34;打开终端terminal-输入下面命令即可&#34;&gt;打开终端Terminal, 输入下面命令即可.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/bin/bash -c &amp;#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-homebrew-使用&#34;&gt;3. Homebrew 使用.&lt;/h2&gt;
&lt;h3 id=&#34;31-brew-install-cask与brew-install合并为brew-install&#34;&gt;3.1 brew install &amp;ndash;cask与brew install合并为brew install.&lt;/h3&gt;
&lt;h3 id=&#34;brew-install-可安装有界面或无界面的软件与应用&#34;&gt;brew install 可安装有界面或无界面的软件与应用.&lt;/h3&gt;
&lt;h3 id=&#34;如果重名-仍然需要brew-install-cask&#34;&gt;如果重名, 仍然需要brew install &amp;ndash;cask&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 搜索软件
brew search git
brew search google-chrome

# 安装
brew install vim
brew install neteasemusic

# 重新安装
brew reinstall vim
brew reinstall neteasemusic

# 升级软件
brew upgrade curl
brew upgrade google-chrome

# 不升级软件
brew pin curl

# 卸载软件与应用
brew uninstall git
brew uninstall  QQ

# 查看软件与应用
brew info git
brew info sourcetree
brew list

# 启动软件
brew services start mariadb

# 重新启动软件
brew services restart nginx

# 关闭软件
brew services stop mariadb
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;32-使用别名-更快速-下面别名写zshrc或bashrc中-source-zshrc或bashrc重新生效&#34;&gt;3.2 使用别名, 更快速, 下面别名写~/.zshrc或~/.bashrc中, source ~/.zshrc或.bashrc重新生效.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Brew

alias bsearch=&amp;#39;brew search&amp;#39;
alias bupdate=&amp;#39;brew update&amp;#39;
alias blist=&amp;#39;brew list&amp;#39;
alias boutdated=&amp;#39;brew outdated&amp;#39;
alias bupout=&amp;#39;brew update &amp;amp;&amp;amp; brew outdated&amp;#39;
alias binstall=&amp;#39;brew install&amp;#39;
alias buninstall=&amp;#39;brew uninstall&amp;#39;
alias breinstall=&amp;#39;brew reinstall&amp;#39;
alias bupgrade=&amp;#39;brew upgrade&amp;#39;
alias bremove=&amp;#39;brew remove&amp;#39;
alias binfo=&amp;#39;brew info&amp;#39;

# brew services
alias bservices=&amp;#39;brew services&amp;#39;
alias bstart=&amp;#39;brew services start&amp;#39;
alias bsrestart=&amp;#39;brew services restart&amp;#39;
alias bstop=&amp;#39;brew services stop&amp;#39;
alias bslist=&amp;#39;brew services list&amp;#39;

# brew cask
alias bcinstall=&amp;#39;brew install --cask&amp;#39;
alias bcreinstall=&amp;#39;brew reinstall --cask&amp;#39;
alias bcinfo=&amp;#39;brew --cask info&amp;#39;
alias bcuninstall=&amp;#39;brew uninstall --cask&amp;#39;
alias bcremove=&amp;#39;brew remove --cask&amp;#39;
alias bcupgrade=&amp;#39;brew upgrade --cask&amp;#39;
alias bcoutdated=&amp;#39;brew --cask outdated&amp;#39;
alias bclist=&amp;#39;brew list --cask &amp;#39;
alias bcask=&amp;#39;brew --cask&amp;#39;
alias bcua=&amp;#39;brew cu -a&amp;#39;
alias buca=&amp;#39;brew cu -a&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;33-查看所有有界面gui可更新软件&#34;&gt;3.3 查看所有有界面Gui可更新软件.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;安装brew-cask-upgrade, 升级管理&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew tap buo/cask-upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;px&#34; width=&#34;px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;查看所有有界面可升级的软件&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew cu -a
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;选择Y更新所有, 也可brew upgrade visual-studio-code, 更新指定软件&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/homebrew/brew-cask-upgrade.png&#34; alt=&#34;brew-cask-upgrade&#34;  /&gt;
&lt;/p&gt;
&lt;h2 id=&#34;4-此方式homebrew已经弃用新的试了下也不行-待解决homebrew安装指定版本的软件&#34;&gt;4. (此方式Homebrew已经弃用,新的试了下也不行, 待解决)Homebrew安装指定版本的软件.&lt;/h2&gt;
&lt;h3 id=&#34;41-使用brew-info查看软件信息&#34;&gt;4.1 使用brew info查看软件信息&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew info vim
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/homebrew/install-target-version1.png&#34; alt=&#34;vim&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;42-访问来源-hahahugoshortcode16s2hbhb&#34;&gt;4.2 访问来源, 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/vim.rb&#34; target=&#34;_blank&#34;&gt;https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/vim.rb&lt;/a&gt; 

&lt;/h3&gt;
&lt;h3 id=&#34;43-查看历史信息&#34;&gt;4.3 查看历史信息&lt;/h3&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/homebrew/install-target-version2.png&#34; alt=&#34;vim&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;44-显示历史信息-点击需要安装的vim版本-823100&#34;&gt;4.4 显示历史信息, 点击需要安装的vim版本, 8.2.3100&lt;/h3&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/homebrew/install-target-version3.png&#34; alt=&#34;vim&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;45-根据当前系统找到对应sha256-复制&#34;&gt;4.5 根据当前系统找到对应sha256, 复制&lt;/h3&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/homebrew/install-target-version4.png&#34; alt=&#34;vim&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;46-安装-拼接出地址-直接安装&#34;&gt;4.6 安装, 拼接出地址, 直接安装.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/f73c37f7282bf9c542aeba15b4ae7862cb65c757ed455594eecc5ced52bb307d/Formula/vim.rb
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Oh My Zsh配置和插件 终端神器 Li.007</title>
      <link>https://lizicai.com/p/oh-my-zsh%E9%85%8D%E7%BD%AE%E5%92%8C%E6%8F%92%E4%BB%B6%E7%BB%88%E7%AB%AF%E7%A5%9E%E5%99%A8-li.007/</link>
      <pubDate>Mon, 19 Jul 2021 21:47:33 +0800</pubDate>
      <guid>https://lizicai.com/p/oh-my-zsh%E9%85%8D%E7%BD%AE%E5%92%8C%E6%8F%92%E4%BB%B6%E7%BB%88%E7%AB%AF%E7%A5%9E%E5%99%A8-li.007/</guid>
      <description>&lt;h2 id=&#34;1-oh-my-zsh是什么&#34;&gt;1. Oh My Zsh是什么&lt;/h2&gt;
&lt;h3 id=&#34;oh-my-zsh是一个开源的社区驱动的框架用于管理zsh-配置让天下没有难用的终端terminal-终端terminal神器&#34;&gt;Oh My Zsh是一个开源的、社区驱动的框架，用于管理zsh 配置。让天下没有难用的终端(Terminal), 终端terminal神器.&lt;/h3&gt;
&lt;h3 id=&#34;适用于mac-linux平台&#34;&gt;适用于Mac Linux平台.&lt;/h3&gt;
&lt;h2 id=&#34;2-oh-my-zsh安装-hahahugoshortcode65s0hbhb&#34;&gt;2. Oh My Zsh安装, 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/ohmyzsh/ohmyzsh&#34; target=&#34;_blank&#34;&gt;Oh My Zsh官网&lt;/a&gt; 

&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sh -c &amp;#34;$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-oh-my-zsh插件-git-zsh-autosuggestions-fasd-zsh-syntax-highlighting-让终端起飞&#34;&gt;3. Oh My Zsh插件, Git zsh-autosuggestions fasd zsh-syntax-highlighting 让终端起飞.&lt;/h2&gt;
&lt;!--### 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins&#34; target=&#34;_blank&#34;&gt;Oh My Zsh全部插件&lt;/a&gt; 

--&gt;
&lt;h3 id=&#34;31-git插件-oh-my-zsh自带-把所有的git命令做了别名-更快使用git命令&#34;&gt;3.1 Git插件, Oh My Zsh自带, 把所有的git命令做了别名, 更快使用git命令.&lt;/h3&gt;
&lt;p&gt;在~/.zshrc中启用&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;plugins=(git)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 终端内
# gb 等于 git branch
# st 等价git status
# gcmsg 等于 git commit -m
# gm 等于git merge
# gco 等于git checkout
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git&#34; target=&#34;_blank&#34;&gt;全部别名地址&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;32-zsh-autosuggestions-显示之前运行的命令-按control--e即可补全&#34;&gt;3.2 zsh-autosuggestions 显示之前运行的命令, 按&amp;lt;control + e&amp;gt;即可补全.&lt;/h3&gt;
&lt;p&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;安装zsh-autosuggestions&lt;/a&gt;
&lt;/div&gt;


&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md&#34; target=&#34;_blank&#34;&gt;zsh-autosuggestions安装官网&lt;/a&gt; 

&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;在~/.zshrc中启用&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;plugins=(git zsh-autosuggestions)
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;重新生效&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sourch ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;效果展示, Control &amp;#43; e即可补全&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/ohmyzsh/zsh-autosuggestions.gif&#34; alt=&#34;效果&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;33-fasd时空机-可以跳到任何之前去过的目录-再也不必cd来cd去了-可以和更多的命令连用&#34;&gt;3.3 fasd时空机, 可以跳到任何之前去过的目录, 再也不必cd来cd去了, 可以和更多的命令连用.&lt;/h3&gt;
&lt;h4 id=&#34;fasd可以记录访问目录的权重-常访问目录权重高-匹配放在前面&#34;&gt;fasd可以记录访问目录的权重, 常访问目录权重高, 匹配放在前面.&lt;/h4&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;安装fasd&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew install fasd
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;初始化到~/.zshrc中, j用作fasd的别名&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 插件增加fasd
plugins=(git zsh-autosuggestions fasd)
eval &amp;#34;$(fasd --init auto)&amp;#34;
alias j=&amp;#39;fasd_cd -d&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;重新生效~/.zshrc&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;使用效果, 直接回车就可跳转, 也可使用tab依权重选择&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/ohmyzsh/fasd.gif&#34; alt=&#34;fasd&#34;  /&gt;
&lt;/p&gt;
&lt;p&gt;目录关键词也能识别出来&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/command/fasd-folder.gif&#34; alt=&#34;fasd-folder&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;5&#34;
    src=&#34;https://s.lizicai.com/icon/number/5.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;和其他命令连用,和vim连用,vim可以在任何目录打开之前编辑过的文件&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alias v=&amp;#39;jf -e vim&amp;#39;
alias py3f=&amp;#34;jf -e python3&amp;#34;
# 写入.zshrc中
# source ~/.zshrc生效
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/ohmyzsh/fasd-vim.gif&#34; alt=&#34;vim fasd&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;6&#34;
    src=&#34;https://s.lizicai.com/icon/number/6.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;更多别名,  存入.zshrc中&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;alias jan=&amp;#39;fasd -a&amp;#39;        # any
alias js=&amp;#39;fasd -si&amp;#39;       # show / search / select
alias jd=&amp;#39;fasd -d&amp;#39;        # directory
alias jf=&amp;#39;fasd -f&amp;#39;        # file
alias jsd=&amp;#39;fasd -sid&amp;#39;     # interactive directory selection
alias jsf=&amp;#39;fasd -sif&amp;#39;     # interactive file selection
alias j=&amp;#39;fasd_cd -d&amp;#39;     # cd, same functionality as j in autojump
alias jz=&amp;#39;fasd_cd -d -i&amp;#39; # cd with interactive selection
alias jdd=&amp;#39;fasd -D&amp;#39; # 删除一个路径

alias v=&amp;#39;jf -e vim&amp;#39;
alias nv=&amp;#39;jf -e nvim&amp;#39;
alias batf=&amp;#39;jf -e bat&amp;#39;
alias catf=&amp;#39;jf -e cat&amp;#39;
alias py3f=&amp;#34;jf -e python3&amp;#34;
alias lsf=&amp;#34;jd -e ls&amp;#34;
alias shf=&amp;#39;jf -e sh&amp;#39;
alias commandf=&amp;#39;jf -e command&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;34-zsh-syntax-highlighting高亮显示正确的命令&#34;&gt;3.4 zsh-syntax-highlighting高亮显示正确的命令.&lt;/h3&gt;
&lt;p&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;安装zsh-syntax-highlighting&lt;/a&gt;
&lt;/div&gt;


&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/INSTALL.md&#34; target=&#34;_blank&#34;&gt;zsh-syntax-highlighting官网地址&lt;/a&gt; 

&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;在~/.zshrc中启用&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;plugins=(git fasd zsh-autosuggestions  zsh-syntax-highlighting)
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;source ~/.zshrc 生效&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;使用效果, 演示&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/ohmyzsh/zsh-syntax-highlighting.gif&#34; alt=&#34;zsh-syntax-highlighting&#34;  /&gt;
&lt;/p&gt;
&lt;h2 id=&#34;4-oh-my-zsh-主题&#34;&gt;4. Oh My Zsh 主题&lt;/h2&gt;
&lt;h3 id=&#34;hahahugoshortcode65s19hbhb&#34;&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/ohmyzsh/ohmyzsh/wiki/Themes&#34; target=&#34;_blank&#34;&gt;主题截图演示地址&lt;/a&gt; 

&lt;/strong&gt;&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 主题都存放在这个目录下
ls ~/.oh-my-zsh/themes/

# 在.zshrc中, 选择喜欢的主题就行.
ZSH_THEME=&amp;#34;robbyrussell&amp;#34;

# 重新生效, 就能看到效果了
source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>2021苹果返校季促销活动买Mac和iPad送AirPods无线耳机 Li.006</title>
      <link>https://lizicai.com/p/2021%E8%8B%B9%E6%9E%9C%E8%BF%94%E6%A0%A1%E5%AD%A3%E4%BF%83%E9%94%80%E6%B4%BB%E5%8A%A8%E4%B9%B0mac%E5%92%8Cipad%E9%80%81airpods%E6%97%A0%E7%BA%BF%E8%80%B3%E6%9C%BA-li.006/</link>
      <pubDate>Sun, 18 Jul 2021 22:08:57 +0800</pubDate>
      <guid>https://lizicai.com/p/2021%E8%8B%B9%E6%9E%9C%E8%BF%94%E6%A0%A1%E5%AD%A3%E4%BF%83%E9%94%80%E6%B4%BB%E5%8A%A8%E4%B9%B0mac%E5%92%8Cipad%E9%80%81airpods%E6%97%A0%E7%BA%BF%E8%80%B3%E6%9C%BA-li.006/</guid>
      <description>&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/news/2021backschool-banner.png&#34; alt=&#34;2021 Back to school&#34;  /&gt;
&lt;/p&gt;
&lt;h2 id=&#34;1-谁可以购买-购买资格-hahahugoshortcode6s0hbhb&#34;&gt;1. 谁可以购买, 购买资格, &lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.apple.com.cn/cn-k12/shop/browse/open/salespolicies/edu&#34; target=&#34;_blank&#34;&gt;官方参考&lt;/a&gt; 

&lt;/strong&gt;.&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;幼儿园、小学和中学 — 中国大陆的公立或私立幼儿园、小学或中学的任何雇员。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;高等教育机构 — 中国大陆高校（即指公立或私立大学及专科院校）的教职工，以及在中国大陆高校就读或已被录取的学生。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;高等教育机构学生的父母 — 代表目前在中国大陆高校就读或已被录取的子女进行购买的父母。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3 id=&#34;学生-购买需要-学证或录取通知书-和身份证非中国居民需护照&#34;&gt;学生. 购买需要: 学⽣证或录取通知书, 和身份证(非中国居民需护照).&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;学生&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;是否有资格购买&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;已录取(拿到高等院校录取通知书)&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;在读大学生&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;在读大专生&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;在读研究生&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;在读博士生&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;教职工-购买需要-教职证&#34;&gt;教职工. 购买需要: 教职⼯证.&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;教职工&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;是否有资格购买&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;幼儿园老师或学校职员&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;小学老师或学校职员&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;中学老师或学校职员&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;大陆(公立或私立)大学教师和学校员工&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;大陆(公立或私立)专科院校教师和学校员工&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;高校学生父母-购买需要-的学证或录取通知书和身份证中国居需要提供护照&#34;&gt;高校学生父母. 购买需要: ⼦⼥的学⽣证或录取通知书和身份证(⾮中国居⺠需要提供护照)&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;父母&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;是否有资格购买&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;子女在读或已被高等院校录取&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;补充常见非教育优惠人群&#34;&gt;补充常见非教育优惠人群.&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;非教育优惠人群&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;是否有资格购买&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;幼儿园学生 小学生 初中生 高中生&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;培训机构机构教职工&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;2-优惠时间&#34;&gt;2. 优惠时间.&lt;/h2&gt;
&lt;h3 id=&#34;2021年7月16日--2021年9月27日&#34;&gt;2021年7月16日 ~ 2021年9月27日&lt;/h3&gt;
&lt;h2 id=&#34;3-购买渠道&#34;&gt;3. 购买渠道&lt;/h2&gt;
&lt;h3 id=&#34;31-线上渠道-适用所有人&#34;&gt;3.1 线上渠道, 适用所有人.&lt;/h3&gt;
&lt;h4 id=&#34;hahahugoshortcode6s14hbhb&#34;&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.apple.com.cn/cn-k12/shop&#34; target=&#34;_blank&#34;&gt;Apple官网教育商店&lt;/a&gt; 

&lt;/strong&gt;&lt;/h4&gt;
&lt;h4 id=&#34;hahahugoshortcode6s15hbhb&#34;&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://apple.tmall.com/&#34; target=&#34;_blank&#34;&gt;天猫 Apple Store官方旗舰店&lt;/a&gt; 

&lt;/strong&gt;&lt;/h4&gt;
&lt;h4 id=&#34;致电-400-666-8800&#34;&gt;致电 &lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;tel:4006668800&#34;&gt;400-666-8800&lt;/a&gt;&lt;/h4&gt;
&lt;h3 id=&#34;32-线下渠道-所在城市已有apple-store-零售店&#34;&gt;3.2 线下渠道, 所在城市已有Apple Store 零售店.&lt;/h3&gt;
&lt;h2 id=&#34;4-哪些产品购买可赠送airpods耳机-mac全部型号和ipad部分型号&#34;&gt;4. 哪些产品购买可赠送AirPods耳机, Mac(全部型号)和iPad(部分型号).&lt;/h2&gt;
&lt;h3 id=&#34;mac-全部型号-ipad部分型号可赠送airpods二代&#34;&gt;Mac 全部型号, iPad部分型号可赠送Airpods(二代).&lt;/h3&gt;
&lt;h3 id=&#34;m2芯片的macbook大概10月发布了-预算充足可以再等等&#34;&gt;M2芯片的MacBook大概10月发布了, 预算充足可以再等等.&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;strong&gt;Mac或iPad型号&lt;/strong&gt;&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;strong&gt;是否参加返校季活动&lt;/strong&gt;&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;strong&gt;教育优惠限购类型&lt;/strong&gt;&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;strong&gt;教育优惠限购数量&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;MacBook Pro 13或16寸&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;笔记本电脑&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 1 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;MacBook Air&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;笔记本电脑&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 1 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;Mac mini&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Mac mini&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 1 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;Mac Pro&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;台式电脑&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 1 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;iMac 24或27寸&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;台式电脑&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 1 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;iMac Pro&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;台式电脑&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 1 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;iPad Pro&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;iPad&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 2 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;iPad Air&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;iPad&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 2 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;iPad&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;iPad&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 2 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;iPad mini&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;iPad&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;每年可购买 2 台&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;不同类别可以同时购买同样有教育优惠, 买一台MacBook Pro和一台iPad Pro都有教育优惠, 但仅送一次耳机&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;同一教育优惠限购类型有数量限制, 如iPad限购2台, iPad和iPad mini同样会占用数量, 超出数量部分无法参加活动, 也没有教育优惠&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;hahahugoshortcode6s26hbhb&#34;&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.apple.com.cn/retail/&#34; target=&#34;_blank&#34;&gt;在线查找城市零售店&lt;/a&gt; 

&lt;/strong&gt;&lt;/h4&gt;
&lt;h4 id=&#34;hahahugoshortcode6s27hbhb&#34;&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.apple.com.cn/retail/storelist/&#34; target=&#34;_blank&#34;&gt;完整城市零售店&lt;/a&gt; 

&lt;/strong&gt;&lt;/h4&gt;
&lt;h2 id=&#34;5-比较有性价比的配件&#34;&gt;5. 比较有&amp;quot;性价比&amp;quot;的配件.&lt;/h2&gt;
&lt;h3 id=&#34;51-airpods可以加700元左右即可升级赠送airpods-pro降噪耳机&#34;&gt;5.1 AirPods可以加700元左右即可升级赠送AirPods Pro(降噪耳机)&lt;/h3&gt;
&lt;h3 id=&#34;52-final-cut-prologic-pro五件套仅需要1298元-hahahugoshortcode6s28hbhb&#34;&gt;5.2 Final Cut Pro,Logic Pro五件套仅需要1298元, &lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.apple.com.cn/cn-k12/shop/product/BMGE2CH/A&#34; target=&#34;_blank&#34;&gt;官网购买地址&lt;/a&gt; 

&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&#34;共有final-cut-pro-logic-pro-motion-compressor-mainstage-五款优秀的视频和音乐制作软件&#34;&gt;共有Final Cut Pro, Logic Pro, Motion, Compressor, MainStage 五款优秀的视频和音乐制作软件.&lt;/h4&gt;
&lt;h4 id=&#34;想学习制作视频和音乐不要错过&#34;&gt;想学习制作视频和音乐不要错过&lt;/h4&gt;
&lt;h4 id=&#34;也可以过段时间购买-软件优惠一直有的&#34;&gt;也可以过段时间购买, 软件优惠一直有的.&lt;/h4&gt;
&lt;h3 id=&#34;53-apple-care-购买同样有教育优惠价格&#34;&gt;5.3 Apple Care, 购买同样有教育优惠价格.&lt;/h3&gt;
&lt;h3 id=&#34;54-apple-pencil第二代-教育优惠价格895-无教育优惠价格969&#34;&gt;5.4 Apple Pencil(第二代), 教育优惠价格895, 无教育优惠价格969.&lt;/h3&gt;
&lt;h2 id=&#34;6-附录完整图片&#34;&gt;6. 附录完整图片.&lt;/h2&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/news/2021backschool.png&#34; alt=&#34;2021 Back School&#34;  /&gt;
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>acme.sh被收购 更换默认证书颁发机构为ZeroSSL 还安全吗? Li.005</title>
      <link>https://lizicai.com/p/acme.sh%E8%A2%AB%E6%94%B6%E8%B4%AD-%E6%9B%B4%E6%8D%A2%E9%BB%98%E8%AE%A4%E8%AF%81%E4%B9%A6%E9%A2%81%E5%8F%91%E6%9C%BA%E6%9E%84%E4%B8%BAzerossl-%E8%BF%98%E5%AE%89%E5%85%A8%E5%90%97-li.005/</link>
      <pubDate>Sun, 18 Jul 2021 00:03:06 +0800</pubDate>
      <guid>https://lizicai.com/p/acme.sh%E8%A2%AB%E6%94%B6%E8%B4%AD-%E6%9B%B4%E6%8D%A2%E9%BB%98%E8%AE%A4%E8%AF%81%E4%B9%A6%E9%A2%81%E5%8F%91%E6%9C%BA%E6%9E%84%E4%B8%BAzerossl-%E8%BF%98%E5%AE%89%E5%85%A8%E5%90%97-li.005/</guid>
      <description>&lt;h2 id=&#34;1-acmesh是什么&#34;&gt;1. acme.sh是什么.&lt;/h2&gt;
&lt;h3 id=&#34;11-acmesh是实现acme-自动证书管理环境---automatic-certificate-management-environment-的客户端-acme由-lets-encrypt-实现的协议与该协议兼容的软件可以用它与-lets-encrypt-通信以获取证书&#34;&gt;1.1 acme.sh是实现ACME (自动证书管理环境 - Automatic Certificate Management Environment) 的客户端, ACME由 Let’s Encrypt 实现的协议。与该协议兼容的软件可以用它与 Let’s Encrypt 通信以获取证书.&lt;/h3&gt;
&lt;h3 id=&#34;12-acmesh被zerossl商业收购-acmesh更改默认申请证书的服务商为zerossl&#34;&gt;1.2 acme.sh被ZeroSSL商业收购, acme.sh更改默认申请证书的服务商为ZeroSSL.&lt;/h3&gt;
&lt;h3 id=&#34;13-收购关系图-被收购管理上复杂-意味暴露信息更扩散-更多的人有有这些数据权限&#34;&gt;1.3 收购关系图, 被收购管理上复杂, 意味暴露信息更扩散, 更多的人有有这些数据权限.&lt;/h3&gt;

&lt;figure &gt;
    
        &lt;img src=&#34;https://s.lizicai.com/acme.sh/acmesh%e5%85%ac%e5%8f%b8%e5%85%b3%e7%b3%bb.png&#34;  /&gt;
    
    
&lt;/figure&gt;

&lt;h2 id=&#34;2-先说下我的观点&#34;&gt;2. 先说下我的观点.&lt;/h2&gt;
&lt;p&gt;


&lt;style&gt;
&lt;/style&gt;
&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-task-img&#34; &gt;
    &lt;img height=&#34;29px&#34; width=&#34;29px&#34; alt=&#34;done&#34;
    src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;开源都是爱发电的, 真的是用爱发电&lt;/a&gt;
&lt;/div&gt;




&lt;style&gt;
&lt;/style&gt;
&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-task-img&#34; &gt;
    &lt;img height=&#34;29px&#34; width=&#34;29px&#34; alt=&#34;done&#34;
    src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;开源能够商业收购, 即了不起也是幸运的事情, 毕竟内卷时代, 为爱发电, 又能获得收入实属难得&lt;/a&gt;
&lt;/div&gt;




&lt;style&gt;
&lt;/style&gt;
&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-task-img&#34; &gt;
    &lt;img height=&#34;29px&#34; width=&#34;29px&#34; alt=&#34;done&#34;
    src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;2021年7月21日, 官方文档中已明确说明默认证书申请机构是ZeroSSL(在这之前没有明确说明)&lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;3-为什么acmesh更换默认证书颁发机构影响如此大&#34;&gt;3. 为什么acme.sh更换默认证书颁发机构影响如此大.&lt;/h2&gt;
&lt;h3 id=&#34;31-使用acmesh客户端申请证书人数众多&#34;&gt;3.1 使用acme.sh客户端申请证书人数众多&lt;/h3&gt;
&lt;h3 id=&#34;32-大部分用户翻墙科学上网就是使用这个acmesh客户端申请证书&#34;&gt;3.2 大部分用户翻墙科学上网就是使用这个acme.sh客户端申请证书.&lt;/h3&gt;
&lt;h3 id=&#34;33-每次申请证书暴露用户的信息&#34;&gt;3.3 每次申请证书暴露用户的信息.&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;申请服务器的IP&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;申请SSL证书的域名&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;域名DNS指向的IP&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;acme.sh &amp;amp; ZeroSS&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;27px&#34; width=&#34;27px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;27px&#34; width=&#34;27px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;27px&#34; width=&#34;27px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;4-暴露这么多信息-会怎样&#34;&gt;4. 暴露这么多信息, 会怎样?&lt;/h2&gt;
&lt;h2 id=&#34;41-目前想到比较紧急的&#34;&gt;4.1 目前想到比较紧急的&lt;/h2&gt;
&lt;p&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;科学上网变得更不安全了, 商业公司的数据可能说卖就卖了, 被收购&lt;/a&gt;
&lt;/div&gt;



&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;那些使用CloudFlare 代理的用户也不再安全, 在申请证书时就暴露自己IP地址了&lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;42-避免的信息暴露一些方式&#34;&gt;4.2 避免的信息暴露一些方式&lt;/h2&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;立即更改默认证书颁发机构为letsencrypt&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;acme.sh --set-default-ca  --server  letsencrypt
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;更换其他实现acme(自动证书管理环境)的客户端&lt;/a&gt;
&lt;/div&gt;

&lt;br&gt;
&lt;p&gt;&lt;strong&gt;如Certbot&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;使用CloudFlare代理的用户, 在CloudeFlare和个人服务器之间使用自签证书&lt;/a&gt;
&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>Hugo和GitHub Pages搭建静态网站 Li.004</title>
      <link>https://lizicai.com/p/hugo%E5%92%8Cgithub-pages%E6%90%AD%E5%BB%BA%E9%9D%99%E6%80%81%E7%BD%91%E7%AB%99-li.004/</link>
      <pubDate>Fri, 16 Jul 2021 10:58:24 +0800</pubDate>
      <guid>https://lizicai.com/p/hugo%E5%92%8Cgithub-pages%E6%90%AD%E5%BB%BA%E9%9D%99%E6%80%81%E7%BD%91%E7%AB%99-li.004/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Hugo是一个用Go 编写的静态网站生成器.&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;GitHub Pages是GitHub提供的一个网页寄存服务，
于2008年推出。可以用于存放静态网页，包括博客、项目文档甚至整本书.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hugo和Github Pages组合就可以免费创建博客网站.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%ad%a6%e4%b9%a0%e8%b7%af%e7%ba%bfli.028/&#34; target=&#34;_blank&#34;&gt;本篇文章属于Hugo学习路线Li.028一部分&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;1-安装hugo-hugo仅需一个可执行文件-hugoe支持windows-mac-linux平台&#34;&gt;1. 安装Hugo, Hugo仅需一个可执行文件, Hugoe支持Windows Mac Linux平台.&lt;/h2&gt;
&lt;h3 id=&#34;11-windows安装&#34;&gt;1.1 Windows安装.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;创建三个文件夹&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;创建一个新的文件夹，D:\Hugo。&lt;/p&gt;
&lt;p&gt;创建一个新的文件夹，D:\Hugo\bin。&lt;/p&gt;
&lt;p&gt;创建一个新的文件夹，D:\Hugo\Sites。&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;下载Hugo执行文件, 解压存放到D:\Hugo\bin\中&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;下载Windows版本的&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/gohugoio/hugo/releases&#34; target=&#34;_blank&#34;&gt;Hugo&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;解压出&lt;strong&gt;文件&lt;/strong&gt;, &lt;strong&gt;文件&lt;/strong&gt;复制到&lt;strong&gt;D:\Hugo\bin&lt;/strong&gt;中.&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;把PATH=PATH%;D:\Hugo\bin添加到Windows环境变量中&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/hugo/windowpath1.png&#34; alt=&#34;windowpath&#34;  /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/hugo/windowpath2.png&#34; alt=&#34;windowpath&#34;  /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/hugo/windowpath3.png&#34; alt=&#34;windowpath&#34;  /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/hugo/windowpath4.png&#34; alt=&#34;windowpath&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;检查正确运行&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;打开Power Shell&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hugo version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;显示hugo版本就是正常.&lt;/p&gt;
&lt;h3 id=&#34;12-mac直接使用brew-install-hugo-hahahugoshortcode19s6hbhb&#34;&gt;1.2 Mac直接使用brew install hugo, 
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://brew.sh/index_zh-cn&#34; target=&#34;_blank&#34;&gt;Brew安装&lt;/a&gt; 

.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;brew install hugo
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;13-linux下载文件并移动到usrlocalbin下即可-mac也可以使用这种方式hugo版本mac-os&#34;&gt;1.3 linux下载文件并移动到/usr/local/bin/下即可, Mac也可以使用这种方式(Hugo版本Mac OS).&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;下载Linux 64版本Hugo&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/gohugoio/hugo/releases&#34; target=&#34;_blank&#34;&gt;Hugo下载地址&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;解压出hugo文件,移动hugo到/usr/local/bin/文件下&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 以0.85版本为例
wget https://github.com/gohugoio/hugo/releases/download/v0.85.0/hugo_0.85.0_Linux-64bit.tar.gz
tar xvf hugo_0.85.0_Linux-64bit.tar.gz
mv hugo /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;检查正确运行&lt;/a&gt;
&lt;/div&gt;

&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hugo version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;显示hugo版本就是正常.&lt;/p&gt;
&lt;h2 id=&#34;2-使用hugo-创建静态网站&#34;&gt;2. 使用Hugo, 创建静态网站.&lt;/h2&gt;
&lt;h3 id=&#34;21-创建静态网站文件夹&#34;&gt;2.1 创建静态网站文件夹&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~
hugo new site mywebsite
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;22-写第一篇markdown文章&#34;&gt;2.2 写第一篇markdown文章&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/mac/markdown/markdownli.002/&#34; target=&#34;_blank&#34;&gt;markdown语法参考&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~/mywebsite
hugo new posts/test.md
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;生成的readme.md是放在~/mywebsite/content中&lt;/p&gt;
&lt;h3 id=&#34;23-打开contentreadmemd添加内容&#34;&gt;2.3 打开content/readme.md添加内容&lt;/h3&gt;
&lt;p&gt;添加内容&amp;quot;我写的第1篇文章&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;更改draft: true 为 draft:false&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;24-启动hugo服务&#34;&gt;2.4 启动hugo服务&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~/mywebsite
hugo server
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;跳转到&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;http://localhost:1313&#34; target=&#34;_blank&#34;&gt;http://localhost:1313&lt;/a&gt; 

&lt;/strong&gt;即可预览.&lt;/p&gt;
&lt;h2 id=&#34;3-下载使用-hahahugoshortcode19s13hbhb&#34;&gt;3. 下载使用 &lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://themes.gohugo.io/&#34; target=&#34;_blank&#34;&gt;Hugo Theme(主题)&lt;/a&gt; 

&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id=&#34;31-下载主题-在mywebsite下载存放到themes文件夹中&#34;&gt;3.1 下载主题, 在~/mywebsite下载存放到themes文件夹中.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~/.mywebsite
git clone git@github.com:leezicai/hugo-PaperMod.git themes/papermod
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;32-使用主题-预览&#34;&gt;3.2 使用主题, 预览.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~/mywebsite
# 关闭上一个预览程序control + c
hugo server --theme=papermod
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;跳转到&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;http://localhost:1313&#34; target=&#34;_blank&#34;&gt;http://localhost:1313&lt;/a&gt; 

&lt;/strong&gt;即可预览.&lt;/p&gt;
&lt;h2 id=&#34;4-创建github项目mywebsite&#34;&gt;4. 创建GitHub项目mywebsite&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在GitHub中创建test的public公共类型项目. 创建完后访问地址https://github.com/leezicai/mywebsite&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;5-生成本地静态网站-并推送到github的mywebsite&#34;&gt;5. 生成本地静态网站, 并推送到Github的mywebsite.&lt;/h2&gt;
&lt;h3 id=&#34;51-hugo命令生成静态网页&#34;&gt;5.1 Hugo命令生成静态网页&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;注意baseUrl后的地址是HTTPS的类型, github pages强制https类型&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;baseUrl的结束有/&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;mywebsite注意大小写&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~/mywebsite
hugo --theme=papermod --baseUrl=&amp;#34;https://leezicai.github.io/mywebsite/&amp;#34; --destination=mywebsite
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这里会生成文件到mywebsite文件夹下.&lt;/p&gt;
&lt;h3 id=&#34;52-初始化并推荐送到githubcom上&#34;&gt;5.2 初始化并推荐送到Github.com上.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~/mywebsite/mywebsite

git init

git remote add github git@github.com:leezicai/mywebsite.git

git config user.email &amp;#34;test@test.com&amp;#34;

git config user.name &amp;#34;leezicai&amp;#34;

git add .

git commit -m &amp;#34;init&amp;#34;

git push -u github master:master
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;6-github进入mywebsite-设置github-pages&#34;&gt;6. Github进入mywebsite, 设置GitHub Pages.&lt;/h2&gt;
&lt;h3 id=&#34;61-进入以我的项目setting设置里&#34;&gt;6.1 进入,以我的项目setting设置里&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/leezicai/mywebsite&#34; target=&#34;_blank&#34;&gt;https://github.com/leezicai/mywebsite&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;设置-&amp;gt;Pages&lt;/p&gt;
&lt;p&gt;选择Source为master即可&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Theme Chooser必须要选择一个主题, 否则404&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;7-查看github-pages&#34;&gt;7. 查看GitHub Pages.&lt;/h2&gt;
&lt;p&gt;刷新进入https://github.com/leezicai/mywebsite/settings&lt;/p&gt;
&lt;p&gt;设置-&amp;gt;Github Pages下, 看到你的网站地址.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://leezicai.github.io/mywebsite/&#34; target=&#34;_blank&#34;&gt;https://leezicai.github.io/mywebsite/&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;8-图片链接&#34;&gt;8. 图片链接.&lt;/h2&gt;
&lt;h3 id=&#34;81-相对路径引入图片&#34;&gt;8.1 相对路径引入图片.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;图片和test.md同一层时, hugo生成静态博客时test.md会生成文件夹,图片就成了test.md的上一层文件夹中, ../表示在上一层目录&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;本地和Github Pages相对路径不一致, 本地同样不显示&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mv Alexey-Sviridkin-VXb42m0uM3s.jpg ~/mywebsite/content/posts/
![cat](../Alexey-Sviridkin-VXb42m0uM3s.jpg)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;82-使用根目录引入图片&#34;&gt;8.2 使用根目录引入图片.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;~/mywebsite/static/&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;相对路径, mywebsite与github pages的项目名一致&lt;/strong&gt;
&lt;strong&gt;本地是无法显示图片的, 因为本地和Github Pages地址不一致, Home目录(根目录)也不一致&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mv Alexey-Sviridkin-VXb42m0uM3s.jpg ~/mywebsite/static/

# 相对路径, mywebsite与github pages的项目名一致.
# 本地是无法显示图片的, 因为本地和Github Pages地址不一致, 相对路径也不一致.
![猫](/mywebsite/Alexey-Sviridkin-VXb42m0uM3s.jpg)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;9-hugo-可以开启支持markdown的html元素&#34;&gt;9. Hugo 可以开启支持markdown的HTML元素.&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;如使用的config.yml格式, 添加如下即可支持&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;markup:
    goldmark:
        renderer:
            unsafe: true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;如使用的config.toml格式, 添加如下即可支持&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[markup]
  defaultMarkdownHandler = &amp;#34;goldmark&amp;#34;
  [markup.goldmark]
    [markup.goldmark.renderer]
      unsafe = true
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;a href=&amp;#34;https://github.com&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;Github.com&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;效果如下&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com&#34; target=&#34;_blank&#34;&gt;Github.com&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Markdown编辑软件 Li.003</title>
      <link>https://lizicai.com/p/markdown%E7%BC%96%E8%BE%91%E8%BD%AF%E4%BB%B6-li.003/</link>
      <pubDate>Wed, 14 Jul 2021 23:28:27 +0800</pubDate>
      <guid>https://lizicai.com/p/markdown%E7%BC%96%E8%BE%91%E8%BD%AF%E4%BB%B6-li.003/</guid>
      <description>&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%ad%a6%e4%b9%a0%e8%b7%af%e7%ba%bfli.028/&#34; target=&#34;_blank&#34;&gt;本篇文章属于Hugo学习路线Li.028一部分&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/markdown/markdwon-logo.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&#34;1-windows-mac-linux全平台支持的工具&#34;&gt;1. Windows Mac Linux全平台支持的工具.&lt;/h2&gt;
&lt;h3 id=&#34;marktext-免费开源-支持mac-windows-linux&#34;&gt;MarkText, 免费开源, 支持Mac Windows Linux.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/marktext/marktext/releases&#34; target=&#34;_blank&#34;&gt;MarkText&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;visual-studio-code-开源-免费-全平台支持windows-mac-linux&#34;&gt;Visual Studio Code, 开源, 免费, 全平台支持(Windows Mac Linux).&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://code.visualstudio.com/download&#34; target=&#34;_blank&#34;&gt;Visual Studio Code&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;sublime-text-4-收费-全平台支持windows-mac-linux&#34;&gt;Sublime Text 4, 收费, 全平台支持(Windows Mac Linux)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.sublimetext.com/download&#34; target=&#34;_blank&#34;&gt;Sublime Text 4&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/jonschlinkert/sublime-markdown-extended&#34; target=&#34;_blank&#34;&gt;插件sublime-markdown-extended&lt;/a&gt; 


&lt;h3 id=&#34;atom-开源-免费-全平台支持windows-mac-linux&#34;&gt;Atom, 开源, 免费, 全平台支持(Windows Mac Linux).&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/atom/atom/releases&#34; target=&#34;_blank&#34;&gt;Atom&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/atom/markdown-preview&#34; target=&#34;_blank&#34;&gt;插件Markdown Preview&lt;/a&gt; 


&lt;h3 id=&#34;vim-开源-免费-全平台支持windows-mac-linux&#34;&gt;Vim 开源 免费 全平台支持(Windows Mac Linux).&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://www.vim.org/download.php&#34; target=&#34;_blank&#34;&gt;Vim&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/tpope/vim-markdown&#34; target=&#34;_blank&#34;&gt;vim插件tpope/vim-markdown&lt;/a&gt; 


&lt;h2 id=&#34;2-mac-iphone-ipad-端工具&#34;&gt;2. Mac iPhone iPad 端工具.&lt;/h2&gt;
&lt;h3 id=&#34;marktext-免费开源-支持mac-windows-linux-1&#34;&gt;MarkText, 免费开源, 支持Mac Windows Linux.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/marktext/marktext/releases&#34; target=&#34;_blank&#34;&gt;MarkText&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;ulysses-付费-支持平台mac-iphone-ipad&#34;&gt;Ulysses 付费 (支持平台Mac iPhone iPad).&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://ulysses.app/&#34; target=&#34;_blank&#34;&gt;Ulysses&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;ia-writer-付费-支持平台mac-iphone-ipad&#34;&gt;iA Writer 付费 (支持平台Mac iPhone iPad).&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://ia.net/downloads&#34; target=&#34;_blank&#34;&gt;iA Writer&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;bear-付费支持平台mac-iphone-ipad&#34;&gt;Bear 付费(支持平台Mac iPhone iPad).&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://bear.app/&#34; target=&#34;_blank&#34;&gt;Bear&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;pretext-免费&#34;&gt;Pretext 免费&lt;/h3&gt;
&lt;p&gt;Pretext&lt;/p&gt;
&lt;h2 id=&#34;3-android应用&#34;&gt;3. Android应用&lt;/h2&gt;
&lt;h3 id=&#34;坚果云&#34;&gt;坚果云&lt;/h3&gt;
&lt;h3 id=&#34;石墨文档&#34;&gt;石墨文档&lt;/h3&gt;
</description>
    </item>
    
    <item>
      <title>Markdown语法 Li.002</title>
      <link>https://lizicai.com/p/markdown%E8%AF%AD%E6%B3%95-li.002/</link>
      <pubDate>Wed, 14 Jul 2021 15:58:10 +0800</pubDate>
      <guid>https://lizicai.com/p/markdown%E8%AF%AD%E6%B3%95-li.002/</guid>
      <description>&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/p/hugo%e5%ad%a6%e4%b9%a0%e8%b7%af%e7%ba%bfli.028/&#34; target=&#34;_blank&#34;&gt;本篇文章属于Hugo学习路线Li.028一部分&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&#34;justify-content: center;text-align:center;color: var(--secondary);&#34;&gt;
&lt;div &gt;
    &lt;img src=&#34;https://s.lizicai.com/markdown/markdwon-logo.png&#34; alt=&#34;&#34; style=&#34;max-width: px; max-height: px;&#34;&gt;
    &lt;p style=&#34;padding-top:6px;font-size:15px;letter-spacing: 0.03rem;&#34; &gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Markdown&lt;/strong&gt;是一种轻量级标记语言，创始人为约翰·格鲁伯。它允许人们使用易读易写的纯文本格式编写文档，
然后转换成有效的XHTML文档。这种语言吸收了很多在电子邮件中已有的纯文本标记的特性。
Markdown文件类型结尾是.md或.markdown形式.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;优点: &lt;strong&gt;简单 统一(写一次任何地方显示一致) 支持网站平台多&lt;/strong&gt;(Github Gitlab Wordpresse 知乎 简书等)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;编辑软件推荐:&lt;/strong&gt;
&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://typora.io/#download&#34; target=&#34;_blank&#34;&gt;Typora&lt;/a&gt; 

&lt;/strong&gt; 和
&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/marktext/marktext/releases&#34; target=&#34;_blank&#34;&gt;MarkText&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/mac/markdown/markdown%E5%B7%A5%E5%85%B7%E9%9B%86li003/&#34; target=&#34;_blank&#34;&gt;更多应用&lt;/a&gt; 

&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;1-标题&#34;&gt;1. 标题&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 标题1
## 标题2
### 标题3
#### 标题4
##### 标题5
###### 标题6
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;标题1&#34;&gt;标题1&lt;/h1&gt;
&lt;h2 id=&#34;标题2&#34;&gt;标题2&lt;/h2&gt;
&lt;h3 id=&#34;标题3&#34;&gt;标题3&lt;/h3&gt;
&lt;h4 id=&#34;标题4&#34;&gt;标题4&lt;/h4&gt;
&lt;h5 id=&#34;标题5&#34;&gt;标题5&lt;/h5&gt;
&lt;h6 id=&#34;标题6&#34;&gt;标题6&lt;/h6&gt;
&lt;h2 id=&#34;2-图片与链接&#34;&gt;2. 图片与链接.&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[知乎](https://zhihu.com)

![图片](https://images.unsplash.com/photo-1545065942-3a37886535d5?ixlib=rb-1.2.1&amp;amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=2250&amp;amp;q=80)

#目录路径,访问的当前网站根目录下的图片.
![猫](/Alexey-Sviridkin-VXb42m0uM3s.jpg)
![猫](../../../Alexey-Sviridkin-VXb42m0uM3s.jpg)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://zhihu.com&#34;&gt;知乎&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://images.unsplash.com/photo-1545065942-3a37886535d5?ixlib=rb-1.2.1&amp;amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=2250&amp;amp;q=80&#34; alt=&#34;图片&#34;  /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://lizicai.com/Alexey-Sviridkin-VXb42m0uM3s.jpg&#34; alt=&#34;猫&#34;  /&gt;

&lt;img loading=&#34;lazy&#34; src=&#34;../../../Alexey-Sviridkin-VXb42m0uM3s.jpg&#34; alt=&#34;猫&#34;  /&gt;
&lt;/p&gt;
&lt;h2 id=&#34;3-段落&#34;&gt;3. 段落&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;段落一
没有空行, 仍然是段落一

空一行就是段落二
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;段落一
没有空行, 仍然是段落一&lt;/p&gt;
&lt;p&gt;空一行就是段落二&lt;/p&gt;
&lt;h2 id=&#34;4-列表-有序列表与无序列表&#34;&gt;4 列表. 有序列表与无序列表.&lt;/h2&gt;
&lt;h3 id=&#34;41-有序列表&#34;&gt;4.1 有序列表&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1. 有序列表一
2. 有序列表一
3. 有序列表一
&lt;/code&gt;&lt;/pre&gt;&lt;ol&gt;
&lt;li&gt;有序列表一&lt;/li&gt;
&lt;li&gt;有序列表一&lt;/li&gt;
&lt;li&gt;有序列表一&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;42-无序列表--与同义&#34;&gt;4.2 无序列表. -与*同义.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;* 无序列表一
* 无序列表二
    * 无序列表一一
    * 无序列表一二
        * 无序列表一一一
- 无序列表一
- 无序列表二
    - 无序列表一一
    - 无序列表一二
        - 无序列表一一一
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;无序列表一&lt;/li&gt;
&lt;li&gt;无序列表二
&lt;ul&gt;
&lt;li&gt;无序列表一一&lt;/li&gt;
&lt;li&gt;无序列表一二
&lt;ul&gt;
&lt;li&gt;无序列表一一一&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;无序列表一&lt;/li&gt;
&lt;li&gt;无序列表二
&lt;ul&gt;
&lt;li&gt;无序列表一一&lt;/li&gt;
&lt;li&gt;无序列表一二
&lt;ul&gt;
&lt;li&gt;无序列表一一一&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;5-代码块-&#34;&gt;5. 代码块``` ```&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;#34;```&amp;#34;
6个`包围就是代码区域
&amp;#34;```&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public static void main(){
    System.out.println(&amp;#34;Hello&amp;#34;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;6-markdown同样支持所有html标签&#34;&gt;6. Markdown同样支持所有HTML标签&lt;/h2&gt;
&lt;p&gt;例如a img标签&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;a href=&amp;#34;https://github.com&amp;#34; target=&amp;#34;_blank&amp;#34; &amp;gt;Github.com&amp;lt;/a&amp;gt;
&amp;lt;img src=&amp;#34;https://images.unsplash.com/photo-1545065942-3a37886535d5?ixlib=rb-1.2.1&amp;amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=2250&amp;amp;q=80&amp;#34;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://github.com&#34; target=&#34;_blank&#34;&gt;Github.com&lt;/a&gt;&lt;/p&gt;
&lt;img src=&#34;https://images.unsplash.com/photo-1545065942-3a37886535d5?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=2250&amp;q=80&#34;&gt;
&lt;h2 id=&#34;7-表格&#34;&gt;7. 表格&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;| 标题一 | 标题二 | 标题三 |
| ---   | ---   | ---   |
| 内容一 | 内容二 | 内容三 |
&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;标题一&lt;/th&gt;
          &lt;th&gt;标题二&lt;/th&gt;
          &lt;th&gt;标题三&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;内容一&lt;/td&gt;
          &lt;td&gt;内容二&lt;/td&gt;
          &lt;td&gt;内容三&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;8-引用&#34;&gt;8. 引用.&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;引用内容 线上服务
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;引用内容 线上服务&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;9-强调&#34;&gt;9. 强调****&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;普通 **强调**
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;普通 &lt;strong&gt;强调&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;10-任务--&#34;&gt;10. 任务* -&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;- [ ] 任务一
- [x] 完成任务二
  - [x] 完成任务三
- [ ] 待完成任务四
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 任务一&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 完成任务二
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 完成任务三&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 待完成任务四&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;11分隔线-&#34;&gt;11.分隔线 &amp;mdash;&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;分隔线

---
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;分隔线&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;12字符转义&#34;&gt;12.字符转义\&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;\*
\\
\-
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;*&lt;/p&gt;
&lt;p&gt;\&lt;/p&gt;
&lt;p&gt;-&lt;/p&gt;
&lt;h2 id=&#34;13-删除线&#34;&gt;13. 删除线~~~~&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;~~删除线~~
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;del&gt;删除线&lt;/del&gt;&lt;/p&gt;
&lt;h2 id=&#34;14-数学公式-其它内容&#34;&gt;14. 数学公式, 其它内容.&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;abbr title=&amp;#34;Graphics Interchange Format&amp;#34;&amp;gt;GIF&amp;lt;/abbr&amp;gt; is a bitmap image format.

H&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;O

X&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; + Y&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; = Z&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;

Press &amp;lt;kbd&amp;gt;&amp;lt;kbd&amp;gt;CTRL&amp;lt;/kbd&amp;gt;+&amp;lt;kbd&amp;gt;ALT&amp;lt;/kbd&amp;gt;+&amp;lt;kbd&amp;gt;Delete&amp;lt;/kbd&amp;gt;&amp;lt;/kbd&amp;gt; to end the session.

Most &amp;lt;mark&amp;gt;salamanders&amp;lt;/mark&amp;gt; are nocturnal, and hunt for insects, worms, and other small creatures.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;abbr title=&#34;Graphics Interchange Format&#34;&gt;GIF&lt;/abbr&gt; is a bitmap image format.&lt;/p&gt;
&lt;p&gt;H&lt;sub&gt;2&lt;/sub&gt;O&lt;/p&gt;
&lt;p&gt;X&lt;sup&gt;n&lt;/sup&gt; + Y&lt;sup&gt;n&lt;/sup&gt; = Z&lt;sup&gt;n&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Press &lt;kbd&gt;&lt;kbd&gt;CTRL&lt;/kbd&gt;+&lt;kbd&gt;ALT&lt;/kbd&gt;+&lt;kbd&gt;Delete&lt;/kbd&gt;&lt;/kbd&gt; to end the session.&lt;/p&gt;
&lt;p&gt;Most &lt;mark&gt;salamanders&lt;/mark&gt; are nocturnal, and hunt for insects, worms, and other small creatures.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Git基础教程和Sourcetree使用一 Li.001</title>
      <link>https://lizicai.com/p/git%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B%E5%92%8Csourcetree%E4%BD%BF%E7%94%A8%E4%B8%80-li.001/</link>
      <pubDate>Tue, 06 Jul 2021 01:10:17 +0800</pubDate>
      <guid>https://lizicai.com/p/git%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B%E5%92%8Csourcetree%E4%BD%BF%E7%94%A8%E4%B8%80-li.001/</guid>
      <description>&lt;h2 id=&#34;1-git是什么&#34;&gt;1. Git是什么&lt;/h2&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/git.png&#34; alt=&#34;git&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;11-git是一个文件版本管理软件&#34;&gt;1.1 Git是一个文件版本管理软件.&lt;/h3&gt;
&lt;p&gt;可以理解回去任意过去时间查看写了什么内容, 文件时光机, 不再担心文件丢失.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可对文本类、代码、工程、财务文件追踪, 上传云服务上安全保存, 随时可以任何电脑继续之前内容.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;12-版本管理是什么&#34;&gt;1.2 版本管理是什么?&lt;/h3&gt;
&lt;p&gt;比如你收集了很多素材, 写出第1个版本的&amp;quot;论文.word&amp;quot;.&lt;/p&gt;
&lt;p&gt;拿给老师看了, 说需要修改, 你会怎么做.&lt;/p&gt;
&lt;p&gt;大部分人肯定会 论文复制1.word, 然后在复制出来的文档更改.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;而不会修改原始文档&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;原因是收集的大量素材是以后会重要的参考, 绝对不会随意丢弃.&lt;/p&gt;
&lt;p&gt;如果请求老师修改意见, 论文会出来一个新的版本, 论文修改2.word.&lt;/p&gt;
&lt;p&gt;像这种修改论文方式就是一种版本管理.&lt;/p&gt;
&lt;h2 id=&#34;2-为什么选择git-而不是svnsubversion&#34;&gt;2. 为什么选择Git, 而不是SVN(Subversion)&lt;/h2&gt;
&lt;h3 id=&#34;21-git在很几个方面比svn更易用&#34;&gt;2.1 Git在很几个方面比SVN更易用.&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;软件&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;最大交友网站Github使用git&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;文件上传下载速度&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;分布式网络依赖更低&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;分布式可本地提交&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Svn&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;no&#34; src=&#34;https://s.lizicai.com/icon/task/no.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Git&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;
&lt;img height=&#34;29px&#34; width=&#34;29px&#34;
alt=&#34;done&#34; src=&#34;https://s.lizicai.com/icon/task/done.svg&#34;&gt;&lt;/img&gt;

&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;最大交友网站Github使用git, 平台优势&lt;/a&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;由于Git的易用形成平台优势, Git的开源免费, 使得越来越多人使用, 从而形成非常多代码交易平台.&lt;/li&gt;
&lt;li&gt;GitHub(微软家的)通过Git进行版本控制的软件源代码托管服务平台, 世界最大的代码交流网站.&lt;/li&gt;
&lt;li&gt;Svn虽是开源, svn集中式版本管理种种弊端难以流行起来.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;文件上传下载速度&lt;/a&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Git上传大量小文件速度更快, 而绝大部分代码文件是小文件, Git优势明显.&lt;/li&gt;
&lt;li&gt;Svn大量小文件比Git慢&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;分布式网络依赖更低&lt;/a&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Svn每次提交必须同步代码, 然后提交到服务器中.&lt;/li&gt;
&lt;li&gt;Git只需要在合并代码时, 拉代码, 合并, 提交服务器.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;分布式可本地提交&lt;/a&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Git拉取分支后, 可以本地开发, 增加新功能, 可以直接提交本地, 跟踪版本记录.&lt;/li&gt;
&lt;li&gt;Svn开发新功能后, 必须提交到服务器上才会记录版本.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;3-git在github平台的基础用法-创建项目-提交请求-推送到远程&#34;&gt;3. Git在Github平台的基础用法, 创建项目 提交请求 推送到远程.&lt;/h2&gt;
&lt;h3 id=&#34;31-注册github账户&#34;&gt;3.1 注册Github账户&lt;/h3&gt;
&lt;p&gt;注册地址&lt;a href=&#34;https://github.com&#34; target=&#34;_blank&#34;&gt;Github.com&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;32-在github创建一个空仓库&#34;&gt;3.2 在Github创建一个空仓库&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;title=&amp;#34;创建仓库&amp;#34;&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/github-create-repo1.png&#34; alt=&#34;github创建仓库&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;仓库设置, 这里选择private(私有仓库)&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/github-create-repo2.png&#34; alt=&#34;github创建仓库&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;检查, 创建空仓库成功&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/github-create-repo3.png&#34; alt=&#34;github创建仓库&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;33-使用sourcetree克隆远程github空仓库到本地&#34;&gt;3.3 使用Sourcetree克隆远程Github空仓库到本地.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;下载安装Sourcetree&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;下载地址&lt;a href=&#34;https://www.sourcetreeapp.com/&#34; target=&#34;_blank&#34;&gt;&lt;a href=&#34;https://www.sourcetreeapp.com&#34;&gt;www.sourcetreeapp.com&lt;/a&gt;&lt;/a&gt;, 支持windows mac端.&lt;/p&gt;
&lt;p&gt;mac如有安装址homebrew, 命令brew cask install sourcetree直接安装.&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;初始化Sourcetree, 用户名, 用户邮箱&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/sourcetree1.png&#34; alt=&#34;sourcetree1&#34;  /&gt;

&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/sourcetree2.png&#34; alt=&#34;sourcetree2&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;复制在Github创建仓库地址&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/gitube-repo-url1.png&#34; alt=&#34;github repo url&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;输入在Github创建的项目地址, 鼠标点击目标路径自动成一个本地的文件夹test&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/sourcetree3-2.png&#34; alt=&#34;sourcetree3&#34;  /&gt;

&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/sourcetree4-1.png&#34; alt=&#34;sourcetree4&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;5&#34;
    src=&#34;https://s.lizicai.com/icon/number/5.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;输入Github用户, Github密码&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/sourcetree5.png&#34; alt=&#34;sourcetree5&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;6&#34;
    src=&#34;https://s.lizicai.com/icon/number/6.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;检查, 从Github拉取空仓库成功&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/sourcetree6.png&#34; alt=&#34;sourcetree6&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;34-创建文件-在本地提交&#34;&gt;3.4 创建文件, 在本地提交&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;使用文本编辑软件, 在根目录test文件中创建readme.md文件&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/edit1.png&#34; alt=&#34;edit&#34;  /&gt;

&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/edit2.png&#34; alt=&#34;edit&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;随意输入2行字, 保存文件名为readme.md的文件&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/edit3.png&#34; alt=&#34;edit&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;3&#34;
    src=&#34;https://s.lizicai.com/icon/number/3.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;查看Sourcetree, 可以看到新建的readme.md文件&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/edit4.png&#34; alt=&#34;edit&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;4&#34;
    src=&#34;https://s.lizicai.com/icon/number/4.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;勾选文件, 填写提交内容, 点击提交&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/commit1.png&#34; alt=&#34;commit&#34;  /&gt;

&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/commit2.png&#34; alt=&#34;commit&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;5&#34;
    src=&#34;https://s.lizicai.com/icon/number/5.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;检查, 提交成功 在提交历史可查看到.&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/commit3.png&#34; alt=&#34;commit&#34;  /&gt;
&lt;/p&gt;
&lt;h3 id=&#34;35-把本地提交内容推送到远程github上&#34;&gt;3.5 把本地提交内容推送到远程Github上.&lt;/h3&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;1&#34;
    src=&#34;https://s.lizicai.com/icon/number/1.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;推送&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/push1.png&#34; alt=&#34;push&#34;  /&gt;

&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/push2.png&#34; alt=&#34;push&#34;  /&gt;
&lt;/p&gt;


&lt;div class=&#34;div-left&#34; style=&#34;display:flex; padding: 1px; align-items: center;&#34;&gt;
&lt;a class=&#34;div-left-nu-img&#34;&gt;
    &lt;img height=&#34;26px&#34; width=&#34;26px&#34; alt=&#34;2&#34;
    src=&#34;https://s.lizicai.com/icon/number/2.svg&#34;&gt;&lt;/img&gt;
&lt;/a&gt;
&amp;nbsp;&amp;nbsp;
&lt;a class=&#34;div-left&#34;&gt;检查Github项目是否推送成功&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;登录&lt;a href=&#34;https://github.com&#34; target=&#34;_blank&#34;&gt;Github.com&lt;/a&gt;, 查看项目, &amp;ldquo;第一Github项目和Github&amp;quot;显示在网页readme.md, 与本地的一致.&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.lizicai.com/git/push3.png&#34; alt=&#34;push&#34;  /&gt;
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>关于李子菜 Lizicai</title>
      <link>https://lizicai.com/about/</link>
      <pubDate>Tue, 22 Jun 2021 14:38:31 +0800</pubDate>
      <guid>https://lizicai.com/about/</guid>
      <description>
&lt;figure &gt;
    
        &lt;img src=&#34;https://lizicai.com/apple-touch-icon.svg&#34; width=&#34;200px&#34;  /&gt;
    
    
&lt;/figure&gt;

&lt;h2 id=&#34;1-网站内容&#34;&gt;1. 网站内容.&lt;/h2&gt;
&lt;h3 id=&#34;mac-windows-linux-iphone-android软件使用&#34;&gt;Mac Windows Linux iPhone Android软件使用&lt;/h3&gt;
&lt;h3 id=&#34;也分享下科技新闻&#34;&gt;也分享下科技新闻&lt;/h3&gt;
&lt;h3 id=&#34;网站主要介绍软件使用操作-定位入门级别&#34;&gt;网站主要介绍软件使用操作, 定位入门级别&lt;/h3&gt;
&lt;h2 id=&#34;2-网站使用hugo生成-主题是papermod&#34;&gt;2. 网站使用Hugo生成, 主题是PaperMod.&lt;/h2&gt;
&lt;h3 id=&#34;hahahugoshortcode1s1hbhb&#34;&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://lizicai.com/mac/hugo/hugo%e5%92%8cgithub-pages%e6%90%ad%e5%bb%ba%e9%9d%99%e6%80%81%e7%bd%91%e7%ab%99li.004/&#34; target=&#34;_blank&#34;&gt;Hugo使用&lt;/a&gt; 

&lt;/strong&gt;&lt;/h3&gt;
&lt;h3 id=&#34;hahahugoshortcode1s2hbhb&#34;&gt;&lt;strong&gt;
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/adityatelange/hugo-PaperMod&#34; target=&#34;_blank&#34;&gt;Hugo-PaperMod主题&lt;/a&gt; 

&lt;/strong&gt;&lt;/h3&gt;
&lt;h3 id=&#34;个人修改版的hahahugoshortcode1s3hbhb&#34;&gt;个人修改版的
&lt;a style=&#34;color:var(--mylinkcolor)&#34; href=&#34;https://github.com/leezicai/hugo-PaperMod&#34; target=&#34;_blank&#34;&gt;Hugo-PaperMod&lt;/a&gt; 

&lt;/h3&gt;
&lt;h3 id=&#34;增加一些定制shortcodes-lizcaicom-使用的configyml也一并上传了-readme中文说明暂无计划&#34;&gt;增加一些定制shortcodes, lizcai.com 使用的config.yml也一并上传了, readme中文说明暂无计划.&lt;/h3&gt;
&lt;h2 id=&#34;3-打赏donate-如果网站有帮助-可以打赏一杯咖啡&#34;&gt;3. 打赏Donate. 如果网站有帮助, 可以打赏一杯咖啡☕️&lt;/h2&gt;

&lt;div style=&#34;display:flex;justify-content: center;text-align:center;&#34;&gt;
&lt;div style=&#34;margin-left: 1px;margin-right: 1px&#34;&gt;
    &lt;img src=&#34;https://lizicai.com/alipay.png&#34; alt=&#34;支付宝&#34; style=&#34;max-width: 180px; max-height: 180px;&#34;&gt;
    &lt;p&gt;支付宝&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&#34;margin-left: 1px;margin-right: 1px &#34;&gt;
    &lt;img src=&#34;https://lizicai.com/wechat.png&#34; alt=&#34;微信&#34; style=&#34;max-width: 180px; max-height: 180px;&#34;&gt;
&lt;p&gt;微信&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>归档</title>
      <link>https://lizicai.com/archives/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://lizicai.com/archives/</guid>
      <description></description>
    </item>
    
    <item>
      <title>搜索</title>
      <link>https://lizicai.com/search/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://lizicai.com/search/</guid>
      <description></description>
    </item>
    
  </channel>
</rss>
