0%

-c: 建立压缩档案
-x:解压
-t:查看内容
-r:向压缩归档文件末尾追加文件
-u:更新原压缩包中的文件

这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。

-z:有gzip属性的
-j:有bz2属性的
-Z:有compress属性的
-v:显示所有过程
-O:将文件解开到标准输出

-C: 指定目录

下面的参数-f是必须的

-f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。

# tar -cf all.tar *.jpg
这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示产生新的包,-f指定包的文件名。

# tar -rf all.tar *.gif

这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。

# tar -uf all.tar logo.gif
这条命令是更新原来tar包all.tar中logo.gif文件,-u是表示更新文件的意思。

# tar -tf all.tar
这条命令是列出all.tar包中所有文件,-t是列出文件的意思

# tar -xf all.tar
这条命令是解出all.tar包中所有文件,-x是解开的意思

压缩

tar –cvf jpg.tar *.jpg //将目录里所有jpg文件打包成tar.jpg

tar –czf jpg.tar.gz *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用gzip压缩,生成一个gzip压缩过的包,命名为jpg.tar.gz

tar –cjf jpg.tar.bz2 *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用bzip2压缩,生成一个bzip2压缩过的包,命名为jpg.tar.bz2

tar –cZf jpg.tar.Z *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用compress制定压缩,生成一个umcompress压缩过的包,命名为jpg.tar.Z

rar a jpg.rar *.jpg //rar格式的压缩,需要先下载rar for linux

zip jpg.zip *.jpg //zip格式的压缩,需要先下载zip for linux

解压

tar –xvf file.tar //解压 tar包

tar -xzvf file.tar.gz //解压tar.gz

tar -xjvf file.tar.bz2 //解压 tar.bz2

tar –xZvf file.tar.Z //解压tar.Z

unrar e file.rar //解压rar

unzip file.zip //解压zip

总结

1、*.tar 用 tar –xvf 解压

2、*.gz 用 gzip -d或者gunzip 解压

3、*.tar.gz和*.tgz 用 tar –xzf 解压

4、*.bz2 用 bzip2 -d或者用bunzip2 解压

5、*.tar.bz2用tar –xjf 解压

6、*.Z 用 uncompress 解压

7、*.tar.Z 用tar –xZf 解压

8、*.rar 用 unrar e解压

9、*.zip 用 unzip 解压

本文地址: https://github.com/maxzhao-it/blog/post/10705/

上一篇文章Docker从0安装MySql8(Linux)欢迎阅读。

默认自己已经会用 Docker 并且已经使用了国内源。

安装 PostgreSql

一、镜像安装

查找 PostgreSql 镜像

1
sudo docker search postgresql

获取 PostgreSql 镜像

1
sudo  docker pull postgres

这里下载好的镜像为最新版的 PostgreSql

Downloaded newer image for postgres:latest

启动镜像

1
2
3
4
5
6
7
# 创建容器
sudo docker run --name postgres -e POSTGRES_PASSWORD=maxzhao -p 5432:5432 -d postgres:latest
# 进入容器
sudo docker exec -it postgres bash
# 登录 PostgreSql maxzhao
# 注意:这是容器内登录 U大写
psql -Upostgres -dpostgres

修改 PostgreSql 的配置

查看文件在容器内的位置,进入容器之后,一般就在下面目录中

1
cd /var/lib/postgresql/data/
  • pg_hba.conf
  • postgresql.conf

1、从容器拷贝文件到宿主机

1
sudo docker cp postgres:/var/lib/postgresql/data/pg_hba.conf  /home/maxzhao/soft/postgresql/

2、从宿主机拷贝文件到容器

1
sudo docker cp /home/maxzhao/soft/postgresql/pg_hba.conf postgres:/var/lib/postgresql/data/

3、提交修改

1
sudo docker commit -m "描述内容" -a "maxzhao" postgres  postgres:latest

其中,-m 来指定提交的说明信息,跟我们使用的版本控制工具一样;-a 可以指定更新的用户信息;之后是用来创建镜像的容器的 ID;最后指定目标镜像的仓库名和 tag 信息。

创建成功后会返回这个镜像的 ID 信息。

查看容器运行情况

1
docker ps 

查看镜像

1
2
sudo docker images
sudo docker ps

启动镜像

1
sudo docker start mysql

RUN | START

docker run 只在第一次运行时使用,将镜像放到容器中,以后再次启动这个容器时,只需要使用命令docker start 即可。

推荐:

Docker从0安装MySql8(Linux)

MySQL8.0创建用户及其配置

本文地址: https://github.com/maxzhao-it/blog/post/33142/

前言

当前 ArchLinux 的安装需要有一定的基础,如果基础薄弱,可以选择其它容易上手的发行版,先试试。

比如 Manjaro Linux ,这里也有详细的安装介绍

此处安装为 UEFI + GPT 安装。

这里可能还要抨击一下 时间在 2019年之前的所有的安装教程,他们写的都不对

一、制作启动盘

略过。

可以参考U盘安装manjaro

二、安装 Arch Linux

U盘启动选择第一项直接启动,这里不需要过多的操作。

联网

这里选择的联网方式为手机USB 联网,手机直接用 USB 共性网络,然后在命令行执行

1
2
dhcpcd
ping www.baidu.com

如果有响应则 ctrl + c 取消。

附:如果像我一样是个新手,并且还想体验“高深”技术的乐趣,那么最好不要搞那些花里胡哨的操作,因为系统会崩溃,然后会造成重装,其实多重装几次也是不错的,我自己重装了五六次,现在都不要看文档就可以装了。

编辑镜像文件(下载用的源)

编辑

1
sudo vim  /etc/pacman.d/mirrorlist 

然后在开头写入

1
2
3
4
Server = http://mirrors.aliyun.com/archlinux/$repo/os/$arch
Server = http://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch
# 清华大学
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch

然后刷新

1
sudo pacman -Syy

分区

