程序开发人员在日常开发过程中,使用 git 可能会遇到这样一个情况:
也就是说,我们需要 git 根据不同项目使用不同的账号及邮箱提交相关记录,本文就是专门解决这个问题的。
本地设置有两种方式,命令方式 和 配置文件方式,两种方式选择任意一种,都可以配置当前git项目提交git信息的账号及邮箱。
对于本地 git repo 配置,先进入 本地git repo 目录,使用命令:
1 | git config user.name "your-username" |
对于本地 git repo 配置,先进入 本地git项目 目录,编辑 .git/config 文件,增加以下信息:
1 | [user] |
保存并退出。以上 命令方式 和 配置文件方式 两种方式,都可以在 本地git repo 目录下,通过以下命令查看本地项目的账号及邮箱是否更改成功。
1 | git config user.name |
对于很多个 本地git repo 来说,每个 本地git repo 都要设置自定义化git本地账号及邮箱,有时我们不想每个都设置,我们可以使用git的全局配置,所有 本地git repo 都是使用全局配置!
全局设置有两种方式,命令方式 和 配置文件方式,两种方式选择任意一种,都可以配置全局git项目提交git信息的账号及邮箱。
在git服务器中,任意非 本地git repo 中,使用以下命令配置全局配置:
1 | git config --global user.name "your-username" |
编辑 〜/.gitconfig,其内容与 .git/config 文件中的内容相同,即将 [user] 部分信息添加至 〜/.gitconfig 文件中,内容如下:
1 | [user] |
保存并退出。任意非 本地git repo 中,在使用以下命令查看是否配置成功
1 | git config user.name |
好了,这次git config全局及本地配置就到这里了!
个人Vim命令速查表。
vim-cheatsheet | Vim官网 | Github | Vim中文文档
注:一般模式下,任意一个动作都可以重复。
1 | h # 光标左移,同 <Left> 键 |
1 | i # 在光标处进入插入模式 |
注:由 i, I, a, A, o, O 等命令进入插入模式
1 | <Up> # 光标向上移动 |
在插入模式下,最常用的补全
1 | Ctrl+n # 插入模式下文字自动补全 |
智能补全
1 | Ctrl+X # 进入补全模式 |
1 | r # 替换当前字符 |
copy 命令的格式为:
1 | :[range]copy{address} |
参数说明:
例如,:5copy. 表示复制Vim当前打开的文件的第 5 行到当前行 (用 . 表示),即为第 5 行创建一份副本,并放到当前行下方。
下标列出了使用 copy 命令的缩写形式 t 进行文件复制的一些实例及用途,用于理解复制命令 copy 的用途。
1 | :3,5t. # 把第 3 行到第 5 行的内容复制到当前行下方 |
常用复制粘贴命令:
1 | p # 粘贴到光标后 |
文本编辑、复制粘贴中的内容可以简单总结为:
1 | ci'、ci"、ci(、ci[、ci{、ci< # 分别更改这些配对标点符号中的文本内容 |
cit、dit、yit、vit,分别操作一对标签之间的内容,编辑html、xml很好用!
另外,如果把上面的 i 改成 a 可以同时操作配对标点和配对标点内的内容。
1 | :[range]move{address} |
参数说明:
例如:
1 | :m+1 # 下移1行 |
1 | $ # 到行末 |
1 | u # 撤销命令可以组合,例如Nu N是任意整数,表示撤销N步操作,下同 |
一般模式下的查找命令:
1 | /pattern # 从光标处向文件尾搜索 pattern |
一般模式下的替换命令:
1 | :[range]s[ubstitute]/{pattern}/{string}/[flags] |
参数说明:
[range]取值 | 含义 |
---|---|
无 | 默认光标所在行 |
. | 光标所在当前行 |
N | 第 N 行 |
$ | 最后一行 |
‘a | 标记 a 所在的行(之前要用 ma 做过标记) |
$-1 | 倒数第二行,可以对某一行加减某个数值获得确定的某行 |
1,10 | 第1~10行 |
1,$ | 第一行到最后一行 |
1,. | 第一行到当前行 |
.,$ | 当前行到最后一行 |
‘a,’b | 标记 a 所在的行 到 标记 b 所在的行(之前要用 ma、mb 做过标记) |
% | 所有行(和 1,$ 等价) |
?str? | 从当前位置向上搜索,找到第一个str的行(str可以是正则) |
/str/ | 从当前位置向下搜索,找到第一个str的行(str可以是正则) |
注意,上面的所有用于range的表示方法都可以通过 +、- 操作来设置相对偏移量。
[flags]取值 | 含义 |
---|---|
g | 对指定范围内的所有匹配项(global)进行替换 |
c | 在替换前请求用户进行确认(confirm) |
e | 忽略执行过程中的错误 |
i | 不区分大小写 |
无 | 只在指定范围内的第一个匹配项进行替换 |
举例:
1 | :s/p1/p2/g # 将当前行中全替换p1为p2 |
注:Vim 可视模式下可以选择一块编辑区域,然后对选中的文件内容执行插入、删除、替换、改变大小写等操作。!
1 | v # 切换到面向字符的可视模式 |
此外: Vim normal 命令可以在命令行模式执行普通模式下的命令,当 normal 命令与 Vim 可视化模式结合时,只需很少的操作就能完成大量重复性工作。
多行注释
1 | Ctrl+v # 进入命令行模式,按Ctrl + v进入可视模式,然后按j, 或者k选中多行,把需要注释的行标记起来 |
取消多行注释
1 | Ctrl+v # 进入命令行模式,按Ctrl + v进入可视模式,按字母l横向选中列的个数,例如#、//(需要选中2列) |
复杂注释
1 | :起始行号,结束行号s/^/注释符/g(注意冒号) # 在指定的行首添加注释 |
1 | Ctrl+O # 跳转到上一个位置 |
1 | :w # 保存文件(会修改文件的时间戳) |
1 | vim filename # 打开或新建文件,并将光标置于第一行首 |
1 | :ls # 查案缓存列表 |
1 | :sp <filename> # 上下切分窗口并在新窗口打开文件 filename |
1 | :tabs # 显示所有标签页 |
1 | :marks # 显示所有书签 |
1 | :h tutor # 入门文档 |
1 | :!command # 执行一次性shell命令,如下命令::!pwd |
1 | :copen # 打开 quickfix 窗口(查看编译,grep等信息) |
1 | :set spell # 打开拼写检查 |
1 | za # 切换折叠 |
文档加密
加密方式打开文件时,并在屏幕左下角提示输入密码两次才可进行操作,保存文件退出后必须输入正常密码才能正确打开文件,否则会显示乱码。
1 | vim -x file_name# 输入加密密码 -> 确认密码! 注意:不修改内容也要保存。:wq,不然密码设定不会生效。 |
文档解密
1 | :X # 命令行模式下,提示输入密码,不输入而是按 Enter。注意:不修改内容也要保存。:wq,不然解密设定不会生效。 |
1 | qa # 开始录制名字为 a 的宏 |
1 | Ctrl+X Ctrl+E # 插入模式下向上滚屏 |
命令行模式下:
1 | :history # 查看所有命令行模式下输入的命令历史 |
普通模式下:
1 | q/ # 查看使用/输入的搜索历史 |
查看寄存器值
1 | :reg # 查看所有寄存器值 |
调取寄存器值
1 | "{register_name} # 普通模式下调取寄存器值 |
Vim寄存器分类
名称 | 引用方式 | 说明 |
---|---|---|
无名寄存器 | “” | 默认寄存器,所有的复制和修改操作(x、s、d、c、y)都会将该数据复制到无名寄存器 |
字母寄存器 | “a - “z 或 “A - “Z | {register_name}只能是一位的26个英文字母,从a-z,A-Z寄存器内容将会合并到对应小写字母内容后边 |
复制专用寄存器 | “0(数字0) | 仅当使用复制操作(y)时,该数据将会同时被复制到无名寄存器和复制专用寄存器 |
逐级临时缓存寄存器 | “1 - “9 | 所有不带范围(‘(’,‘)’,‘{’,‘}’)、操作涉及1行以上的删除修改操作(x、s、d、c)的数据都会复制到逐级临时缓存寄存器,并在新的数据加入时,逐级先后推移。1的数据复制到2,2的复制到3,最后的9寄存器内容将会被删除 |
黑洞寄存器 | “_ | 几乎所有的操作涉及的数据都会被复制到寄存器,如果想让操作的数据不经过寄存器,可以指定黑洞寄存器,数据到该寄存器就会消失掉,不能显示,也不存在 |
系统剪切板 | “+ 或”* | 与Vim外部的GUI交互数据时,需要使用专用的系统剪切板 |
表达式寄存器 | “= | 所有寄存器里最特殊的一个,用于计算表达式。输入完该寄存器应用后,会在命令行里提示“=”,按需输入表达式,结果将会显示到光标处 |
其他寄存器 |
编辑Vim配置文件:
1 | :edit $MYVIMRC # 在Vim的命令模式下使用该命令打开 vim 配置文件 |
Vim配置说明:
注:Vim配置可以在命令模式下单个设置,只在当前窗口生效!
1 | syntax # 列出已经定义的语法项 |
vim-commentary:批量注释工具, 可以注释多行和去除多行注释。
1 | gcc # 注释当前行 |
nerdtree:该插件用于列出当前路径的目录树。
1 | ? # 快速帮助文档 |
1 | :AsyncRun ls # 异步运行命令 ls 结果输出到 quickfix 使用 :copen 查看 |
1 | 普通模式 # 按 Esc 或 Ctrl+[ 进入,左下角显示文件名或为空 |
开发人员多少都会遇到文件的上传下载,特别是Java的Spring框架。那么我们能不能实现一些通用工具类,实现文件上传和下载的功能,可以有效地避免重复开发代码。
因此,我在网上查找了相关资料,并在此基础上加以改进,支持文件上传及下载功能,而且代码非常精简。如有问题,欢迎大家指正!
文件上传及下载需要两个依赖:
1 | <dependency> |
Spring文件上传一般从请求中获取文件对象,或者直接上传文件获取文件对象。这里提供两个方法,可以满足以上两种情形!当然,如果想自定义文件上传路径,也可以在这两个方法的基础上再增加一个文件路径参数,具体还是看大家的需求情况吧!
1 | package com.chloneda.utils; |
文件下载需要知道文件所在路径,并通过文件流的响应方式返回给前端下载,具体代码如下:
1 | package com.chloneda.utils; |
文件的上传下载是比较普遍的功能需求,这里通过请求响应的方式实现,可以满足日常的开发需求!
注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎
最近打算对Maven的pom.xml文件进行一下深入研究,做一下总结,惊喜的是网上已经有比较详细的资料,为避免重复造轮子,所以转载了这篇文章。
setting.xml主要用于配置maven的运行环境等一系列通用的属性,是全局级别的配置文件;而pom.xml主要描述了项目的maven坐标,依赖关系,开发者需要遵循的规则,缺陷管理系统,组织和licenses,以及其他所有的项目相关因素,是项目级别的配置文件。
一个典型的pom.xml文件配置如下:
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
一般来说,上面的几个配置项对任何项目都是必不可少的,定义了项目的基本属性。
这里有必要对一个不太常用的属性classifier做一下解释,因为有时候引用某个jar包,classifier不写的话会报错。
classifier元素用来帮助定义构件输出的一些附属构件。附属构件与主构件对应,比如主构件是 kimi-app-2.0.0.jar,该项目可能还会通过使用一些插件生成 如kimi-app-2.0.0-javadoc.jar (Java文档)、 kimi-app-2.0.0-sources.jar(Java源代码) 这样两个附属构件。这时候,javadoc、sources就是这两个附属构件的classifier,这样附属构件也就拥有了自己唯一的坐标。
classifier的用途
引用它的时候就要注明JDK版本,否则maven不知道你到底需要哪一套jar包:
1 | <dependency> |
1 | <build> |
pom里面的仓库与setting.xml里的仓库功能是一样的。主要的区别在于,pom里的仓库是个性化的。比如一家大公司里的setting文件是公用的,所有项目都用一个setting文件,但各个子项目却会引用不同的第三方库,所以就需要在pom里设置自己需要的仓库地址。
1 | <!--项目分发信息,在执行mvn deploy后表示要发布的位置。 --> |
1 | <!--发现依赖和扩展的远程仓库列表。 --> |
1 | <!--在列的项目构建profile,如果被激活,会修改构建处理 --> |
profile配置项在setting.xml中也有,是pom.xml中profile元素的裁剪版本,包含了id,activation, repositories, pluginRepositories和 properties元素。这里的profile元素只包含这五个子元素是因为setting.xml只关心构建系统这个整体(这正是settings.xml文件的角色定位),而非单独的项目对象模型设置。如果一个settings中的profile被激活,它的值会覆盖任何其它定义在POM中或者profile.xml中的带有相同id的profile。
pom.xml中的profile可以看做pom.xml的副本,拥有与pom.xml相同的子元素与配置方法。它包含可选的activation(profile的触发器)和一系列的changes。例如test过程可能会指向不同的数据库(相对最终的deployment)或者不同的dependencies或者不同的repositories,并且是根据不同的JDK来改变的。只需要其中一个成立就可以激活profile,如果第一个条件满足了,那么后面就不会在进行匹配。
1 | <!--描述使用报表插件产生报表的规范,特定的maven 插件能输出相应的定制和配置报表. --> |
1 | <!--项目的问题管理系统(Bugzilla, Jira, Scarab,或任何你喜欢的问题管理系统)的名称和URL,本例为 jira --> |
1 | <!--项目的名称, Maven产生的文档用 --> |
本文尽量采用通俗易懂、循序渐进的方式,让大家真正优雅地使用close()方法!
平时我们使用资源后一般都会关闭资源,即close()方法,但这个步骤重复性很高,还面临上述执行顺序不明的风险,而且很多人还是不能正确合理地关闭资源。
我们来看看close()是怎么错误地关闭资源的?
先来看看如下的错误关闭资源方式:
1 | package com.chloneda.jutils.test; |
上面代码的资源关闭写在了try代码块中,一旦close方法调用之前(比如3步骤)就抛出异常,那么关闭资源的代码就永远不会得到执行。
如果我们把关闭资源的代码放在finally中行不行呢?
1 | try { |
答案是不行!如果在 2步骤 的try中conn获得数据库链接抛出异常,那么conn仍然为null,此时进入finally代码块中,执行close()就报空指针异常了,关闭资源没有意义!因此,我们需要在close()之前判断一下conn等是否为空,只有不为空的时候才需要close。
针对上述场景,得到常见的使用close()方式如下:
1 | /** |
这是常见的close()!但是finally代码块的代码重复性太高了,这还只是三个资源的关闭,如果有很多个资源需要在finally中关闭,那不是需要编写很多不优雅的代码?其实,关闭资源是没啥逻辑的代码,我们需要精简代码,减少代码重复性,优雅地编程!
自从Java7以后,我们可以使用 AutoCloseable接口 (Closeable接口也可以)来优雅的关闭资源了 看看修改例子:
1 | /** |
上面的finally代码块的代码量是不是减少了许多,就单纯地调用的静态的 close(AutoCloseable closeable) 方法。为什么可以这样呢?
其实Connection、Statement、ResultSet三个接口都继承了AutoCloseable接口。所以只要涉及到资源的关闭,继承了AutoCloseable接口,实现了close()方法,我们都可以调用 close(AutoCloseable closeable) 方法进行资源关闭。
此外,java IO流的很多类都实现了 Closeable接口,而Closeable接口又继承自 AutoCloseable接口,也可以调用上面的 close(AutoCloseable closeable) 方法进行资源关闭。是不是一语惊醒梦中人啊?
其实Java7以后,还有一种关闭资源的方式,也就是 try-with-resources,这种方式也是我们推荐的!很优雅!
我们来看看它是怎么优雅地关闭资源的!
1 | /** |
这种方式就省略了finally,不必重复编写关闭资源的代码了!而且资源也得到了关闭!怎么验证这个问题?可以查看底下的 实际应用 章节!
其实try-with-resources关闭资源的操作,本质上是继承了java.lang.AutoCloseable接口,实现了close方法,所以使用try-with-resources能关闭资源。很神奇吧!
这个章节就是验证使用try-with-resources可以关闭资源的问题的!
上面我们说了使用try-with-resources关闭资源,只要是继承了java.lang.AutoCloseable接口 实现close()方法就可以使用!
我们自定义一个资源类,来看看实际应用吧!
1 | package com.chloneda.jutils.test; |
结果输出。
1 | useResource:{} 正在使用资源! |
看到运行结果了吗?Resources类实现AutoCloseable接口,实现了close()方法,try-with-resources 就会自动关闭资源!
一旦Resources类没有继承java.lang.AutoCloseable接口,没有实现close()方法,AutoClosableTest类的try模块就在编译期报错,提示信息如下。
1 | Incompatible types. |
最后,需要说明的是try-with-resources就是一个JVM语法糖!关于JVM语法糖可以查查相关资料,看看Java中有哪些有趣的语法糖!
《Effective Java》在第三版中也推荐使用try-with-resources语句替代try-finally语句。
所以在处理必须关闭的资源时,使用try-with-resources语句替代try-finally语句。生成的代码更简洁,更清晰,并且生成的异常更有用。 try-with-resources语句在编写必须关闭资源的代码时会更容易,也不会出错,而使用try-finally语句实际上是不可能的。
如此,推荐大家使用try-with-resources优雅地关闭资源!