Commit on 2025/03/21 周五 14:35:28.01
This commit is contained in:
parent
c34b41dd9d
commit
6bbb13cc82
176
Java/Docker指南.md
176
Java/Docker指南.md
@ -60,7 +60,7 @@ Docker是一个CS架构的程序,由两部分组成:
|
|||||||
|
|
||||||
1. docker push,将本地镜像上传到远程仓库(例如 Docker Hub)
|
1. docker push,将本地镜像上传到远程仓库(例如 Docker Hub)
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker login #docker hub登录
|
docker login #docker hub登录
|
||||||
# 假设已有本地镜像 myimage,需要先打上标签:
|
# 假设已有本地镜像 myimage,需要先打上标签:
|
||||||
docker tag myimage yourusername/myimage:latest
|
docker tag myimage yourusername/myimage:latest
|
||||||
@ -70,31 +70,31 @@ docker push yourusername/myimage:latest
|
|||||||
|
|
||||||
2. docker pull ,从远程仓库拉取镜像到本地。
|
2. docker pull ,从远程仓库拉取镜像到本地。
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker pull yourusername/myimage:latest
|
docker pull yourusername/myimage:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
3. docker save,将本地镜像保存为 tar 文件,方便备份或传输
|
3. docker save,将本地镜像保存为 tar 文件,方便备份或传输
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker save -o myimage.tar yourusername/myimage:latest
|
docker save -o myimage.tar yourusername/myimage:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
4. docker load,从 tar 文件中加载镜像到本地 Docker。
|
4. docker load,从 tar 文件中加载镜像到本地 Docker。
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker load -i myimage.tar
|
docker load -i myimage.tar
|
||||||
```
|
```
|
||||||
|
|
||||||
5. docker images ,查看本地镜像
|
5. docker images ,查看本地镜像
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker images
|
docker images
|
||||||
```
|
```
|
||||||
|
|
||||||
6. docker build ,构建镜像 -t后面跟镜像名
|
6. docker build ,构建镜像 -t后面跟镜像名
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker build -t yourusername/myimage:latest .
|
docker build -t yourusername/myimage:latest .
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ docker build -t yourusername/myimage:latest .
|
|||||||
|
|
||||||
-v <宿主机目录>:<容器目录>` 或 `--volume : 如 -v /host/data:/app/data
|
-v <宿主机目录>:<容器目录>` 或 `--volume : 如 -v /host/data:/app/data
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker run --name test-container -d test:latest
|
docker run --name test-container -d test:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -124,49 +124,49 @@ docker run --name test-container -d test:latest
|
|||||||
|
|
||||||
-it : 给当前进入的容器创建一个标准输入、输出终端
|
-it : 给当前进入的容器创建一个标准输入、输出终端
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker exec -it test-container sh
|
docker exec -it test-container sh
|
||||||
```
|
```
|
||||||
|
|
||||||
3. docker logs ,查看 test-container 的日志输出:
|
3. docker logs ,查看 test-container 的日志输出:
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker logs --since 1h test-container #查看最近1h
|
docker logs --since 1h test-container #查看最近1h
|
||||||
```
|
```
|
||||||
|
|
||||||
4. docker stop 停止正在运行的 test-container:
|
4. docker stop 停止正在运行的 test-container:
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker stop test-container
|
docker stop test-container
|
||||||
```
|
```
|
||||||
|
|
||||||
5. docker start 启动一个已停止的 test-container:
|
5. docker start 启动一个已停止的 test-container:
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker start test-container
|
docker start test-container
|
||||||
```
|
```
|
||||||
|
|
||||||
6. docker cp 复制文件(或目录)到容器内部,先cd到文件所在目录
|
6. docker cp 复制文件(或目录)到容器内部,先cd到文件所在目录
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker cp localfile.txt test-container:/target_dir/
|
docker cp localfile.txt test-container:/target_dir/
|
||||||
```
|
```
|
||||||
|
|
||||||
7. docker stats ,查看docker中运行的所有容器的运行状态(CPU 内存占用)
|
7. docker stats ,查看docker中运行的所有容器的运行状态(CPU 内存占用)
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker stats
|
docker stats
|
||||||
```
|
```
|
||||||
|
|
||||||
8. docker container ls,查看运行容器的创建时间、端口映射等
|
8. docker container ls,查看运行容器的创建时间、端口映射等
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker container ls
|
docker container ls
|
||||||
```
|
```
|
||||||
|
|
||||||
9. docker ps 查看 Docker 容器的状态,默认情况下,它只显示正在运行的容器
|
9. docker ps 查看 Docker 容器的状态,默认情况下,它只显示正在运行的容器
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker ps -a #查看所有容器,包括已经停止或启动失败的容器
|
docker ps -a #查看所有容器,包括已经停止或启动失败的容器
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ docker ps -a #查看所有容器,包括已经停止或启动失败的容器
|
|||||||
|
|
||||||
- **示例**:将宿主机的 `/path/on/host` 挂载到容器内的 `/app/data`:
|
- **示例**:将宿主机的 `/path/on/host` 挂载到容器内的 `/app/data`:
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker run -v /path/on/host:/app/data your_image
|
docker run -v /path/on/host:/app/data your_image
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -212,25 +212,25 @@ docker ps -a #查看所有容器,包括已经停止或启动失败的容器
|
|||||||
|
|
||||||
- **示例**:创建并挂载名为 `my_volume` 的卷到容器内的 `/app/data`:
|
- **示例**:创建并挂载名为 `my_volume` 的卷到容器内的 `/app/data`:
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker run -v my_volume:/app/data your_image
|
docker run -v my_volume:/app/data your_image
|
||||||
```
|
```
|
||||||
|
|
||||||
创建命名卷
|
创建命名卷
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker volume create my_volume
|
docker volume create my_volume
|
||||||
```
|
```
|
||||||
|
|
||||||
查看命名卷,这将列出所有 Docker 管理的卷。
|
查看命名卷,这将列出所有 Docker 管理的卷。
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker volume ls
|
docker volume ls
|
||||||
```
|
```
|
||||||
|
|
||||||
显示该命名卷的详细信息
|
显示该命名卷的详细信息
|
||||||
|
|
||||||
```
|
```text
|
||||||
zy123@hcss-ecs-588d:~/zbparse$ sudo docker volume inspect html
|
zy123@hcss-ecs-588d:~/zbparse$ sudo docker volume inspect html
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -259,13 +259,13 @@ Docker 网络的主要作用是实现容器之间的**通信和隔离**,同时
|
|||||||
|
|
||||||
1.创建自定义网络 ,名为 `app-net`
|
1.创建自定义网络 ,名为 `app-net`
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker network create app-net
|
docker network create app-net
|
||||||
```
|
```
|
||||||
|
|
||||||
2.启动 MySQL 容器,并加入 `app-net` 网络,同时为其指定别名 `db`
|
2.启动 MySQL 容器,并加入 `app-net` 网络,同时为其指定别名 `db`
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker run -d --name mysql \
|
docker run -d --name mysql \
|
||||||
--network app-net \
|
--network app-net \
|
||||||
--network-alias db \
|
--network-alias db \
|
||||||
@ -287,7 +287,7 @@ docker run -d --name mysql \
|
|||||||
|
|
||||||
3.启动 Web 应用容器,加入同一个 `app-net` 网络
|
3.启动 Web 应用容器,加入同一个 `app-net` 网络
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker run -d --name webapp \
|
docker run -d --name webapp \
|
||||||
--network app-net \
|
--network app-net \
|
||||||
your_webapp_image:latest
|
your_webapp_image:latest
|
||||||
@ -295,7 +295,7 @@ docker run -d --name webapp \
|
|||||||
|
|
||||||
4.验证容器间通信,进入 Web 应用容器,尝试通过别名 `db` 连接 MySQL:
|
4.验证容器间通信,进入 Web 应用容器,尝试通过别名 `db` 连接 MySQL:
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker exec -it webapp bash
|
docker exec -it webapp bash
|
||||||
# 在 webapp 容器内执行,比如使用 ping 测试网络连通性:
|
# 在 webapp 容器内执行,比如使用 ping 测试网络连通性:
|
||||||
ping db
|
ping db
|
||||||
@ -303,7 +303,7 @@ ping db
|
|||||||
|
|
||||||
举个例子,如果你的 Java 应用运行在容器 B 中,而数据库容器 A 已经通过 `--network-alias db` 起了别名,那么在 Java 应用中,你只需要写:
|
举个例子,如果你的 Java 应用运行在容器 B 中,而数据库容器 A 已经通过 `--network-alias db` 起了别名,那么在 Java 应用中,你只需要写:
|
||||||
|
|
||||||
```
|
```text
|
||||||
String dbUrl = "jdbc:mysql://db:3306/your_database";
|
String dbUrl = "jdbc:mysql://db:3306/your_database";
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -311,7 +311,7 @@ String dbUrl = "jdbc:mysql://db:3306/your_database";
|
|||||||
|
|
||||||
否则:
|
否则:
|
||||||
|
|
||||||
```
|
```text
|
||||||
String dbUrl = "jdbc:mysql://<宿主机IP或localhost>:3306/your_database";
|
String dbUrl = "jdbc:mysql://<宿主机IP或localhost>:3306/your_database";
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -322,13 +322,13 @@ String dbUrl = "jdbc:mysql://<宿主机IP或localhost>:3306/your_database";
|
|||||||
|
|
||||||
接时可以使用 `--alias` 参数为容器在该网络中设置别名
|
接时可以使用 `--alias` 参数为容器在该网络中设置别名
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker network connect app-net mysql --alias db
|
docker network connect app-net mysql --alias db
|
||||||
```
|
```
|
||||||
|
|
||||||
6.断开连接
|
6.断开连接
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker network disconnect app-net mysql
|
docker network disconnect app-net mysql
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -336,7 +336,7 @@ docker network disconnect app-net mysql
|
|||||||
|
|
||||||
需要注意的是,只有当网络中没有容器连接时才能删除。
|
需要注意的是,只有当网络中没有容器连接时才能删除。
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker network rm app-net
|
docker network rm app-net
|
||||||
docker network prune #删除所有未使用的网络
|
docker network prune #删除所有未使用的网络
|
||||||
```
|
```
|
||||||
@ -361,7 +361,7 @@ sudo apt-get remove docker docker-engine docker.io containerd runc
|
|||||||
|
|
||||||
在安装新版 Docker 前,需要更新 apt 源并安装一些依赖包,以便能够通过 HTTPS 协议访问 Docker 官方仓库。
|
在安装新版 Docker 前,需要更新 apt 源并安装一些依赖包,以便能够通过 HTTPS 协议访问 Docker 官方仓库。
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
|
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
|
||||||
```
|
```
|
||||||
@ -372,7 +372,7 @@ sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
|
|||||||
|
|
||||||
**3.添加 Docker 官方 GPG 密钥**
|
**3.添加 Docker 官方 GPG 密钥**
|
||||||
|
|
||||||
```
|
```text
|
||||||
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -386,13 +386,13 @@ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o
|
|||||||
|
|
||||||
这是最关键的一步,配置docker官方地址,往往**很难下载**!!!
|
这是最关键的一步,配置docker官方地址,往往**很难下载**!!!
|
||||||
|
|
||||||
```
|
```text
|
||||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
```
|
```
|
||||||
|
|
||||||
推荐使用以下阿里云的镜像加速源
|
推荐使用以下阿里云的镜像加速源
|
||||||
|
|
||||||
```
|
```text
|
||||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -404,7 +404,7 @@ cat /etc/apt/sources.list.d/docker.list 可以查看是否配置成功
|
|||||||
|
|
||||||
更新 apt 缓存后,安装最新版的 Docker Engine、CLI 工具和 containerd:
|
更新 apt 缓存后,安装最新版的 Docker Engine、CLI 工具和 containerd:
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo apt update #如果是docker官方,这一步可能失败!
|
sudo apt update #如果是docker官方,这一步可能失败!
|
||||||
sudo apt install docker-ce docker-ce-cli containerd.io
|
sudo apt install docker-ce docker-ce-cli containerd.io
|
||||||
```
|
```
|
||||||
@ -441,11 +441,11 @@ linux vim:
|
|||||||
|
|
||||||
### docker配置代理
|
### docker配置代理
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
|
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
[Service]
|
[Service]
|
||||||
Environment="HTTP_PROXY=http://127.0.0.1:7890"
|
Environment="HTTP_PROXY=http://127.0.0.1:7890"
|
||||||
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
|
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
|
||||||
@ -454,12 +454,12 @@ Environment="NO_PROXY=localhost,127.0.0.1"
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo systemctl daemon-reload //加载配置文件,更新环境变量
|
sudo systemctl daemon-reload //加载配置文件,更新环境变量
|
||||||
sudo systemctl restart docker
|
sudo systemctl restart docker
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
systemctl show --property=Environment docker //验证是否配置成功
|
systemctl show --property=Environment docker //验证是否配置成功
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -469,13 +469,13 @@ systemctl show --property=Environment docker //验证是否配置成功
|
|||||||
|
|
||||||
1.编辑 Docker 配置文件,如果该文件不存在,可以创建一个新的文件。
|
1.编辑 Docker 配置文件,如果该文件不存在,可以创建一个新的文件。
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo vim /etc/docker/daemon.json
|
sudo vim /etc/docker/daemon.json
|
||||||
```
|
```
|
||||||
|
|
||||||
2.添加多个镜像仓库配置
|
2.添加多个镜像仓库配置
|
||||||
|
|
||||||
```
|
```text
|
||||||
{
|
{
|
||||||
"registry-mirrors": [
|
"registry-mirrors": [
|
||||||
"http://hub-mirror.c.163.com",
|
"http://hub-mirror.c.163.com",
|
||||||
@ -491,13 +491,13 @@ sudo vim /etc/docker/daemon.json
|
|||||||
|
|
||||||
3.重启 Docker 服务以应用
|
3.重启 Docker 服务以应用
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo systemctl restart docker
|
sudo systemctl restart docker
|
||||||
```
|
```
|
||||||
|
|
||||||
4.验证配置
|
4.验证配置
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker info
|
docker info
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -513,7 +513,7 @@ docker info
|
|||||||
|
|
||||||
在 Dockerfile 中,RUN 指令用于在构建镜像的过程中执行命令,这些命令会在镜像的一个临时容器中执行,然后将执行结果作为新的镜像层保存下来。常见的用途包括安装软件包、修改系统配置、编译代码等。
|
在 Dockerfile 中,RUN 指令用于在构建镜像的过程中执行命令,这些命令会在镜像的一个临时容器中执行,然后将执行结果作为新的镜像层保存下来。常见的用途包括安装软件包、修改系统配置、编译代码等。
|
||||||
|
|
||||||
```
|
```text
|
||||||
RUN cd $JAVA_DIR \
|
RUN cd $JAVA_DIR \
|
||||||
&& tar -xf ./jdk8.tar.gz \
|
&& tar -xf ./jdk8.tar.gz \
|
||||||
&& mv ./jdk1.8.0_144 ./java8
|
&& mv ./jdk1.8.0_144 ./java8
|
||||||
@ -525,7 +525,7 @@ RUN cd $JAVA_DIR \
|
|||||||
|
|
||||||
当你修改原镜像时,只需使用相同的镜像名执行:
|
当你修改原镜像时,只需使用相同的镜像名执行:
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker build -t zbparse .
|
docker build -t zbparse .
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -544,7 +544,7 @@ Docker 会根据 **Dockerfile 和上下文的变化**来判断哪些层需要重
|
|||||||
|
|
||||||
以下方法可以删除none镜像。
|
以下方法可以删除none镜像。
|
||||||
|
|
||||||
```
|
```text
|
||||||
# 查找无标签镜像
|
# 查找无标签镜像
|
||||||
docker images -f "dangling=true"
|
docker images -f "dangling=true"
|
||||||
# 删除无标签镜像
|
# 删除无标签镜像
|
||||||
@ -561,7 +561,7 @@ docker rmi $(docker images -f "dangling=true" -q)
|
|||||||
|
|
||||||
1. 编写dockerfile文件
|
1. 编写dockerfile文件
|
||||||
|
|
||||||
```
|
```text
|
||||||
# 使用官方 Python 运行时作为父镜像
|
# 使用官方 Python 运行时作为父镜像
|
||||||
FROM python:3.8-slim
|
FROM python:3.8-slim
|
||||||
|
|
||||||
@ -599,19 +599,19 @@ docker rmi $(docker images -f "dangling=true" -q)
|
|||||||
|
|
||||||
5. 构造镜像 -t后面是镜像名 ,最后的点号 (`.`) 代表当前目录
|
5. 构造镜像 -t后面是镜像名 ,最后的点号 (`.`) 代表当前目录
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker build -t zbparse .
|
docker build -t zbparse .
|
||||||
```
|
```
|
||||||
|
|
||||||
5. 运行容器 -p后面,第一个5000代表宿主机端口,第二个5000代表容器内端口 ,zbparse-container为创建的容器名,zbparse是使用的镜像名字
|
5. 运行容器 -p后面,第一个5000代表宿主机端口,第二个5000代表容器内端口 ,zbparse-container为创建的容器名,zbparse是使用的镜像名字
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker run -d -p 5000:5000 --name zbparse-container zbparse
|
docker run -d -p 5000:5000 --name zbparse-container zbparse
|
||||||
```
|
```
|
||||||
|
|
||||||
6. 查看日志 ,若无报错贼容器正常启动
|
6. 查看日志 ,若无报错贼容器正常启动
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker logs zbparse-container
|
docker logs zbparse-container
|
||||||
docker logs --tail 10 [容器ID或名称] 查看最近10条日志
|
docker logs --tail 10 [容器ID或名称] 查看最近10条日志
|
||||||
docker logs --since 1h [容器ID或名称] 查看最近1小时的日志
|
docker logs --since 1h [容器ID或名称] 查看最近1小时的日志
|
||||||
@ -619,32 +619,32 @@ docker logs --since 1h [容器ID或名称] 查看最近1小时的日志
|
|||||||
|
|
||||||
7. 停止和删除容器,先停止后删除
|
7. 停止和删除容器,先停止后删除
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker stop zbparse-container
|
docker stop zbparse-container
|
||||||
docker rm zbparse-container
|
docker rm zbparse-container
|
||||||
```
|
```
|
||||||
|
|
||||||
8. 删除镜像
|
8. 删除镜像
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker rmi zbparse
|
docker rmi zbparse
|
||||||
```
|
```
|
||||||
|
|
||||||
9. 进入容器,可以查看容器内的数据
|
9. 进入容器,可以查看容器内的数据
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker exec -it zbparse-container /bin/bash
|
docker exec -it zbparse-container /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
10. 保存镜像为tar文件 (最简单的应该是上传docker hub镜像库,但是现在貌似被墙了)
|
10. 保存镜像为tar文件 (最简单的应该是上传docker hub镜像库,但是现在貌似被墙了)
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker save -o zbparse.tar zbparse
|
docker save -o zbparse.tar zbparse
|
||||||
```
|
```
|
||||||
|
|
||||||
11. 使用scp传输文件
|
11. 使用scp传输文件
|
||||||
|
|
||||||
```
|
```text
|
||||||
scp zbparse.tar root@118.178.236.139:/home/zy
|
scp zbparse.tar root@118.178.236.139:/home/zy
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -652,13 +652,13 @@ scp zbparse.tar root@118.178.236.139:/home/zy
|
|||||||
|
|
||||||
12. 加载镜像
|
12. 加载镜像
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo docker load -i zbparse.tar
|
sudo docker load -i zbparse.tar
|
||||||
```
|
```
|
||||||
|
|
||||||
13. 上传镜像
|
13. 上传镜像
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker login #输入邮箱 密码
|
docker login #输入邮箱 密码
|
||||||
docker tag zbparse yourusername/zbparse #标记你的 Docker 镜像
|
docker tag zbparse yourusername/zbparse #标记你的 Docker 镜像
|
||||||
#其中yourusername/zbparse是标记名
|
#其中yourusername/zbparse是标记名
|
||||||
@ -676,7 +676,7 @@ docker tag zbparse 646228430smile/zbparse:latest 这里的646228430smile是用
|
|||||||
|
|
||||||
14. 查看镜像
|
14. 查看镜像
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker images
|
docker images
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -686,7 +686,7 @@ docker images
|
|||||||
|
|
||||||
- **linux中构建镜像问题:**
|
- **linux中构建镜像问题:**
|
||||||
|
|
||||||
```
|
```text
|
||||||
RuntimeError: can‘t start new thread。
|
RuntimeError: can‘t start new thread。
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -697,7 +697,7 @@ RUN pip config set global.progress_bar off
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
=> [flask_app internal] load build definition from Dockerfile 0.0s
|
=> [flask_app internal] load build definition from Dockerfile 0.0s
|
||||||
=> => transferring dockerfile: 982B 0.0s
|
=> => transferring dockerfile: 982B 0.0s
|
||||||
=> ERROR [flask_app internal] load metadata for docker.io/library/python:3.8-slim 60.4s
|
=> ERROR [flask_app internal] load metadata for docker.io/library/python:3.8-slim 60.4s
|
||||||
@ -719,14 +719,14 @@ exit status 1
|
|||||||
|
|
||||||
- **docker运行权限问题**
|
- **docker运行权限问题**
|
||||||
|
|
||||||
```
|
```text
|
||||||
OpenBLAS blas_thread_init: pthread_create failed for thread 1 of 4: Operation not permitted
|
OpenBLAS blas_thread_init: pthread_create failed for thread 1 of 4: Operation not permitted
|
||||||
OpenBLAS blas_thread_init: RLIMIT_NPROC -1 current, -1 max
|
OpenBLAS blas_thread_init: RLIMIT_NPROC -1 current, -1 max
|
||||||
```
|
```
|
||||||
|
|
||||||
解决方法:
|
解决方法:
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker run --name zbparse-container --security-opt seccomp=unconfined zbparse
|
docker run --name zbparse-container --security-opt seccomp=unconfined zbparse
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -740,7 +740,7 @@ docker run --name zbparse-container --security-opt seccomp=unconfined zbparse
|
|||||||
|
|
||||||
验证安装
|
验证安装
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker compose version
|
docker compose version
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -748,19 +748,19 @@ docker compose version
|
|||||||
|
|
||||||
下载二进制文件(或者下载别人的镜像复制到服务器中的/usr/local/bin下)
|
下载二进制文件(或者下载别人的镜像复制到服务器中的/usr/local/bin下)
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo curl -L "https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
sudo curl -L "https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
```
|
```
|
||||||
|
|
||||||
赋予执行权限
|
赋予执行权限
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo chmod +x /usr/local/bin/docker-compose
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
```
|
```
|
||||||
|
|
||||||
验证安装
|
验证安装
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose --version
|
docker-compose --version
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -793,7 +793,7 @@ docker-compose --version
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
version: '3'
|
version: '3'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
@ -839,7 +839,7 @@ volumes:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
build:
|
build:
|
||||||
context: ./web_app
|
context: ./web_app
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
@ -855,13 +855,13 @@ build: ./web_app #两种写法是等效的
|
|||||||
|
|
||||||
**构建镜像:**这个命令根据 docker-compose.yml 中各服务的配置构建镜像。如果你修改了 Dockerfile 或者项目代码需要打包进镜像时,就需要运行该命令来构建新的镜像。
|
**构建镜像:**这个命令根据 docker-compose.yml 中各服务的配置构建镜像。如果你修改了 Dockerfile 或者项目代码需要打包进镜像时,就需要运行该命令来构建新的镜像。
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose build
|
docker-compose build
|
||||||
```
|
```
|
||||||
|
|
||||||
**启动容器:**这个命令用于启动服务,参数 `-d` 表示以后台守护进程的方式运行。如果镜像不存在,它会自动构建镜像;但如果镜像已经存在,则默认直接使用现有的镜像启动容器。
|
**启动容器:**这个命令用于启动服务,参数 `-d` 表示以后台守护进程的方式运行。如果镜像不存在,它会自动构建镜像;但如果镜像已经存在,则默认直接使用现有的镜像启动容器。
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -869,19 +869,19 @@ docker-compose up -d
|
|||||||
|
|
||||||
**只针对 pyapp 服务进行重构和启动,不影响其他服务运行**
|
**只针对 pyapp 服务进行重构和启动,不影响其他服务运行**
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose build pyapp
|
docker-compose build pyapp
|
||||||
```
|
```
|
||||||
|
|
||||||
启动容器并进入bash
|
启动容器并进入bash
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker compose run --rm -it pyapp /bin/bash
|
docker compose run --rm -it pyapp /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
运行脚本
|
运行脚本
|
||||||
|
|
||||||
```
|
```text
|
||||||
python typecho_markdown_upload/main.py
|
python typecho_markdown_upload/main.py
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -889,7 +889,7 @@ python typecho_markdown_upload/main.py
|
|||||||
|
|
||||||
**更新并重启容器**
|
**更新并重启容器**
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose up --build -d
|
docker-compose up --build -d
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -901,40 +901,40 @@ docker-compose up --build -d
|
|||||||
|
|
||||||
**查看服务的日志输出**
|
**查看服务的日志输出**
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose logs flask_app --since 1h #只显示最近 1 小时
|
docker-compose logs flask_app --since 1h #只显示最近 1 小时
|
||||||
```
|
```
|
||||||
|
|
||||||
**停止并删除所有由 docker-compose 启动的容器、网络等(默认不影响挂载卷)。**
|
**停止并删除所有由 docker-compose 启动的容器、网络等(默认不影响挂载卷)。**
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose down #不能单独指定
|
docker-compose down #不能单独指定
|
||||||
```
|
```
|
||||||
|
|
||||||
**删除停止的容器**
|
**删除停止的容器**
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose rm
|
docker-compose rm
|
||||||
docker-compose rm flask_app
|
docker-compose rm flask_app
|
||||||
```
|
```
|
||||||
|
|
||||||
**停止运行的容器**
|
**停止运行的容器**
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose stop
|
docker-compose stop
|
||||||
docker-compose stop flask_app #指定某个服务
|
docker-compose stop flask_app #指定某个服务
|
||||||
```
|
```
|
||||||
|
|
||||||
**启动服务**
|
**启动服务**
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose start #启动所有停止的..
|
docker-compose start #启动所有停止的..
|
||||||
docker-compose start flask_app
|
docker-compose start flask_app
|
||||||
```
|
```
|
||||||
|
|
||||||
**重启服务(停止+启动)**
|
**重启服务(停止+启动)**
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose restart
|
docker-compose restart
|
||||||
docker-compose restart flask_app #指定某个服务
|
docker-compose restart flask_app #指定某个服务
|
||||||
```
|
```
|
||||||
@ -953,13 +953,13 @@ docker-compose up生成的容器名默认是 `项目名_服务名_索引号`
|
|||||||
|
|
||||||
如
|
如
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose -p my_custom_project up -d
|
docker-compose -p my_custom_project up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
在docker-compose.yml中指定容器名
|
在docker-compose.yml中指定容器名
|
||||||
|
|
||||||
```
|
```text
|
||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
@ -986,7 +986,7 @@ services:
|
|||||||
|
|
||||||
一个**基础镜像可以构造多个容器**,互不影响,
|
一个**基础镜像可以构造多个容器**,互不影响,
|
||||||
|
|
||||||
```
|
```text
|
||||||
db:
|
db:
|
||||||
image: mysql:8.0
|
image: mysql:8.0
|
||||||
environment:
|
environment:
|
||||||
@ -998,7 +998,7 @@ db:
|
|||||||
- db_data_project1:/var/lib/mysql
|
- db_data_project1:/var/lib/mysql
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
db:
|
db:
|
||||||
image: mysql:8.0
|
image: mysql:8.0
|
||||||
environment:
|
environment:
|
||||||
@ -1036,13 +1036,13 @@ db:
|
|||||||
|
|
||||||
1.创建一个 Docker 网络
|
1.创建一个 Docker 网络
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker network create my_shared_network
|
docker network create my_shared_network
|
||||||
```
|
```
|
||||||
|
|
||||||
2.创建 MySQL 的 `docker-compose-mysql.yml`
|
2.创建 MySQL 的 `docker-compose-mysql.yml`
|
||||||
|
|
||||||
```
|
```text
|
||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
mysql:
|
mysql:
|
||||||
@ -1063,7 +1063,7 @@ networks:
|
|||||||
|
|
||||||
3.在 `docker-compose-app.yml` 里连接这个 MySQL
|
3.在 `docker-compose-app.yml` 里连接这个 MySQL
|
||||||
|
|
||||||
```
|
```text
|
||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
web_app:
|
web_app:
|
||||||
@ -1100,13 +1100,13 @@ networks:
|
|||||||
|
|
||||||
4.启动 MySQL 容器
|
4.启动 MySQL 容器
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose -f docker-compose-mysql.yml up -d
|
docker-compose -f docker-compose-mysql.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
5.启动 Web 应用
|
5.启动 Web 应用
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker-compose -f docker-compose-app.yml up -d
|
docker-compose -f docker-compose-app.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@
|
|||||||
|
|
||||||
这里使用了第二种CSS引入方式,内嵌样式,<style>包裹,里面用了三种CSS选择器
|
这里使用了第二种CSS引入方式,内嵌样式,<style>包裹,里面用了三种CSS选择器
|
||||||
|
|
||||||
```
|
```text
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@ -221,7 +221,7 @@ box-sizing: border-box,此时指定width height为盒子的高宽,而不是c
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@ -386,7 +386,7 @@ function 函数名(参数1,参数2..){
|
|||||||
|
|
||||||
如下示例:
|
如下示例:
|
||||||
|
|
||||||
```
|
```text
|
||||||
function add(a, b){
|
function add(a, b){
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
@ -398,7 +398,7 @@ var result=add(10,20)可以接收返回值
|
|||||||
|
|
||||||
第二种可以通过var去定义函数的名字,具体格式如下:
|
第二种可以通过var去定义函数的名字,具体格式如下:
|
||||||
|
|
||||||
```
|
```text
|
||||||
var functionName = function (参数1,参数2..){
|
var functionName = function (参数1,参数2..){
|
||||||
//要执行的代码
|
//要执行的代码
|
||||||
}
|
}
|
||||||
@ -406,7 +406,7 @@ var functionName = function (参数1,参数2..){
|
|||||||
|
|
||||||
如下示例:
|
如下示例:
|
||||||
|
|
||||||
```
|
```text
|
||||||
var add = function(a,b){
|
var add = function(a,b){
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
@ -464,7 +464,7 @@ var arr = [1,2,3,4]; //1,2,3,4 是存储在数组中的数据(元素)
|
|||||||
|
|
||||||
普通for循环:会遍历每个数组元素,无论是否有值
|
普通for循环:会遍历每个数组元素,无论是否有值
|
||||||
|
|
||||||
```
|
```text
|
||||||
var arr = [1,2,3,4];
|
var arr = [1,2,3,4];
|
||||||
arr[10] = 50;
|
arr[10] = 50;
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i = 0; i < arr.length; i++) {
|
||||||
@ -474,7 +474,7 @@ arr[10] = 50;
|
|||||||
|
|
||||||
foreach:
|
foreach:
|
||||||
|
|
||||||
```
|
```text
|
||||||
arr.forEach(function(e){
|
arr.forEach(function(e){
|
||||||
console.log(e);
|
console.log(e);
|
||||||
})
|
})
|
||||||
@ -482,7 +482,7 @@ arr.forEach(function(e){
|
|||||||
|
|
||||||
在ES6中,引入箭头函数的写法,语法类似java中lambda表达式,修改上述代码如下:
|
在ES6中,引入箭头函数的写法,语法类似java中lambda表达式,修改上述代码如下:
|
||||||
|
|
||||||
```
|
```text
|
||||||
arr.forEach((e) => {
|
arr.forEach((e) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
})
|
})
|
||||||
@ -563,7 +563,7 @@ String对象也提供了一些常用的属性和方法,如下表格所示:
|
|||||||
|
|
||||||
##### 自定义对象
|
##### 自定义对象
|
||||||
|
|
||||||
```
|
```text
|
||||||
var 对象名 = {
|
var 对象名 = {
|
||||||
属性名1: 属性值1,
|
属性名1: 属性值1,
|
||||||
属性名2: 属性值2,
|
属性名2: 属性值2,
|
||||||
@ -600,7 +600,7 @@ JSON对象:**J**ava**S**cript **O**bject **N**otation,JavaScript对象标记
|
|||||||
|
|
||||||
JSON字符串示例:
|
JSON字符串示例:
|
||||||
|
|
||||||
```
|
```text
|
||||||
var jsonstr = '{"name":"Tom", "age":18, "addr":["北京","上海","西安"]}';
|
var jsonstr = '{"name":"Tom", "age":18, "addr":["北京","上海","西安"]}';
|
||||||
alert(jsonstr.name);
|
alert(jsonstr.name);
|
||||||
```
|
```
|
||||||
@ -609,7 +609,7 @@ alert(jsonstr.name);
|
|||||||
|
|
||||||
JSON字符串=》JS对象
|
JSON字符串=》JS对象
|
||||||
|
|
||||||
```
|
```text
|
||||||
var obj = JSON.parse(jsonstr);
|
var obj = JSON.parse(jsonstr);
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -617,7 +617,7 @@ var obj = JSON.parse(jsonstr);
|
|||||||
|
|
||||||
JS对象=》JS字符串
|
JS对象=》JS字符串
|
||||||
|
|
||||||
```
|
```text
|
||||||
var jsonstr=JSON.stringify(obj)
|
var jsonstr=JSON.stringify(obj)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -646,7 +646,7 @@ fn:函数,需要周期性执行的功能代码
|
|||||||
|
|
||||||
毫秒值:间隔时间
|
毫秒值:间隔时间
|
||||||
|
|
||||||
```
|
```text
|
||||||
//定时器 - setInterval -- 周期性的执行某一个函数
|
//定时器 - setInterval -- 周期性的执行某一个函数
|
||||||
var i = 0;
|
var i = 0;
|
||||||
setInterval(function(){
|
setInterval(function(){
|
||||||
@ -676,7 +676,7 @@ setTimeout(function(){
|
|||||||
|
|
||||||
location是指代浏览器的地址栏对象,对于这个对象,我们常用的是href**属性**,用于获取或者设置浏览器的地址信息,添加如下代码:
|
location是指代浏览器的地址栏对象,对于这个对象,我们常用的是href**属性**,用于获取或者设置浏览器的地址信息,添加如下代码:
|
||||||
|
|
||||||
```
|
```text
|
||||||
//获取浏览器地址栏信息
|
//获取浏览器地址栏信息
|
||||||
alert(location.href);
|
alert(location.href);
|
||||||
//设置浏览器地址栏信息
|
//设置浏览器地址栏信息
|
||||||
@ -723,7 +723,7 @@ DOM:Document Object Model 文档对象模型。也就是 JavaScript 将 HTML
|
|||||||
|
|
||||||
示例代码:
|
示例代码:
|
||||||
|
|
||||||
```
|
```text
|
||||||
<body>
|
<body>
|
||||||
<img id="h1" src="img/off.gif"> <br><br>
|
<img id="h1" src="img/off.gif"> <br><br>
|
||||||
|
|
||||||
@ -738,7 +738,7 @@ DOM:Document Object Model 文档对象模型。也就是 JavaScript 将 HTML
|
|||||||
|
|
||||||
- document.getElementById(): 根据标签的id属性获取标签对象,id是唯一的,所以获取到是单个标签对象。
|
- document.getElementById(): 根据标签的id属性获取标签对象,id是唯一的,所以获取到是单个标签对象。
|
||||||
|
|
||||||
```
|
```text
|
||||||
<script>
|
<script>
|
||||||
//1. 获取Element元素
|
//1. 获取Element元素
|
||||||
|
|
||||||
@ -750,7 +750,7 @@ DOM:Document Object Model 文档对象模型。也就是 JavaScript 将 HTML
|
|||||||
|
|
||||||
- document.getElementsByTagName() : 根据标签的名字获取标签对象,同名的标签有很多,所以返回值是数组。<font color=red>重点!</font>
|
- document.getElementsByTagName() : 根据标签的名字获取标签对象,同名的标签有很多,所以返回值是数组。<font color=red>重点!</font>
|
||||||
|
|
||||||
```
|
```text
|
||||||
var divs = document.getElementsByTagName('div');
|
var divs = document.getElementsByTagName('div');
|
||||||
for (let i = 0; i < divs.length; i++) {
|
for (let i = 0; i < divs.length; i++) {
|
||||||
alert(divs[i]);
|
alert(divs[i]);
|
||||||
@ -765,7 +765,7 @@ for (let i = 0; i < divs.length; i++) {
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
```
|
```text
|
||||||
var divs = document.getElementsByClassName('cls');
|
var divs = document.getElementsByClassName('cls');
|
||||||
var div1 = divs[0];
|
var div1 = divs[0];
|
||||||
div1.innerHTML = "传智教育666";
|
div1.innerHTML = "传智教育666";
|
||||||
@ -777,7 +777,7 @@ JavaScript对于事件的绑定提供了2种方式:
|
|||||||
|
|
||||||
- 方式1:通过html标签中的事件属性进行绑定
|
- 方式1:通过html标签中的事件属性进行绑定
|
||||||
|
|
||||||
```
|
```text
|
||||||
<input type="button" id="btn1" value="事件绑定1" onclick="on()">
|
<input type="button" id="btn1" value="事件绑定1" onclick="on()">
|
||||||
<script>
|
<script>
|
||||||
function on(){
|
function on(){
|
||||||
@ -788,7 +788,7 @@ JavaScript对于事件的绑定提供了2种方式:
|
|||||||
|
|
||||||
- 方式2:通过DOM中Element元素的事件属性进行绑定
|
- 方式2:通过DOM中Element元素的事件属性进行绑定
|
||||||
|
|
||||||
```
|
```text
|
||||||
<input type="button" id="btn2" value="事件绑定2">
|
<input type="button" id="btn2" value="事件绑定2">
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('btn2').onclick = function(){
|
document.getElementById('btn2').onclick = function(){
|
||||||
@ -831,13 +831,13 @@ MVVM:其实是Model-View-ViewModel的缩写,有3个单词,具体释义如下
|
|||||||
|
|
||||||
第二步:然后编写<script>标签来引入vue.js文件,代码如下:
|
第二步:然后编写<script>标签来引入vue.js文件,代码如下:
|
||||||
|
|
||||||
```
|
```text
|
||||||
<script src="js/vue.js"></script>
|
<script src="js/vue.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
第三步:在js代码区域定义vue对象,代码如下:
|
第三步:在js代码区域定义vue对象,代码如下:
|
||||||
|
|
||||||
```
|
```text
|
||||||
<script>
|
<script>
|
||||||
//定义Vue对象
|
//定义Vue对象
|
||||||
new Vue({
|
new Vue({
|
||||||
@ -894,7 +894,7 @@ MVVM:其实是Model-View-ViewModel的缩写,有3个单词,具体释义如下
|
|||||||
|
|
||||||
data属性中数据变化,我们知道可以通过赋值来改变,但是视图数据为什么会发生变化呢?**只有表单项标签!所以双向绑定一定是使用在表单项标签上的**。
|
data属性中数据变化,我们知道可以通过赋值来改变,但是视图数据为什么会发生变化呢?**只有表单项标签!所以双向绑定一定是使用在表单项标签上的**。
|
||||||
|
|
||||||
```
|
```text
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<a v-bind:href="url">链接1</a>
|
<a v-bind:href="url">链接1</a>
|
||||||
@ -917,19 +917,19 @@ data属性中数据变化,我们知道可以通过赋值来改变,但是视
|
|||||||
|
|
||||||
v-on: 用来给html标签绑定事件的
|
v-on: 用来给html标签绑定事件的
|
||||||
|
|
||||||
```
|
```text
|
||||||
<input type="button" value="点我一下" v-on:click="handle()">
|
<input type="button" value="点我一下" v-on:click="handle()">
|
||||||
```
|
```
|
||||||
|
|
||||||
简写:
|
简写:
|
||||||
|
|
||||||
```
|
```text
|
||||||
<input type="button" value="点我一下" @click="handle()">
|
<input type="button" value="点我一下" @click="handle()">
|
||||||
```
|
```
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
|
||||||
```
|
```text
|
||||||
<script>
|
<script>
|
||||||
//定义Vue对象
|
//定义Vue对象
|
||||||
new Vue({
|
new Vue({
|
||||||
@ -948,14 +948,14 @@ script:
|
|||||||
|
|
||||||
#### v-if和v-show
|
#### v-if和v-show
|
||||||
|
|
||||||
```
|
```text
|
||||||
年龄<input type="text" v-model="age">经判定,为:
|
年龄<input type="text" v-model="age">经判定,为:
|
||||||
<span v-if="age <= 35">年轻人(35及以下)</span>
|
<span v-if="age <= 35">年轻人(35及以下)</span>
|
||||||
<span v-else-if="age > 35 && age < 60">中年人(35-60)</span>
|
<span v-else-if="age > 35 && age < 60">中年人(35-60)</span>
|
||||||
<span v-else>老年人(60及以上)</span>
|
<span v-else>老年人(60及以上)</span>
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
年龄<input type="text" v-model="age">经判定,为:
|
年龄<input type="text" v-model="age">经判定,为:
|
||||||
<span v-show="age <= 35">年轻人(35及以下)</span>
|
<span v-show="age <= 35">年轻人(35及以下)</span>
|
||||||
<span v-show="age > 35 && age < 60">中年人(35-60)</span>
|
<span v-show="age > 35 && age < 60">中年人(35-60)</span>
|
||||||
@ -968,7 +968,7 @@ v-show和v-if的作用效果是一样的,只是原理不一样。v-if指令,
|
|||||||
|
|
||||||
v-for: 从名字我们就能看出,这个指令是用来遍历的。其语法格式如下:
|
v-for: 从名字我们就能看出,这个指令是用来遍历的。其语法格式如下:
|
||||||
|
|
||||||
```
|
```text
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<div v-for="addr in addrs">{{addr}}</div>
|
<div v-for="addr in addrs">{{addr}}</div>
|
||||||
<hr>
|
<hr>
|
||||||
@ -976,7 +976,7 @@ v-for: 从名字我们就能看出,这个指令是用来遍历的。其语法
|
|||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
<script>
|
<script>
|
||||||
//定义Vue对象
|
//定义Vue对象
|
||||||
new Vue({
|
new Vue({
|
||||||
@ -1068,13 +1068,13 @@ Axios的使用比较简单,主要分为2步:
|
|||||||
| axios.post(url [, data[, config]]) | 发送post请求 |
|
| axios.post(url [, data[, config]]) | 发送post请求 |
|
||||||
| axios.put(url [, data[, config]]) | 发送put请求 |
|
| axios.put(url [, data[, config]]) | 发送put请求 |
|
||||||
|
|
||||||
```
|
```text
|
||||||
axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then(result => {
|
axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then(result => {
|
||||||
console.log(result.data);
|
console.log(result.data);
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
axios.post("http://yapi.smart-xwork.cn/mock/169327/emp/deleteById","id=1").then(result => {
|
axios.post("http://yapi.smart-xwork.cn/mock/169327/emp/deleteById","id=1").then(result => {
|
||||||
console.log(result.data);
|
console.log(result.data);
|
||||||
})
|
})
|
||||||
@ -1089,7 +1089,7 @@ axios.post("http://yapi.smart-xwork.cn/mock/169327/emp/deleteById","id=1").then(
|
|||||||
3. 拿到数据,数据需要绑定给vue的data属性
|
3. 拿到数据,数据需要绑定给vue的data属性
|
||||||
4. 在<tr>标签上通过v-for指令遍历数据,展示数据,这里同Vue中的步骤。
|
4. 在<tr>标签上通过v-for指令遍历数据,展示数据,这里同Vue中的步骤。
|
||||||
|
|
||||||
```
|
```text
|
||||||
<script>
|
<script>
|
||||||
new Vue({
|
new Vue({
|
||||||
el: "#app",
|
el: "#app",
|
||||||
|
@ -99,7 +99,7 @@ IDEA 会自动解析 `pom.xml`,下载依赖并构建项目结构。
|
|||||||
|
|
||||||
1.新建一个上层目录,如下,MyProject1和MyProject2的内容拷贝过去。
|
1.新建一个上层目录,如下,MyProject1和MyProject2的内容拷贝过去。
|
||||||
|
|
||||||
```
|
```text
|
||||||
ParentProject/
|
ParentProject/
|
||||||
├── pom.xml <-- 父模块(聚合模块)
|
├── pom.xml <-- 父模块(聚合模块)
|
||||||
├── MyProject1/ <-- 子模块1
|
├── MyProject1/ <-- 子模块1
|
||||||
@ -112,7 +112,7 @@ ParentProject/
|
|||||||
|
|
||||||
父模块 `pom.xml` 示例:
|
父模块 `pom.xml` 示例:
|
||||||
|
|
||||||
```
|
```text
|
||||||
<project>
|
<project>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.example</groupId>
|
<groupId>com.example</groupId>
|
||||||
@ -130,7 +130,7 @@ ParentProject/
|
|||||||
|
|
||||||
3.修改子模块 `pom.xml` ,加上:
|
3.修改子模块 `pom.xml` ,加上:
|
||||||
|
|
||||||
```
|
```text
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.example</groupId>
|
<groupId>com.example</groupId>
|
||||||
<artifactId>ParentProject</artifactId>
|
<artifactId>ParentProject</artifactId>
|
||||||
@ -155,7 +155,7 @@ ParentProject/
|
|||||||
|
|
||||||
在第二个项目的 `pom.xml` 中添加依赖坐标
|
在第二个项目的 `pom.xml` 中添加依赖坐标
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.example</groupId>
|
<groupId>com.example</groupId>
|
||||||
<artifactId>my-first-project</artifactId>
|
<artifactId>my-first-project</artifactId>
|
||||||
@ -181,7 +181,7 @@ Maven 重建
|
|||||||
|
|
||||||
可以到mvn的中央仓库(https://mvnrepository.com/)中搜索获取依赖的坐标信息
|
可以到mvn的中央仓库(https://mvnrepository.com/)中搜索获取依赖的坐标信息
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- 第1个依赖 : logback -->
|
<!-- 第1个依赖 : logback -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -207,7 +207,7 @@ Maven 重建
|
|||||||
|
|
||||||
A依赖B,B依赖C,如果A不想将C依赖进来,可以同时排除C,被排除的资源**无需指定版本**。
|
A依赖B,B依赖C,如果A不想将C依赖进来,可以同时排除C,被排除的资源**无需指定版本**。
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.itheima</groupId>
|
<groupId>com.itheima</groupId>
|
||||||
<artifactId>maven-projectB</artifactId>
|
<artifactId>maven-projectB</artifactId>
|
||||||
@ -254,7 +254,7 @@ A依赖B,B依赖C,如果A不想将C依赖进来,可以同时排除C,被
|
|||||||
|
|
||||||
1. 导入依赖junit
|
1. 导入依赖junit
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
@ -267,7 +267,7 @@ A依赖B,B依赖C,如果A不想将C依赖进来,可以同时排除C,被
|
|||||||
|
|
||||||
3. 创建test方法
|
3. 创建test方法
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Test
|
@Test
|
||||||
public void test1(){
|
public void test1(){
|
||||||
System.out.println("hello1");
|
System.out.println("hello1");
|
||||||
@ -326,7 +326,7 @@ A依赖B,B依赖C,如果A不想将C依赖进来,可以同时排除C,被
|
|||||||
|
|
||||||
新建HelloController类
|
新建HelloController类
|
||||||
|
|
||||||
```
|
```text
|
||||||
package edu.whut.controller;
|
package edu.whut.controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@ -343,7 +343,7 @@ public class HelloController {
|
|||||||
|
|
||||||
然后启动服务器,main程序
|
然后启动服务器,main程序
|
||||||
|
|
||||||
```
|
```text
|
||||||
package edu.whut;
|
package edu.whut;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
@ -369,7 +369,7 @@ public class SprintbootQuickstartApplication {
|
|||||||
|
|
||||||
- 在Springboot的环境中,对原始的API进行了封装,接收参数的形式更加简单。 如果是简单参数,参数名与形参变量名相同,定义同名的形参即可接收参数。
|
- 在Springboot的环境中,对原始的API进行了封装,接收参数的形式更加简单。 如果是简单参数,参数名与形参变量名相同,定义同名的形参即可接收参数。
|
||||||
|
|
||||||
```
|
```text
|
||||||
@RestController
|
@RestController
|
||||||
public class RequestController {
|
public class RequestController {
|
||||||
// http://localhost:8080/simpleParam?name=Tom&age=10
|
// http://localhost:8080/simpleParam?name=Tom&age=10
|
||||||
@ -391,7 +391,7 @@ public class RequestController {
|
|||||||
|
|
||||||
在方法形参前面加上 @RequestParam 然后通过value属性执行请求参数名,从而完成映射。代码如下:
|
在方法形参前面加上 @RequestParam 然后通过value属性执行请求参数名,从而完成映射。代码如下:
|
||||||
|
|
||||||
```
|
```text
|
||||||
@RestController
|
@RestController
|
||||||
public class RequestController {
|
public class RequestController {
|
||||||
// http://localhost:8080/simpleParam?name=Tom&age=20
|
// http://localhost:8080/simpleParam?name=Tom&age=20
|
||||||
@ -418,7 +418,7 @@ public class RequestController {
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
```
|
```text
|
||||||
@RequestMapping("/complexpojo")
|
@RequestMapping("/complexpojo")
|
||||||
public String complexpojo(User user){
|
public String complexpojo(User user){
|
||||||
System.out.println(user);
|
System.out.println(user);
|
||||||
@ -426,7 +426,7 @@ public class RequestController {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ -437,7 +437,7 @@ public class User {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
package edu.whut.pojo;
|
package edu.whut.pojo;
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ -452,7 +452,7 @@ public class Address {
|
|||||||
|
|
||||||
数组参数:**请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数**
|
数组参数:**请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数**
|
||||||
|
|
||||||
```
|
```text
|
||||||
@RestController
|
@RestController
|
||||||
public class RequestController {
|
public class RequestController {
|
||||||
//数组集合参数
|
//数组集合参数
|
||||||
@ -470,7 +470,7 @@ public class RequestController {
|
|||||||
|
|
||||||
json数组:
|
json数组:
|
||||||
|
|
||||||
```
|
```text
|
||||||
{
|
{
|
||||||
"退还时间点": [
|
"退还时间点": [
|
||||||
"与中标人签订合同后 5日内",
|
"与中标人签订合同后 5日内",
|
||||||
@ -513,7 +513,7 @@ Postman发送JSON格式数据:
|
|||||||
- 传递json格式的参数,在Controller中会使用实体类进行封装。
|
- 传递json格式的参数,在Controller中会使用实体类进行封装。
|
||||||
- 封装规则:**JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数。需要使用 @RequestBody标识。**
|
- 封装规则:**JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数。需要使用 @RequestBody标识。**
|
||||||
|
|
||||||
```
|
```text
|
||||||
@RestController
|
@RestController
|
||||||
public class RequestController {
|
public class RequestController {
|
||||||
//JSON参数
|
//JSON参数
|
||||||
@ -532,7 +532,7 @@ public class RequestController {
|
|||||||
//把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)
|
//把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)
|
||||||
String json = JSONObject.toJSONString(responseResult);
|
String json = JSONObject.toJSONString(responseResult);
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba</groupId>
|
<groupId>com.alibaba</groupId>
|
||||||
<artifactId>fastjson</artifactId>
|
<artifactId>fastjson</artifactId>
|
||||||
@ -553,7 +553,7 @@ http://localhost:880/user/1/0
|
|||||||
|
|
||||||
上述的这种传递请求参数的形式呢,我们称之为:路径参数。
|
上述的这种传递请求参数的形式呢,我们称之为:路径参数。
|
||||||
|
|
||||||
```
|
```text
|
||||||
@RestController
|
@RestController
|
||||||
public class RequestController {
|
public class RequestController {
|
||||||
//路径参数
|
//路径参数
|
||||||
@ -595,7 +595,7 @@ public class RequestController {
|
|||||||
|
|
||||||
定义在一个实体类Result来包含以上信息。代码如下:
|
定义在一个实体类Result来包含以上信息。代码如下:
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ -631,7 +631,7 @@ Controller层接收请求,调用Service层;Service层先调用Dao层获取
|
|||||||
|
|
||||||
**但是**,这样每次要更换ServiceA->ServiceB时,需要修改Controller层的代码!
|
**但是**,这样每次要更换ServiceA->ServiceB时,需要修改Controller层的代码!
|
||||||
|
|
||||||
```
|
```text
|
||||||
private EmpService empService=new EmpServiceA(); //原来
|
private EmpService empService=new EmpServiceA(); //原来
|
||||||
private EmpService empService=new EmpServiceB(); //现在
|
private EmpService empService=new EmpServiceB(); //现在
|
||||||
```
|
```
|
||||||
@ -697,7 +697,7 @@ Component衍生注解
|
|||||||
|
|
||||||
1. `@RequestMapping("/jsonParam")`:这是一个控制器方法级别的注解,用于将HTTP请求映射到相应的处理方法上。在这个例子中,它表示当收到路径为 "/jsonParam" 的HTTP请求时,应该调用这个方法来处理请求。`@RequestMapping` 注解可以用来指定路径、HTTP方法、请求参数等信息,以便Spring框架能够正确地将请求分发到对应的处理方法上。
|
1. `@RequestMapping("/jsonParam")`:这是一个控制器方法级别的注解,用于将HTTP请求映射到相应的处理方法上。在这个例子中,它表示当收到路径为 "/jsonParam" 的HTTP请求时,应该调用这个方法来处理请求。`@RequestMapping` 注解可以用来指定路径、HTTP方法、请求参数等信息,以便Spring框架能够正确地将请求分发到对应的处理方法上。
|
||||||
|
|
||||||
```
|
```text
|
||||||
@RequestMapping("/jsonParam")
|
@RequestMapping("/jsonParam")
|
||||||
public String jsonParam(@RequestBody User user){
|
public String jsonParam(@RequestBody User user){
|
||||||
System.out.println(user);
|
System.out.println(user);
|
||||||
@ -714,7 +714,7 @@ Component衍生注解
|
|||||||
|
|
||||||
4. `@PathVariable` 注解用于将路径变量 `{id}` 的值绑定到方法的参数 `id` 上。当请求的路径是 "/path/123" 时,`@PathVariable` 会将路径中的 "123" 值绑定到方法的参数 `id` 上,使得方法能够获取到这个值。在这个例子中,方法的参数 `id` 的值将会是整数值 123。
|
4. `@PathVariable` 注解用于将路径变量 `{id}` 的值绑定到方法的参数 `id` 上。当请求的路径是 "/path/123" 时,`@PathVariable` 会将路径中的 "123" 值绑定到方法的参数 `id` 上,使得方法能够获取到这个值。在这个例子中,方法的参数 `id` 的值将会是整数值 123。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public String pathParam(@PathVariable Integer id) {
|
public String pathParam(@PathVariable Integer id) {
|
||||||
System.out.println(id);
|
System.out.println(id);
|
||||||
return "OK";
|
return "OK";
|
||||||
@ -728,11 +728,11 @@ Component衍生注解
|
|||||||
|
|
||||||
5. `@RequestParam`,如果方法的参数名与请求参数名不同,需要在 `@RequestParam` 注解中指定请求参数的名字。
|
5. `@RequestParam`,如果方法的参数名与请求参数名不同,需要在 `@RequestParam` 注解中指定请求参数的名字。
|
||||||
|
|
||||||
```
|
```text
|
||||||
@RequestParam(defaultValue = "1" Integer page) //若page为null,可以设置page的默认值为1
|
@RequestParam(defaultValue = "1" Integer page) //若page为null,可以设置page的默认值为1
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
@RequestMapping("/example")
|
@RequestMapping("/example")
|
||||||
public String exampleMethod(@RequestParam String name, @RequestParam("age") int userAge) {
|
public String exampleMethod(@RequestParam String name, @RequestParam("age") int userAge) {
|
||||||
// 在方法内部使用获取到的参数值进行处理
|
// 在方法内部使用获取到的参数值进行处理
|
||||||
@ -770,7 +770,7 @@ Component衍生注解
|
|||||||
| @AllArgsConstructor | 为实体类生成除了static修饰的字段之外带有各参数的构造器方法。 |
|
| @AllArgsConstructor | 为实体类生成除了static修饰的字段之外带有各参数的构造器方法。 |
|
||||||
| **@Slf4j** | 可以log.info("输出日志信息"); |
|
| **@Slf4j** | 可以log.info("输出日志信息"); |
|
||||||
|
|
||||||
```
|
```text
|
||||||
//equals 方法用于比较两个对象的内容是否相同
|
//equals 方法用于比较两个对象的内容是否相同
|
||||||
Address addr1 = new Address("SomeProvince", "SomeCity");
|
Address addr1 = new Address("SomeProvince", "SomeCity");
|
||||||
Address addr2 = new Address("SomeProvince", "SomeCity");
|
Address addr2 = new Address("SomeProvince", "SomeCity");
|
||||||
@ -816,7 +816,7 @@ http://localhost:8080/user/deleteUser?id=1 GET:删除id为1的用户
|
|||||||
|
|
||||||
**基于REST风格URL如下:**
|
**基于REST风格URL如下:**
|
||||||
|
|
||||||
```
|
```text
|
||||||
http://localhost:8080/users/1 GET:查询id为1的用户
|
http://localhost:8080/users/1 GET:查询id为1的用户
|
||||||
http://localhost:8080/users POST:新增用户
|
http://localhost:8080/users POST:新增用户
|
||||||
http://localhost:8080/users PUT:修改用户
|
http://localhost:8080/users PUT:修改用户
|
||||||
@ -869,7 +869,7 @@ http://localhost:8080/users/1 DELETE:删除id为1的用户
|
|||||||
|
|
||||||
2. 在springboot项目中,可以编写main/resources/application.properties文件,配置数据库连接信息。
|
2. 在springboot项目中,可以编写main/resources/application.properties文件,配置数据库连接信息。
|
||||||
|
|
||||||
```
|
```text
|
||||||
#驱动类名称
|
#驱动类名称
|
||||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||||
#数据库连接的url
|
#数据库连接的url
|
||||||
@ -890,7 +890,7 @@ spring.datasource.password=1234
|
|||||||
|
|
||||||
@Select注解:代表的就是select查询,用于书写select查询语句
|
@Select注解:代表的就是select查询,用于书写select查询语句
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface UserMapper {
|
public interface UserMapper {
|
||||||
//查询所有用户数据
|
//查询所有用户数据
|
||||||
@ -926,7 +926,7 @@ Lombok是一个实用的Java类库,可以通过简单的注解来简化和消
|
|||||||
|
|
||||||
**使用**
|
**使用**
|
||||||
|
|
||||||
```
|
```text
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ -947,7 +947,7 @@ public class User {
|
|||||||
|
|
||||||
2. 开启mybatis的日志,并指定输出到控制台
|
2. 开启mybatis的日志,并指定输出到控制台
|
||||||
|
|
||||||
```
|
```text
|
||||||
#指定mybatis输出日志的位置, 输出控制台
|
#指定mybatis输出日志的位置, 输出控制台
|
||||||
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
|
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
```
|
```
|
||||||
@ -962,7 +962,7 @@ mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
|
|||||||
|
|
||||||
**作用于单个字段**
|
**作用于单个字段**
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface EmpMapper {
|
public interface EmpMapper {
|
||||||
//SQL语句中的id值不能写成固定数值,需要变为动态的数值
|
//SQL语句中的id值不能写成固定数值,需要变为动态的数值
|
||||||
@ -984,7 +984,7 @@ public interface EmpMapper {
|
|||||||
|
|
||||||
**作用于多个字段**
|
**作用于多个字段**
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface EmpMapper {
|
public interface EmpMapper {
|
||||||
//会自动将生成的主键值,赋值给emp对象的id属性
|
//会自动将生成的主键值,赋值给emp对象的id属性
|
||||||
@ -1043,7 +1043,7 @@ eg:通过页面原型以及需求描述我们要实现的查询:
|
|||||||
|
|
||||||
解决方案:
|
解决方案:
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface EmpMapper {
|
public interface EmpMapper {
|
||||||
|
|
||||||
@ -1093,7 +1093,7 @@ public interface EmpMapper {
|
|||||||
<mapper namespace="edu.whut.mapper.EmpMapper">
|
<mapper namespace="edu.whut.mapper.EmpMapper">
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
```
|
```text
|
||||||
|
|
||||||
XML映射文件的namespace属性为Mapper接口**全限定名**(包+类名)
|
XML映射文件的namespace属性为Mapper接口**全限定名**(包+类名)
|
||||||
|
|
||||||
@ -1133,7 +1133,7 @@ public interface EmpMapper {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
<select id="list" resultType="com.itheima.pojo.Emp">
|
<select id="list" resultType="com.itheima.pojo.Emp">
|
||||||
select * from emp
|
select * from emp
|
||||||
<where>
|
<where>
|
||||||
@ -1156,7 +1156,7 @@ public interface EmpMapper {
|
|||||||
|
|
||||||
mapper接口:
|
mapper接口:
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface EmpMapper {
|
public interface EmpMapper {
|
||||||
//批量删除
|
//批量删除
|
||||||
@ -1168,7 +1168,7 @@ xml:
|
|||||||
|
|
||||||
语法:
|
语法:
|
||||||
|
|
||||||
```
|
```text
|
||||||
<foreach collection="集合名称" item="集合遍历出来的元素/项" separator="每一次遍历使用的分隔符"
|
<foreach collection="集合名称" item="集合遍历出来的元素/项" separator="每一次遍历使用的分隔符"
|
||||||
open="遍历开始前拼接的片段" close="遍历结束后拼接的片段">
|
open="遍历开始前拼接的片段" close="遍历结束后拼接的片段">
|
||||||
</foreach>
|
</foreach>
|
||||||
@ -1176,7 +1176,7 @@ xml:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
<delete id="deleteByIds">
|
<delete id="deleteByIds">
|
||||||
delete from emp where id in
|
delete from emp where id in
|
||||||
<foreach collection="ids" item="id" separator="," open="(" close=")">
|
<foreach collection="ids" item="id" separator="," open="(" close=")">
|
||||||
@ -1253,7 +1253,7 @@ public PageBean page(Integer page, Integer pageSize) {
|
|||||||
|
|
||||||
4、Controller
|
4、Controller
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/emps")
|
@RequestMapping("/emps")
|
||||||
@ -1284,7 +1284,7 @@ public class EmpController {
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
```
|
```text
|
||||||
<select id="pageQuery" resultType="com.sky.entity.Employee">
|
<select id="pageQuery" resultType="com.sky.entity.Employee">
|
||||||
select * from employee
|
select * from employee
|
||||||
<where>
|
<where>
|
||||||
@ -1317,7 +1317,7 @@ public class EmpController {
|
|||||||
> - byte[] getBytes(); //获取文件内容的字节数组
|
> - byte[] getBytes(); //获取文件内容的字节数组
|
||||||
> - InputStream getInputStream(); //获取接收到的文件内容的输入流
|
> - InputStream getInputStream(); //获取接收到的文件内容的输入流
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
public class UploadController {
|
public class UploadController {
|
||||||
@ -1346,7 +1346,7 @@ public class UploadController {
|
|||||||
|
|
||||||
那么如果需要上传大文件,可以在application.properties进行如下配置:
|
那么如果需要上传大文件,可以在application.properties进行如下配置:
|
||||||
|
|
||||||
```
|
```text
|
||||||
#配置单个文件最大上传大小
|
#配置单个文件最大上传大小
|
||||||
spring.servlet.multipart.max-file-size=10MB
|
spring.servlet.multipart.max-file-size=10MB
|
||||||
|
|
||||||
@ -1390,7 +1390,7 @@ pom文件中添加如下依赖:
|
|||||||
|
|
||||||
上传文件的工具类
|
上传文件的工具类
|
||||||
|
|
||||||
```
|
```text
|
||||||
package edu.whut.utils;
|
package edu.whut.utils;
|
||||||
import com.aliyun.oss.OSS;
|
import com.aliyun.oss.OSS;
|
||||||
import com.aliyun.oss.OSSClientBuilder;
|
import com.aliyun.oss.OSSClientBuilder;
|
||||||
@ -1473,7 +1473,7 @@ public class AliOSSUtils {
|
|||||||
|
|
||||||
对象/map集合
|
对象/map集合
|
||||||
|
|
||||||
```
|
```text
|
||||||
user:
|
user:
|
||||||
name: zhangsan
|
name: zhangsan
|
||||||
age: 18
|
age: 18
|
||||||
@ -1482,7 +1482,7 @@ user:
|
|||||||
|
|
||||||
数组/List/Set集合
|
数组/List/Set集合
|
||||||
|
|
||||||
```
|
```text
|
||||||
hobby:
|
hobby:
|
||||||
- java
|
- java
|
||||||
- game
|
- game
|
||||||
@ -1495,7 +1495,7 @@ hobby:
|
|||||||
|
|
||||||
前面获取配置项中的属性值,需要通过@Value注解,有时过于繁琐!!!
|
前面获取配置项中的属性值,需要通过@Value注解,有时过于繁琐!!!
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Component
|
@Component
|
||||||
public class AliOSSUtils {
|
public class AliOSSUtils {
|
||||||
|
|
||||||
@ -1529,7 +1529,7 @@ Spring提供的简化方式套路:
|
|||||||
|
|
||||||
4. (可选)引入依赖pom.xml
|
4. (可选)引入依赖pom.xml
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
@ -1593,7 +1593,7 @@ Spring提供的简化方式套路:
|
|||||||
|
|
||||||
引入依赖
|
引入依赖
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
<artifactId>jjwt</artifactId>
|
<artifactId>jjwt</artifactId>
|
||||||
@ -1603,7 +1603,7 @@ Spring提供的简化方式套路:
|
|||||||
|
|
||||||
生成与解析:
|
生成与解析:
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class JwtUtils {
|
public class JwtUtils {
|
||||||
|
|
||||||
private static String signKey = "itheima";
|
private static String signKey = "itheima";
|
||||||
@ -1646,7 +1646,7 @@ public class JwtUtils {
|
|||||||
|
|
||||||
**令牌可以存储当前登录用户的信息:id、username等等,传入claims**
|
**令牌可以存储当前登录用户的信息:id、username等等,传入claims**
|
||||||
|
|
||||||
```
|
```text
|
||||||
Map<String, Object> claims = new HashMap<>();
|
Map<String, Object> claims = new HashMap<>();
|
||||||
claims.put("id",emp.getId());
|
claims.put("id",emp.getId());
|
||||||
claims.put("name",e.getName());
|
claims.put("name",e.getName());
|
||||||
@ -1656,7 +1656,7 @@ String jwt=JwtUtils.generateJwt(claims);
|
|||||||
|
|
||||||
**解析令牌:**
|
**解析令牌:**
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Autowired
|
@Autowired
|
||||||
private HttpServletRequest request;
|
private HttpServletRequest request;
|
||||||
|
|
||||||
@ -1684,7 +1684,7 @@ private HttpServletRequest request;
|
|||||||
|
|
||||||
1. **定义拦截器,实现HandlerInterceptor接口,并重写其所有方法**
|
1. **定义拦截器,实现HandlerInterceptor接口,并重写其所有方法**
|
||||||
|
|
||||||
```
|
```text
|
||||||
//自定义拦截器
|
//自定义拦截器
|
||||||
@Component
|
@Component
|
||||||
public class LoginCheckInterceptor implements HandlerInterceptor {
|
public class LoginCheckInterceptor implements HandlerInterceptor {
|
||||||
@ -1720,7 +1720,7 @@ public class LoginCheckInterceptor implements HandlerInterceptor {
|
|||||||
|
|
||||||
2. **注册配置拦截器,实现WebMvcConfigurer接口,并重写addInterceptors方法**
|
2. **注册配置拦截器,实现WebMvcConfigurer接口,并重写addInterceptors方法**
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebConfig implements WebMvcConfigurer {
|
public class WebConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
@ -1754,7 +1754,7 @@ addPathPatterns指定拦截路径;
|
|||||||
|
|
||||||
主要在preHandle中写逻辑
|
主要在preHandle中写逻辑
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Override //目标资源方法执行前执行。 返回true:放行 返回false:不放行
|
@Override //目标资源方法执行前执行。 返回true:放行 返回false:不放行
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
System.out.println("preHandle .... ");
|
System.out.println("preHandle .... ");
|
||||||
@ -1819,7 +1819,7 @@ addPathPatterns指定拦截路径;
|
|||||||
- 定义全局异常处理器非常简单,就是定义一个类,在类上加上一个注解**@RestControllerAdvice**,加上这个注解就代表我们定义了一个全局异常处理器。
|
- 定义全局异常处理器非常简单,就是定义一个类,在类上加上一个注解**@RestControllerAdvice**,加上这个注解就代表我们定义了一个全局异常处理器。
|
||||||
- 在全局异常处理器当中,需要定义一个方法来捕获异常,在这个方法上需要加上注解**@ExceptionHandler**。通过@ExceptionHandler注解当中的value属性来指定我们要捕获的是哪一类型的异常。
|
- 在全局异常处理器当中,需要定义一个方法来捕获异常,在这个方法上需要加上注解**@ExceptionHandler**。通过@ExceptionHandler注解当中的value属性来指定我们要捕获的是哪一类型的异常。
|
||||||
|
|
||||||
```
|
```text
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
public class GlobalExceptionHandler {
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
@ -1878,7 +1878,7 @@ logging:
|
|||||||
|
|
||||||
在@Transactional注解的后面指定一个属性**propagation**,通过 propagation 属性来指定传播行为。可以在嵌套的子事务上加入。
|
在@Transactional注解的后面指定一个属性**propagation**,通过 propagation 属性来指定传播行为。可以在嵌套的子事务上加入。
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -1905,7 +1905,7 @@ AOP英文全称:Aspect Oriented Programming(面向切面编程、面向方
|
|||||||
|
|
||||||
1. 导入依赖:在pom.xml中导入AOP的依赖
|
1. 导入依赖:在pom.xml中导入AOP的依赖
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-aop</artifactId>
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
@ -1914,7 +1914,7 @@ AOP英文全称:Aspect Oriented Programming(面向切面编程、面向方
|
|||||||
|
|
||||||
2. 编写AOP程序:针对于特定方法根据业务需要进行编程
|
2. 编写AOP程序:针对于特定方法根据业务需要进行编程
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Component
|
@Component
|
||||||
@Aspect //当前类为切面类
|
@Aspect //当前类为切面类
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -2016,7 +2016,7 @@ eg:@Order(1)
|
|||||||
|
|
||||||
execution主要根据方法的返回值、包名、类名、方法名、方法参数等信息来匹配,语法为:
|
execution主要根据方法的返回值、包名、类名、方法名、方法参数等信息来匹配,语法为:
|
||||||
|
|
||||||
```
|
```text
|
||||||
execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) throws 异常?)
|
execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) throws 异常?)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -2030,7 +2030,7 @@ execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) th
|
|||||||
|
|
||||||
eg:
|
eg:
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Before("execution(void com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer))")
|
@Before("execution(void com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer))")
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -2040,7 +2040,7 @@ eg:
|
|||||||
|
|
||||||
- `*` :单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、**任意类型的一个参数**,也可以通配包、类、方法名的一部分
|
- `*` :单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、**任意类型的一个参数**,也可以通配包、类、方法名的一部分
|
||||||
|
|
||||||
```
|
```text
|
||||||
execution(* edu.*.service.*.update*(*))
|
execution(* edu.*.service.*.update*(*))
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -2058,7 +2058,7 @@ execution(* edu.*.service.*.update*(*))
|
|||||||
|
|
||||||
1. **新建anno包,在这个包下**编写自定义注解
|
1. **新建anno包,在这个包下**编写自定义注解
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@ -2077,7 +2077,7 @@ public @interface MyLog {
|
|||||||
|
|
||||||
2. 在业务类要做为连接点的**方法上添加**自定义注解
|
2. 在业务类要做为连接点的**方法上添加**自定义注解
|
||||||
|
|
||||||
```
|
```text
|
||||||
@MyLog //自定义注解(表示:当前方法属于目标方法)
|
@MyLog //自定义注解(表示:当前方法属于目标方法)
|
||||||
public void delete(Integer id) {
|
public void delete(Integer id) {
|
||||||
//1. 删除部门
|
//1. 删除部门
|
||||||
@ -2089,7 +2089,7 @@ public @interface MyLog {
|
|||||||
|
|
||||||
3. aop切面类上使用类似如下的切面表达式:
|
3. aop切面类上使用类似如下的切面表达式:
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Before("@annotation(edu.whut.anno.MyLog)")
|
@Before("@annotation(edu.whut.anno.MyLog)")
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -2140,7 +2140,7 @@ Object[] args = joinPoint.**getArgs()**; 可以获取调用方法时传递的
|
|||||||
|
|
||||||
如果项目已经打包上线了,这个时候我们又如何来设置Java系统属性和命令行参数呢?
|
如果项目已经打包上线了,这个时候我们又如何来设置Java系统属性和命令行参数呢?
|
||||||
|
|
||||||
```
|
```text
|
||||||
java -Dserver.port=9000 -jar XXXXX.jar --server.port=10010
|
java -Dserver.port=9000 -jar XXXXX.jar --server.port=10010
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -2154,7 +2154,7 @@ java -Dserver.port=9000 -jar XXXXX.jar --server.port=10010
|
|||||||
|
|
||||||
- **@Autowired注解**:最常见的方式是使用@Autowired注解自动装配Bean。Spring会自动在其容器中查找匹配类型的Bean并注入到被@Autowired标注的字段或方法中。
|
- **@Autowired注解**:最常见的方式是使用@Autowired注解自动装配Bean。Spring会自动在其容器中查找匹配类型的Bean并注入到被@Autowired标注的字段或方法中。
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Service
|
@Service
|
||||||
public class MyService {
|
public class MyService {
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -2203,7 +2203,7 @@ class SpringbootWebConfig2ApplicationTests {
|
|||||||
- 如果要管理的bean对象来自于第三方(不是自定义的),是无法用@Component 及衍生注解声明bean的,就需要用到**@Bean**注解。
|
- 如果要管理的bean对象来自于第三方(不是自定义的),是无法用@Component 及衍生注解声明bean的,就需要用到**@Bean**注解。
|
||||||
- 如果需要定义第三方Bean时, 通常会单独定义一个**配置类**
|
- 如果需要定义第三方Bean时, 通常会单独定义一个**配置类**
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Configuration //配置类 (在配置类当中对第三方bean进行集中的配置管理)
|
@Configuration //配置类 (在配置类当中对第三方bean进行集中的配置管理)
|
||||||
public class CommonConfig {
|
public class CommonConfig {
|
||||||
|
|
||||||
@ -2256,7 +2256,7 @@ SpringBoot的自动配置就是当Spring容器启动后,一些配置类、bean
|
|||||||
|
|
||||||
**导入普通类:**
|
**导入普通类:**
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Component
|
@Component
|
||||||
public class TokenParser {
|
public class TokenParser {
|
||||||
|
|
||||||
@ -2267,7 +2267,7 @@ public class TokenParser {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中
|
@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class SpringbootWebConfig2Application {
|
public class SpringbootWebConfig2Application {
|
||||||
@ -2328,7 +2328,7 @@ public @interface EnableHeaderConfig {
|
|||||||
|
|
||||||
- 在使用时只需在启动类上加上@EnableXxxxx注解即可
|
- 在使用时只需在启动类上加上@EnableXxxxx注解即可
|
||||||
|
|
||||||
```
|
```text
|
||||||
@EnableHeaderConfig //使用第三方依赖提供的Enable开头的注解
|
@EnableHeaderConfig //使用第三方依赖提供的Enable开头的注解
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class SpringbootWebConfig2Application {
|
public class SpringbootWebConfig2Application {
|
||||||
|
112
Java/Java笔记本.md
112
Java/Java笔记本.md
@ -81,13 +81,13 @@ IDEA快捷键:
|
|||||||
|
|
||||||
2. 在 `System.out.println()` 方法中,"ln" 代表 "line",表示换行。因此,`println` 实际上是 "print line" 的缩写。这个方法会在输出文本后自动换行.
|
2. 在 `System.out.println()` 方法中,"ln" 代表 "line",表示换行。因此,`println` 实际上是 "print line" 的缩写。这个方法会在输出文本后自动换行.
|
||||||
|
|
||||||
```
|
```text
|
||||||
System.out.println("nihao "+1.3331); #Java 会自动将数值转换为字符串
|
System.out.println("nihao "+1.3331); #Java 会自动将数值转换为字符串
|
||||||
```
|
```
|
||||||
|
|
||||||
当直接打印一个没有重写 `toString()` 方法的对象时,Java 默认会调用 `Object` 类的 `toString()` 方法,其输出格式通常为:
|
当直接打印一个没有重写 `toString()` 方法的对象时,Java 默认会调用 `Object` 类的 `toString()` 方法,其输出格式通常为:
|
||||||
|
|
||||||
```
|
```text
|
||||||
java.lang.Object@15db9742
|
java.lang.Object@15db9742
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ IDEA快捷键:
|
|||||||
|
|
||||||
当打印重写`toString()` 方法的对象时:
|
当打印重写`toString()` 方法的对象时:
|
||||||
|
|
||||||
```
|
```text
|
||||||
class Person {
|
class Person {
|
||||||
private String name;
|
private String name;
|
||||||
private int age;
|
private int age;
|
||||||
@ -120,7 +120,7 @@ IDEA快捷键:
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
Person{name='Alice', age=30}
|
Person{name='Alice', age=30}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ IDEA快捷键:
|
|||||||
|
|
||||||
3. 一维数组创建:
|
3. 一维数组创建:
|
||||||
|
|
||||||
```
|
```text
|
||||||
// 方式1:先声明,再指定长度(默认值为0、null等)
|
// 方式1:先声明,再指定长度(默认值为0、null等)
|
||||||
int[] arr1 = new int[10]; // 创建一个长度为10的int数组
|
int[] arr1 = new int[10]; // 创建一个长度为10的int数组
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ IDEA快捷键:
|
|||||||
|
|
||||||
4. 字符串创建
|
4. 字符串创建
|
||||||
|
|
||||||
```
|
```text
|
||||||
String str = "Hello, World!"; //(1)直接赋值
|
String str = "Hello, World!"; //(1)直接赋值
|
||||||
|
|
||||||
String str = new String("Hello, World!"); //使用 new 关键字
|
String str = new String("Hello, World!"); //使用 new 关键字
|
||||||
@ -196,7 +196,7 @@ LocalDateTime.now(),获取当前时间
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
// 文件:com/example/PrivateExample.java
|
// 文件:com/example/PrivateExample.java
|
||||||
package com.example;
|
package com.example;
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ public class PrivateExample {
|
|||||||
|
|
||||||
修饰符不仅可以用来修饰成员变量和方法,也可以用来**修饰类**。顶级类只能使用 `public` 或默认(即不写任何修饰符,称为包访问权限)。内部类可以使用所有访问修饰符(`public`、`protected`、`private` 和默认),这使得你可以更灵活地控制嵌套类的访问范围。
|
修饰符不仅可以用来修饰成员变量和方法,也可以用来**修饰类**。顶级类只能使用 `public` 或默认(即不写任何修饰符,称为包访问权限)。内部类可以使用所有访问修饰符(`public`、`protected`、`private` 和默认),这使得你可以更灵活地控制嵌套类的访问范围。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class OuterClass {
|
public class OuterClass {
|
||||||
// 内部类使用private,只能在OuterClass内部访问
|
// 内部类使用private,只能在OuterClass内部访问
|
||||||
private class InnerPrivateClass {
|
private class InnerPrivateClass {
|
||||||
@ -258,7 +258,7 @@ public class OuterClass {
|
|||||||
|
|
||||||
用途:适用于内部类与外部类关系密切,需要频繁访问外部类成员的情况。
|
用途:适用于内部类与外部类关系密切,需要频繁访问外部类成员的情况。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class OuterClass {
|
public class OuterClass {
|
||||||
class InnerClass implements Runnable {
|
class InnerClass implements Runnable {
|
||||||
// static int count = 0; // 编译错误
|
// static int count = 0; // 编译错误
|
||||||
@ -294,7 +294,7 @@ public class OuterClass {
|
|||||||
|
|
||||||
用途:适用于只在方法或代码块中使用的类,有助于将实现细节隐藏在方法内部。
|
用途:适用于只在方法或代码块中使用的类,有助于将实现细节隐藏在方法内部。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class OuterClass {
|
public class OuterClass {
|
||||||
public void startThread() {
|
public void startThread() {
|
||||||
class LocalInnerClass implements Runnable {
|
class LocalInnerClass implements Runnable {
|
||||||
@ -327,7 +327,7 @@ public class OuterClass {
|
|||||||
|
|
||||||
用途:适合当内部类工作不依赖外部类实例时使用,常用于实现与外部类关系不那么密切的帮助类。
|
用途:适合当内部类工作不依赖外部类实例时使用,常用于实现与外部类关系不那么密切的帮助类。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class OuterClass {
|
public class OuterClass {
|
||||||
// 外部类的静态成员
|
// 外部类的静态成员
|
||||||
private static int staticVar = 10;
|
private static int staticVar = 10;
|
||||||
@ -371,7 +371,7 @@ public class OuterClass {
|
|||||||
|
|
||||||
用途:适用于创建一次性使用的实例,通常用于接口或抽象类的实现。
|
用途:适用于创建一次性使用的实例,通常用于接口或抽象类的实现。
|
||||||
|
|
||||||
```
|
```text
|
||||||
//eg1
|
//eg1
|
||||||
public class OuterClass {
|
public class OuterClass {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@ -413,7 +413,7 @@ public class GUIApp {
|
|||||||
|
|
||||||
1. 创建`ActionListener`实例
|
1. 创建`ActionListener`实例
|
||||||
|
|
||||||
```
|
```text
|
||||||
new ActionListener() {
|
new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
System.out.println("Button was clicked!");
|
System.out.println("Button was clicked!");
|
||||||
@ -432,7 +432,7 @@ new ActionListener() {
|
|||||||
|
|
||||||
2. 将匿名内部类添加为事件监听器
|
2. 将匿名内部类添加为事件监听器
|
||||||
|
|
||||||
```
|
```text
|
||||||
button.addActionListener(...);
|
button.addActionListener(...);
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ Lambda表达式特别适用于**只有单一抽象方法**的接口(也即**
|
|||||||
|
|
||||||
**`@FunctionalInterface` 注解**:这是一个可选的注解,用于表示接口是一个函数式接口。虽然不是强制的,但它可以帮助编译器识别意图,并检查接口是否确实只有一个抽象方法。
|
**`@FunctionalInterface` 注解**:这是一个可选的注解,用于表示接口是一个函数式接口。虽然不是强制的,但它可以帮助编译器识别意图,并检查接口是否确实只有一个抽象方法。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class LambdaExample {
|
public class LambdaExample {
|
||||||
// 定义函数式接口,doSomething 有两个参数
|
// 定义函数式接口,doSomething 有两个参数
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
@ -479,7 +479,7 @@ public class LambdaExample {
|
|||||||
可选的大括号:如果主体只有一个语句,可以不使用大括号。
|
可选的大括号:如果主体只有一个语句,可以不使用大括号。
|
||||||
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,使用大括号需显示retrun;如果函数是void则不需要返回值。
|
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,使用大括号需显示retrun;如果函数是void则不需要返回值。
|
||||||
|
|
||||||
```
|
```text
|
||||||
// 定义一个函数式接口
|
// 定义一个函数式接口
|
||||||
interface Calculator {
|
interface Calculator {
|
||||||
int add(int a, int b);
|
int add(int a, int b);
|
||||||
@ -507,7 +507,7 @@ public class LambdaReturnExample {
|
|||||||
|
|
||||||
`list.forEach`这个方法接受一个**函数式接口**作为参数。它只有一个抽象方法 `accept(T t)`因此,可以使用 lambda 表达式来**实现**。
|
`list.forEach`这个方法接受一个**函数式接口**作为参数。它只有一个抽象方法 `accept(T t)`因此,可以使用 lambda 表达式来**实现**。
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -536,7 +536,7 @@ public class Main {
|
|||||||
|
|
||||||
如果返回正数,则 `a` 应该排在 `b` 的后面。
|
如果返回正数,则 `a` 应该排在 `b` 的后面。
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -564,7 +564,7 @@ public class Main {
|
|||||||
|
|
||||||
**1.静态初始化块(Static Initialization Block)**
|
**1.静态初始化块(Static Initialization Block)**
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class MyClass {
|
public class MyClass {
|
||||||
static int num1, num2;
|
static int num1, num2;
|
||||||
|
|
||||||
@ -590,7 +590,7 @@ public class MyClass {
|
|||||||
|
|
||||||
输出:
|
输出:
|
||||||
|
|
||||||
```
|
```text
|
||||||
静态代码块1执行
|
静态代码块1执行
|
||||||
静态代码块2执行
|
静态代码块2执行
|
||||||
main方法执行
|
main方法执行
|
||||||
@ -603,7 +603,7 @@ main方法执行
|
|||||||
|
|
||||||
**2.在声明时直接初始化**
|
**2.在声明时直接初始化**
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class MyClass {
|
public class MyClass {
|
||||||
// 直接在声明时初始化静态成员变量
|
// 直接在声明时初始化静态成员变量
|
||||||
public static int staticVariable = 42;
|
public static int staticVariable = 42;
|
||||||
@ -614,7 +614,7 @@ public class MyClass {
|
|||||||
|
|
||||||
静态成员变量的访问不需要创建 `MyClass` 的实例,可以直接通过类名访问:
|
静态成员变量的访问不需要创建 `MyClass` 的实例,可以直接通过类名访问:
|
||||||
|
|
||||||
```
|
```text
|
||||||
int value = MyClass.staticVariable;
|
int value = MyClass.staticVariable;
|
||||||
MyClass obj = new MyClass();
|
MyClass obj = new MyClass();
|
||||||
System.out.println("obj.num1 = " + obj.staticVariable); #通过示例访问也可以
|
System.out.println("obj.num1 = " + obj.staticVariable); #通过示例访问也可以
|
||||||
@ -638,7 +638,7 @@ System.out.println("obj.num1 = " + obj.staticVariable); #通过示例访问也
|
|||||||
- 非静态成员变量。
|
- 非静态成员变量。
|
||||||
- 非静态方法(必须通过对象实例访问)。
|
- 非静态方法(必须通过对象实例访问)。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class MyClass {
|
public class MyClass {
|
||||||
private static int staticVar = 10;
|
private static int staticVar = 10;
|
||||||
private int instanceVar = 20;
|
private int instanceVar = 20;
|
||||||
@ -664,7 +664,7 @@ public class MyClass {
|
|||||||
|
|
||||||
调用静态方法:
|
调用静态方法:
|
||||||
|
|
||||||
```
|
```text
|
||||||
MyClass.staticMethod(); // 通过类名直接调用静态方法
|
MyClass.staticMethod(); // 通过类名直接调用静态方法
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -680,7 +680,7 @@ MyClass.staticMethod(); // 通过类名直接调用静态方法
|
|||||||
|
|
||||||
因为父类的成员变量和方法都是默认的访问修饰符,可以继承给子类,而子类也定义了同名的xxx,发生了**变量隐藏**(shadowing)。
|
因为父类的成员变量和方法都是默认的访问修饰符,可以继承给子类,而子类也定义了同名的xxx,发生了**变量隐藏**(shadowing)。
|
||||||
|
|
||||||
```
|
```text
|
||||||
class Parent {
|
class Parent {
|
||||||
int num = 10;
|
int num = 10;
|
||||||
void display() {
|
void display() {
|
||||||
@ -711,7 +711,7 @@ MyClass.staticMethod(); // 通过类名直接调用静态方法
|
|||||||
|
|
||||||
输出:
|
输出:
|
||||||
|
|
||||||
```
|
```text
|
||||||
Child class num: 20
|
Child class num: 20
|
||||||
Parent class num: 10
|
Parent class num: 10
|
||||||
Parent class method
|
Parent class method
|
||||||
@ -721,7 +721,7 @@ MyClass.staticMethod(); // 通过类名直接调用静态方法
|
|||||||
|
|
||||||
可以使用 `super` 关键字调用父类的构造方法。这通常在子类的构造方法中使用,用于显式地调用父类的构造方法。
|
可以使用 `super` 关键字调用父类的构造方法。这通常在子类的构造方法中使用,用于显式地调用父类的构造方法。
|
||||||
|
|
||||||
```
|
```text
|
||||||
class Parent {
|
class Parent {
|
||||||
Parent() {
|
Parent() {
|
||||||
System.out.println("Parent class constructor");
|
System.out.println("Parent class constructor");
|
||||||
@ -745,7 +745,7 @@ public class Main {
|
|||||||
|
|
||||||
输出:
|
输出:
|
||||||
|
|
||||||
```
|
```text
|
||||||
Parent class constructor
|
Parent class constructor
|
||||||
Child class constructor
|
Child class constructor
|
||||||
```
|
```
|
||||||
@ -771,7 +771,7 @@ final 关键字,意思是最终的、不可修改的,最见不得变化 ,
|
|||||||
3. **数据类型**:变量的数据类型,如int、String、class等。
|
3. **数据类型**:变量的数据类型,如int、String、class等。
|
||||||
4. **变量名**:变量的名称。
|
4. **变量名**:变量的名称。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public static final int MAX_COUNT = 100; #定义常量
|
public static final int MAX_COUNT = 100; #定义常量
|
||||||
protected static volatile int counter; #定义成员变量
|
protected static volatile int counter; #定义成员变量
|
||||||
```
|
```
|
||||||
@ -790,7 +790,7 @@ protected static volatile int counter; #定义成员变量
|
|||||||
|
|
||||||
**继承**
|
**继承**
|
||||||
|
|
||||||
```
|
```text
|
||||||
[修饰符] class 子类名 extends 父类名{
|
[修饰符] class 子类名 extends 父类名{
|
||||||
类体部分
|
类体部分
|
||||||
}
|
}
|
||||||
@ -820,7 +820,7 @@ Java继承了父类**非私有**的成员变量和成员方法,但是请注意
|
|||||||
|
|
||||||
2. **向上转型(Upcasting)**:动态多态;子类对象可以赋值给父类引用,这样做可以隐藏对象的真实类型,只能调用**父类中声明的方法**。
|
2. **向上转型(Upcasting)**:动态多态;子类对象可以赋值给父类引用,这样做可以隐藏对象的真实类型,只能调用**父类中声明的方法**。
|
||||||
|
|
||||||
```
|
```text
|
||||||
class Animal {
|
class Animal {
|
||||||
public void makeSound() {
|
public void makeSound() {
|
||||||
System.out.println("Animal makes sound");
|
System.out.println("Animal makes sound");
|
||||||
@ -856,7 +856,7 @@ Java继承了父类**非私有**的成员变量和成员方法,但是请注意
|
|||||||
- **重载**发生在同一个类中,与继承无关;
|
- **重载**发生在同一个类中,与继承无关;
|
||||||
- **重写**发生在子类中,依赖继承关系,实现运行时多态。
|
- **重写**发生在子类中,依赖继承关系,实现运行时多态。
|
||||||
|
|
||||||
```
|
```text
|
||||||
class Calculator {
|
class Calculator {
|
||||||
int add(int a, int b) {
|
int add(int a, int b) {
|
||||||
return a + b;
|
return a + b;
|
||||||
@ -879,7 +879,7 @@ class Calculator {
|
|||||||
**必须实现抽象方法**
|
**必须实现抽象方法**
|
||||||
如果一个子类继承了抽象类,通常必须实现抽象类中的所有抽象方法,否则该子类也必须声明为抽象类。例如:
|
如果一个子类继承了抽象类,通常必须实现抽象类中的所有抽象方法,否则该子类也必须声明为抽象类。例如:
|
||||||
|
|
||||||
```
|
```text
|
||||||
abstract class Animal {
|
abstract class Animal {
|
||||||
// 抽象方法,没有方法体
|
// 抽象方法,没有方法体
|
||||||
public abstract void makeSound();
|
public abstract void makeSound();
|
||||||
@ -908,7 +908,7 @@ class Dog extends Animal {
|
|||||||
1. **定义一个新的子类**
|
1. **定义一个新的子类**
|
||||||
创建一个子类继承抽象类并实现所有抽象方法,然后使用子类实例化对象:
|
创建一个子类继承抽象类并实现所有抽象方法,然后使用子类实例化对象:
|
||||||
|
|
||||||
```
|
```text
|
||||||
Animal animal = new Dog();
|
Animal animal = new Dog();
|
||||||
animal.makeSound(); // 输出:Dog barks
|
animal.makeSound(); // 输出:Dog barks
|
||||||
```
|
```
|
||||||
@ -916,7 +916,7 @@ class Dog extends Animal {
|
|||||||
2. **使用匿名内部类**
|
2. **使用匿名内部类**
|
||||||
使用匿名内部类实现抽象类相当于临时创建了一个**未命名的子类**,并且立即实例化了这个子类的对象。
|
使用匿名内部类实现抽象类相当于临时创建了一个**未命名的子类**,并且立即实例化了这个子类的对象。
|
||||||
|
|
||||||
```
|
```text
|
||||||
Animal animal = new Animal() {
|
Animal animal = new Animal() {
|
||||||
@Override
|
@Override
|
||||||
public void makeSound() {
|
public void makeSound() {
|
||||||
@ -956,7 +956,7 @@ class Dog extends Animal {
|
|||||||
- 类可以实现多个接口(多继承)。
|
- 类可以实现多个接口(多继承)。
|
||||||
- 类只能继承一个抽象类(单继承)。
|
- 类只能继承一个抽象类(单继承)。
|
||||||
|
|
||||||
```
|
```text
|
||||||
// 定义接口
|
// 定义接口
|
||||||
interface Flyable {
|
interface Flyable {
|
||||||
void fly();
|
void fly();
|
||||||
@ -1009,7 +1009,7 @@ public class Main {
|
|||||||
- `void clear()`:移除集合中的所有元素。
|
- `void clear()`:移除集合中的所有元素。
|
||||||
- `boolean isEmpty()`:如果集合为空,则返回 `true`。
|
- `boolean isEmpty()`:如果集合为空,则返回 `true`。
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@ -1051,7 +1051,7 @@ public class CollectionExample {
|
|||||||
2. `next()`:返回迭代器的下一个元素,并将迭代器移动到下一个位置。
|
2. `next()`:返回迭代器的下一个元素,并将迭代器移动到下一个位置。
|
||||||
3. `remove()`:从迭代器当前位置删除元素。该方法是可选的,不是所有的迭代器都支持。
|
3. `remove()`:从迭代器当前位置删除元素。该方法是可选的,不是所有的迭代器都支持。
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
@ -1093,7 +1093,7 @@ public class Main {
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
```
|
```text
|
||||||
// 使用 entrySet() 方法获取 Map 中所有键值对的集合,并使用增强型 for 循环遍历键值对
|
// 使用 entrySet() 方法获取 Map 中所有键值对的集合,并使用增强型 for 循环遍历键值对
|
||||||
System.out.println("Entries in the map:");
|
System.out.println("Entries in the map:");
|
||||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||||
@ -1109,7 +1109,7 @@ public class Main {
|
|||||||
|
|
||||||
默认是小根堆,输出1,2,5,8
|
默认是小根堆,输出1,2,5,8
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
@ -1140,7 +1140,7 @@ public class Main {
|
|||||||
|
|
||||||
### JAVA异常处理
|
### JAVA异常处理
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class ExceptionExample {
|
public class ExceptionExample {
|
||||||
// 方法声明中添加 throws 关键字,指定可能抛出的异常类型
|
// 方法声明中添加 throws 关键字,指定可能抛出的异常类型
|
||||||
public static void main(String[] args) throws SomeException, AnotherException {
|
public static void main(String[] args) throws SomeException, AnotherException {
|
||||||
@ -1181,7 +1181,7 @@ Arrays.toString()
|
|||||||
作用:方便地输出数组。
|
作用:方便地输出数组。
|
||||||
这个方法是是用来将数组转换成String类型输出的,入参可以是long,float,double,int,boolean,byte,object 型的数组。
|
这个方法是是用来将数组转换成String类型输出的,入参可以是long,float,double,int,boolean,byte,object 型的数组。
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
@ -1211,7 +1211,7 @@ public class Main {
|
|||||||
|
|
||||||
**类路径**是JVM在运行时用来查找类文件和资源文件的一组目录或JAR包。在许多项目(例如Maven或Gradle项目)中,`src/main/resources`目录下的内容在编译时会被复制到输出目录(如`target/classes`),`src/main/java` 下编译后的 class 文件也会放到这里。
|
**类路径**是JVM在运行时用来查找类文件和资源文件的一组目录或JAR包。在许多项目(例如Maven或Gradle项目)中,`src/main/resources`目录下的内容在编译时会被复制到输出目录(如`target/classes`),`src/main/java` 下编译后的 class 文件也会放到这里。
|
||||||
|
|
||||||
```
|
```text
|
||||||
MyProject/
|
MyProject/
|
||||||
├── src/
|
├── src/
|
||||||
│ └── main/
|
│ └── main/
|
||||||
@ -1226,7 +1226,7 @@ MyProject/
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
// 获取 resources 根目录下的 emp.xml 文件路径
|
// 获取 resources 根目录下的 emp.xml 文件路径
|
||||||
String empFile = this.getClass().getClassLoader().getResource("emp.xml").getFile();
|
String empFile = this.getClass().getClassLoader().getResource("emp.xml").getFile();
|
||||||
|
|
||||||
@ -1261,7 +1261,7 @@ String ttImgPath = resourceUrl != null ? resourceUrl.getFile() : null;
|
|||||||
|
|
||||||
**1.获取类的字节码(Class对象)**:有三种方法
|
**1.获取类的字节码(Class对象)**:有三种方法
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class Test1Class{
|
public class Test1Class{
|
||||||
public static void main(String[] args){
|
public static void main(String[] args){
|
||||||
Class c1 = Student.class;
|
Class c1 = Student.class;
|
||||||
@ -1282,7 +1282,7 @@ public class Test1Class{
|
|||||||
|
|
||||||
**2.获取类的构造器**
|
**2.获取类的构造器**
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class Cat{
|
public class Cat{
|
||||||
private String name;
|
private String name;
|
||||||
private int age;
|
private int age;
|
||||||
@ -1301,7 +1301,7 @@ public class Cat{
|
|||||||
|
|
||||||
- 获取构造器列表
|
- 获取构造器列表
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class TestConstructor {
|
public class TestConstructor {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1386,7 +1386,7 @@ public class Test2Constructor(){
|
|||||||
|
|
||||||
示例:`Cat` 类与测试类
|
示例:`Cat` 类与测试类
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class Cat {
|
public class Cat {
|
||||||
private String name;
|
private String name;
|
||||||
public int age;
|
public int age;
|
||||||
@ -1406,7 +1406,7 @@ public class Cat {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@ -1478,7 +1478,7 @@ public class FieldReflectionTest {
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
```
|
```text
|
||||||
@Test
|
@Test
|
||||||
public void testListUser(){
|
public void testListUser(){
|
||||||
List<User>list=userMapper.list();
|
List<User>list=userMapper.list();
|
||||||
@ -1494,7 +1494,7 @@ public class FieldReflectionTest {
|
|||||||
|
|
||||||
原理可能是:
|
原理可能是:
|
||||||
|
|
||||||
```
|
```text
|
||||||
//自定义注解
|
//自定义注解
|
||||||
@Retention(RetentionPolicy.RUNTIME) //指定注解在运行时可用,这样才能通过反射获取到该注解。
|
@Retention(RetentionPolicy.RUNTIME) //指定注解在运行时可用,这样才能通过反射获取到该注解。
|
||||||
@Target(ElementType.METHOD) //指定注解可用于方法上。
|
@Target(ElementType.METHOD) //指定注解可用于方法上。
|
||||||
@ -1539,7 +1539,7 @@ public class AnnotationTest4 {
|
|||||||
|
|
||||||
定义:
|
定义:
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@ -1564,7 +1564,7 @@ public @interface MyAnnotation {
|
|||||||
|
|
||||||
**简化使用**:当注解只有一个元素需要设置时,且该元素的名字是`value`,在使用该注解时可以不用显式地指定元素名
|
**简化使用**:当注解只有一个元素需要设置时,且该元素的名字是`value`,在使用该注解时可以不用显式地指定元素名
|
||||||
|
|
||||||
```
|
```text
|
||||||
@MyAnnotation(5) // 等同于 @MyAnnotation(value = 5)
|
@MyAnnotation(5) // 等同于 @MyAnnotation(value = 5)
|
||||||
public void someMethod() {
|
public void someMethod() {
|
||||||
// 方法实现
|
// 方法实现
|
||||||
@ -1576,7 +1576,7 @@ public void someMethod() {
|
|||||||
|
|
||||||
如果要同时设置`description`,则不能省略元素名:
|
如果要同时设置`description`,则不能省略元素名:
|
||||||
|
|
||||||
```
|
```text
|
||||||
@MyAnnotation(value = 5, description = "Specific description")
|
@MyAnnotation(value = 5, description = "Specific description")
|
||||||
public void anotherMethod() {
|
public void anotherMethod() {
|
||||||
// 方法实现
|
// 方法实现
|
||||||
@ -1588,7 +1588,7 @@ public void anotherMethod() {
|
|||||||
|
|
||||||
**获得注解上的value:**反射
|
**获得注解上的value:**反射
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class MyClass {
|
public class MyClass {
|
||||||
|
|
||||||
@MyAnnotation(value = "specific value")
|
@MyAnnotation(value = "specific value")
|
||||||
@ -1601,7 +1601,7 @@ public class MyClass {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
public class AnnotationReader {
|
public class AnnotationReader {
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
### 启动Mysql
|
### 启动Mysql
|
||||||
|
|
||||||
```
|
```text
|
||||||
net start mysql // 启动mysql服务
|
net start mysql // 启动mysql服务
|
||||||
net stop mysql // 停止mysql服务
|
net stop mysql // 停止mysql服务
|
||||||
```
|
```
|
||||||
|
|
||||||
### 修改root账户密码
|
### 修改root账户密码
|
||||||
|
|
||||||
```
|
```text
|
||||||
mysqladmin -u root password 123456
|
mysqladmin -u root password 123456
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -19,11 +19,11 @@ mysqladmin -u root password 123456
|
|||||||
|
|
||||||
### 登录
|
### 登录
|
||||||
|
|
||||||
```
|
```text
|
||||||
mysql -u用户名 -p密码 [-h数据库服务器的IP地址 -P端口号]
|
mysql -u用户名 -p密码 [-h数据库服务器的IP地址 -P端口号]
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
mysql -uroot -p123456
|
mysql -uroot -p123456
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -109,13 +109,13 @@ drop database if exists itcast; -- itcast数据库存在时删除,不存在也
|
|||||||
|
|
||||||
**查询当前数据库下所有表**
|
**查询当前数据库下所有表**
|
||||||
|
|
||||||
```
|
```text
|
||||||
show tables;
|
show tables;
|
||||||
```
|
```
|
||||||
|
|
||||||
**查看指定表的结构(字段)**
|
**查看指定表的结构(字段)**
|
||||||
|
|
||||||
```
|
```text
|
||||||
desc tb_tmps; ( tb_tmps为表名)
|
desc tb_tmps; ( tb_tmps为表名)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ eg:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
```
|
```text
|
||||||
create table tb_user (
|
create table tb_user (
|
||||||
id int comment 'ID,唯一标识', # id是一行数据的唯一标识(不能重复)
|
id int comment 'ID,唯一标识', # id是一行数据的唯一标识(不能重复)
|
||||||
username varchar(20) comment '用户名',
|
username varchar(20) comment '用户名',
|
||||||
@ -156,7 +156,7 @@ create table tb_user (
|
|||||||
| 默认约束 | 保存数据时,如果未指定该字段值,则采用默认值 | default |
|
| 默认约束 | 保存数据时,如果未指定该字段值,则采用默认值 | default |
|
||||||
| **外键约束** | 让两张表的数据建立连接,保证数据的一致性和完整性 | foreign key |
|
| **外键约束** | 让两张表的数据建立连接,保证数据的一致性和完整性 | foreign key |
|
||||||
|
|
||||||
```
|
```text
|
||||||
create table tb_user (
|
create table tb_user (
|
||||||
id int primary key auto_increment comment 'ID,唯一标识',
|
id int primary key auto_increment comment 'ID,唯一标识',
|
||||||
username varchar(20) not null unique comment '用户名',
|
username varchar(20) not null unique comment '用户名',
|
||||||
@ -268,7 +268,7 @@ DQL英文全称是Data Query Language(数据查询语言),用来查询数据
|
|||||||
|
|
||||||
### 语法
|
### 语法
|
||||||
|
|
||||||
```
|
```text
|
||||||
SELECT
|
SELECT
|
||||||
字段列表
|
字段列表
|
||||||
FROM
|
FROM
|
||||||
@ -330,7 +330,7 @@ LIMIT
|
|||||||
|
|
||||||
案例:查询 入职时间 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间 且 性别为女 的员工信息
|
案例:查询 入职时间 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间 且 性别为女 的员工信息
|
||||||
|
|
||||||
```
|
```text
|
||||||
select *
|
select *
|
||||||
from tb_emp
|
from tb_emp
|
||||||
where entrydate between '2000-01-01' and '2010-01-01'
|
where entrydate between '2000-01-01' and '2010-01-01'
|
||||||
@ -339,7 +339,7 @@ where entrydate between '2000-01-01' and '2010-01-01'
|
|||||||
|
|
||||||
案例8:查询 职位是 2 (讲师), 3 (学工主管), 4 (教研主管) 的员工信息
|
案例8:查询 职位是 2 (讲师), 3 (学工主管), 4 (教研主管) 的员工信息
|
||||||
|
|
||||||
```
|
```text
|
||||||
select *
|
select *
|
||||||
from tb_emp
|
from tb_emp
|
||||||
where job in (2,3,4);
|
where job in (2,3,4);
|
||||||
@ -367,7 +367,7 @@ select 聚合函数(字段列表) from 表名 ;
|
|||||||
|
|
||||||
> 注意 : 聚合函数会忽略空值,对NULL值不作为统计。
|
> 注意 : 聚合函数会忽略空值,对NULL值不作为统计。
|
||||||
|
|
||||||
```
|
```text
|
||||||
# count(*) 推荐此写法(MySQL底层进行了优化)
|
# count(*) 推荐此写法(MySQL底层进行了优化)
|
||||||
select count(*) from tb_emp;
|
select count(*) from tb_emp;
|
||||||
```
|
```
|
||||||
@ -382,13 +382,13 @@ select count(*) from tb_emp;
|
|||||||
>
|
>
|
||||||
> 分组查询通常会使用**聚合函数**进行计算。
|
> 分组查询通常会使用**聚合函数**进行计算。
|
||||||
|
|
||||||
```
|
```text
|
||||||
select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组后过滤条件];
|
select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组后过滤条件];
|
||||||
```
|
```
|
||||||
|
|
||||||
例如,假设我们有一个名为 `orders` 的表,其中包含 `customer_id` 和 `amount` 列,我们想要计算每个客户的订单总金额,可以这样写查询:
|
例如,假设我们有一个名为 `orders` 的表,其中包含 `customer_id` 和 `amount` 列,我们想要计算每个客户的订单总金额,可以这样写查询:
|
||||||
|
|
||||||
```
|
```text
|
||||||
SELECT customer_id, SUM(amount) AS total_amount
|
SELECT customer_id, SUM(amount) AS total_amount
|
||||||
FROM orders
|
FROM orders
|
||||||
GROUP BY customer_id;
|
GROUP BY customer_id;
|
||||||
@ -398,7 +398,7 @@ GROUP BY customer_id;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
SELECT customer_id, SUM(amount) AS total_amount
|
SELECT customer_id, SUM(amount) AS total_amount
|
||||||
FROM orders
|
FROM orders
|
||||||
GROUP BY customer_id
|
GROUP BY customer_id
|
||||||
@ -435,7 +435,7 @@ order by 字段1 排序方式1 , 字段2 排序方式2 … ;
|
|||||||
|
|
||||||
### 分页查询
|
### 分页查询
|
||||||
|
|
||||||
```
|
```text
|
||||||
select 字段列表 from 表名 limit 起始索引, 每页显示记录数 ;
|
select 字段列表 from 表名 limit 起始索引, 每页显示记录数 ;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -549,7 +549,7 @@ where tb_emp.dept_id = tb_dept.id; -- 消除笛卡尔积
|
|||||||
|
|
||||||
- 显示内连接
|
- 显示内连接
|
||||||
|
|
||||||
```
|
```text
|
||||||
select tb_emp.name , tb_dept.name
|
select tb_emp.name , tb_dept.name
|
||||||
from tb_emp inner join tb_dept
|
from tb_emp inner join tb_dept
|
||||||
on tb_emp.dept_id = tb_dept.id;
|
on tb_emp.dept_id = tb_dept.id;
|
||||||
@ -575,7 +575,7 @@ select 字段列表 from 表1 right [ outer ] join 表2 on 连接条
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
-- 右外连接
|
-- 右外连接
|
||||||
select dept.name , emp.name
|
select dept.name , emp.name
|
||||||
from tb_emp AS emp right join tb_dept AS dept
|
from tb_emp AS emp right join tb_dept AS dept
|
||||||
@ -696,7 +696,7 @@ select e.*, d.* from (select * from emp where entrydate > '2006-01-01') e left j
|
|||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
```
|
```text
|
||||||
-- 开启事务
|
-- 开启事务
|
||||||
start transaction ;
|
start transaction ;
|
||||||
|
|
||||||
@ -738,7 +738,7 @@ rollback ;
|
|||||||
|
|
||||||
**创建索引**
|
**创建索引**
|
||||||
|
|
||||||
```
|
```text
|
||||||
-- 添加索引
|
-- 添加索引
|
||||||
create index idx_sku_sn on tb_sku (sn); #在添加索引时,也需要消耗时间
|
create index idx_sku_sn on tb_sku (sn); #在添加索引时,也需要消耗时间
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
**linux上安装Git**
|
**linux上安装Git**
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install git
|
sudo apt install git
|
||||||
```
|
```
|
||||||
@ -195,7 +195,10 @@ git config --global https.proxy https://127.0.0.1:7890
|
|||||||
git config --global http.proxy socks5://127.0.0.1:7890
|
git config --global http.proxy socks5://127.0.0.1:7890
|
||||||
git config --global https.proxy socks5://127.0.0.1:7890
|
git config --global https.proxy socks5://127.0.0.1:7890
|
||||||
|
|
||||||
|
**取消代理**
|
||||||
|
|
||||||
|
git config --global --unset http.proxy
|
||||||
|
git config --global --unset https.proxy
|
||||||
|
|
||||||
**或者使用国产的gitee或者自己服务器上搭建gitea进行代码托管!!!**
|
**或者使用国产的gitee或者自己服务器上搭建gitea进行代码托管!!!**
|
||||||
|
|
||||||
@ -221,7 +224,7 @@ git config --global https.proxy socks5://127.0.0.1:7890
|
|||||||
|
|
||||||
如果还不想提交本地修改,可以将更改暂存起来:
|
如果还不想提交本地修改,可以将更改暂存起来:
|
||||||
|
|
||||||
```
|
```text
|
||||||
git stash
|
git stash
|
||||||
git pull
|
git pull
|
||||||
git stash pop
|
git stash pop
|
||||||
@ -235,7 +238,7 @@ git stash pop
|
|||||||
|
|
||||||
如果确定不需要这些修改,可以放弃它们:
|
如果确定不需要这些修改,可以放弃它们:
|
||||||
|
|
||||||
```
|
```text
|
||||||
git reset --hard
|
git reset --hard
|
||||||
git pull
|
git pull
|
||||||
```
|
```
|
||||||
@ -244,7 +247,7 @@ git pull
|
|||||||
|
|
||||||
**但是推荐先提交本地的代码!!!**
|
**但是推荐先提交本地的代码!!!**
|
||||||
|
|
||||||
```
|
```text
|
||||||
git add .
|
git add .
|
||||||
git commit -m "描述本次修改的提交信息"
|
git commit -m "描述本次修改的提交信息"
|
||||||
git pull
|
git pull
|
||||||
@ -305,7 +308,7 @@ remote: Support for password authentication was removed on August 13, 2021. remo
|
|||||||
|
|
||||||
- 如果你还没有 SSH 密钥,可以使用以下命令生成:
|
- 如果你还没有 SSH 密钥,可以使用以下命令生成:
|
||||||
|
|
||||||
```
|
```text
|
||||||
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -320,7 +323,7 @@ remote: Support for password authentication was removed on August 13, 2021. remo
|
|||||||
|
|
||||||
**使用 SSH URL 克隆仓库**:
|
**使用 SSH URL 克隆仓库**:
|
||||||
|
|
||||||
```
|
```text
|
||||||
git clone git@github.com:zhangww-web/reptile.git
|
git clone git@github.com:zhangww-web/reptile.git
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -343,7 +346,7 @@ SSH 连接 GitHub 并触发身份验证,流程如下:
|
|||||||
|
|
||||||
**如果避免每次git pull都要验证身份?**
|
**如果避免每次git pull都要验证身份?**
|
||||||
|
|
||||||
```
|
```text
|
||||||
git config --global credential.helper store //将凭据保存到磁盘上(明文存储):
|
git config --global credential.helper store //将凭据保存到磁盘上(明文存储):
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -355,7 +358,7 @@ git config --global credential.helper store //将凭据保存到磁盘上(明
|
|||||||
|
|
||||||
到项目根目录,git bash here
|
到项目根目录,git bash here
|
||||||
|
|
||||||
```
|
```text
|
||||||
git rm -r --cached 'dictory'/
|
git rm -r --cached 'dictory'/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
- head 查看前n行
|
- head 查看前n行
|
||||||
|
|
||||||
```
|
```text
|
||||||
head -n 100 文件名
|
head -n 100 文件名
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
- **ls** 列出所有文件,但默认只是显示出最基础的文件和文件夹,如果需要更详细的信息,则使用ls -la,这将列出包括隐藏文件在内的所有文件和文件夹,并且给出对应的权限、大小和日期等信息。
|
- **ls** 列出所有文件,但默认只是显示出最基础的文件和文件夹,如果需要更详细的信息,则使用ls -la,这将列出包括隐藏文件在内的所有文件和文件夹,并且给出对应的权限、大小和日期等信息。
|
||||||
|
|
||||||
```
|
```text
|
||||||
zy123@hcss-ecs-588d:~$ ls -la
|
zy123@hcss-ecs-588d:~$ ls -la
|
||||||
total 44
|
total 44
|
||||||
drwxr-xr-x 6 zy123 zy123 4096 Feb 26 08:53 .
|
drwxr-xr-x 6 zy123 zy123 4096 Feb 26 08:53 .
|
||||||
@ -122,19 +122,19 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
- **mv** 移动文件和文件夹,也可以用来修改名称,如:
|
- **mv** 移动文件和文件夹,也可以用来修改名称,如:
|
||||||
|
|
||||||
```
|
```text
|
||||||
mv /home/hello.py /home/helloworld.py
|
mv /home/hello.py /home/helloworld.py
|
||||||
```
|
```
|
||||||
|
|
||||||
将上文的hello.py重命名为helloworld.py,
|
将上文的hello.py重命名为helloworld.py,
|
||||||
|
|
||||||
```
|
```text
|
||||||
mv /home/helloworld.py /home/Python/helloworld.py
|
mv /home/helloworld.py /home/Python/helloworld.py
|
||||||
```
|
```
|
||||||
|
|
||||||
将helloworld.py 由home文件夹移动到了次级的Python文件夹。
|
将helloworld.py 由home文件夹移动到了次级的Python文件夹。
|
||||||
|
|
||||||
```
|
```text
|
||||||
mv /home/hello.py .
|
mv /home/hello.py .
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
- **cp** 复制文件
|
- **cp** 复制文件
|
||||||
|
|
||||||
```
|
```text
|
||||||
cp /home/Python/hellowrold.py /home/Python/HelloWorld.py
|
cp /home/Python/hellowrold.py /home/Python/HelloWorld.py
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
- **grep **是用于在文件或标准输入中搜索**符合条件的行**的命令。
|
- **grep **是用于在文件或标准输入中搜索**符合条件的行**的命令。
|
||||||
|
|
||||||
```
|
```text
|
||||||
grep "pattern" filename #pattern可以是一个正则表达式
|
grep "pattern" filename #pattern可以是一个正则表达式
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
- **awk** 是一个功能强大的文本处理工具,它可以对文本文件进行分列处理、模式匹配和报告生成。它的语法类似一种简单的脚本语言。
|
- **awk** 是一个功能强大的文本处理工具,它可以对文本文件进行分列处理、模式匹配和报告生成。它的语法类似一种简单的脚本语言。
|
||||||
|
|
||||||
```
|
```text
|
||||||
awk 'pattern { action }' filename
|
awk 'pattern { action }' filename
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
`$1, $2, ...`:代表各个字段(默认分隔符是空白字符,可以通过 `-F` 参数指定其他分隔符)。
|
`$1, $2, ...`:代表各个字段(默认分隔符是空白字符,可以通过 `-F` 参数指定其他分隔符)。
|
||||||
|
|
||||||
```
|
```text
|
||||||
awk '{print $1, $3}' filename #印指定列
|
awk '{print $1, $3}' filename #印指定列
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ DNS解析:可能需等待几分钟生效
|
|||||||
10.0.0.5 27/Feb/2025:10:32:10 "GET /error_page HTTP/1.1" 500 2048 ERROR
|
10.0.0.5 27/Feb/2025:10:32:10 "GET /error_page HTTP/1.1" 500 2048 ERROR
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
grep 'ERROR' access.log | awk '{print $2}'
|
grep 'ERROR' access.log | awk '{print $2}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -195,13 +195,13 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
- **lsof**"List Open Files"显示系统中当前打开的文件。 `-i`*会显示所有正在使用网络连接的进程*
|
- **lsof**"List Open Files"显示系统中当前打开的文件。 `-i`*会显示所有正在使用网络连接的进程*
|
||||||
|
|
||||||
```
|
```text
|
||||||
lsof -i :80 #查看 80 端口上的进程,或者判断80端口是否被占用!
|
lsof -i :80 #查看 80 端口上的进程,或者判断80端口是否被占用!
|
||||||
```
|
```
|
||||||
|
|
||||||
- **usermode** 修改用户账户信息的命令
|
- **usermode** 修改用户账户信息的命令
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo usermod -aG docker zy123 #-aG一起用,添加zy123到group组
|
sudo usermod -aG docker zy123 #-aG一起用,添加zy123到group组
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -209,14 +209,14 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
1. 数字方式:数字方式使用三个(或四个)数字来表示所有者、组用户和其他用户的权限。每个数字代表读 (4)、写 (2)、执行 (1) 权限的和。
|
1. 数字方式:数字方式使用三个(或四个)数字来表示所有者、组用户和其他用户的权限。每个数字代表读 (4)、写 (2)、执行 (1) 权限的和。
|
||||||
|
|
||||||
```
|
```text
|
||||||
chmod 644 filename
|
chmod 644 filename
|
||||||
#所有者:读 + 写 = 6 组用户:读 = 4 其他用户:读 = 4
|
#所有者:读 + 写 = 6 组用户:读 = 4 其他用户:读 = 4
|
||||||
```
|
```
|
||||||
|
|
||||||
2. 符号方式
|
2. 符号方式
|
||||||
|
|
||||||
```
|
```text
|
||||||
chmod [用户类别][操作符][权限] filename
|
chmod [用户类别][操作符][权限] filename
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ DNS解析:可能需等待几分钟生效
|
|||||||
- `w`:写权限
|
- `w`:写权限
|
||||||
- `x`:执行权限
|
- `x`:执行权限
|
||||||
|
|
||||||
```
|
```text
|
||||||
chmod u+x filename #为所有者增加执行权限
|
chmod u+x filename #为所有者增加执行权限
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ DNS解析:可能需等待几分钟生效
|
|||||||
|
|
||||||
**nano**:Debian 11自带了简便易用的nano文本编辑器
|
**nano**:Debian 11自带了简便易用的nano文本编辑器
|
||||||
|
|
||||||
```
|
```text
|
||||||
nano /etc/apt/sources.list #打开sources.list文件
|
nano /etc/apt/sources.list #打开sources.list文件
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -317,7 +317,7 @@ Ctrl+X:退出
|
|||||||
|
|
||||||
### 抓包
|
### 抓包
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo tcpdump -nn -i any port 1000 //查看请求端口1000的源 IP 地址
|
sudo tcpdump -nn -i any port 1000 //查看请求端口1000的源 IP 地址
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ Ctrl+X:退出
|
|||||||
|
|
||||||
生成密钥
|
生成密钥
|
||||||
|
|
||||||
```
|
```text
|
||||||
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
|||||||
|
|
||||||
除此之外,还需要给文件和相关文件夹合适的权限:
|
除此之外,还需要给文件和相关文件夹合适的权限:
|
||||||
|
|
||||||
```
|
```text
|
||||||
chmod 600 authorized_keys
|
chmod 600 authorized_keys
|
||||||
chmod 700 ~/.ssh
|
chmod 700 ~/.ssh
|
||||||
```
|
```
|
||||||
@ -415,7 +415,7 @@ chmod 700 ~/.ssh
|
|||||||
|
|
||||||
### Bash
|
### Bash
|
||||||
|
|
||||||
```
|
```text
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# 定义变量,注意等号两边不能有空格
|
# 定义变量,注意等号两边不能有空格
|
||||||
@ -447,13 +447,13 @@ greet $name
|
|||||||
|
|
||||||
赋予可执行权限
|
赋予可执行权限
|
||||||
|
|
||||||
```
|
```text
|
||||||
chmod +x hello_world.sh
|
chmod +x hello_world.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
执行
|
执行
|
||||||
|
|
||||||
```
|
```text
|
||||||
./hello_world.sh
|
./hello_world.sh
|
||||||
或者
|
或者
|
||||||
./hello_world.sh Alice #传参
|
./hello_world.sh Alice #传参
|
||||||
@ -465,7 +465,7 @@ chmod +x hello_world.sh
|
|||||||
|
|
||||||
**如何设置定时任务?**
|
**如何设置定时任务?**
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo crontab -e
|
sudo crontab -e
|
||||||
#在里面添加:
|
#在里面添加:
|
||||||
10 0 * * * /path/toyour/xx.sh #让gpt写
|
10 0 * * * /path/toyour/xx.sh #让gpt写
|
||||||
@ -501,7 +501,7 @@ sudo crontab -e
|
|||||||
|
|
||||||
**docker 部署**
|
**docker 部署**
|
||||||
|
|
||||||
```
|
```text
|
||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
@ -576,7 +576,7 @@ wget -O /home/zy123/VPN/config.yaml "https://illo1.no-mad-world.club/link/2zXAEz
|
|||||||
|
|
||||||
类似这样:
|
类似这样:
|
||||||
|
|
||||||
```
|
```text
|
||||||
port: 7890
|
port: 7890
|
||||||
socks-port: 7891
|
socks-port: 7891
|
||||||
allow-lan: false
|
allow-lan: false
|
||||||
@ -637,7 +637,7 @@ proxies:
|
|||||||
|
|
||||||
**启动Clash**
|
**启动Clash**
|
||||||
|
|
||||||
```
|
```text
|
||||||
./CrashCore -d . & //后台启动
|
./CrashCore -d . & //后台启动
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -645,13 +645,13 @@ proxies:
|
|||||||
|
|
||||||
1.创建 `systemd` 服务文件
|
1.创建 `systemd` 服务文件
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo vim /etc/systemd/system/clash.service
|
sudo vim /etc/systemd/system/clash.service
|
||||||
```
|
```
|
||||||
|
|
||||||
2.在文件中添加以下内容:
|
2.在文件中添加以下内容:
|
||||||
|
|
||||||
```
|
```text
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Clash Proxy Service
|
Description=Clash Proxy Service
|
||||||
After=network.target
|
After=network.target
|
||||||
@ -676,19 +676,19 @@ WantedBy=multi-user.target
|
|||||||
|
|
||||||
启动服务:
|
启动服务:
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo systemctl start clash
|
sudo systemctl start clash
|
||||||
```
|
```
|
||||||
|
|
||||||
停止服务:
|
停止服务:
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo systemctl stop clash
|
sudo systemctl stop clash
|
||||||
```
|
```
|
||||||
|
|
||||||
查看服务状态:
|
查看服务状态:
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo systemctl status clash
|
sudo systemctl status clash
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -704,7 +704,7 @@ YACD 是一个基于 **Clash** 的 Web 管理面板,用于管理您的 Clash
|
|||||||
|
|
||||||
下载yacd
|
下载yacd
|
||||||
|
|
||||||
```
|
```text
|
||||||
git clone https://github.com/haishanh/yacd.git
|
git clone https://github.com/haishanh/yacd.git
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -712,7 +712,7 @@ git clone https://github.com/haishanh/yacd.git
|
|||||||
|
|
||||||
构建yacd
|
构建yacd
|
||||||
|
|
||||||
```
|
```text
|
||||||
cd ~/VPN/yacd
|
cd ~/VPN/yacd
|
||||||
pnpm install
|
pnpm install
|
||||||
pnpm build
|
pnpm build
|
||||||
@ -720,7 +720,7 @@ pnpm build
|
|||||||
|
|
||||||
启动yacd
|
启动yacd
|
||||||
|
|
||||||
```
|
```text
|
||||||
nohup pnpm serve --host 0.0.0.0 & //如果不是0.0.0.0 不能在windows上打开
|
nohup pnpm serve --host 0.0.0.0 & //如果不是0.0.0.0 不能在windows上打开
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -728,7 +728,7 @@ nohup pnpm serve --host 0.0.0.0 & //如果不是0.0.0.0 不能在windows上
|
|||||||
|
|
||||||
**停止进程**
|
**停止进程**
|
||||||
|
|
||||||
```
|
```text
|
||||||
ps aux | grep pnpm
|
ps aux | grep pnpm
|
||||||
|
|
||||||
kill xxx
|
kill xxx
|
||||||
@ -752,19 +752,19 @@ kill xxx
|
|||||||
|
|
||||||
1.创建数据目录
|
1.创建数据目录
|
||||||
|
|
||||||
```
|
```text
|
||||||
mkdir -p /data/filebrowser/{srv,config,db}
|
mkdir -p /data/filebrowser/{srv,config,db}
|
||||||
```
|
```
|
||||||
|
|
||||||
2.目录授权
|
2.目录授权
|
||||||
|
|
||||||
```
|
```text
|
||||||
chmod -R 777 /data/filebrowser/
|
chmod -R 777 /data/filebrowser/
|
||||||
```
|
```
|
||||||
|
|
||||||
3.编辑 docker-compose.yaml 文件
|
3.编辑 docker-compose.yaml 文件
|
||||||
|
|
||||||
```
|
```text
|
||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
filebrowser:
|
filebrowser:
|
||||||
@ -786,7 +786,7 @@ services:
|
|||||||
|
|
||||||
[Gitea Docker 安装与使用详解:轻量级自托管 Git 服务教程-CSDN博客](https://blog.csdn.net/m0_70878103/article/details/144908188)
|
[Gitea Docker 安装与使用详解:轻量级自托管 Git 服务教程-CSDN博客](https://blog.csdn.net/m0_70878103/article/details/144908188)
|
||||||
|
|
||||||
```
|
```text
|
||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
gitea:
|
gitea:
|
||||||
@ -811,7 +811,7 @@ services:
|
|||||||
|
|
||||||
github地址:[icret/EasyImages2.0: 简单图床 - 一款功能强大无数据库的图床 2.0版](https://github.com/icret/EasyImages2.0)
|
github地址:[icret/EasyImages2.0: 简单图床 - 一款功能强大无数据库的图床 2.0版](https://github.com/icret/EasyImages2.0)
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo -i # 切换到root用户
|
sudo -i # 切换到root用户
|
||||||
|
|
||||||
apt update -y # 升级packages
|
apt update -y # 升级packages
|
||||||
@ -822,7 +822,7 @@ apt install wget curl sudo vim git # Debian系统比较干净,安装常用的
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
version: '3.3'
|
version: '3.3'
|
||||||
services:
|
services:
|
||||||
easyimage:
|
easyimage:
|
||||||
@ -843,7 +843,7 @@ services:
|
|||||||
|
|
||||||
网页打开显示bug:
|
网页打开显示bug:
|
||||||
|
|
||||||
```
|
```text
|
||||||
cd /data/easyimage/config/config.php
|
cd /data/easyimage/config/config.php
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -902,13 +902,13 @@ py脚本3:将本地图片上传到easyimage图床并将链接返回替换md文
|
|||||||
|
|
||||||
注意:nginx一定要对typecho目录有操作权限!
|
注意:nginx一定要对typecho目录有操作权限!
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo chmod 755 -R ./typecho
|
sudo chmod 755 -R ./typecho
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
services:
|
services:
|
||||||
nginx:
|
nginx:
|
||||||
image: nginx
|
image: nginx
|
||||||
@ -973,7 +973,7 @@ networks:
|
|||||||
|
|
||||||
卸载:
|
卸载:
|
||||||
|
|
||||||
```
|
```text
|
||||||
sudo -i # 切换到root
|
sudo -i # 切换到root
|
||||||
|
|
||||||
cd /root/data/docker_data/typecho # 进入docker-compose所在的文件夹
|
cd /root/data/docker_data/typecho # 进入docker-compose所在的文件夹
|
||||||
@ -1062,11 +1062,11 @@ slug为页面缩略名,在新增文章时可以传入,默认是index数字
|
|||||||
|
|
||||||
[【好玩的Docker项目】10分钟搭建你专属的下载神器——qbittorrent-我不是咕咕鸽](https://blog.laoda.de/archives/docker-install-qbittorrent)
|
[【好玩的Docker项目】10分钟搭建你专属的下载神器——qbittorrent-我不是咕咕鸽](https://blog.laoda.de/archives/docker-install-qbittorrent)
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker pull linuxserver/qbittorrent
|
docker pull linuxserver/qbittorrent
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
cd ~
|
cd ~
|
||||||
mkdir /root/data/docker_data/qBittorrent #创建qbitorrent数据文件夹
|
mkdir /root/data/docker_data/qBittorrent #创建qbitorrent数据文件夹
|
||||||
cd /root/data/docker_data/qBittorrent
|
cd /root/data/docker_data/qBittorrent
|
||||||
@ -1075,7 +1075,7 @@ nano docker-compose.yml #创建并编辑文件
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
services:
|
services:
|
||||||
qbittorrent:
|
qbittorrent:
|
||||||
image: linuxserver/qbittorrent
|
image: linuxserver/qbittorrent
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
int[] arr1 = {1, 2, 3};
|
int[] arr1 = {1, 2, 3};
|
||||||
int[] arr2 = {1, 2, 3};
|
int[] arr2 = {1, 2, 3};
|
||||||
boolean isEqual = Arrays.equals(arr1, arr2); // true
|
boolean isEqual = Arrays.equals(arr1, arr2); // true
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -43,7 +43,7 @@
|
|||||||
- 如果返回零,说明 `o1` 等于 `o2`。
|
- 如果返回零,说明 `o1` 等于 `o2`。
|
||||||
- 如果返回正数,说明 `o1` 排在 `o2`后面。
|
- 如果返回正数,说明 `o1` 排在 `o2`后面。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class TestComparator {
|
public class TestComparator {
|
||||||
// 定义一个升序排序的 Comparator
|
// 定义一个升序排序的 Comparator
|
||||||
static Comparator<Integer> ascComparator = new Comparator<Integer>() {
|
static Comparator<Integer> ascComparator = new Comparator<Integer>() {
|
||||||
@ -78,7 +78,7 @@ public class TestComparator {
|
|||||||
|
|
||||||
**自定义比较器排序二维数组** 用Lambda表达式实现`Comparator<int[]>接口`
|
**自定义比较器排序二维数组** 用Lambda表达式实现`Comparator<int[]>接口`
|
||||||
|
|
||||||
```
|
```text
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class IntervalSort {
|
public class IntervalSort {
|
||||||
@ -107,7 +107,7 @@ public class IntervalSort {
|
|||||||
|
|
||||||
**逻辑比较**
|
**逻辑比较**
|
||||||
|
|
||||||
```
|
```text
|
||||||
boolean flag = false;
|
boolean flag = false;
|
||||||
|
|
||||||
if (!flag) { //! 是 Java 中的逻辑非运算符,只能用于对布尔值取反。
|
if (!flag) { //! 是 Java 中的逻辑非运算符,只能用于对布尔值取反。
|
||||||
@ -140,7 +140,7 @@ if (flag == false) { //更常用!
|
|||||||
|
|
||||||
需要String先转为char [] 数组,排序好之后再转为String类型!!
|
需要String先转为char [] 数组,排序好之后再转为String类型!!
|
||||||
|
|
||||||
```
|
```text
|
||||||
char[] charArray = str.toCharArray();
|
char[] charArray = str.toCharArray();
|
||||||
Arrays.sort(charArray);
|
Arrays.sort(charArray);
|
||||||
String sortedStr = new String(charArray);
|
String sortedStr = new String(charArray);
|
||||||
@ -205,7 +205,7 @@ String sortedStr = new String(charArray);
|
|||||||
System.out.println("After removal: " + map); // 输出 {apple=10, banana=20}
|
System.out.println("After removal: " + map); // 输出 {apple=10, banana=20}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ String sortedStr = new String(charArray);
|
|||||||
System.out.println("Array length: " + length); // 输出 5
|
System.out.println("Array length: " + length); // 输出 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -372,7 +372,7 @@ public void setZeroes(int[][] matrix) {
|
|||||||
System.out.println(); // 换行,便于输出格式化
|
System.out.println(); // 换行,便于输出格式化
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -398,7 +398,7 @@ for (int i = 0; i < list.size(); i++) {
|
|||||||
}
|
}
|
||||||
System.out.println(); // 换行
|
System.out.println(); // 换行
|
||||||
}
|
}
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ List<int[]> merged = new ArrayList<>();
|
|||||||
merged.add(current);
|
merged.add(current);
|
||||||
|
|
||||||
return merged.toArray(new int[merged.size()][]);
|
return merged.toArray(new int[merged.size()][]);
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -545,7 +545,7 @@ return merged.toArray(new int[merged.size()][]);
|
|||||||
System.out.println("队列是否为空: " + minHeap.isEmpty()); // 输出 true
|
System.out.println("队列是否为空: " + minHeap.isEmpty()); // 输出 true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -585,7 +585,7 @@ public class QueueExample {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -604,7 +604,7 @@ Deque<Integer> stack = new ArrayDeque<>();
|
|||||||
stack.push(1); // 入栈
|
stack.push(1); // 入栈
|
||||||
Integer top1=stack.peek()
|
Integer top1=stack.peek()
|
||||||
Integer top = stack.pop(); // 出栈
|
Integer top = stack.pop(); // 出栈
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -671,7 +671,7 @@ public class DequeExample {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -707,7 +707,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -729,7 +729,7 @@ public class ArraySortExample {
|
|||||||
System.out.println(Arrays.toString(numbers)); // 输出 [1, 2, 5, 5, 6, 9]
|
System.out.println(Arrays.toString(numbers)); // 输出 [1, 2, 5, 5, 6, 9]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```text
|
||||||
|
|
||||||
#### 集合排序
|
#### 集合排序
|
||||||
|
|
||||||
@ -752,7 +752,7 @@ public class ListSortExample {
|
|||||||
System.out.println(numbers); // 输出 [1, 2, 5, 5, 6, 9]
|
System.out.println(numbers); // 输出 [1, 2, 5, 5, 6, 9]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```text
|
||||||
|
|
||||||
#### **自定义排序**
|
#### **自定义排序**
|
||||||
|
|
||||||
@ -795,7 +795,7 @@ public class ComparatorSortExample {
|
|||||||
System.out.println(people); // 输出 [Alice (25), Bob (20), Charlie (30)]
|
System.out.println(people); // 输出 [Alice (25), Bob (20), Charlie (30)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@ build.gradle(:app)中引入了hwtxtreaderlib的依赖,而app只是个demo测
|
|||||||
|
|
||||||
- 在app的build.gradle中,添加依赖
|
- 在app的build.gradle中,添加依赖
|
||||||
|
|
||||||
```
|
```text
|
||||||
implementation project(':hwtxtreaderlib')
|
implementation project(':hwtxtreaderlib')
|
||||||
```
|
```
|
||||||
|
|
||||||
- 在settings.gradle中,设置项目包括的模块
|
- 在settings.gradle中,设置项目包括的模块
|
||||||
|
|
||||||
```
|
```text
|
||||||
include ':app', ':hwtxtreaderlib'
|
include ':app', ':hwtxtreaderlib'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
34
Java/微服务.md
34
Java/微服务.md
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
修改mp-demo中的`com.itheima.mp.mapper`包下的`UserMapper`接口,让其继承`BaseMapper`:
|
修改mp-demo中的`com.itheima.mp.mapper`包下的`UserMapper`接口,让其继承`BaseMapper`:
|
||||||
|
|
||||||
```
|
```text
|
||||||
public interface UserMapper extends BaseMapper<User> {
|
public interface UserMapper extends BaseMapper<User> {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -68,7 +68,7 @@ public class User {
|
|||||||
| value | String | 否 | "" | 主键字段名 |
|
| value | String | 否 | "" | 主键字段名 |
|
||||||
| type | Enum | 否 | IdType.NONE | 指定主键类型 |
|
| type | Enum | 否 | IdType.NONE | 指定主键类型 |
|
||||||
|
|
||||||
```
|
```text
|
||||||
@TableName("user")
|
@TableName("user")
|
||||||
public class User {
|
public class User {
|
||||||
@TableId(value="id",type=IdType.AUTO)
|
@TableId(value="id",type=IdType.AUTO)
|
||||||
@ -93,7 +93,7 @@ public class User {
|
|||||||
|
|
||||||
exist:默认为true,表示是数据库字段,若
|
exist:默认为true,表示是数据库字段,若
|
||||||
|
|
||||||
```
|
```text
|
||||||
@TableField(exist=false)
|
@TableField(exist=false)
|
||||||
private String address;
|
private String address;
|
||||||
```
|
```
|
||||||
@ -151,7 +151,7 @@ mybatis-plus:
|
|||||||
|
|
||||||
**QueryWrapper**
|
**QueryWrapper**
|
||||||
|
|
||||||
```
|
```text
|
||||||
/**查询出名字中带o的,存款大于等于1000元的人的id,username,info,balance
|
/**查询出名字中带o的,存款大于等于1000元的人的id,username,info,balance
|
||||||
* SELECT id,username,info,balance
|
* SELECT id,username,info,balance
|
||||||
* FROM user
|
* FROM user
|
||||||
@ -171,7 +171,7 @@ void testQueryWrapper(){
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
//更新用户名为jack的用户的余额为2000
|
//更新用户名为jack的用户的余额为2000
|
||||||
@Test
|
@Test
|
||||||
void testUpdateByQueryWrapper() {
|
void testUpdateByQueryWrapper() {
|
||||||
@ -192,7 +192,7 @@ void testUpdateByQueryWrapper() {
|
|||||||
UPDATE user SET balance = balance - 200 WHERE id in (1, 2, 4)
|
UPDATE user SET balance = balance - 200 WHERE id in (1, 2, 4)
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Test
|
@Test
|
||||||
void testUpdateWrapper() {
|
void testUpdateWrapper() {
|
||||||
List<Long> ids = List.of(1L, 2L, 4L);
|
List<Long> ids = List.of(1L, 2L, 4L);
|
||||||
@ -215,7 +215,7 @@ void testUpdateWrapper() {
|
|||||||
- LambdaQueryWrapper
|
- LambdaQueryWrapper
|
||||||
- LambdaUpdateWrapper
|
- LambdaUpdateWrapper
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Test
|
@Test
|
||||||
void testLambdaQueryWrapper() {
|
void testLambdaQueryWrapper() {
|
||||||
// 1.构建条件 WHERE username LIKE "%o%" AND balance >= 1000
|
// 1.构建条件 WHERE username LIKE "%o%" AND balance >= 1000
|
||||||
@ -242,7 +242,7 @@ void testLambdaQueryWrapper() {
|
|||||||
|
|
||||||
1.先在业务层利用wrapper创建条件,传递参数
|
1.先在业务层利用wrapper创建条件,传递参数
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Test
|
@Test
|
||||||
void testCustomWrapper() {
|
void testCustomWrapper() {
|
||||||
// 1.准备自定义查询条件
|
// 1.准备自定义查询条件
|
||||||
@ -256,7 +256,7 @@ void testCustomWrapper() {
|
|||||||
|
|
||||||
2. 自定义mapper层把wrapper和其他业务参数传进去,自定义sql语句书写sql的前半部分,后面拼接。
|
2. 自定义mapper层把wrapper和其他业务参数传进去,自定义sql语句书写sql的前半部分,后面拼接。
|
||||||
|
|
||||||
```
|
```text
|
||||||
package com.itheima.mp.mapper;
|
package com.itheima.mp.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
@ -287,7 +287,7 @@ selectBatchIds:根据主键 ID 批量查询记录。
|
|||||||
|
|
||||||
selectOne:根据指定条件查询单条记录。
|
selectOne:根据指定条件查询单条记录。
|
||||||
|
|
||||||
```
|
```text
|
||||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("username", "alice");
|
queryWrapper.eq("username", "alice");
|
||||||
User user = userMapper.selectOne(queryWrapper);
|
User user = userMapper.selectOne(queryWrapper);
|
||||||
@ -296,7 +296,7 @@ User user = userMapper.selectOne(queryWrapper);
|
|||||||
|
|
||||||
selectList:根据指定条件查询多条记录。
|
selectList:根据指定条件查询多条记录。
|
||||||
|
|
||||||
```
|
```text
|
||||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.ge("age", 18);
|
queryWrapper.ge("age", 18);
|
||||||
List<User> users = userMapper.selectList(queryWrapper);
|
List<User> users = userMapper.selectList(queryWrapper);
|
||||||
@ -309,7 +309,7 @@ List<User> users = userMapper.selectList(queryWrapper);
|
|||||||
|
|
||||||
insert:插入一条记录。
|
insert:插入一条记录。
|
||||||
|
|
||||||
```
|
```text
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setUsername("alice");
|
user.setUsername("alice");
|
||||||
user.setAge(20);
|
user.setAge(20);
|
||||||
@ -321,7 +321,7 @@ int rows = userMapper.insert(user);
|
|||||||
|
|
||||||
updateById:根据主键 ID 更新记录。
|
updateById:根据主键 ID 更新记录。
|
||||||
|
|
||||||
```
|
```text
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setId(1L);
|
user.setId(1L);
|
||||||
user.setAge(25);
|
user.setAge(25);
|
||||||
@ -331,7 +331,7 @@ int rows = userMapper.updateById(user);
|
|||||||
|
|
||||||
update:根据指定条件更新记录。
|
update:根据指定条件更新记录。
|
||||||
|
|
||||||
```
|
```text
|
||||||
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
|
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
|
||||||
updateWrapper.eq("username", "alice");
|
updateWrapper.eq("username", "alice");
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ deleteBatchIds:根据主键 ID 批量删除记录。
|
|||||||
|
|
||||||
delete:根据指定条件删除记录。
|
delete:根据指定条件删除记录。
|
||||||
|
|
||||||
```
|
```text
|
||||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("username", "alice");
|
queryWrapper.eq("username", "alice");
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ int rows = userMapper.delete(queryWrapper);
|
|||||||
|
|
||||||
首先,定义`IUserService`,继承`IService`:
|
首先,定义`IUserService`,继承`IService`:
|
||||||
|
|
||||||
```
|
```text
|
||||||
package com.itheima.mp.service;
|
package com.itheima.mp.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
@ -389,7 +389,7 @@ public interface IUserService extends IService<User> {
|
|||||||
|
|
||||||
然后,编写`UserServiceImpl`类,继承`ServiceImpl`,实现`UserService`:
|
然后,编写`UserServiceImpl`类,继承`ServiceImpl`,实现`UserService`:
|
||||||
|
|
||||||
```
|
```text
|
||||||
package com.itheima.mp.service.impl;
|
package com.itheima.mp.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
@ -72,20 +72,20 @@ build context(`context: .`):
|
|||||||
COPY . .(在 Dockerfile 中):
|
COPY . .(在 Dockerfile 中):
|
||||||
这条指令会将构建上下文中的所有内容复制到镜像中的当前工作目录(这里是 `/flask_project`)。
|
这条指令会将构建上下文中的所有内容复制到镜像中的当前工作目录(这里是 `/flask_project`)。
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker exec -it zbparse-flask_app-1 sh
|
docker exec -it zbparse-flask_app-1 sh
|
||||||
```
|
```
|
||||||
|
|
||||||
这个命令会直接进入到flask_project目录内部ls之后可以看到:
|
这个命令会直接进入到flask_project目录内部ls之后可以看到:
|
||||||
|
|
||||||
```
|
```text
|
||||||
Dockerfile README.md docker-compose.yml flask_app md_files requirements.txt
|
Dockerfile README.md docker-compose.yml flask_app md_files requirements.txt
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
如果这个基础上再` cd / `会切换到这个容器的根目录,可以看到flask_project文件夹以及其他基础系统环境。如:
|
如果这个基础上再` cd / `会切换到这个容器的根目录,可以看到flask_project文件夹以及其他基础系统环境。如:
|
||||||
|
|
||||||
```
|
```text
|
||||||
bin boot dev etc flask_project home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
|
bin boot dev etc flask_project home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -101,7 +101,7 @@ bin boot dev etc flask_project home lib lib64 media mnt opt proc roo
|
|||||||
|
|
||||||
**完整的容器名**
|
**完整的容器名**
|
||||||
|
|
||||||
```
|
```text
|
||||||
<项目名>-<服务名>-<序号>
|
<项目名>-<服务名>-<序号>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ docker exec -it **zbparse-flask_app-1** sh
|
|||||||
|
|
||||||
**删除所有悬空镜像**(无容器引用的 `<none>` 镜像)
|
**删除所有悬空镜像**(无容器引用的 `<none>` 镜像)
|
||||||
|
|
||||||
```
|
```text
|
||||||
docker image prune
|
docker image prune
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ docker image prune
|
|||||||
|
|
||||||
1.编写ps1脚本
|
1.编写ps1脚本
|
||||||
|
|
||||||
```
|
```text
|
||||||
# 切换到指定目录
|
# 切换到指定目录
|
||||||
cd D:\PycharmProjects\zbparse
|
cd D:\PycharmProjects\zbparse
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ python flask_app\run_serve.py
|
|||||||
打开系统环境变量Path,添加一条:C:\ProgramData\anaconda3\condabin
|
打开系统环境变量Path,添加一条:C:\ProgramData\anaconda3\condabin
|
||||||
|
|
||||||
或者 CMD 中 set PATH=%PATH%;新添加的路径
|
或者 CMD 中 set PATH=%PATH%;新添加的路径
|
||||||
```
|
```text
|
||||||
|
|
||||||
- 重启终端可以刷新环境变量
|
- 重启终端可以刷新环境变量
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ python flask_app\run_serve.py
|
|||||||
|
|
||||||
```
|
```
|
||||||
conda init powershell
|
conda init powershell
|
||||||
```
|
```text
|
||||||
|
|
||||||
4.进入到存放run.ps1文件的目录,在搜索栏中输入powershell
|
4.进入到存放run.ps1文件的目录,在搜索栏中输入powershell
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ conda init powershell
|
|||||||
|
|
||||||
```
|
```
|
||||||
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
|
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
|
|||||||
|
|
||||||
```
|
```
|
||||||
.\run.ps1
|
.\run.ps1
|
||||||
```
|
```text
|
||||||
|
|
||||||
**注意!!!**
|
**注意!!!**
|
||||||
|
|
||||||
@ -277,19 +277,19 @@ find "$ROOT_DIR" -mindepth 2 -depth -type d -mtime +7 -print -exec rm -rf {} \;
|
|||||||
|
|
||||||
echo "清理完成。"
|
echo "清理完成。"
|
||||||
|
|
||||||
```
|
```text
|
||||||
|
|
||||||
2. 添加权限。
|
2. 添加权限。
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo chmod +x ./clean_dir.sh
|
sudo chmod +x ./clean_dir.sh
|
||||||
```
|
```text
|
||||||
|
|
||||||
3. 执行
|
3. 执行
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo ./clean_dir.sh
|
sudo ./clean_dir.sh
|
||||||
```
|
```text
|
||||||
|
|
||||||
4. 以 root 用户的身份编辑 crontab 文件,从而设置或修改系统定时任务(cron jobs)。每天零点10分清理
|
4. 以 root 用户的身份编辑 crontab 文件,从而设置或修改系统定时任务(cron jobs)。每天零点10分清理
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ sudo crontab -e
|
|||||||
在里面添加:
|
在里面添加:
|
||||||
|
|
||||||
10 0 * * * /home/Z/clean_dir.sh
|
10 0 * * * /home/Z/clean_dir.sh
|
||||||
```
|
```text
|
||||||
|
|
||||||
**目前测试服务器和正式服务器都写上了!无需变动**
|
**目前测试服务器和正式服务器都写上了!无需变动**
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ END {
|
|||||||
print "管道FD:", pipe
|
print "管道FD:", pipe
|
||||||
print "其他FD:", other
|
print "其他FD:", other
|
||||||
}'
|
}'
|
||||||
```
|
```text
|
||||||
|
|
||||||
**可以发现文件FD很大,基本上发送一个请求文件FD就加一,且不会衰减:**
|
**可以发现文件FD很大,基本上发送一个请求文件FD就加一,且不会衰减:**
|
||||||
|
|
||||||
@ -362,7 +362,7 @@ def create_logger(app, subfolder):
|
|||||||
logger.propagate = False
|
logger.propagate = False
|
||||||
g.logger = logger
|
g.logger = logger
|
||||||
g.output_folder = output_folder #输出文件夹路径
|
g.output_folder = output_folder #输出文件夹路径
|
||||||
```
|
```text
|
||||||
|
|
||||||
handler:每当 logger 生成一条日志信息时,这条信息会被传递给所有关联的 handler,由 handler 决定如何输出这条日志。例如,`FileHandler` 会把日志写入文件,而 `StreamHandler` 会将日志输出到控制台。
|
handler:每当 logger 生成一条日志信息时,这条信息会被传递给所有关联的 handler,由 handler 决定如何输出这条日志。例如,`FileHandler` 会把日志写入文件,而 `StreamHandler` 会将日志输出到控制台。
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ mem_before = memory_usage()[0]
|
|||||||
result=my_function()
|
result=my_function()
|
||||||
mem_after = memory_usage()[0]
|
mem_after = memory_usage()[0]
|
||||||
print(f"Memory before: {mem_before} MiB, Memory after: {mem_after} MiB")
|
print(f"Memory before: {mem_before} MiB, Memory after: {mem_after} MiB")
|
||||||
```
|
```text
|
||||||
|
|
||||||
@profile注解加在函数上,可以逐行分析内存增减情况。
|
@profile注解加在函数上,可以逐行分析内存增减情况。
|
||||||
|
|
||||||
@ -425,7 +425,7 @@ def extract_text_by_page(file_path):
|
|||||||
page = reader.pages[page_num]
|
page = reader.pages[page_num]
|
||||||
text = page.extract_text()
|
text = page.extract_text()
|
||||||
return ""
|
return ""
|
||||||
```
|
```text
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -463,7 +463,7 @@ for stat in stats[:10]:
|
|||||||
print(stat)
|
print(stat)
|
||||||
# 停止内存分配跟踪
|
# 停止内存分配跟踪
|
||||||
tracemalloc.stop()
|
tracemalloc.stop()
|
||||||
```
|
```text
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -479,7 +479,7 @@ tracemalloc能更深入的分析,不仅是自己写的代码,**调用的库
|
|||||||
|
|
||||||
```
|
```
|
||||||
reader =PdfReader(file_path)
|
reader =PdfReader(file_path)
|
||||||
```
|
```text
|
||||||
|
|
||||||
能够确保文件正常关闭。但是没有效果。
|
能够确保文件正常关闭。但是没有效果。
|
||||||
|
|
||||||
@ -532,7 +532,7 @@ def run_in_subprocess(main_func, output_folder, file_path, file_type, unique_id)
|
|||||||
yield item
|
yield item
|
||||||
|
|
||||||
p.join()
|
p.join()
|
||||||
```
|
```text
|
||||||
|
|
||||||
如果开子线程,线程共享同一进程的内存空间,所以如果发生内存泄漏,泄漏的内存会累积在整个进程中,影响所有线程。
|
如果开子线程,线程共享同一进程的内存空间,所以如果发生内存泄漏,泄漏的内存会累积在整个进程中,影响所有线程。
|
||||||
|
|
||||||
@ -562,7 +562,7 @@ def judge_zbfile_exec_sub(file_path):
|
|||||||
args=(file_path,)
|
args=(file_path,)
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
```
|
```text
|
||||||
|
|
||||||
但是存在一个问题:**第一次发送请求执行时间较慢!**
|
但是存在一个问题:**第一次发送请求执行时间较慢!**
|
||||||
|
|
||||||
@ -589,7 +589,7 @@ def warmup_request():
|
|||||||
print(f"Warm-up 请求发送成功,状态码:{response.status_code}")
|
print(f"Warm-up 请求发送成功,状态码:{response.status_code}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Warm-up 请求出错:{e}")
|
print(f"Warm-up 请求出错:{e}")
|
||||||
```
|
```text
|
||||||
|
|
||||||
threading.Thread(target=warmup_request, daemon=True).start()
|
threading.Thread(target=warmup_request, daemon=True).start()
|
||||||
|
|
||||||
@ -621,7 +621,7 @@ def get_next_api_key():
|
|||||||
return next(api_keys)
|
return next(api_keys)
|
||||||
|
|
||||||
api_key = get_next_api_key()
|
api_key = get_next_api_key()
|
||||||
```
|
```text
|
||||||
|
|
||||||
只需轮流使用不同的api_key即可。目前没有启用。
|
只需轮流使用不同的api_key即可。目前没有启用。
|
||||||
|
|
||||||
@ -639,7 +639,7 @@ general/llm下的doubao.py 和通义千问long_plus.py
|
|||||||
@limits(calls=10, period=1) # 每秒最多调用10次
|
@limits(calls=10, period=1) # 每秒最多调用10次
|
||||||
def rate_limiter():
|
def rate_limiter():
|
||||||
pass # 这个函数本身不执行任何操作,只用于限流
|
pass # 这个函数本身不执行任何操作,只用于限流
|
||||||
```
|
```text
|
||||||
|
|
||||||
2. 这是qianwen-plus的限制(针对tpm为1000万,每个请求2万tokens,那么linux和windows总的qps为8时,8x60x2=960<1000。单个为4)
|
2. 这是qianwen-plus的限制(针对tpm为1000万,每个请求2万tokens,那么linux和windows总的qps为8时,8x60x2=960<1000。单个为4)
|
||||||
**经过2.11号测试,calls=4时最高TPM为800,因此把目前稳定版把calls设为5**
|
**经过2.11号测试,calls=4时最高TPM为800,因此把目前稳定版把calls设为5**
|
||||||
@ -651,14 +651,14 @@ def rate_limiter():
|
|||||||
@limits(calls=7, period=1) # 每秒最多调用7次
|
@limits(calls=7, period=1) # 每秒最多调用7次
|
||||||
def qianwen_plus(user_query, need_extra=False):
|
def qianwen_plus(user_query, need_extra=False):
|
||||||
logger = logging.getLogger('model_log') # 通过日志名字获取记录器
|
logger = logging.getLogger('model_log') # 通过日志名字获取记录器
|
||||||
```
|
```text
|
||||||
|
|
||||||
3. qianwen_turbo的限制(TPM为500万,由于它是plus后的手段,稳妥一点,qps设为6,两个服务器分流即calls=3)
|
3. qianwen_turbo的限制(TPM为500万,由于它是plus后的手段,稳妥一点,qps设为6,两个服务器分流即calls=3)
|
||||||
|
|
||||||
```
|
```
|
||||||
@sleep_and_retry
|
@sleep_and_retry
|
||||||
@limits(calls=3, period=1) # 500万tpm,每秒最多调用6次,两个服务器分流就是3次 (plus超限后的保底手段,稳妥一点)
|
@limits(calls=3, period=1) # 500万tpm,每秒最多调用6次,两个服务器分流就是3次 (plus超限后的保底手段,稳妥一点)
|
||||||
```
|
```text
|
||||||
|
|
||||||
**重点!!**后续阿里扩容之后成倍修改这块**calls=?**
|
**重点!!**后续阿里扩容之后成倍修改这块**calls=?**
|
||||||
|
|
||||||
@ -675,7 +675,7 @@ app.connection_limiters['upload'] = ConnectionLimiter(max_connections=100)
|
|||||||
app.connection_limiters['get_deviation'] = ConnectionLimiter(max_connections=100)
|
app.connection_limiters['get_deviation'] = ConnectionLimiter(max_connections=100)
|
||||||
app.connection_limiters['default'] = ConnectionLimiter(max_connections=100)
|
app.connection_limiters['default'] = ConnectionLimiter(max_connections=100)
|
||||||
app.connection_limiters['judge_zbfile'] = ConnectionLimiter(max_connections=100)
|
app.connection_limiters['judge_zbfile'] = ConnectionLimiter(max_connections=100)
|
||||||
```
|
```text
|
||||||
|
|
||||||
2. ConnectionLimiter.py以及每个接口上的装饰器,如
|
2. ConnectionLimiter.py以及每个接口上的装饰器,如
|
||||||
|
|
||||||
@ -683,7 +683,7 @@ app.connection_limiters['upload'] = ConnectionLimiter(max_connections=100)
|
|||||||
@require_connection_limit(timeout=1800)
|
@require_connection_limit(timeout=1800)
|
||||||
|
|
||||||
def zbparse():
|
def zbparse():
|
||||||
```
|
```text
|
||||||
|
|
||||||
这里限制了每个接口内部执行的时间,暂时设置到了30分钟!(不包括排队时间)超时就是解析失败
|
这里限制了每个接口内部执行的时间,暂时设置到了30分钟!(不包括排队时间)超时就是解析失败
|
||||||
|
|
||||||
@ -885,7 +885,7 @@ start_up.py是启动脚本,run_serve也是启动脚本,是对start_up.py的
|
|||||||
yield sse_format(shangwu_deviation_response)
|
yield sse_format(shangwu_deviation_response)
|
||||||
yield sse_format(shangwu_star_deviation_response)
|
yield sse_format(shangwu_star_deviation_response)
|
||||||
yield sse_format(proof_materials_response)
|
yield sse_format(proof_materials_response)
|
||||||
```
|
```text
|
||||||
|
|
||||||
1. 工程标解析目前仍没有解析采购要求这一块,因此后处理返回的只有'资格审查'和''证明材料"和"extracted_info",没有''商务偏离''及'商务带星偏离',也没有'技术偏离'和'技术带星偏离',而货物标解析是完全版。
|
1. 工程标解析目前仍没有解析采购要求这一块,因此后处理返回的只有'资格审查'和''证明材料"和"extracted_info",没有''商务偏离''及'商务带星偏离',也没有'技术偏离'和'技术带星偏离',而货物标解析是完全版。
|
||||||
|
|
||||||
@ -938,7 +938,7 @@ if __name__ == '__main__':
|
|||||||
# 使用 Waitress 启动(生产环境)
|
# 使用 Waitress 启动(生产环境)
|
||||||
from waitress import serve
|
from waitress import serve
|
||||||
serve(app, host='0.0.0.0', port=8080)
|
serve(app, host='0.0.0.0', port=8080)
|
||||||
```
|
```text
|
||||||
|
|
||||||
**Waitress 的工作方式**
|
**Waitress 的工作方式**
|
||||||
|
|
||||||
@ -986,14 +986,14 @@ serve(app, host='0.0.0.0', port=8080)
|
|||||||
|
|
||||||
```
|
```
|
||||||
pip install gevent
|
pip install gevent
|
||||||
```
|
```text
|
||||||
|
|
||||||
启动 Gunicorn 时指定 worker 类型和数量,例如:
|
启动 Gunicorn 时指定 worker 类型和数量,例如:
|
||||||
|
|
||||||
```
|
```
|
||||||
gunicorn -k gevent -w 4 --max-requests 100 flask_app.start_up:create_app --bind 0.0.0.0:5000
|
gunicorn -k gevent -w 4 --max-requests 100 flask_app.start_up:create_app --bind 0.0.0.0:5000
|
||||||
|
|
||||||
```
|
```text
|
||||||
|
|
||||||
使用 `-k gevent`(或者 `-k eventlet`)就可以使用异步 worker,单个 worker 能够处理多个 I/O 密集型请求。
|
使用 `-k gevent`(或者 `-k eventlet`)就可以使用异步 worker,单个 worker 能够处理多个 I/O 密集型请求。
|
||||||
|
|
||||||
@ -1063,7 +1063,7 @@ Python(特别是 CPython 实现)中有一个叫做全局解释器锁(Globa
|
|||||||
|
|
||||||
```
|
```
|
||||||
pool =Pool(processes=10, maxtasksperchild=3)
|
pool =Pool(processes=10, maxtasksperchild=3)
|
||||||
```
|
```text
|
||||||
|
|
||||||
**concurrent.futures.ProcessPoolExecutor**更高级、更统一,没有类似 `maxtasksperchild` 的参数,意味着进程在整个执行期内会一直存活,适合任务本身**比较稳定**的场景。
|
**concurrent.futures.ProcessPoolExecutor**更高级、更统一,没有类似 `maxtasksperchild` 的参数,意味着进程在整个执行期内会一直存活,适合任务本身**比较稳定**的场景。
|
||||||
|
|
||||||
@ -1105,7 +1105,7 @@ if __name__ == '__main__':
|
|||||||
t1.join()
|
t1.join()
|
||||||
t2.join()
|
t2.join()
|
||||||
print('主线程执行结果',num)
|
print('主线程执行结果',num)
|
||||||
```
|
```text
|
||||||
|
|
||||||
运行结果:
|
运行结果:
|
||||||
|
|
||||||
@ -1115,7 +1115,7 @@ work 1551626
|
|||||||
work1 1615783
|
work1 1615783
|
||||||
|
|
||||||
主线程执行结果 1615783
|
主线程执行结果 1615783
|
||||||
```
|
```text
|
||||||
|
|
||||||
这些数值都小于预期的 2000000,因为:
|
这些数值都小于预期的 2000000,因为:
|
||||||
|
|
||||||
@ -1166,7 +1166,7 @@ if __name__ == '__main__':
|
|||||||
t2.join()
|
t2.join()
|
||||||
print('主线程执行结果',num)
|
print('主线程执行结果',num)
|
||||||
|
|
||||||
```
|
```text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1200,7 +1200,7 @@ if __name__ == '__main__':
|
|||||||
results.append(q.get())
|
results.append(q.get())
|
||||||
|
|
||||||
print("Collected data:", results)
|
print("Collected data:", results)
|
||||||
```
|
```text
|
||||||
|
|
||||||
- 当你在主进程中创建了一个 `Queue` 对象,然后将它作为参数传递给子进程时,子进程会获得一个能够与主进程通信的“句柄”。
|
- 当你在主进程中创建了一个 `Queue` 对象,然后将它作为参数传递给子进程时,子进程会获得一个能够与主进程通信的“句柄”。
|
||||||
|
|
||||||
|
40
Java/苍穹外卖.md
40
Java/苍穹外卖.md
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
因为一般后台服务地址不会暴露,所以使用浏览器不能直接访问,可以把nginx作为请求访问的入口,请求到达nginx后转发到具体的服务中,从而保证后端服务的安全。
|
因为一般后台服务地址不会暴露,所以使用浏览器不能直接访问,可以把nginx作为请求访问的入口,请求到达nginx后转发到具体的服务中,从而保证后端服务的安全。
|
||||||
|
|
||||||
```
|
```text
|
||||||
server{
|
server{
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
@ -62,7 +62,7 @@ server{
|
|||||||
|
|
||||||
**2.负载均衡配置**(有两个后端服务器)
|
**2.负载均衡配置**(有两个后端服务器)
|
||||||
|
|
||||||
```
|
```text
|
||||||
upstream webservers{
|
upstream webservers{
|
||||||
server 192.168.100.128:8080;
|
server 192.168.100.128:8080;
|
||||||
server 192.168.100.129:8080;
|
server 192.168.100.129:8080;
|
||||||
@ -156,7 +156,7 @@ protected void addResourceHandlers(ResourceHandlerRegistry registry) {
|
|||||||
|
|
||||||
EmployeeLoginDTO.java
|
EmployeeLoginDTO.java
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Data
|
@Data
|
||||||
@ApiModel(description = "员工登录时传递的数据模型")
|
@ApiModel(description = "员工登录时传递的数据模型")
|
||||||
public class EmployeeLoginDTO implements Serializable {
|
public class EmployeeLoginDTO implements Serializable {
|
||||||
@ -188,7 +188,7 @@ spring security中提供了一个加密类BCryptPasswordEncoder。
|
|||||||
|
|
||||||
- 添加依赖
|
- 添加依赖
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
@ -197,7 +197,7 @@ spring security中提供了一个加密类BCryptPasswordEncoder。
|
|||||||
|
|
||||||
- 添加配置
|
- 添加配置
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
@ -218,7 +218,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
|
|
||||||
- 使用
|
- 使用
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Autowired
|
@Autowired
|
||||||
private BCryptPasswordEncoder bCryptPasswordEncoder;
|
private BCryptPasswordEncoder bCryptPasswordEncoder;
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ ThreadLocal为**每个线程**提供**单独**一份存储空间,具有线程
|
|||||||
|
|
||||||
**每次请求代表一个线程**!!!注:请求可以先经过拦截器,再经过controller=>service=>mapper,都是在一个线程里。
|
**每次请求代表一个线程**!!!注:请求可以先经过拦截器,再经过controller=>service=>mapper,都是在一个线程里。
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class BaseContext {
|
public class BaseContext {
|
||||||
|
|
||||||
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
|
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
|
||||||
@ -321,7 +321,7 @@ public class BaseContext {
|
|||||||
|
|
||||||
JacksonObjectMapper()文件:
|
JacksonObjectMapper()文件:
|
||||||
|
|
||||||
```
|
```text
|
||||||
public class JacksonObjectMapper extends ObjectMapper {
|
public class JacksonObjectMapper extends ObjectMapper {
|
||||||
|
|
||||||
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
|
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
|
||||||
@ -373,7 +373,7 @@ public void startOrStop(Integer status, Long id) {
|
|||||||
|
|
||||||
还有一种:把源对象source的属性值赋给目标**对象**target中与源**对象**source的中有着同属性名的属性
|
还有一种:把源对象source的属性值赋给目标**对象**target中与源**对象**source的中有着同属性名的属性
|
||||||
|
|
||||||
```
|
```text
|
||||||
BeanUtils.copyProperties(source,target);
|
BeanUtils.copyProperties(source,target);
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -566,7 +566,7 @@ public class SpringDataRedisTest {
|
|||||||
|
|
||||||
**哈希测试**
|
**哈希测试**
|
||||||
|
|
||||||
```
|
```text
|
||||||
/**
|
/**
|
||||||
* 操作哈希类型的数据
|
* 操作哈希类型的数据
|
||||||
*/
|
*/
|
||||||
@ -725,7 +725,7 @@ public class SpringDataRedisTest {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
public static String doGet(String url,Map<String,String> paramMap){
|
public static String doGet(String url,Map<String,String> paramMap){
|
||||||
// 创建Httpclient对象
|
// 创建Httpclient对象
|
||||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||||
@ -800,7 +800,7 @@ public static String doGet(String url,Map<String,String> paramMap){
|
|||||||
- 每个分类下的菜品保存一份缓存数据
|
- 每个分类下的菜品保存一份缓存数据
|
||||||
- 数据库中菜品数据有**变更时清理缓存数据**
|
- 数据库中菜品数据有**变更时清理缓存数据**
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate redisTemplate;
|
private RedisTemplate redisTemplate;
|
||||||
/**
|
/**
|
||||||
@ -847,7 +847,7 @@ public static String doGet(String url,Map<String,String> paramMap){
|
|||||||
|
|
||||||
清理缓冲方法:
|
清理缓冲方法:
|
||||||
|
|
||||||
```
|
```text
|
||||||
private void cleanCache(String pattern){
|
private void cleanCache(String pattern){
|
||||||
Set keys = redisTemplate.keys(pattern);
|
Set keys = redisTemplate.keys(pattern);
|
||||||
redisTemplate.delete(keys);
|
redisTemplate.delete(keys);
|
||||||
@ -860,7 +860,7 @@ public static String doGet(String url,Map<String,String> paramMap){
|
|||||||
|
|
||||||
Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
|
Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
|
||||||
|
|
||||||
```
|
```text
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-cache</artifactId> <version>2.7.3</version>
|
<artifactId>spring-boot-starter-cache</artifactId> <version>2.7.3</version>
|
||||||
@ -894,7 +894,7 @@ Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@CachePut(value = "userCache", key = "#user.id")//key的生成:userCache::1
|
@CachePut(value = "userCache", key = "#user.id")//key的生成:userCache::1
|
||||||
public User save(@RequestBody User user){
|
public User save(@RequestBody User user){
|
||||||
@ -917,7 +917,7 @@ Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要
|
|||||||
|
|
||||||
所以,@Cacheable(cacheNames = "userCache",key="#id")中的#id表示的是函数形参中的id,而不能是返回值中的user.id
|
所以,@Cacheable(cacheNames = "userCache",key="#id")中的#id表示的是函数形参中的id,而不能是返回值中的user.id
|
||||||
|
|
||||||
```
|
```text
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@Cacheable(cacheNames = "userCache",key="#id")
|
@Cacheable(cacheNames = "userCache",key="#id")
|
||||||
public User getById(Long id){
|
public User getById(Long id){
|
||||||
@ -930,7 +930,7 @@ Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要
|
|||||||
|
|
||||||
作用: 清理指定缓存
|
作用: 清理指定缓存
|
||||||
|
|
||||||
```
|
```text
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
@CacheEvict(cacheNames = "userCache",key = "#id")//删除某个key对应的缓存数据
|
@CacheEvict(cacheNames = "userCache",key = "#id")//删除某个key对应的缓存数据
|
||||||
public void deleteById(Long id){
|
public void deleteById(Long id){
|
||||||
@ -992,13 +992,13 @@ https://pay.weixin.qq.com/static/product/product_index.shtml
|
|||||||
|
|
||||||
输入代码:
|
输入代码:
|
||||||
|
|
||||||
```
|
```text
|
||||||
cpolar.exe authtoken ZmIwMmQzZDYtZDE2ZS00ZGVjLWE2MTUtOGQ0YTdhOWI2M2Q1
|
cpolar.exe authtoken ZmIwMmQzZDYtZDE2ZS00ZGVjLWE2MTUtOGQ0YTdhOWI2M2Q1
|
||||||
```
|
```
|
||||||
|
|
||||||
3)获取临时域名
|
3)获取临时域名
|
||||||
|
|
||||||
```
|
```text
|
||||||
cpolar.exe http 8080
|
cpolar.exe http 8080
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -1060,7 +1060,7 @@ cron表达式在线生成器:https://cron.qqe2.com/
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```text
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class OrderTask {
|
public class OrderTask {
|
||||||
|
11
update.bat
Normal file
11
update.bat
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
@echo off
|
||||||
|
REM 添加所有改动
|
||||||
|
git add .
|
||||||
|
|
||||||
|
REM 使用当前的日期和时间作为提交信息
|
||||||
|
git commit -m "Commit on %date% %time%"
|
||||||
|
|
||||||
|
REM 推送到远程仓库
|
||||||
|
git push
|
||||||
|
|
||||||
|
pause
|
@ -83,7 +83,7 @@ $$
|
|||||||
|
|
||||||
当误差超过某个预定阈值时,禁用积分作用,仅使用比例(P)和微分(D)控制来快速减小误差,避免因积分作用导致的控制器输出过度响应。
|
当误差超过某个预定阈值时,禁用积分作用,仅使用比例(P)和微分(D)控制来快速减小误差,避免因积分作用导致的控制器输出过度响应。
|
||||||
|
|
||||||
```
|
```text
|
||||||
if (abs(error) > threshold) {
|
if (abs(error) > threshold) {
|
||||||
// 积分作用被分离,即暂时禁用积分作用
|
// 积分作用被分离,即暂时禁用积分作用
|
||||||
integral = 0;
|
integral = 0;
|
||||||
|
@ -321,7 +321,7 @@ $$
|
|||||||
|
|
||||||
假设我们有一个简单的无向图,包含 4 个节点和 4 条边,结构如下:
|
假设我们有一个简单的无向图,包含 4 个节点和 4 条边,结构如下:
|
||||||
|
|
||||||
```
|
```text
|
||||||
1 — 2 — 3
|
1 — 2 — 3
|
||||||
|
|
|
|
||||||
4
|
4
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
3. **对节点顺序敏感** ,节点编号顺序一变,输入就完全变样,但其实图的拓扑并没变(仅节点编号/排列方式不同)。
|
3. **对节点顺序敏感** ,节点编号顺序一变,输入就完全变样,但其实图的拓扑并没变(仅节点编号/排列方式不同)。
|
||||||
|
|
||||||
```
|
```text
|
||||||
A —— B
|
A —— B
|
||||||
| |
|
| |
|
||||||
D —— C
|
D —— C
|
||||||
@ -78,7 +78,7 @@
|
|||||||
1. **聚合(Aggregation)**:将邻居节点的特征聚合起来(如求和、均值、最大值等)。
|
1. **聚合(Aggregation)**:将邻居节点的特征聚合起来(如求和、均值、最大值等)。
|
||||||
2. **变换(Transformation)**:将聚合后的特征通过一个神经网络(如 MLP)进行非线性变换。
|
2. **变换(Transformation)**:将聚合后的特征通过一个神经网络(如 MLP)进行非线性变换。
|
||||||
|
|
||||||
```
|
```text
|
||||||
A
|
A
|
||||||
|
|
|
|
||||||
B
|
B
|
||||||
|
Loading…
x
Reference in New Issue
Block a user