这里只解释用单独硬盘打分区(UEFI+GPT

我们选择 2 个分区,

  1. fat16 为 esp
  2. ext4 为 系统
1
2
3
4
5
6
7
8
9
10
11
lsblk  # 查看硬盘
fdisk /dev/sda # sda是需要甄别的,我的安装硬盘就是 sda
# 这里会提示操作 输入
n #回车
#回车
+300M # 回车 这里是分区的大小
#输入
n #回车
#回车
#回车
w #保存

分区还是很简单的,下面是格式化

1
2
3
mkfs.fat -F16 /dev/sda1 # sda 是上面我们使用的硬盘
mkfs.ext4 /dev/sda2 # 多次回车就可以啦
mkfs.ext4 /dev/sda2 # 查询全部池畔的格式

挂载

1
2
3
4
mount /dev/sda2 /mnt  # sda 是上面我们使用的硬盘
mkdir -p /mnt/boot/EFI
mount /dev/sda1 /mnt/boot/EFI
lsblk #可以详细的看到我们的挂载位置

安装系统

这里需要大量的流量,如果使用 USB 共享网络,建议连WIFI

1
pacstrap -i /mnt base base-devel linux  linux-firmware

其中

  1. base base-devel 是基础
  2. linux linux-firmware 是内核

配置基础系统

配置 fstab

1
2
genfstab -U /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab #里面的 UUID 要与 我们硬盘的UUID匹配

如果我们多次格式化硬盘,需要重新生成 fstab,防止 硬盘的 UUID 不同。

切换到新系统

1
arch-chroot /mnt

安装 vim

1
pacman -S vim

进行本地语言设置

1
vim /etc/locale.gen

开头写入 或者找到注释掉的此代码,删除注释

1
2
en_US.UTF-8 UTF-8
zh_CN.UTF-8 UTF-8

刷新

1
2
locale-gen 
echo LANG=en_US.UTF-8 > /etc/locale.conf

设置时区

执行

1
2
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ntpdate time1.aliyun.com

设置硬件时间

1
hwclock --systohc --utc

安装引导(重点)

安装

1
pacman -S dosfstools grub efibootmgr

如果还有 Windows

还需要安装

1
pacman -S os-prober

部署

1
grub-install --target=x86_64-efi --efi-directory=/boot/EFI --recheck

生成grub.cfg

1
grub-mkconfig -o /boot/grub/grub.cfg

用户管理

1
2
3
passwd  #设置管理密码
useradd -m maxzhao
passwd maxzhao # 设置用户密码

编辑 sudo 权限

1
vim  /etc/sudoers

root ALL=(ALL) ALL 下面添加
maxzhao ALL=(ALL) ALL

重启

重启之前,安装网络,不然重启了也不能联网

1
2
pacman -S dhcp dhcpcd  net-tools  NetworkManager 
pacman -S iw wpa_supplicant # 无线

重启

1
2
exit
reboot

重启之后,root 登录,还是继续使用手机USB共享,方便。

启动基础网络服务

1
2
3
4
systemctl  enable  dhcpcd
systemctl start dhcpcd
systemctl enable NetworkManager
systemctl start NetworkManager

手机共享网络之后

1
dhcpcd

基础安装到此结束,下面安装 GNOME 界面


三、图形界面安装

下面开始安装图形界面

Xorg

首先是装Xorg

  1. pacman -S xorg xorg-server xorg-xinit

触摸板驱动

  1. pacman -S xf86-input-synaptics

显卡驱动

确定显卡型号

1
2
3
4
lspci | grep VGA  
# 下面是我的
00:02.0 VGA compatible controller: Intel Corporation UHD Graphics 630 (Mobile)
01:00.0 VGA compatible controller: NVIDIA Corporation GP107M [GeForce GTX 1050 3 GB Max-Q] (rev a1)

下面安装显卡驱动

1
2
pacman -S nvidia 
pacman -S xf86-video-intel

也可以如下

intel

  1. pacman -S xf86-video-intel

英伟达

  1. pacman -S xf86-video-nv

GNOME桌面

gnome桌面只要安装gnome包即可,还有一个 gnome-extra 包可以提供额外的常用软件和几个游戏,你可以安装时选择你要的软件,没有必要全选,当然也可以不装这个包,我这里只选了 gnome-tweak-tool这个工具

pacman -S gnome gnome-extra gnome-tweak-tool

然后安装gdm登录管理器

pacman -S gnome gdm

gdm 设置为开机自启动,这样开机时会自动载入桌面

systemctl enable gdm

配置源

打开 vim /etc/pacman.conf,在末尾加上

1
2
3
[archlinuxcn]
SigLevel = Optional TrustAll
Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch

或者

1
2
3
[archlinuxcn]
SigLevel = Optional TrustAll
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch

然后安装 key

1
2
sudo pacman -S archlinuxcn-keyring
sudo pacman -Sy

中文字体

没有中文字体,就不能使用gnome-terminal

1
sudo pacman -S wqy-microhei ttf-dejavu wqy-zenhei wqy-microhei wqy-bitmapfont adobe-source-han-sans-cn-fonts adobe-source-han-serif-cn-fonts

刷新字体

1
fc-cache -fv

搜狗输入法

安装依赖

1
2
3
sudo pacman -S fcitx
sudo pacman -S fcitx-configtool
sudo pacman -S fcitx-gtk2 fcitx-gtk3 fcitx-qt4 fcitx-qt5

安装搜狗

1
sudo pacman -S fcitx-sogoupinyin

安装配置工具

1
sudo pacman -S fcitx-configtool

配置搜狗

vim ~/.xprofile

1
2
3
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS="@im=fcitx"

安装 Google Pinyin

1
sudo pacman -S fcitx-googlepinyin

扩展

对于特定用户,还可以在~/.bashrc~/.xinitrc~/.xprofile中设置自己的用户环境。不同之处在于:

  • .bashrc: 每次终端登录时读取并运用里面的设置。
  • .xinitrc: 每次startx启动X界面时读取并运用里面的设置
  • .xprofile: 每次使用gdm等图形登录时读取并运用里面的设

yaourt 或者 yay

Yaourt archlinux 方便使用的关键部件之一,但没有被整合到系统安装中的工具。建议在装完系统重启之后,更新完pacman和基本系统之后,就安装这个工具。
最简单安装 Yaourt的方式是arclinuxcn源

1
pacman -Syu yaourt

四、arch-gnome 编程环境和其它环境安装

Linux上IDEA激活

五、美化

GNOME图标包

这里我使用的 numix-circle 图标包,这个图标包在 aur 里,直接用yaourt即可

pacman -S numix-circle-icon-theme-git

然后在 gnome-tweak-tool 里启用主题

gdm 背景

输入以下指令

1
2
3
curl -L -O http://archibold.io/sh/archibold
sudo chmod +x archibold
./archibold login-backgroung 你的背景的地址

重启后gdm就会变成你要的背景

gnome-shell主题

首先在gnome-tweak-tool里的拓展里启用User themes

然后安装主题,这里我是用的贴吧的@Air_WaweiAir主题,并自己做了些修改。

首先下载主题 然后解压,将Air文件夹放到/usr/share/themes/文件夹里,在gnome-tweak-tool里启用主题

gnome-shell拓展

shell拓展请进入https://extensions.gnome.org/自行按照说明安装

screenfetch 命令行

1
sudo pacman -S screenfetch

要让screenfetch在打开终端是自动输出,在~/.bashrc里加入

screenfetch

效果如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
                  -`                 
.o+` maxzhao@maxzhao-pc
`ooo/ OS: Arch Linux
`+oooo: Kernel: x86_64 Linux 5.3.6-arch1-1-ARCH
`+oooooo: Uptime: 53m
-+oooooo+: Packages: 948
`/:-:++oooo+: Shell: bash
`/++++/+++++++: Resolution: 1920x1080
`/++++++++++++++: DE: GNOME 3.34.1
`/+++ooooooooooooo/` WM: Mutter
./ooosssso++osssssso+` WM Theme:
.oossssso-````/ossssss+` GTK Theme: Adwaita-dark [GTK2/3]
-osssssso. :ssssssso. Icon Theme: Adwaita
:osssssss/ osssso+++. Font: Cantarell 12
/ossssssss/ +ssssooo/- Disk: 8.1G / 443G (2%)
`/ossssso+/:- -:/+osssso+- CPU: Intel Core i7-9750H @ 12x 4.5GHz [53.0°C]
`+sso+:-` `.-/+oso: GPU: GeForce GTX 1050
`++:. `-/+/ RAM: 2807MiB / 7833MiB
.` `/

花里胡哨,没有任何意义

不如直接加上 set nu,给命令行编辑文本添加行号。

Terminal 字体颜色

参考

这里有一个 gentoo-bashrc

1
2
yaourt gentoo-bashrc
cp /usr/share/gentoo-bashrc/bashrc ~/.bashrc

Dock

MacOS 一样的 dock

1
sudo pacman -S dash-to-dock

这里我失败了,显示错误:未找到目标:dash-to-dock

但是 dock却出现在了我的屏幕左边!!!

六、问题:

开机1分30秒过程

原因:可能是开启了一些自启服务,可以到目录
/etc/systemd/system/multi-user.target.wants下查看。

可以使用systemctl disable XXX服务 关闭当前服务的自启。

本文地址: https://github.com/maxzhao-it/blog/post/37802/

前言

vim 是我比较喜欢但又不熟练的编辑器, 我虽然已经不是初学 vi , 但遇到不会的命令还是喜欢执行一下vimtutor 或者 vimtutor zh, 这会让我豁然开朗.

Vim 的几种运行模式

  • 正常模式:可以使用快捷键命令,或按:输入命令行。
  • 插入模式:可以输入文本,在正常模式下,按i、a、o等都可以进入插入模式。
  • 可视模式:正常模式下按v可以进入可视模式, 在可视模式下,移动光标可以选择文本。按V进入可视行模式, 总是整行整行的选中。ctrl+v进入可视块模式。
  • 替换模式:正常模式下,按R进入。

也可以传统的分为

  • 命令模式
  • 输入模式
  • 底线命令模式

vim-vi-workmodel

Vim 常用操作

启动操作

  • vim file: 打开文档;
  • vim + file: 从文件的打开文档;
  • vim +num file: 从第num行开始;

插入操作

在命令模式下执行:

  • a : 在光标后插入
  • o : 在当前行后插入一个新行
  • O : 在当前行前插入一个新行
  • cw : 替换从光标所在位置后到一个单词结尾的字符

简单移动光标

在命令模式下执行:

  • 0 : 数字零,到行头
  • ^ : 到本行第一个不是blank字符的位置(所谓blank字符就是空格,tab,换行,回车等)
  • $ : 到本行行尾
  • /pattern 搜索 pattern 的字符串,n下一个,N上一个

文档跳转

  • [n]G : 到第 N 行 (陈皓注:注意命令中的G是大写的,另我一般使用 : N 到第N行,如 :137 到第137行)
  • gg : 到第一行。(陈皓注:相当于1G,或 :1)
  • G : 到最后一行。
  • w : 到下一个单词的开头(下划线,数字分割)。
  • e : 到下一个单词的结尾(下划线,数字分割)。
  • W : 到下一个单词的开头(空格)。
  • W : 到下一个单词的结尾(空格)。

复制粘贴

  • P : 当前位置之前粘贴

  • p : 当前位置之后粘贴

  • y : 复制可视模式下选中的文本

  • yy or Y: 拷贝当前行当行于

  • y[n]w: 复制一(n)个词。 备注: 所有的 w 都代表一个单词,比如 命令行的 ctrl + w 消除一个单词

  • y[n]l: 复制光标右边1(n)个字符。

  • y[n]h: 复制光标左边1(n)个字符。

  • [n]x: 剪切光标右边n个字符,相当于d[n]l。

  • [n]X: 剪切光标左边n个字符,相当于d[n]h。

  • d[n]w: 删除(剪切)1(n)个单词

  • d[n]l: 删除(剪切)光标右边1(n)个字符。

  • d[n]h: 删除(剪切)光标左边1(n)个字符。

  • d0: 删除(剪切)当前位置到行首的内容

  • [n] dd: 删除(剪切)1(n)行。

  • :m,nd 剪切m行到n行的内容。

保存推出

  • :e <path/to/file> : 打开一个文件
  • :w : 存盘
  • :q! : 退出不保存 :qa! 强行退出所有的正在编辑的文件,就算别的文件有更改。
  • :wq : 保存并推出
  • :saveas <path/to/file> : 另存为 <path/to/file>
  • :xZZ:wq : 保存并退出 (:x 表示仅在需要时保存,ZZ不需要输入冒号并回车)
  • :bn:bp : 你可以同时打开很多文件,使用这两个命令来切换下一个或上一个文件。

到此处还觉得不够用,可以继续向下阅读强化自己,加油勇士.

Vim 详细解读

Vim 操作

启动时操作

  • vim -c cmd file: 在打开文件前,先执行指定的命令;
  • vim -r file: 恢复上次异常退出的文件;
  • vim -R file: 以只读的方式打开文件,但可以强制保存;
  • vim -M file: 以只读的方式打开文件,不可以强制保存;
  • vim -y num file: 将编辑窗口的大小设为num行;
  • vim + file: 从文件的末尾开始;
  • vim +num file: 从第num行开始;
  • vim +/string file: 打开file,并将光标停留在第一个找到的string上。
  • vim –remote file: 用已有的vim进程打开指定的文件。 如果你不想启用多个vim会话,这个很有用。但要注意, 如果你用vim,会寻找名叫VIM的服务器;如果你已经有一个gvim在运行了, 你可以用gvim –remote file在已有的gvim中打开文件。

文档操作

  • :e file –关闭当前编辑的文件,并开启新的文件。 如果对当前文件的修改未保存,vi会警告。
  • :e! file –放弃对当前文件的修改,编辑新的文件。
  • :e+file – 开始新的文件,并从文件尾开始编辑。
  • :e+n file – 开始新的文件,并从第n行开始编辑。
  • :enew –编译一个未命名的新文档。(CTRL-W n)
  • :e – 重新加载当前文档。
  • :e! – 重新加载当前文档,并丢弃已做的改动。
  • :e#或ctrl+^ – 回到刚才编辑的文件,很实用。
  • :f或ctrl+g – 显示文档名,是否修改,和光标位置。
  • :f filename – 改变编辑的文件名,这时再保存相当于另存为。
  • gf – 打开以光标所在字符串为文件名的文件。
  • :w – 保存修改。
  • :n1,n2w filename – 选择性保存从某n1行到另n2行的内容。
  • :wq – 保存并退出。
  • ZZ – 保存并退出。
  • :x – 保存并退出。
  • :q[uit] ——退出当前窗口。(CTRL-W q或CTRL-W CTRL-Q)
  • :saveas newfilename – 另存为
  • :browse e – 会打开一个文件浏览器让你选择要编辑的文件。 如果是终端中,则会打开netrw的文件浏览窗口; 如果是gvim,则会打开一个图形界面的浏览窗口。 实际上:browse后可以跟任何编辑文档的命令,如sp等。 用browse打开的起始目录可以由browsedir来设置:
    • :set browsedir=last – 用上次访问过的目录(默认);
    • :set browsedir=buffer – 用当前文件所在目录;
    • :set browsedir=current – 用当前工作目录;
  • :Sex – 水平分割一个窗口,浏览文件系统;
  • :Vex – 垂直分割一个窗口,浏览文件系统;

光标移动

基本移动

  • h或退格: 左移一个字符;
  • l或空格: 右移一个字符;
  • j: 下移一行;
  • k: 上移一行;
  • gj: 移动到一段内的下一行;
  • gk: 移动到一段内的上一行;
  • +或Enter: 把光标移至下一行第一个非空白字符。
  • -: 把光标移至上一行第一个非空白字符。
  • w: 前移一个单词,光标停在下一个单词开头;
  • W: 移动下一个单词开头,但忽略一些标点;
  • e: 前移一个单词,光标停在下一个单词末尾;
  • E: 移动到下一个单词末尾,如果词尾有标点,则移动到标点;
  • b: 后移一个单词,光标停在上一个单词开头;
  • B: 移动到上一个单词开头,忽略一些标点;
  • ge: 后移一个单词,光标停在上一个单词末尾;
  • gE: 同 ge ,不过‘单词’包含单词相邻的标点。
  • (: 前移1句。
  • ): 后移1句。
  • {: 前移1段。
  • }: 后移1段。
  • fc: 把光标移到同一行的下一个c字符处
  • Fc: 把光标移到同一行的上一个c字符处
  • tc: 把光标移到同一行的下一个c字符前
  • Tc: 把光标移到同一行的上一个c字符后
  • ;: 配合f & t使用,重复一次
  • ,: 配合f & t使用,反向重复一次

上面的操作都可以配合n使用,比如在正常模式(下面会讲到)下输入3h, 则光标向左移动3个字符。

  • 0: 移动到行首。
  • g0: 移到光标所在屏幕行行首。
  • ^: 移动到本行第一个非空白字符。
  • g^: 同 ^ ,但是移动到当前屏幕行第一个非空字符处。
  • : 移动光标所在屏幕行行尾。
  • n|: 把光标移到递n列上。
  • nG: 到文件第n行。
  • :n 移动到第n行。
  • :$ 移动到最后一行。
  • H: 把光标移到屏幕最顶端一行。
  • M: 把光标移到屏幕中间一行。
  • L: 把光标移到屏幕最底端一行。
  • gg: 到文件头部。
  • G: 到文件尾部。

翻屏

  • ctrl+f: 下翻一屏。
  • ctrl+b: 上翻一屏。
  • ctrl+d: 下翻半屏。
  • ctrl+u: 上翻半屏。
  • ctrl+e: 向下滚动一行。
  • ctrl+y: 向上滚动一行。
  • n%: 到文件n%的位置。
  • zz: 将当前行移动到屏幕中央。
  • zt: 将当前行移动到屏幕顶端。
  • zb: 将当前行移动到屏幕底端。

标记

使用标记可以快速移动。到达标记后,可以用Ctrl+o返回原来的位置。 Ctrl+o和Ctrl+i 很像浏览器上的 后退 和 前进 。

  • m{a-z}: 标记光标所在位置,局部标记,只用于当前文件。
  • m{A-Z}: 标记光标所在位置,全局标记。标记之后,退出Vim, 重新启动,标记仍然有效。
  • `{a-z}: 移动到标记位置。
  • ‘{a-z}: 移动到标记行的行首。
  • `{0-9}:回到上[2-10]次关闭vim时最后离开的位置。
  • “: 移动到上次编辑的位置。”也可以,不过“精确到列,而”精确到行 。如果想跳转到更老的位置,可以按C-o,跳转到更新的位置用C-i。
  • `”: 移动到上次离开的地方。
  • `.: 移动到最后改动的地方。
  • :marks 显示所有标记。
  • :delmarks a b – 删除标记a和b。
  • :delmarks a-c – 删除标记a、b和c。
  • :delmarks a c-f – 删除标记a、c、d、e、f。
  • :delmarks! – 删除当前缓冲区的所有标记。
  • :help mark-motions 查看更多关于mark的知识。

改写插入

  • c[n]w: 改写光标后1(n)个词。
  • c[n]l: 改写光标后n个字母。
  • c[n]h: 改写光标前n个字母。
  • [n]cc: 修改当前[n]行。
  • [n]s: 以输入的文本替代光标之后1(n)个字符,相当于c[n]l。
  • [n]S: 删除指定数目的行,并以所输入文本代替之。

注意,类似cnw,dnw,ynw的形式同样可以写为ncw,ndw,nyw。

切复制和寄存器

剪切和复制、粘贴

  • [n]x: 剪切光标右边n个字符,相当于d[n]l。
  • [n]X: 剪切光标左边n个字符,相当于d[n]h。
  • y: 复制在可视模式下选中的文本。
  • yy or Y: 复制整行文本。
  • y[n]w: 复制一(n)个词。
  • y[n]l: 复制光标右边1(n)个字符。
  • y[n]h: 复制光标左边1(n)个字符。
  • yor D: 删除(剪切)当前位置到行尾的内容。
  • d[n]w: 删除(剪切)1(n)个单词
  • d[n]l: 删除(剪切)光标右边1(n)个字符。
  • d[n]h: 删除(剪切)光标左边1(n)个字符。
  • d0: 删除(剪切)当前位置到行首的内容
  • [n] dd: 删除(剪切)1(n)行。
  • :m,nd 剪切m行到n行的内容。
  • d1G或dgg: 剪切光标以上的所有行。
  • dG: 剪切光标以下的所有行。
  • daw和das:剪切一个词和剪切一个句子,即使光标不在词首和句首也没关系。
  • d/f:这是一个比较高级的组合命令,它将删除当前位置 到下一个f之间的内容。
  • p: 在光标之后粘贴。
  • P: 在光标之前粘贴。

文本对象

  • aw:一个词
  • as:一句。
  • ap:一段。
  • ab:一块(包含在圆括号中的)。

y, d, c, v都可以跟文本对象。

寄存器

  • a-z:都可以用作寄存器名。”ayy把当前行的内容放入a寄存器。
  • A-Z:用大写字母索引寄存器,可以在寄存器中追加内容。 如”Ayy把当前行的内容追加到a寄存器中。
  • :reg 显示所有寄存器的内容。
  • “”:不加寄存器索引时,默认使用的寄存器。
  • :当前选择缓冲区,”yy把当前行的内容放入当前选择缓冲区。
  • “+:系统剪贴板。”+yy把当前行的内容放入系统剪贴板。

找与替换

查找

  • /something: 在后面的文本中查找something。
  • ?something: 在前面的文本中查找something。
  • /pattern/+number: 将光标停在包含pattern的行后面第number行上。
  • /pattern/-number: 将光标停在包含pattern的行前面第number行上。
  • n: 向后查找下一个。
  • N: 向前查找下一个。

可以用grep或vimgrep查找一个模式都在哪些地方出现过,

其中:grep是调用外部的grep程序,而:vimgrep是vim自己的查找算法。

用法为: :vim[grep]/pattern/[g] [j] files

g的含义是如果一个模式在一行中多次出现,则这一行也在结果中多次出现。

j的含义是grep结束后,结果停在第j项,默认是停在第一项。

vimgrep前面可以加数字限定搜索结果的上限,如

:1vim/pattern/ % 只查找那个模式在本文件中的第一个出现。

其实vimgrep在读纯文本电子书时特别有用,可以生成导航的目录。

比如电子书中每一节的标题形式为:n. xxxx。你就可以这样:

:vim/^d{1,}./ %

然后用:cw或:copen查看结果,可以用C-w H把quickfix窗口移到左侧,

就更像个目录了。

替换

  • :s/old/new - 用new替换当前行第一个old。
  • :s/old/new/g - 用new替换当前行所有的old。
  • :n1,n2s/old/new/g - 用new替换文件n1行到n2行所有的old。
  • :%s/old/new/g - 用new替换文件中所有的old。
  • :%s/^/xxx/g - 在每一行的行首插入xxx,^表示行首。
  • :%s/表示行尾。
  • 所有替换命令末尾加上c,每个替换都将需要用户确认。 如:%s/old/new/gc,加上i则忽略大小写(ignore)。

还有一种比替换更灵活的方式,它是匹配到某个模式后执行某种命令,

语法为 :[range]g/pattern/command

例如 :%g/^ xyz/normal dd。

表示对于以一个空格和xyz开头的行执行normal模式下的dd命令。

关于range的规定为:

  • 如果不指定range,则表示当前行。
  • m,n: 从m行到n行。
  • 0: 最开始一行(可能是这样)。
  • $: 最后一行
  • .: 当前行
  • %: 所有行

正则表达式

高级的查找替换就要用到正则表达式。

  • \d: 表示十进制数(我猜的)
  • \s: 表示空格
  • \S: 非空字符
  • \a: 英文字母
  • |: 表示 或
  • .: 表示.
  • {m,n}: 表示m到n个字符。这要和 \s与\a等连用,如 \a{m,n} 表示m 到n个英文字母。
  • {m,}: 表示m到无限多个字符。
  • **: 当前目录下的所有子目录。

:help pattern得到更多帮助。


基本排版

  • << 向左缩进一个shiftwidth
  • >> 向右缩进一个shiftwidth
  • :ce(nter) 本行文字居中
  • :le(ft) 本行文字靠左
  • :ri(ght) 本行文字靠右
  • gq 对选中的文字重排,即对过长的文字进行断行
  • gqq 重排当前行
  • gqnq 重排n行
  • gqap 重排当前段
  • gqnap 重排n段
  • gqnj 重排当前行和下面n行
  • gqQ 重排当前段对文章末尾
  • J 拼接当前行和下一行
  • gJ 同 J ,不过合并后不留空格。

拼写检查

  • :set spell-开启拼写检查功能
  • :set nospell-关闭拼写检查功能
  • ]s-移到下一个拼写错误的单词
  • [s-作用与上一命令类似,但它是从相反方向进行搜索
  • z=-显示一个有关拼写错误单词的列表,可从中选择
  • zg-告诉拼写检查器该单词是拼写正确的
  • zw-与上一命令相反,告诉拼写检查器该单词是拼写错误的

统计字数

g ^g可以统计文档字符数,行数。 将光标放在最后一个字符上,用字符数减去行数可以粗略统计中文文档的字数。 以上对 Mac 或 Unix 的文件格式适用。 如果是 Windows 文件格式(即换行符有两个字节),字数的统计方法为: 字符数 - 行数 * 2。


辑多个文件

一次编辑多个文件

我们可以一次打开多个文件,如

1
vi a.txt b.txt c.txt
  • 使用:next(:n)编辑下一个文件。
  • :2n 编辑下2个文件。
  • 使用:previous或:N编辑上一个文件。
  • 使用:wnext,保存当前文件,并编辑下一个文件。
  • 使用:wprevious,保存当前文件,并编辑上一个文件。
  • 使用:args 显示文件列表。
  • :n filenames或:args filenames 指定新的文件列表。
  • vi -o filenames 在水平分割的多个窗口中编辑多个文件。
  • vi -O filenames 在垂直分割的多个窗口中编辑多个文件。

多标签编辑

  • vim -p files: 打开多个文件,每个文件占用一个标签页。
  • :tabe, tabnew – 如果加文件名,就在新的标签中打开这个文件, 否则打开一个空缓冲区。
  • ^w gf – 在新的标签页里打开光标下路径指定的文件。
  • :tabn – 切换到下一个标签。Control + PageDown,也可以。
  • :tabp – 切换到上一个标签。Control + PageUp,也可以。
  • [n] gt – 切换到下一个标签。如果前面加了 n , 就切换到第n个标签。第一个标签的序号就是1。
  • :tab split – 将当前缓冲区的内容在新页签中打开。
  • :tabc[lose] – 关闭当前的标签页。
  • :tabo[nly] – 关闭其它的标签页。
  • :tabs – 列出所有的标签页和它们包含的窗口。
  • :tabm[ove] [N] – 移动标签页,移动到第N个标签页之后。 如 tabm 0 当前标签页,就会变成第一个标签页。

缓冲区

  • :buffers或:ls或:files 显示缓冲区列表。
  • ctrl+^:在最近两个缓冲区间切换。
  • :bn – 下一个缓冲区。
  • :bp – 上一个缓冲区。
  • :bl – 最后一个缓冲区。
  • :b[n]或:[n]b – 切换到第n个缓冲区。
  • :nbw(ipeout) – 彻底删除第n个缓冲区。
  • :nbd(elete) – 删除第n个缓冲区,并未真正删除,还在unlisted列表中。
  • :ba[ll] – 把所有的缓冲区在当前页中打开,每个缓冲区占一个窗口。

屏编辑

  • vim -o file1 file2:水平分割窗口,同时打开file1和file2
  • vim -O file1 file2:垂直分割窗口,同时打开file1和file2

水平分割

  • :split(:sp) – 把当前窗水平分割成两个窗口。(CTRL-W s 或 CTRL-W CTRL-S) 注意如果在终端下,CTRL-S可能会冻结终端,请按CTRL-Q继续。
  • :split filename – 水平分割窗口,并在新窗口中显示另一个文件。
  • :nsplit(:nsp) – 水平分割出一个n行高的窗口。
  • :[N]new – 水平分割出一个N行高的窗口,并编辑一个新文件。 (CTRL-W n或 CTRL-W CTRL-N)
  • ctrl+w f –水平分割出一个窗口,并在新窗口打开名称为光标所在词的文件 。
  • C-w C-^ – 水平分割一个窗口,打开刚才编辑的文件。

垂直分割

  • :vsplit(:vsp) – 把当前窗口分割成水平分布的两个窗口。 (CTRL-W v或CTRL CTRL-V)
  • :[N]vne[w] – 垂直分割出一个新窗口。
  • :vertical 水平分割的命令: 相应的垂直分割。

关闭子窗口

  • :qall – 关闭所有窗口,退出vim。
  • :wall – 保存所有修改过的窗口。
  • :only – 只保留当前窗口,关闭其它窗口。(CTRL-W o)
  • :close – 关闭当前窗口,CTRL-W c能实现同样的功能。 (象 :q :x同样工作 )

调整窗口大小

  • ctrl+w + –当前窗口增高一行。也可以用n增高n行。
  • ctrl+w - –当前窗口减小一行。也可以用n减小n行。
  • ctrl+w _ –当前窗口扩展到尽可能的大。也可以用n设定行数。
  • :resize n – 当前窗口n行高。
  • ctrl+w = – 所有窗口同样高度。
  • n ctrl+w _ – 当前窗口的高度设定为n行。
  • ctrl+w < –当前窗口减少一列。也可以用n减少n列。
  • ctrl+w > –当前窗口增宽一列。也可以用n增宽n列。
  • ctrl+w | –当前窗口尽可能的宽。也可以用n设定列数。

切换和移动窗口

如果支持鼠标,切换和调整子窗口的大小就简单了。

  • ctrl+w ctrl+w: 切换到下一个窗口。或者是ctrl+w w。
  • ctrl+w p: 切换到前一个窗口。
  • ctrl+w h(l,j,k):切换到左(右,下,上)的窗口。
  • ctrl+w t(b):切换到最上(下)面的窗口。
  • ctrl+w H(L,K,J): 将当前窗口移动到最左(右、上、下)面。
  • ctrl+w r:旋转窗口的位置。
  • ctrl+w T: 将当前的窗口移动到新的标签页上。

速编辑

改变大小写

  • ~: 反转光标所在字符的大小写。
  • 可视模式下的U或u:把选中的文本变为大写或小写。
  • gu(U)接范围(如$,或G),可以把从光标当前位置到指定位置之间字母全部 转换成小写或大写。如ggguG,就是把开头到最后一行之间的字母全部变为小 写。再如gu5j,把当前行和下面四行全部变成小写。

替换(normal模式)

  • r: 替换光标处的字符,同样支持汉字。
  • R: 进入替换模式,按esc回到正常模式。

撤消与重做(normal模式)

  • [n] u: 取消一(n)个改动。
  • :undo 5 – 撤销5个改变。
  • :undolist – 你的撤销历史。
  • ctrl + r: 重做最后的改动。
  • U: 取消当前行中所有的改动。
  • :earlier 4m – 回到4分钟前
  • :later 55s – 前进55秒

  • . –重复上一个编辑动作
  • qa:开始录制宏a(键盘操作记录)
  • q:停止录制
  • @a:播放宏a

辑特殊文件

文件加解密

  • vim -x file: 开始编辑一个加密的文件。
  • :X – 为当前文件设置密码。
  • :set key= – 去除文件的密码。

这里是 滇狐总结的比较高级的vi技巧。

文件的编码

  • :e ++enc=utf8 filename, 让vim用utf-8的编码打开这个文件。
  • :w ++enc=gbk,不管当前文件什么编码,把它转存成gbk编码。
  • :set fenc或:set fileencoding,查看当前文件的编码。
  • 在vimrc中添加set fileencoding=ucs-bom,utf-8,cp936,vim会根据要打开的文件选择合适的编码。 注意:编码之间不要留空格。 cp936对应于gbk编码。 ucs-bom对应于windows下的文件格式。

让vim 正确处理文件格式和文件编码,有赖于 ~/.vimrc的正确配置

文件格式

大致有三种文件格式:unix, dos, mac. 三种格式的区别主要在于回车键的编码:dos 下是回车加换行,unix 下只有 换行符,mac 下只有回车符。

  • :e ++ff=dos filename, 让vim用dos格式打开这个文件。
  • :w ++ff=mac filename, 以mac格式存储这个文件。
  • :set ff,显示当前文件的格式。
  • 在vimrc中添加set fileformats=unix,dos,mac,让vim自动识别文件格式。

程辅助

一些按键

  • gd: 跳转到局部变量的定义处;
  • gD: 跳转到全局变量的定义处,从当前文件开头开始搜索;
  • g;: 上一个修改过的地方;
  • g,: 下一个修改过的地方;
  • [[: 跳转到上一个函数块开始,需要有单独一行的{。
  • ]]: 跳转到下一个函数块开始,需要有单独一行的{。
  • []: 跳转到上一个函数块结束,需要有单独一行的}。
  • ][: 跳转到下一个函数块结束,需要有单独一行的}。
  • [{: 跳转到当前块开始处;
  • ]}: 跳转到当前块结束处;
  • [/: 跳转到当前注释块开始处;
  • ]/: 跳转到当前注释块结束处;
  • %: 不仅能移动到匹配的(),{}或[]上,而且能在#if,#else, #endif之间跳跃。

下面的括号匹配对编程很实用的。

  • ci’, di’, yi’:修改、剪切或复制’之间的内容。
  • ca’, da’, ya’:修改、剪切或复制’之间的内容,包含’。
  • ci”, di”, yi”:修改、剪切或复制”之间的内容。
  • ca”, da”, ya”:修改、剪切或复制”之间的内容,包含”。
  • ci(, di(, yi(:修改、剪切或复制()之间的内容。
  • ca(, da(, ya(:修改、剪切或复制()之间的内容,包含()。
  • ci[, di[, yi[:修改、剪切或复制[]之间的内容。
  • ca[, da[, ya[:修改、剪切或复制[]之间的内容,包含[]。
  • ci{, di{, yi{:修改、剪切或复制{}之间的内容。
  • ca{, da{, ya{:修改、剪切或复制{}之间的内容,包含{}。
  • ci<, di<, yi<:修改、剪切或复制<>之间的内容。
  • ca<, da<, ya<:修改、剪切或复制<>之间的内容,包含<>。

ctags

  • ctags -R: 生成tag文件,-R表示也为子目录中的文件生成tags
  • :set tags=path/tags – 告诉ctags使用哪个tag文件
  • :tag xyz – 跳到xyz的定义处,或者将光标放在xyz上按C-],返回用C-t
  • :stag xyz – 用分割的窗口显示xyz的定义,或者C-w ], 如果用C-w n ],就会打开一个n行高的窗口
  • :ptag xyz – 在预览窗口中打开xyz的定义,热键是C-w }。
  • :pclose – 关闭预览窗口。热键是C-w z。
  • :pedit abc.h – 在预览窗口中编辑abc.h
  • :psearch abc – 搜索当前文件和当前文件include的文件,显示包含abc的行。

有时一个tag可能有多个匹配,如函数重载,一个函数名就会有多个匹配。 这种情况会先跳转到第一个匹配处。

  • :[n]tnext – 下一[n]个匹配。
  • :[n]tprev – 上一[n]个匹配。
  • :tfirst – 第一个匹配
  • :tlast – 最后一个匹配
  • :tselect tagname – 打开选择列表

tab键补齐

  • :tag xyz – 补齐以xyz开头的tag名,继续按tab键,会显示其他的。
  • :tag /xyz – 会用名字中含有xyz的tag名补全。

cscope

  • cscope -Rbq: 生成cscope.out文件
  • :cs add /path/to/cscope.out /your/work/dir
  • :cs find c func – 查找func在哪些地方被调用
  • :cw – 打开quickfix窗口查看结果

gtags

Gtags综合了ctags和cscope的功能。 使用Gtags之前,你需要安装GNU Gtags。 然后在工程目录运行 gtags 。

  • :Gtags funcname 定位到 funcname 的定义处。
  • :Gtags -r funcname 查询 funcname被引用的地方。
  • :Gtags -s symbol 定位 symbol 出现的地方。
  • :Gtags -g string Goto string 出现的地方。 :Gtags -gi string 忽略大小写。
  • :Gtags -f filename 显示 filename 中的函数列表。 你可以用 :Gtags -f % 显示当前文件。
  • :Gtags -P pattern 显示路径中包含特定模式的文件。 如 :Gtags -P .h$ 显示所有头文件, :Gtags -P /vm/ 显示vm目录下的文件。

编译

vim提供了:make来编译程序,默认调用的是make, 如果你当前目录下有makefile,简单地:make即可。

如果你没有make程序,你可以通过配置makeprg选项来更改make调用的程序。 如果你只有一个abc.Java文件,你可以这样设置:

1
set makeprg=javac\ abc.java

然后:make即可。如果程序有错,可以通过quickfix窗口查看错误。 不过如果要正确定位错误,需要设置好errorformat,让vim识别错误信息。 如:

1
:setl efm=%A%f:%l:\ %m,%-Z%p^,%-C%.%#

%f表示文件名,%l表示行号, %m表示错误信息,其它的还不能理解。 请参考 :help errorformat。

快速修改窗口

其实是quickfix插件提供的功能, 对编译调试程序非常有用 :)

  • :copen – 打开快速修改窗口。
  • :cclose – 关闭快速修改窗口。

快速修改窗口在make程序时非常有用,当make之后:

  • :cl – 在快速修改窗口中列出错误。
  • :cn – 定位到下一个错误。
  • :cp – 定位到上一个错误。
  • :cr – 定位到第一个错误。

自动补全

  • C-x C-s – 拼写建议。
  • C-x C-v – 补全vim选项和命令。
  • C-x C-l – 整行补全。
  • C-x C-f – 自动补全文件路径。弹出菜单后,按C-f循环选择,当然也可以按 C-n和C-p。
  • C-x C-p 和C-x C-n – 用文档中出现过的单词补全当前的词。 直接按C-p和C-n也可以。
  • C-x C-o – 编程时可以补全关键字和函数名啊。
  • C-x C-i – 根据头文件内关键字补全。
  • C-x C-d – 补全宏定义。
  • C-x C-n – 按缓冲区中出现过的关键字补全。 直接按C-n或C-p即可。

当弹出补全菜单后:

  • C-p 向前切换成员;
  • C-n 向后切换成员;
  • C-e 退出下拉菜单,并退回到原来录入的文字;
  • C-y 退出下拉菜单,并接受当前选项。

多行缩进缩出

  • 正常模式下,按两下>;光标所在行会缩进。
  • 如果先按了n,再按两下>;,光标以下的n行会缩进。
  • 对应的,按两下<;,光标所在行会缩出。
  • 如果在编辑代码文件,可以用=进行调整。
  • 在可视模式下,选择要调整的代码块,按=,代码会按书写规则缩排好。
  • 或者n =,调整n行代码的缩排。

折叠

  • zf – 创建折叠的命令,可以在一个可视区域上使用该命令;
  • zd – 删除当前行的折叠;
  • zD – 删除当前行的折叠;
  • zfap – 折叠光标所在的段;
  • zo – 打开折叠的文本;
  • zc – 收起折叠;
  • za – 打开/关闭当前折叠;
  • zr – 打开嵌套的折行;
  • zm – 收起嵌套的折行;
  • zR (zO) – 打开所有折行;
  • zM (zC) – 收起所有折行;
  • zj – 跳到下一个折叠处;
  • zk – 跳到上一个折叠处;
  • zi – enable/disable fold;

命令行

normal模式下按:进入命令行模式

命令行模式下的快捷键

  • 上下方向键:上一条或者下一条命令。如果已经输入了部分命令,则找上一 条或者下一条匹配的命令。
  • 左右方向键:左/右移一个字符。
  • C-w: 向前删除一个单词。
  • C-h: 向前删除一个字符,等同于Backspace。
  • C-u: 从当前位置移动到命令行开头。
  • C-b: 移动到命令行开头。
  • C-e: 移动到命令行末尾。
  • Shift-Left: 左移一个单词。
  • Shift-Right: 右移一个单词。
  • @: 重复上一次的冒号命令。
  • q: 正常模式下,q然后按’:’,打开命令行历史缓冲区, 可以像编辑文件一样编辑命令。
  • q/和q? 可以打开查找历史记录。

执行外部命令

  • :! cmd 执行外部命令。
  • :!! 执行上一次的外部命令。
  • :sh 调用shell,用exit返回vim。
  • :r !cmd 将命令的返回结果插入文件当前位置。
  • :m,nw !cmd 将文件的m行到n行之间的内容做为命令输入执行命令。

其它

工作目录

  • :pwd 显示vim的工作目录。
  • :cd path 改变vim的工作目录。
  • :set autochdir 可以让vim 根据编辑的文件自动切换工作目录。

一些快捷键

  • K: 打开光标所在词的manpage。
  • *: 向下搜索光标所在词。
  • g*: 同上,但部分符合即可。
  • #: 向上搜索光标所在词。
  • g#: 同上,但部分符合即可。
  • g C-g: 统计全文或统计部分的字数。

在线帮助

  • :h(elp)或F1 打开总的帮助。
  • :help user-manual 打开用户手册。
  • 命令帮助的格式为:第一行指明怎么使用那个命令; 然后是缩进的一段解释这个命令的作用,然后是进一步的信息。
  • :helptags somepath 为somepath中的文档生成索引。
  • :helpgrep 可以搜索整个帮助文档,匹配的列表显示在quickfix窗口中。
  • Ctrl+] 跳转到tag主题,Ctrl+t 跳回。
  • :ver 显示版本信息。

一些小功能

  • 简单计算器: 在插入模式下,输入C-r =,然后输入表达式,就能在 光标处得到计算结果。

本文地址 Vim操作记录

本文地址: https://github.com/maxzhao-it/blog/post/214/

一、前言

在我们的WEB项目中,会写很多很多接口,对于增删改的接口来说,都大致相同。所以在我们的项目中就可以使用通用接口的形式实现增删改。

最终实现是以Entity EntityManager对数据库进行操作。

这里使用SpringBoot JPA 实现通用接口的 删除 功能。其它 Spring等项目思路大致相同。

其它 :

我把实体类、SQL、部分说明等放在了最后。

这里还要参考我的上一篇文章SpringBoot Jpa实体继承通用属性

二、BaseController实现

BaseController 是我们项目中实现通用接口的基础类。

ServiceRepository 都省略了接口类,测试的话自己写一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* BaseController
* 基础的通用接口
*
* @author maxzhao
* @date 2019-08-15 10:33
*/
public class BaseController<T extends BaseEntity, ID> {

@Resource(name = "baseService")
private BaseService<T, ID> baseService;
/**
* 这里是为了让继承此类的接口类,能传入当前接口操作的实体,然后通过 Service 传入 repository
* 传入到 repository 之后 就可以使用 EntityManager 的通用方法了
*
* @param domainClass
*/
public void setDomainClass(Class<T> domainClass) {
baseService.setDomainClass(domainClass);
}

@ApiOperation(value = "/{id}", notes = "逻辑删除", response = ResultObj.class, httpMethod = "DELETE")
@DeleteMapping(value = "{id}")
@ResponseBody
public ResultObj<String> del(@PathVariable(value = "id") ID id) {
return baseService.del(id);
}
}

Service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Slf4j
@Service(value = "baseService")
public class BaseServiceImpl<T extends BaseEntity, ID> implements BaseService<T, ID> {
@Autowired
private BaseRepository<T, ID> baseRepository;
/**
* 这里是 domainClass 的跳板
*
* @param domainClass
*/
@Override
public void setDomainClass(Class<T> domainClass) {
baseRepository.setDomainClass(domainClass);
}

@Override
public ResultObj<String> del(ID id) {
baseRepository.del(id);//这里到 repo 中模拟操作
return ResultObj.getDefaultResponse("删除成功");
}
}

Repository

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

/**
* BaseRepositoryImpl
*
* @author maxzhao
* @date 2019-08-15 11:11
*/
@Repository(value = "baseRepository")
@Transactional(readOnly = true)
public class BaseRepositoryImpl<T extends BaseEntity, ID> implements BaseRepository<T, ID> {
@PersistenceContext
private EntityManager entityManager;
/**
* 某个接口的实体类的类型
*/
private Class<T> domainClass;

@Override
public void setDomainClass(Class<T> domainClass) {
this.domainClass = domainClass;
}

@Override
public Boolean del(ID id) {
T entity = entityManager.find(domainClass, id);
return true;
}
}

至此,一个简单的、通用的删除接口就完成了。

删除是比较简单的,因为我做的项目一般都是逻辑删除,所有必须要自定义删除,而且想通用,就需要通用的实体属性,所以也就有了BaseEntity

BaseEntity 解读

这个类就是我前言中提到的通用实体属性的父类,这样就可以统一实体的通用属性,比如主键、逻辑删除状态、添加时间等。

@MappedSuperclass 实体继承映射注解要加载实体的父类上,比如如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* BaseEntity
* 实体继承映射类基础,保存实体的通用属性
*
* @author maxzhao
* @date 2019-08-15 09:39
*/
@Data
@Accessors(chain = true)
@MappedSuperclass//实体继承映射
public class BaseEntity implements Serializable {
@Id
@Column(name = "ID")
@ApiModelProperty(value = "主键")
private Long id;

@Basic
@Column(name = "DEL_STATUS")
@ApiModelProperty(value = "状态 1启用 0 停用")
private Integer delStatus;
}

@DynamicInsert 注解

@DynamicInsert 在实体类的父类上时,是不会对子类的属性产生效果的,对父类自己的属性也没有效果。

其它代码

接口

1
2
3
4
5
6
7
8
9
10
11
@Api(value = "应用接口日志")
@RestController
@RequestMapping("appLogApi")
public class AppLogApiController extends BaseController<AppLogApi, Long> {

@PostConstruct
public void PostConstruct() {
// 重点在这里,这是我能想出的比较简单的实现方法
super.setDomainClass(AppLogApi.class);
}
}

实体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 应用接口日志
*
* @author author
* @date 2019-7-23 15:38:57
*/
@Accessors(chain = true)
@Data
@Entity
@Table(name = "app_log_api", schema = "", catalog = "")
@ApiModel(value = "应用接口日志", description = "应用接口日志")
public class AppLogApi extends BaseEntity implements Serializable {
private static final long serialVersionUID = -1L;

@Basic
@Column(name = "API")
@ApiModelProperty(value = "请求地址")
private String api;
/******/
public AppLogApi() {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* BaseEntity
* 实体集成映射类基础,保存实体的通用属性
*
* @author maxzhao
* @date 2019-08-15 09:39
*/
@Data
@Accessors(chain = true)
@MappedSuperclass//实体集成映射
public class BaseEntity implements Serializable {
@Id
@Column(name = "ID")
@ApiModelProperty(value = "主键")
private Long id;

@Basic
@Column(name = "DEL_STATUS")
@ApiModelProperty(value = "状态 1启用 0 停用")
private Integer delStatus;
}
1
2
3
4
5
6
7
8
create table gt_boot.app_log_api
(
id bigint(64) not null comment '主键'
primary key,
api varchar(100) null comment '请求地址',
del_status integer null
)
comment '应用接口日志';

@PostConstruct解读

从Java EE5规范开始,Servlet中增加了两个影响Servlet生命周期的注解:

  • @PostConstruct
  • @PreDestroy

修饰一个非静态的void()方法类似与init() destory()类似。写法有如下两种方式:

1
2
3
4
@PostConstruct
public void doA(){}

public @PostConstruct void doB(){}

加载顺序

servlet加载顺序

与本文联系起来说

想要把实体AppLogApi.class传参到BaseRepositoryImpl中,就需要初始化bean之后才可以调用bean,但是@Autowired注入是发生在A的构造方法执行完之后的。

所以要在生成对象时初始化AppLogApi.class参数,就不能在构造函数中实现,这时候@PostContruct的作用就体现出来了, @PostContruct 会在依赖注入完成后被自动调用。

Constructor > @Autowired > @PostConstruct

本文地址: SpringBoot使用JPA实现通用接口(增删查等)

推荐
SpringBoot Jpa实体继承通用属性
IDEA好用的插件
JAVA自定义注解

本文地址: https://github.com/maxzhao-it/blog/post/31330/

RabbitMQ

RabbitMQ是一个出色的消息代理中间件(Message Broker):接受和转发消息。你可以将它看作是一个邮局,
你把自己的信件写上收件人地址,然后放到邮筒里面就不用管了,由邮局负责将这个信件送到目的地。来自

一、安装

我这里使用的是 ArchLInux

1
2
sudo pacman -S rabbitmq
# 会自动安装 socat erlang-nox rabbitmq

RPM 安装

1
2
3
4
5
6
7
8
9
10
11
12
13
# 先安装erlang
rpm -Uvh https://mirrors.ustc.edu.cn/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm
# 下面可以 epel-release 是软件库
yum install epel-release
yum install erlang
#安装RabbitMQ
rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.15/rabbitmq-server-3.6.15-1.el7.noarch.rpm
ll
yum install rabbitmq-server-3.6.15-1.el7.noarch.rpm
# 或者下面安装 mq
# wget ftp://195.220.108.108/linux/centos/7.4.1708/os/x86_64/Packages/socat-1.7.3.2-2.el7.x86_64.rpm
# yum localinstall -C -y --disablerepo=* *.rpm

安装web管理界面

1
2
3
sudo rabbitmq-plugins enable rabbitmq_management
# 查看所有的插件
sudo rabbitmq-plugins list

启动

1
2
3
4
5
6
# 设置开机自启服务
systemctl enable rabbitmq-server
# 启动RabbitMQ
systemctl start rabbitmq-server
# 重启
systemctl restart rabbitmq-server

配置

1
vim /etc/rabbitmq/rabbitmq.config

安装好之后在/usr/share/doc/rabbitmq-server-3.6.15/有参考模板rabbitmq.config.example

配置端口,备注:消息端口5672,则web访问端口为 15672

1
2
3
4
5
6
7
8
[
{rabbit,
[
{loopback_users, []},
{tcp_listeners, [5672]}
]
}
]

参考模板

用户管理

1
2
3
4
5
6
7
8
9
10
11
12
# 修改guest的密码
sudo rabbitmqctl list_users
sudo rabbitmqctl change_password guest guest

# 创建其他管理员账号比如test/test:
sudo rabbitmqctl add_user maxzhao maxzhao
#
sudo rabbitmqctl set_user_tags maxzhao administrator
# /是 vhost的目录 Configure regexp Write regexp Read regexp
sudo rabbitmqctl set_permissions -p / maxzhao ".*" ".*" ".*"
# Sets user topic permissions for an exchange,默认使用 AMQP default 的exchange
# sudo rabbitmqctl set_topic_permissions

添加vhost

1
2
3
4
5
6
7
8
9
10
11
# 查看帮助
sudo rabbitmqctl --help
# 查看创建 vhost 的帮助
sudo rabbitmqctl add_vhost --help
# 创建
sudo rabbitmqctl add_vhost maxzhao_vhost
# 查看
sudo rabbitmqctl list_vhosts
# 赋权 注意 /maxzhao_vhost 与 maxzhao_vhost 不一样
sudo rabbitmqctl set_permissions -p /maxzhao_vhost maxzhao ".*" ".*" ".*"

删除 vhost

1
2
sudo rabbitmqctl add_vhost maxzhaoTest
sudo rabbitmqctl delete_vhost maxzhaoTest

本文地址: https://github.com/maxzhao-it/blog/post/14489/

我这里使用的是 Typora .一个符合我的需求的 Markdown 编辑器.

奈何对于图片的处理, 很是麻烦,所以我选择搭建自己的图床.

网上的方案大致如下:

  1. 搭建私有图床
    如:使用Chevereto搭建免费私有图床
  2. 使用付费图床或免费图床,同时可以配合开源跨平台的的工具PicGo
    付费的如:又拍云、腾讯云、阿里云、七牛云、微博
    免费的如:Github、Gitee
  3. 其他相对非主流方案

仔细考虑下还是使用 GitHub , 本身倾向于 Gitee 毕竟国内访问速度很快, 奈何 Gitee 推送后不能自动更新. 囧

七牛云也是很不错的选择, 奈何需要备案.

创建 GitHub 图床

首先创建一个仓库

创建 token

点击"Developer settings"按钮

![新建 token](/uploads/images/新建 token.png)

输入 note , 如果当前token 只有自己用的话,可以把权限全部选上.

注:创建成功后,会生成一串token,这串token之后不会再显示,所以第一次看到的时候,就要好好保存

![](https://maxzhao-it.github.io/upload/img/新建 token.png)

PicGo介绍

PicGo 就是一款图片上传工具, 支持微博图床七牛图床腾讯云又拍云GitHub等图床. 可以把本地图片或剪切板上的图片发送给图床, 返回 URL 到哪都可以使用.

安装PicGo

yaourt -S picgo-appimage

使用PicGo

https://www.jianshu.com/p/2756724a5dee

推荐:

Manjaro下使用图床工具PicGo

本文地址: https://github.com/maxzhao-it/blog/post/27685/

安装

下载地址:nexus-3.16.0-01-unix.tar.gz

解压:

1
2
3
tar -zxvf nexus-3.16.0-01-unix.tar.gz -C /home/maxzhao/soft/
mv nexus-3.16.0-01 nexus
cd nexus

查看配置文件

1
cat etc/nexus-default.properties 
1
2
3
4
5
6
7
8
9
10
# 端口配置
application-port=8081
application-host=0.0.0.0
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xml
# 项目名配置
nexus-context-path=/
# 这部分不用管
nexus-edition=nexus-pro-edition
nexus-features=\
nexus-pro-feature

启动之前要清楚的目录

1
cat bin/nexus.vmoptions

可以进行详细的配置存储路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-Xms1200M
-Xmx1200M
-XX:MaxDirectMemorySize=2G
-XX:+UnlockDiagnosticVMOptions
-XX:+UnsyncloadClass
-XX:+LogVMOutput
# 日志目录 ./就是 nexus3/目录
-XX:LogFile=./sonatype-work/nexus3/log/jvm.log
-XX:-OmitStackTraceInFastThrow
-Djava.net.preferIPv4Stack=true
-Dkaraf.home=.
-Dkaraf.base=.
-Dkaraf.etc=etc/karaf
-Djava.util.logging.config.file=etc/karaf/java.util.logging.properties
# 所有的work,包括nexus.properties
-Dkaraf.data=./sonatype-work/nexus3
# 所有的tmp
-Djava.io.tmpdir=./sonatype-work/nexus3/tmp
-Dkaraf.startLocalConsole=false

配置路径权限

1
2
# xxx 是当前 sonatype-work 所在的路径
sudo chown -R 账号.账号组 /xxx/sonatype-work

启动

1
sh bin/nexus start

访问:127.0.0.1:8081

原始账号密码为 admin / admin123

20210606 更新:原始秘密在 nexus3/etc/admin.password文件中。

Nexus 使用

内置仓库介绍

  • Maven Gentral:该仓库代理Maven中央仓库,其策略为Release,因此只会下载和缓存中央仓库中的发布版本构件。

  • Release:这是一个策略为Release的宿主类型仓库,用来部署组织内部的发布版本构件。

  • Snapshots:这是一个策略为Snapshot的宿主类型仓库,用来部署组织内部的快照版本构件。

  • 3rd party:这是一个策略为Release的宿主类型仓库,用来部署无法从公共仓库获得的第三方发布版本构件。

  • Apache Snapshots: 这是一个策略为Snapshot的代理仓库,用来代理Apache Maven仓库的快照版本构件。

  • Codehaus Snapshots: 这是一个策略为Snapshot的代理仓库,用来代理Codehaus Maven仓库的快照版本构件。

  • Google code: 这是一个策略为Release的代理仓库,用来代理Google Code Maven仓库发布版本构件。

  • java.net Maven2:这是一个策略为Release的代理仓库,用来代理java.net Maven仓库的发布版本构件

  • Public Repositories:该仓库组将上述所有策略为Release的仓库聚合并通过一致的地址提供服务

  • Public Snapshot Repositories: 该仓库组将上述所有的策略为Snapshot的仓库聚合并通过一致的地址提供服务。(在nexus-oss-webapp-1.9.2.3 这版本中没有此项)

Nexus仓库分类概念

Maven可以直接从宿主仓库下载构件;maven也可以从代理仓库下载构件,而代理仓库会间接地从远程仓库下载并缓存构件;最后,为了方便,Maven可以从仓库组下载构件,而仓库组没有实际内容,它会转向其包含的宿主仓库或者代理仓库获得市级构件的内容。

创建Nexus宿主仓库

创建一个宿主仓库首先单击界面左边导航栏中的Repositories链接,在右边的面板中,选择create,接着在下拉菜单中选择maven2 (hosted),就会看到如下图的配置界面:

2019-04-16 15-24-29 的屏幕截图.png

  • Repository Name 仓库名称
  • Repository Policy 读者可以根据自己的需要来配置该仓库是发布版本构件仓库还是快照版本构件仓库。
  • Storage 表示该仓库的存储目录,左边列表Blob Stores就是本地的存储目录创建,default是默认地址,都存储在/xxx/nexus3/sonatype-work/nexus3/blobs/下 。

Access Setting 小组中

  • Deployment Policy用来配置该仓库的部署策略,选项有只读(禁止部署)、关闭重新部署(同一构件只能部署一次)以及允许重新部署。

  • Allow file Browsing 表示是否允许浏览仓库内容

  • Include in Search 表示是否对该仓库进行索引并提供搜索

  • Publish URL 用来控制是否通过URL提供服务,如果选择false当访问仓库的地址时,会得到HTTP404 Not Found 错误

  • Not Found Cache TTL
    表示当一个文件没有找到后,缓存这一不存在的信息的时间。以默认值1440分钟为例,如果某文件不存在,那么在之后的1440分钟内,如果Nexus再次得到该文件的请求,它将直接返回不存在的信息,而不会查找位呢间系统。

创建Nexus代理仓库

操作和创建宿主仓库类似,主要Repository Type 的值改为proxy 这时看到如下图:

2019-04-16 15-29-50 的屏幕截图.png

对于代理仓库来说,最重要的是远程仓库地址即

  • Remote Storage Location,用户必须输入有效的值

  • Download Remote Indexes 表示是否下载远程仓库的索引

  • Checksum Policy 配置校验出错时的策略,用户可以选择忽略、记录警告信息或者拒绝下载。

  • Authentication 当远程仓库需要认证的时候这里的时候,这里的Authentication 配置就能派上用处。

  • Artifact Max Age 构件缓存最长的时间,对于快照版本来说 Artifact Max Age 默认值为 -1,表示构件混存后就一直保存着,不在重新下载,对于快照版来说默认值为1440分钟表示每隔

  • Metadata Max Age 仓库元数据文件缓存的最长时间

  • Http Request Setting 和 Override HTTP proxy Setting 其中前者用来配置Nexus访问远程仓库时HTTP请求参数,后者用来配置HTTP代理

创建Nexus仓库组

创建仓库组同其他的一样步骤是在选择Repository Group 就会看到如下的:

配置中的信息同其他的一样,仓库组中没有Release 和Snapshot
,这不同于宿主仓库和代理仓库。在配置界面中可以选择Nexus中的仓库,将其聚合成一个虚拟的仓库组,注意,仓库组所包含的仓库的顺序决定了仓库组便利其所含仓库的次序,因此最好将常用的仓库放在前面,当用户从仓库组下载构件的时候,就能经快的访问到包含构件的仓库。

Nexus的索引与构件搜索

需要搜索Maven 中央库,首先需要设置Nexus中的Maven Central 代理仓库下载远程索引 如下图:

Download Remote Indexes 属性设置为true 默认为false

true是开启,false是关闭 由于中央仓库内容比较多,因此其索引文件比较大,需要查看下载如何了,我们可以单击界面左边导航栏中的 Scheduled Tasks 链接后,就可以看到系统调度的任务其状态为
runing,在说哦因下载完毕之后,该任务就会消失。

Scheduled Tasks 界面:

配置Maven 从Nexus下载构件

当需要为项目添加Nexus私服上的public仓库时,可以在项目pom.xml文件配置 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

<project>
<repositories>
<repository>
<id>nexus</id>
<url>http://http://localhost:4040/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<url>http://localhost:4040/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

这样的配置只对当前的Maven项目有效,实际应用中,我们往往想要通过一次配置就完成能让本机所有的Maven项目都使用自己的Maven私服。这时配置本地仓库setting.xml 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

<settings>
<mirrors>
<mirror>
<id>central</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:4040/content/groups/public/</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>JDK1.6</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.6</jdk>
</activation>
<properties>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.compilerVersion>1.6</maven.compiler.compilerVersion>
</properties>
</profile>
<profile>
<id>central</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>central</activeProfile>
<activeProfile>JDK1.6</activeProfile>
</activeProfiles>
</settings>

使用Maven 部署构件至Nexus

日常开发生成的快照版本构件可以直接部署到Nexus中策略为Snapshot的宿主仓库中,项目正式发布的构件则应该部署到Nexus中策略为Release的宿主仓库中。POM.XML配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<project>
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Releases Repository</name>
<url>http://localhost:4040/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshots Repository</name>
<url>http://localhost:4040/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
</project>

Nexus 的仓库对于黎明用户是只读的为了能够部署构件,还需要在setting.xml 中配置认证信息代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

<servers>

<server>
<id>releases</id>
<username>admin</username>
<password>iapppay</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>iapppay</password>
</server>
</servers>

mvn 命令上传jar

setting.xml配置 server 信息

1
2
3
4
5
6
7
<servers>
<server>
<id>maxzhao</id>
<username>admin</username>
<password>maxzhao</password>
</server>
</servers>

pom.xml配置

1
2
3
4
5
6
7
8
9
10
11
12
13

<distributionManagement>
<repository>
<!-- 这里的ID要和setting的id一致 -->
<id>maxzhao</id>
<url>http://127.0.0.1:8081/repository/maxzhao/</url>
</repository>
<!--这是打成快照版本的配置 -->
<snapshotRepository>
<id>maxzhao</id>
<url>http://127.0.0.1:8081/repository/maxzhao/</url>
</snapshotRepository>
</distributionManagement>

执行mvn脚本

1
mvn deploy:deploy-file -DgroupId=gt.maxzhao -DartifactId=maxzhao-table -Dversion=1.0 -Dpackaging=jar -DrepositoryId=maxzhao -Dfile=/run/media/maxzhao/study/mycode-java/maxzhao/maxzhao-table/target/maxzhao-table-1.0-SNAPSHOT.jar  -Durl=http://127.0.0.1:8081/repository/maxzhao/
  • -DgroupId=jar包的组名
  • -DartifactId=jar包名称
  • -Dversion=jar包版本
  • -Dfile=jar包绝对路径
  • -DrepositoryId=yang

本文地址:Manjaro下安装Nexus

本文地址: https://github.com/maxzhao-it/blog/post/12074/