mock&stub

说明

Stub 就是⼀个纯粹的模拟服务,⽤于替代真实的服务,收到请求返回指定结果,不会记录任何信息。
Mock 则更进⼀步,还会记录调⽤⾏为,可以根据⾏为来验证系统的正确性(断⾔)。
源于单元测试,⽬前应⽤范围单元,集成,接⼜,功能(前后端,服务间,与第三⽅间,⼦功能间)测试中

各语言实现技术

Java/Android:Mockito;JMockit ,EasyMock,PowerMock
Python:3.3以上版本⾃带Mock,magicMock
Go:gomock
.NET:Moq
C++:Google Mock,MockCpp

阅读全文
jmeter安装与使用

安装运行

安装

下载解压即可

1
./jmeter-server -Djava.rmi.server.hostname=192.168.13.128 -Dserver_port=1099

jemter支持客户端配置测试数据上传influxdb&Grafana:

添加Backend Listener 组件InfluxdbBackendListenerClient,用于收集数据并发送给influxdb

命令行运行

1
2
3
4
5
6
7
8
jmeter -n -t <testplan filename> -l <listener filename>
-h, –help -> prints usage information and exit
-n, –nongui -> run JMeter in nongui mode
-t, –testfile <argument> -> the jmeter test(.jmx) file to run
-l, –logfile <argument> -> the file to log samples to
-r, –runremote -> Start remote servers (as defined in remote_hosts)
-H, –proxyHost <argument> -> Set a proxy server for JMeter to use
-P, –proxyPort <argument> -> Set proxy server port for JMeter to use

组件

执行顺序:

配置元件
前置处理器
定时器/逻辑控制器
取样-请求-samplers
后置处理器
断言
监听器

逻辑控制组件 - Loop Controller

录制回放

JMeter 脚本录制之前的业务步骤梳理、明确
创建代理HTTP(S) Test Script Recorder
添加Thread Group
添加Recorder Controller
代理中的配置: 端口、包含URL过滤(include)、排除URL过滤(exclude)、存放位置
开启JMeter代理
配置浏览器的代理
在浏览器中完成业务操作
JMeter 中完成录制之后检查

自动压测

JMeter 脚本(.jmx 文件) - 压测逻辑
Shell – 控制逻辑(并发数的更改)
JMeter 静默运行– 脱离UI限制,使得自动化运行更稳定
jmeter –n –t $jmx_file -l $jtl_file(jtl 文件是jmeter压测请求响应数据的原始文件)

java request

问题:

不是所有的接口都是http 协议
稀有协议的请求必须定制化用程序开发
jmx 本质上只是配置文件,不是程序代码
团队一起开发jmx 会很头疼,JMeter UI中处理XML冲突
原理及优势:
纯Java 程序,实现了JMeter中提供接口– “JavaSamplerClient”
将Java 程序集成到JMeter中,通过Java Request实现调度
Java 程序实现与压测“目标”的交互
JMeter 来控制Java程序的生命周期、并发调度、收集结果报告等处理

自己写程序,流程控制自由、灵活;纯代码编程,源码管理方便,容易推进团队合作开发;要Java程序可以实现的就是能够支持的

实现:

Java Request 执行类必须继承AbstractJavaSamplerClient 抽象类
各种Post Get Delete 请求需要使用java 的HttpClient 来实现
接口请求之间的交互在java 代码中来控制
HttpResponse 中的Json 返回值解析使用java 中的json 解析库来进行解析
除了最终的运行和数据交互需要进入jmeter,基本上已经俨然变成了java 程序开发活动

jmeter中的Beanshell

小型嵌入式Java 源码解释器
BeanShell PreProcessor :在Sampler 执行之前会被执行
BeanShell PostProcessor:在Sampler 执行之后会被执行
BeanShell Sampler: 可以直接嵌入BeanShell代码

BeanShell 用途:
帮助生成测试执行过程中的数据
嵌入Java 程序, 执行对应逻辑操作

Beanshell PreProcessor:
在Sampler 请求实际调用之前被执行
支持在BeanShell PreProcessor中直接写代码或者在Java项目中编写代码,打包导入JMeter之后再被调用
Demo:

调用Java代码: long timestamp = System.currentTimeMillis();
将生成的时间戳字符串放入JMeter 的全局变量中:
vars.put(“timestamp”, timestamp + “”);
后续请求通过引用${timestamp} 来使用该变量

JMeter中的Beanshell PostProcessor

在Sampler 请求实际调用发生之后再被执行
支持在BeanShell PostProcessor中直接写代码或者在Java项目中编写代码,打包导入JMeter之后再被调用
Demo:

打包输出成jar文件,然后放入JMeter_Path/lib/ext 目录下
在Beanshell PostProcessor中调用封装后的Java函数
得到函数返回值之后,将返回值放入JMeter变量组vars
后续请求中可以直接使用对应的变量值

分布式

确定JMeter 控制节点与 Agent节点的运行位置
控制节点与Agent节点之间的网络通信保持畅通
防火墙 – 关闭 或者 设定开放具体端口
各个节点上安装好 JMeter
确定各节点的IP与JMeter启动后需要占用的端口号
启动Agent 节点的远程监听模式
配置控制节点的jmeter.properties

启动分布式压测Agent节点(同一台机器启动多个远程压测节点时需要避开端口冲突):
jmeter-server -Djava.rmi.server.hostname= -Dserver_port=

配置JMeter 控制节点,将控制节点指向各个Agent节点:
打开 jmeter.properties, 找到remote_hosts 配置项
将Agent 压测节点的对应 hostname (IP) 、端口 填入

远程静默压测(只能看到命令行参数的变动与监控平台曲线变化)

打开GUI运行远程压测的问题:
GUI不能关闭
控制节点不能停止运行
虽然控制节点可以不承担 “发压” 工作,但是控制节点也不能关机
结论: 压测时间持续长,尽量别用自己的工作机当控制节点

首先保证所有agent都已经启动,运行JMeter静默压测,不用启动GUI,支持远程分布式压测
jmeter -n -r -t -l
看监控页面,等待结束,结果记录导入看测试报告

工具

swagger转换jmx

https://github.com/Pactortester/swaggerjmx

关联文件扩展名

关联文件扩展名 .jmx 双击该命令以打开JMeter GUI

  • jmeter-n.cmd 用于非GUI, jmeterw.cmd 用于在没有控制台窗口的情况下打开JMeter
  • 使用jmeter-t.cmd打开jmx会在后台打开gui和cmd,使用jmeterw不会打开任何东西。
  1. 使用Assoc命令设置JMeter .jmx脚本的文件类型关联

    1
    Assoc .jmx=jmeter 
  2. 使用FType命令为.jmx脚本定义JMeter可执行文件

    1
    FType jmeter='c:\apps\jmeter\bin\jmeter-t.cmd' %1 

问题

编码:

转码程序贴入Beanshell PostProcessor

阅读全文
压缩解压缩

tar

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

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

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

下面的参数-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包中所有文件,-t是解开的意思

压缩

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 解压

解压jdk到指定文件夹:

tar -xzvf jdk-8u131-linux-x64.tar.gz -C /usr/local/java

阅读全文
数据库权限

grant 权限 on 数据库对象 to 用户

普通数据用户(查询、插入、更新、删除)

1
2
3
4
5
6
grant select on testdb.* to common_user@’%’
grant insert on testdb.* to common_user@’%’
grant update on testdb.* to common_user@’%’
grant delete on testdb.* to common_user@'%'
--或者
grant select, insert, update, delete on testdb.* to common_user@’%’

数据库开发人员(创建表、索引、视图、存储过程、函数等)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
--grant 创建、修改、删除 MySQL 数据表结构权限。
grant create on testdb.* to developer@’192.168.0.%’;
grant alter on testdb.* to developer@’192.168.0.%’;
grant drop on testdb.* to developer@’192.168.0.%’;
--grant 操作 MySQL 外键权限。
--grant 操作 MySQL 临时表权限。
grant create temporary tables on testdb.* to developer@’192.168.0.%’;
--grant 操作 MySQL 索引权限。
grant index on testdb.* to developer@’192.168.0.%’;
--grant 操作 MySQL 视图、查看视图源代码 权限。
grant create view on testdb.* to developer@’192.168.0.%’;
grant show view on testdb.* to developer@’192.168.0.%’;
--grant 操作 MySQL 存储过程、函数 权限。
grant create routine on testdb.* to developer@’192.168.0.%’; — now, can show procedure status
grant alter routine on testdb.* to developer@’192.168.0.%’; — now, you can drop a procedure
grant execute on testdb.* to developer@’192.168.0.%’;

普通 DBA

1
2
--管理某个 MySQL 数据库的权限。其中,关键字 “privileges” 可以省略。
grant all privileges on testdb to dba@’localhost’

高级 DBA

1
2
--管理 MySQL 中所有数据库的权限。
grant all on *.* to dba@’localhost’

MySQL grant 权限作用层次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
--grant 作用在整个 MySQL 服务器上
grant select on *.* to dba@localhost; — dba 可以查询 MySQL 中所有数据库中的表。
grant all on *.* to dba@localhost; — dba 可以管理 MySQL 中的所有数据库

--grant 作用在单个数据库上
grant select on testdb.* to dba@localhost; — dba 可以查询 testdb 中的表。

--grant 作用在单个数据表上
grant select, insert, update, delete on testdb.orders to dba@localhost;
--这里在给一个用户授权多张表时,可以多次执行以上语句。例如:
grant select(user_id,username) on smp.users to mo_user@’%’ identified by123345′;
grant select on smp.mo_sms to mo_user@’%’ identified by123345′;

--grant 作用在表中的列上
grant select(id, se, rank) on testdb.apache_log to dba@localhost;

--grant 作用在存储过程、函数上
grant execute on procedure testdb.pr_add to ‘dba’@'localhost’
grant execute on function testdb.fn_add to ‘dba’@'localhost’

查看 MySQL 用户权限

1
2
3
4
--查看当前用户(自己)权限
show grants;
--查看其他 MySQL 用户权限
show grants for zhangkh@localhost;

权限撤销

1
2
3
--revoke 跟 grant 的语法差不多,只需要把关键字 “to” 换成 “from” 即可
grant all on *.* to dba@localhost;
revoke all on *.* from dba@localhost;

注意事项

1. grant, revoke 用户权限后,该用户只有重新连接 MySQL 数据库,权限才能生效。

2. 如果想让授权的用户,也可以将这些权限 grant 给其他用户,需要选项 “grant option“

1
2
grant select on testdb.* to dba@localhost with grant option;
--ps:这个特性一般用不到。实际中,数据库权限最好由 DBA 来统一管理。

mysql授权表共有5个表:user、db、host、tables_priv和columns_priv。

user表

user表列出可以连接服务器的用户及其口令,并且它指定他们有哪种全局(超级用户)权限。在user表启用的任何权限均是全局权限,并适用于所有数据库。例如,如果你启用了DELETE权限,在这里列出的用户可以从任何表中删除记录,所以在你这样做之前要认真考虑。

db表

db表列出数据库,而用户有权限访问它们。在这里指定的权限适用于一个数据库中的所有表。

host表

host表与db表结合使用在一个较好层次上控制特定主机对数据库的访问权限,这可能比单独使用db好些。这个表不受GRANT和REVOKE语句的影响,所以,你可能发觉你根本不是用它。

tables_priv表

tables_priv表指定表级权限,在这里指定的一个权限适用于一个表的所有列。

columns_priv表

columns_priv表指定列级权限。这里指定的权限适用于一个表的特定列。

注:

对于GRANT USAGE ON,查看手册有如下介绍和实例:

mysql> GRANT USAGE ON . TO ‘zhangkh’@’localhost’;

一个账户有用户名zhangkh,没有密码。该账户只用于从本机连接。未授予权限。通过GRANT语句中的USAGE权限,你可以创建账户而不授予任何权限。它可以将所有全局权限设为’N’。假定你将在以后将具体权限授予该账户。

阅读全文
mysql安装及使用

环境搭建5.7

1
2
3
4
docker run --name mysql -v ~/docker/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d -p 13306:3306 mysql:5.7

docker exec -it mysql bash
mysql -uroot -p
添加用户与赋权

创建用户

1
2
3
4
CREATE USER 'username'@'host' IDENTIFIED BY 'password';
--username – 你将创建的用户名说明:
--host – 指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost, 如 果想让该用户可以从任意远程主机登陆,可以使用通配符%
--password – 该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登 陆服务

授权

1
2
3
4
GRANT privileges ON databasename.tablename TO 'username'@'host';
--privileges – 用户的操作权限,如SELECT , INSERT , UPDATE 等(详细列表见该文最后面).如果要授予所有的权限则使用ALL说明:
--databasename – 数据库名
--tablename-表名,如果要授予该用户对所有数据库和表的相应操作权限则可用* 表示, 如*.*

设置与更改用户密码

1
2
3
SET PASSWORD FOR 'username'@'host' = PASSWORD('newpassword');
--如果是当前登陆用户用
SET PASSWORD = PASSWORD("newpassword");

撤销用户权限

1
REVOKE privilege ON databasename.tablename FROM 'username'@'host';

删除用户

1
DROP USER ‘username’@'host’;

权限刷新

1
flush privileges;

example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 进⼊mysql
mysql> use mysql;
mysql> update user set authentication_string = password('123456') where user =
‘root’; #修改root密码
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root'
WITH GRANT OPTION; #添加权限
# 添加用户
create user test identified by 'test';
create database testdb;
grant all privileges on testdb.* to test@'%' identified by 'test';
flush privileges;
select user,host from mysql.user;
show grants for test;
show variables like 'validate_password%';
权限说明
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
ALTER : Allows use of ALTER TABLE. 
ALTER ROUTINE : Alters or drops stored routines.
CREATE : Allows use of CREATE TABLE.
CREATE ROUTINE : Creates stored routines.
CREATE TEMPORARY TABLE : Allows use of CREATE TEMPORARY TABLE.
CREATE USER : Allows use of CREATE USER, DROP USER, RENAME USER, and REVOKE ALL PRIVILEGES.
CREATE VIEW : Allows use of CREATE VIEW.
DELETE : Allows use of DELETE.
DROP : Allows use of DROP TABLE.
EXECUTE : Allows the user to run stored routines.
FILE : Allows use of SELECT… INTO OUTFILE and LOAD DATA INFILE.
INDEX : Allows use of CREATE INDEX and DROP INDEX.
INSERT : Allows use of INSERT.
LOCK TABLES : Allows use of LOCK TABLES on tables for which the user also has SELECT privileges.
PROCESS : Allows use of SHOW FULL PROCESSLIST.
RELOAD : Allows use of FLUSH.
REPLICATION : Allows the user to ask where slave or master
CLIENT : servers are.
REPLICATION SLAVE : Needed for replication slaves.
SELECT : Allows use of SELECT.
SHOW DATABASES : Allows use of SHOW DATABASES.
SHOW VIEW : Allows use of SHOW CREATE VIEW.
SHUTDOWN : Allows use of mysqladmin shutdown.
SUPER : Allows use of CHANGE MASTER, KILL, PURGE MASTER LOGS, and SET GLOBAL SQL statements. Allows mysqladmin debug command. Allows one extra connection to be made if maximum connections are reached.
UPDATE : Allows use of UPDATE.
USAGE : Allows connection without any specific privileges.

8.0以上

随机密码

5.7以后安装mysql以后 系统会自动生成随机密码,需要使用随机密码 登陆 ,登陆成功后再修改MySQL的密码,随机密码在 MySQL安装路径下 data 文件夹中的SYZ.err中

修改密码

在MySQL 8.04前

1
SET PASSWORD=PASSWORD('[新密码]')

MySQL8.0.4后,这样默认是不行的。因为之前,MySQL的密码认证插件是“mysql_native_password”,而现在使用的是“caching_sha2_password”。

可以使用以下的方法修改root密码,新密码即要修改的密码

1
2
3
use mysql;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';
FLUSH PRIVILEGES;

另一种修改密码的方式,新密码即要修改的密码,回车之后会要求输入原始密码

1
mysqladmin -u root -p password 新密码

类型

  1. 数值数据类型
    整数类型: TINYINT、SMALLINT、MEDIUMINT、INT、
    BIGINT
    浮点数类型:FLOAT、DOUBLE
    定点⼩数: DECIMAL
  2. ⽇期/时间类型
    YEAR、TIME、DATE、DATETIME、TIMESTAMP
  3. 字符串类型,其中字符串又可以分为⽂本字符串和⼆进制字符串
    ⽂本字符串:
    CHAR、VARCHAR、TEXT、ENUM、SET等 
    ⼆进制字符串
    BIT、BINARY、VARBINARY、BLOB

DDl

定义数据库对象:库、表、列列(Create,Drop,Alter,Show,Rename)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE TABLE `users` (
`empno` int(10) NOT NULL,
`name` varchar(50) NOT NULL,
`birth` date DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`salary` decimal(8,2) DEFAULT NULL,
`regtime` datetime DEFAULT
CURRENT_TIMESTAMP,
PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT
CHARSET=utf8;
# 修改表字段类型
ALTER TABLE users MODIFY age date ;
# 修改字段名和类型
ALTER TABLE users change age birthday date ;
SHOW TABLES;
# 重命名表
RENAME TABLE users TO pay_users;
# 删除表
DROP TABLE IF EXISTS users;
# 删除所有信息
TRUNCATE users;

DML

数据操作,增、删、改、查数据库记录(insert,delete,update)

1
2
3
4
5
6
# 插⼊单条数据
INSERT INTO tbl_name (col1,col2) VALUES (value1,value2);
# 删除数据
DELETE FROM tbl_name;
# 更新数据
update users1 set birth ='1989-01-31' where name=‘fang'

简单查询

1.选择所有数据
2.选择特定⾏
3.选择特定列
4.排序⾏
5.模糊查询
6.⽇期函数

1
2
3
4
5
6
7
8
9
10
11
1.精确查询:= <>
2.别名:as
3.限制⾏:limit m,n
4.⽐较运算符:>,>=,<,<=
5.逻辑运算符:and 两条件同时满⾜,or⼀个条件满⾜就⾏ and优先级⾼于or
6.去重 distinct
7.区间运算
8.排序 order by desc降序,asc 升序
9.模糊查询:like % _ notlike
10.集合运算 in , not in
11.⾮空运算 is null,is not null
聚合函数

count,sum,avg,max,min

分组筛选
1
2
3
4
5
SELECT <列列名>
FROM <表名>
[WHERE <查询表达式>]
[GROUP BY <分组列列名>]
[HAVING <分组后的查询表达式>]

WHERE⼦子句句从数据源中去掉不不符合其搜索条件的数据
GROUP BY⼦子句句搜集数据⾏行行到各个组中,统计函数为各个组计算统计值
HAVING⼦子句句去掉不不符合其组搜索条件的各组数据⾏

多表联接

1
2
3
4
5
6
7
8
9
10
11
12
13
# WHERE(等值连接)
select 列名 from 表A a ,表B b where a.key=b.key
# 内联接(INNER JOIN)
select 列列名 from 表A a inner join 表B b on a.key=b.key
# 外联接(OUTER JOIN)
# 左外联接:
select 列名 from 表A a left join 表B b on a.key=b.key
# 右外联接:
select 列名 from 表A a right join 表B b on a.key=b.key
# CROSS JOIN(笛卡尔积):
SELECT t1.id, t2.id FROM t1 CROSS JOIN t2;
# Union :
SELECT * FROM t1 union select * from t2;

备份恢复

1
2
3
4
5
6
7
8
mysqldump -help
# 备份:
mysqldump -u ⽤户名 -p --databases db > 备份⽂件名.sql
# 恢复:
通过mysqldump备份的⽂件,如果⽤了--all-databases或--databases选项,则在备份⽂件中包含 CREATE DATABASE和 USE语句,不需要指定⼀个数据库名去恢复备份⽂件。
shell> mysql –u ⽤户名 –p < 备份⽂件.sql
mysql> source备份⽂件.sql;
如果通过mysqldump备份的是单个数据库,且没有使⽤--databases选项,则备份⽂件中不包含 CREATE DATABASE和 USE语句,那么在恢复的时候必须先创建数据库。

存储过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 删除存储过程,如果这个名字的已存在
DROP PROCEDURE if exists insert_data_pro;
# 由于语句较多,使⽤这个告诉mysql,看看$$就表⽰语句结束了。
DELIMITER $$
# 建⽴存储过程名字叫 insert_data_pro
CREATE
PROCEDURE insert_data_pro()
BEGIN # 开始
DECLARE i INT; #定义 i
SET i=0; # 设置初始值为0
WHILE i>=0 && i<= 10000 DO # 循环 插⼊10000条数据,可以变化。
INSERT INTO
big_data(name1,age,email)values(concat(‘bq’,i),rand()*50,concat('bq',i,'@qq.com'));
# 写的sql,concat是将多个str连在⼀起。
SET i=i + 1;
END WHILE; #结束循环
END$$ #存储过程结束
DELIMITER ; #恢复设置
# 下⾯是调⽤存储过程
call insert_data_pro();

索引,慢查询

1
2
3
CREATE INDEX index_name ON big_data(name);
explain + 查询SQL - ⽤于显⽰SQL执⾏信息参数
# MySQL Explain详解 https://www.cnblogs.com/tufujie/p/9413852.html

存储引擎

1
2
3
4
5
6
7
8
9
10
show ENGINES;
# InnoDB:MySQL 5.7中的默认存储引擎。 InnoDB是⼀种适⽤于MySQL的事务安全(ACID兼容)存储引擎,具有提交,回滚和崩溃恢复功能,可保护⽤户数据。 InnoDB⾏级锁定(没有升级到更粗略的粒度锁)和Oracle风格的⼀致⾮锁定读取增加了多⽤户并发性和性能。InnoDB将⽤户数据存储在聚簇索引中,以减少基于主键的常见查询的I / O. 为了保持数据完整性, InnoDB还⽀持FOREIGN KEY参照完整性约束。
# MyISAM:这些表占⽤空间⼩。 表级锁定 限制了读/写⼯作负载的性能,因此它通常⽤于Web和数据仓库配置中的只读或⼤部分读取⼯作负载。
# Memory:将所有数据存储在RAM中,以便在需要快速查找⾮关键数据的环境中快速访问。这台发动机以前被称为HEAP发动机。它的⽤例正在减少; InnoDB其缓冲池存储区提供了⼀种通⽤且持久的⽅式来将⼤部分或全部数据保存在内存中,并 NDBCLUSTER为⼤型分布式数据集提供快速键值查找。
# CSV:它的表实际上是以逗号分隔值的⽂本⽂件。CSV表允许您以CSV格式导⼊或转储数据,以便与读取和写⼊相同格式的脚本和应⽤程序交换数据。由于CSV表未编制索引,因此通常InnoDB在正常操作期间将数据保留在表中,并且仅在导⼊或导出阶段使⽤CSV表。
# Archive:这些紧凑的⽆索引表⽤于存储和检索⼤量很少引⽤的历史,存档或安全审计信息。
# Blackhole:Blackhole存储引擎接受但不存储数据
# NDB(也称为 NDBCLUSTER) - 该集群数据库引擎特别适⽤于需要尽可能⾼的正常运⾏时间和可⽤性的应⽤程序
# Merge:适⽤于数据仓库等VLDB环境。
# Federated:提供链接单独的MySQL服务器以从许多物理服务器创建⼀个逻辑数据库的功能。⾮常适合分布式或数据集市环境。
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
SELECT * 
FROM employees;

SELECT *
FROM employees
LIMIT 100;

SELECT *
FROM employees
WHERE last_name='Facello';

SELECT *
FROM employees
WHERE last_name<>'Facello' and emp_no<10020;

SELECT last_name 姓,first_name 名
FROM employees
WHERE hire_date>'2000-01-01';

SELECT *
FROM employees t
WHERE t.gender='M' AND t.last_name='Pettey';

SELECT *
FROM employees t
WHERE t.gender='M' AND t.last_name='Pettey' or t.gender='M' AND t.last_name='Hutton';

SELECT DISTINCT (last_name)
FROM employees t
ORDER BY t.last_name DESC;

SELECT last_name,hire_date
FROM employees
WHERE hire_date>='2000'
ORDER BY hire_date DESC ,last_name ASC;

SELECT last_name,hire_date
FROM employees
WHERE last_name NOT IN ('Facello','Hutton');

SELECT last_name,hire_date
FROM employees
WHERE last_name IN ('Facello','Hutton');

SELECT last_name,hire_date
FROM employees
WHERE hire_date is NULL;


SELECT EXTRACT(YEAR FROM CURDATE());

SELECT last_name,EXTRACT(YEAR FROM CURDATE()),EXTRACT(YEAR FROM hire_date)
FROM employees
WHERE EXTRACT(YEAR FROM CURDATE())-EXTRACT(YEAR FROM hire_date)>20;

SELECT last_name,hire_date
FROM employees
WHERE hire_date<DATE_SUB(CURDATE(),INTERVAL 20 YEAR);

SELECT DISTINCT(emp_no)
FROM salaries
WHERE salary BETWEEN 20000 AND 50000;

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name LIKE 'b%';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name REGEXP '^b';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name LIKE '%nd';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name REGEXP 'nd$';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name LIKE '%we%';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name REGEXP 'we';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name LIKE '_____';

SELECT last_name 姓,first_name 名
FROM employees
WHERE LENGTH(first_name)=5;

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name REGEXP '^.....$';


SELECT COUNT(salary)
FROM salaries
WHERE emp_no=10001;

SELECT SUM(salary)
FROM salaries
WHERE emp_no=10001;

SELECT MAX(salary)
FROM salaries
WHERE emp_no=10001;

SELECT MIN(salary)
FROM salaries
WHERE emp_no=10001;

SELECT ROUND(AVG(salary),2)
FROM salaries
WHERE emp_no=10001;

SELECT MAX(hire_date),gender
FROM employees
GROUP BY gender;

SELECT emp_no,AVG(salary) 平均薪资,MAX(salary) 最高薪资,MIN(salary) 最低薪资
FROM salaries
GROUP BY emp_no;

SELECT emp_no
FROM dept_emp
GROUP BY emp_no
HAVING COUNT(emp_no)>1;

SELECT * FROM employees
WHERE emp_no in(
SELECT emp_no FROM dept_emp
GROUP BY emp_no
HAVING COUNT(emp_no)>1);

SELECT * FROM employees
WHERE emp_no=(
SELECT emp_no FROM salaries
WHERE to_date='9999-01-01'
ORDER BY salary DESC LIMIT 1);

SELECT * FROM salaries
WHERE emp_no in(
SELECT emp_no FROM salaries
GROUP BY emp_no HAVING COUNT(emp_no)>=18);


SELECT a.emp_no,a.first_name,b.dept_no
FROM employees a,dept_emp b
WHERE a.emp_no=b.emp_no;

SELECT a.emp_no,a.first_name,b.dept_no,c.dept_name
FROM employees a,dept_emp b,departments c
WHERE a.emp_no=b.emp_no AND b.dept_no=c.dept_no;

SELECT a.emp_no,a.first_name
FROM employees a
INNER JOIN dept_emp b ON a.emp_no=b.emp_no
INNER JOIN departments c ON b.dept_no=c.dept_no
WHERE c.dept_name='Customer Service'

SELECT COUNT(a.emp_no)
FROM employees a
LEFT JOIN dept_emp b ON a.emp_no=b.emp_no
LEFT JOIN departments c ON b.dept_no=c.dept_no
WHERE c.dept_name='Customer Service'

SELECT COUNT(a.emp_no)
FROM employees a
RIGHT JOIN dept_emp b ON a.emp_no=b.emp_no
RIGHT JOIN departments c ON b.dept_no=c.dept_no
WHERE c.dept_name='Customer Service'

SELECT *
FROM departments UNION ALL
SELECT * FROM departments ORDER BY dept_no;

SELECT emp_no,MD5(salary) 薪水保密
FROM salaries WHERE to_date='9999-01-01'
ORDER BY salary ASC LIMIT 10;

SELECT emp_no,MD5(salary) 薪水保密
FROM salaries WHERE to_date='9999-01-01'
ORDER BY salary ASC LIMIT 10;

SELECT emp_no,MD5(salary) 薪水保密
FROM salaries WHERE to_date>CURDATE()
ORDER BY salary LIMIT 10;

UPDATE salaries SET salary=salary+3000
WHERE emp_no IN(
SELECT DISTINCT(emp_no) FROM dept_emp
WHERE EXTRACT(YEAR FROM from_date)=2002
AND to_date>CURDATE()
)


CREATE TABLE `testdata`(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`payload` json DEFAULT NULL,
`response` json DEFAULT NULL,
PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
DESC testdata;

INSERT INTO testdata (payload,response)
VALUES('{"id":1,"name":"test"}','{"code":40000,"msg":"ok"}');

INSERT INTO testdata (payload,response)
VALUES(JSON_OBJECT("id",3,"name","dev1"),
JSON_ARRAY(1,3,5));

SELECT id,payload->'$.id',payload->'$.name',response->'$[0]',response->'$[2]' FROM testdata;

SELECT * FROM testdata WHERE payload->'$.name'='test';


存储过程

DROP TABLE IF EXISTS big_data;

CREATE TABLE big_data(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
name1 VARCHAR(16) DEFAULT NULL,
age INT(11),
email VARCHAR(64) DEFAULT NULL
)ENGINE=MYISAM DEFAULT CHARSET=utf8;

DROP PROCEDURE if exists insert_data_pro;

DELIMITER $$
CREATE
PROCEDURE insert_data_pro()
BEGIN
DECLARE i INT;
SET i=0;
WHILE i>=0 && i<= 10000 DO
INSERT INTO
big_data(name1,age,email)values(concat('test',i),rand()*50,concat('test',i,'@qq.com'));
SET i=i + 1;
END WHILE;
END$$
DELIMITER ;

call insert_data_pro();

ALTER TABLE big_data ENGINE=INNODB;

阅读全文
Spring Boot 打包

Spring Boot 打包

war包

SpringBoot写的项目,自身嵌入了tomcat,所以可以直接运行jar包。但是,每次启动jar包创建的都是新的tomcat,这回造成上传文件丢失等问题。因此,我们需要将项目打成war包,部署到tomcat上。

1.修改pom.xml中的jar为war

1
2
3
4
<groupId>cn.bookcycle.panda</groupId>
<artifactId>panda-payservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>1234

修改为:

1
2
3
4
<groupId>cn.bookcycle.panda</groupId>
<artifactId>panda-payservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>1234

2.在pom.xml中添加打war包的maven插件和设置打包的时候跳过单元测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<!--如果想在没有web.xml文件的情况下构建WAR,请设置为false-->
<failOnMissingWebXml>false</failOnMissingWebXml>
<!--设置war包的名字-->
<warName>checkroom</warName>
</configuration>
</plugin>

<!-- 让打包的时候跳过测试代码 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin> 123456789101112131415161718

3.在pom.xml中添加servlet包

1
2
3
4
<dependency>  
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>1234

4.排除Spring Boot内置的tomcat

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>1234

修改为

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>12345678910

5.在main方法所属的类的同级包下,新建SpringBootStartApplication类

1
2
3
4
5
6
7
public class SpringBootStartApplication extends SpringBootServletInitializer {

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// 注意的Application是启动类,就是main方法所属的类
return builder.sources(Application.class);
}1234567

6.打war包

1
mvn clean package

7.访问项目

产品路径:项目文件夹target/***.war

将war包拷贝到Tomcat的webapps下,然后启动Tomcat

访问路径是:http://localhost:端口号/war包名/@RequestMapping中的value值

注意:

1
2
3
4
- 端口号是Tomcat的端口号,不是Spring Boot中配置的项目端口号
- 如果打包过程中遇到
[WARNING] The requested profile “pom.xml” could not be activated because it does not exist.
可以在打包的时候,清空Goals栏下面的Profiles栏的内容

jar包

1、修改项目发布形式

1
<packaging>jar</packaging>

2、配置加载第三方jar包的目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<skip>true</skip>
<encoding>UTF-8</encoding>
<compilerArguments>
<extdirs>${project.basedir}/src/main/resources/lib</extdirs>
</compilerArguments>
</configuration>
</plugin>

3、指定第三方jar包的打包路径

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 主要配置:将引用的第三方 jar 包打进生成的 jar 文件的 BOOT-INF/lib 目录中 -->
<resources>
<resource>
<directory>src\main\resources\lib</directory>
<targetPath>BOOT-INF\lib</targetPath>
<!-- <includes>
<include>**/*.jar</include>
</includes>-->
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>

4、执行mvn clean package命令即可生成相应jar包

阅读全文
Linux环境变量

Linux设置环境变量的方法

一、在/etc/profile文件中添加变量

用vim在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是“永久的”。
例如:编辑/etc/profile文件,添加CLASSPATH变量

1
2
vim /etc/profile
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib

注:修改文件后要想马上生效还要运行source /etc/profile不然只能在下次重进此用户时生效。

二、在用户目录下的.bash_profile文件中增加变量

用vim ~/.bash_profile文件中增加变量,改变量仅会对当前用户有效,并且是“永久的”。

1
2
vim ~/.bash.profile
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib

注:修改文件后要想马上生效还要运行$ source ~/.bash_profile不然只能在下次重进此用户时生效。

三、直接运行export命令定义变量

在shell的命令行下直接使用 export 变量名=变量值 定义变量,该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。

1
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib

example:配置JAVA_HOME

1
2
3
4
5
6
7
8
# 添加环境变量,编辑配置文件
vim /etc/profile
export JAVA_HOME=/etc/alternatives/java_sdk_1.8.0_openjdk
export JRE_HOME=/etc/alternatives/java_sdk_1.8.0_openjdk/jre
export CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
# 加载配置
source /etc/profile

Linux环境变量使用

一、Linux中常见的环境变量有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PATH:指定命令的搜索路径
PATH声明用法:
PATH=$PAHT:<PATH 1>:<PATH 2>:<PATH 3>:--------:< PATH n >
export PATH # 你可以自己加上指定的路径,中间用冒号隔开。环境变量更改后,在用户下次登陆时生效。
# 查看当前当前系统PATH路径
echo $PATH

HOME # 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)。
HISTSIZE # 指保存历史命令记录的条数。
LOGNAME # 指当前用户的登录名。
HOSTNAME # 指主机的名称,许多应用程序如果要用到主机名的话,通常是从这个环境变量中来取得的
SHELL # 指当前用户用的是哪种Shell。
LANG/LANGUGE # 和语言相关的环境变量,使用多种语言的用户可以修改此环境变量。
MAIL # 指当前用户的邮件存放目录。
# 注意:上述变量的名字并不固定,如HOSTNAME在某些Linux系统中可能设置成HOST

二、Linux也提供了修改和查看环境变量的命令,下面通过几个实例来说明:

1
2
3
4
5
6
7
8
9
10
11
12
# 显示某个环境变量值
echo $PATH
# 设置一个新的环境变量
export HELLO="hello" (可以无引号)
# 显示所有环境变量
env
# 显示本地定义的shell变量
set
# 清除环境变量
unset HELLO
# 设置只读环境变量
readonly HELLO
阅读全文
Linux信息获取

linux下如何查看已安装的centos版本信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Linux查看当前操作系统版本信息
cat /proc/version
Linux version 2.6.32-696.el6.x86_64 (mockbuild@c1bm.rdu2.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) ) #1 SMP Tue Mar 21 19:29:05 UTC 2017
# Linux查看版本当前操作系统内核信息
uname -a
Linux localhost.localdomain 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 athlon i386 GNU/Linux
# linux查看版本当前操作系统发行信息
cat /etc/issue
#
cat /etc/centos-release
CentOS release 6.9 (Final)
# Linux查看cpu相关信息,包括型号、主频、内核信息等
cat /etc/cpuinfo
# Linux查看版本说明当前CPU运行在32bit模式下(但不代表CPU不支持64bit)
getconf LONG_BIT 64

uname的使用

1
2
3
4
5
6
7
8
9
10
11
12
# uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。
# 显示全部信息
uname -a
-m # 或--machine:显示电脑类型;
-r # 或--release:显示操作系统的发行编号;
-s # 或--sysname:显示操作系统名称;
-v # 显示操作系统的版本;
-p # 或--processor:输出处理器类型或"unknown";
-i # 或--hardware-platform:输出硬件平台或"unknown";
-o # 或--operating-system:输出操作系统名称;
--help # 显示帮助;
--version # 显示版本信息。

查看Linux版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看系统版本信息的命令(使用命令时提示command not found,需要安装yum install redhat-lsb -y)
lsb_release -a
[root@localhost ~]# lsb_release -a
LSB Version: :core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0- noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS Linux release 6.0 (Final)
Release: 6.0
Codename: Final
# 注:这个命令适用于所有的linux,包括RedHat、SUSE、Debian等发行版。
# 查看centos版本号 cat /etc/issue
CentOS release 6.9 (Final)
Kernel \r on an \m
# 使用 file /bin/ls
file /bin/ls

用户信息

1
cat  /etc/passwd 
阅读全文
maven

settings.xml文件说明

包含了本地仓库位置,远程仓库服务器以及认证信息等。
settings.xml存在于两个地方:

1
2
1. 安装的地方:$M2_HOME/conf/settings.xml
2. 用户的目录:${user.home}/.m2/settings.xml

前者又被叫做全局配置,后者被称为用户配置。如果两者都存在,它们的内容将被合并,并且用户范围的settings.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

<!--本地仓库。该值表示构建系统本地仓库的路径。其默认值为${user.home}/.m2/repository。 -->
<localRepository>usr/local/maven</localRepository>

<!--Maven是否需要和用户交互以获得输入。如果Maven需要和用户交互以获得输入,则设置成true,反之则应为false。默认为true。 -->
<interactiveMode>true</interactiveMode>

<!--Maven是否需要使用plugin-registry.xml文件来管理插件版本。 -->
<!--如果设置为true,则在{user.home}/.m2下需要有一个plugin-registry.xml来对plugin的版本进行管理 -->
<!--默认为false。 -->
<usePluginRegistry>false</usePluginRegistry>

<!--表示Maven是否需要在离线模式下运行。如果构建系统需要在离线模式下运行,则为true,默认为false。 -->
<!--当由于网络设置原因或者安全因素,构建服务器不能连接远程仓库的时候,该配置就十分有用。 -->
<offline>false</offline>

<!--当插件的组织Id(groupId)没有显式提供时,供搜寻插件组织Id(groupId)的列表。 -->
<!--该元素包含一个pluginGroup元素列表,每个子元素包含了一个组织Id(groupId)。 -->
<!--当我们使用某个插件,并且没有在命令行为其提供组织Id(groupId)的时候,Maven就会使用该列表。 -->
<!--默认情况下该列表包含了org.apache.maven.plugins。 -->
<pluginGroups>
<!--plugin的组织Id(groupId) -->
<pluginGroup>org.codehaus.mojo</pluginGroup>
</pluginGroups>

<!--用来配置不同的代理,多代理profiles可以应对笔记本或移动设备的工作环境:通过简单的设置profile id就可以很容易的更换整个代理配置。 -->
<proxies>
<!--代理元素包含配置代理时需要的信息 -->
<proxy>
<!--代理的唯一定义符,用来区分不同的代理元素。 -->
<id>myproxy</id>
<!--该代理是否是激活的那个。true则激活代理。当我们声明了一组代理,而某个时候只需要激活一个代理的时候,该元素就可以派上用处。 -->
<active>true</active>
<!--代理的协议。 协议://主机名:端口,分隔成离散的元素以方便配置。 -->
<protocol>http://…</protocol>
<!--代理的主机名。协议://主机名:端口,分隔成离散的元素以方便配置。 -->
<host>proxy.somewhere.com</host>
<!--代理的端口。协议://主机名:端口,分隔成离散的元素以方便配置。 -->
<port>8080</port>
<!--代理的用户名,用户名和密码表示代理服务器认证的登录名和密码。 -->
<username>proxyuser</username>
<!--代理的密码,用户名和密码表示代理服务器认证的登录名和密码。 -->
<password>somepassword</password>
<!--不该被代理的主机名列表。该列表的分隔符由代理服务器指定;例子中使用了竖线分隔符,使用逗号分隔也很常见。 -->
<nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts>
</proxy>
</proxies>

<!--配置服务端的一些设置。一些设置如安全证书不应该和pom.xml一起分发。这种类型的信息应该存在于构建服务器上的settings.xml文件中。 -->
<servers>
<!--服务器元素包含配置服务器时需要的信息 -->
<server>
<!--这是server的id(注意不是用户登陆的id),该id与distributionManagement中repository元素的id相匹配。 -->
<id>server001</id>
<!--鉴权用户名。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 -->
<username>my_login</username>
<!--鉴权密码 。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 -->
<password>my_password</password>
<!--鉴权时使用的私钥位置。和前两个元素类似,私钥位置和私钥密码指定了一个私钥的路径(默认是/home/hudson/.ssh/id_dsa)以及如果需要的话,一个密钥 -->
<!--将来passphrase和password元素可能会被提取到外部,但目前它们必须在settings.xml文件以纯文本的形式声明。 -->
<privateKey>${usr.home}/.ssh/id_dsa</privateKey>
<!--鉴权时使用的私钥密码。 -->
<passphrase>some_passphrase</passphrase>
<!--文件被创建时的权限。如果在部署的时候会创建一个仓库文件或者目录,这时候就可以使用权限(permission)。-->
<!--这两个元素合法的值是一个三位数字,其对应了unix文件系统的权限,如664,或者775。 -->
<filePermissions>664</filePermissions>
<!--目录被创建时的权限。 -->
<directoryPermissions>775</directoryPermissions>
<!--传输层额外的配置项 -->
<configuration></configuration>
</server>
</servers>

<!--为仓库列表配置的下载镜像列表。 -->
<mirrors>
<!--给定仓库的下载镜像。 -->
<mirror>
<!--该镜像的唯一标识符。id用来区分不同的mirror元素。 -->
<id>planetmirror.com</id>
<!--镜像名称 -->
<name>PlanetMirror Australia</name>
<!--该镜像的URL。构建系统会优先考虑使用该URL,而非使用默认的服务器URL。 -->
<url>http://downloads.planetmirror.com/pub/maven2</url>
<!--被镜像的服务器的id。例如,如果我们要设置了一个Maven中央仓库(http://repo1.maven.org/maven2)的镜像,-->
<!--就需要将该元素设置成central。这必须和中央仓库的id central完全一致。 -->
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>

<!--根据环境参数来调整构建配置的列表。settings.xml中的profile元素是pom.xml中profile元素的裁剪版本。-->
<!--它包含了id,activation, repositories, pluginRepositories和 properties元素。-->
<!--这里的profile元素只包含这五个子元素是因为这里只关心构建系统这个整体(这正是settings.xml文件的角色定位),而非单独的项目对象模型设置。-->
<!--如果一个settings中的profile被激活,它的值会覆盖任何其它定义在POM中或者profile.xml中的带有相同id的profile。 -->
<profiles>
<!--根据环境参数来调整的构件的配置 -->
<profile>
<!--该配置的唯一标识符。 -->
<id>test</id>
<!--自动触发profile的条件逻辑。Activation是profile的开启钥匙。-->
<!--如POM中的profile一样,profile的力量来自于它能够在某些特定的环境中自动使用某些特定的值;这些环境通过activation元素指定。-->
<!--activation元素并不是激活profile的唯一方式。settings.xml文件中的activeProfile元素可以包含profile的id。-->
<!--profile也可以通过在命令行,使用-P标记和逗号分隔的列表来显式的激活(如,-P test)。 -->
<activation>
<!--profile默认是否激活的标识 -->
<activeByDefault>false</activeByDefault>
<!--activation有一个内建的java版本检测,如果检测到jdk版本与期待的一样,profile被激活。 -->
<jdk>1.7</jdk>
<!--当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。 -->
<os>
<!--激活profile的操作系统的名字 -->
<name>Windows XP</name>
<!--激活profile的操作系统所属家族(如 'windows') -->
<family>Windows</family>
<!--激活profile的操作系统体系结构 -->
<arch>x86</arch>
<!--激活profile的操作系统版本 -->
<version>5.1.2600</version>
</os>
<!--如果Maven检测到某一个属性(其值可以在POM中通过${名称}引用),其拥有对应的名称和值,Profile就会被激活。-->
<!--如果值字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹配属性值字段 -->
<property>
<!--激活profile的属性的名称 -->
<name>mavenVersion</name>
<!--激活profile的属性的值 -->
<value>2.0.3</value>
</property>
<!--提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活profile。-->
<!--另一方面,exists则会检查文件是否存在,如果存在则激活profile。 -->
<file>
<!--如果指定的文件存在,则激活profile。 -->
<exists>/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/</exists>
<!--如果指定的文件不存在,则激活profile。 -->
<missing>/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/</missing>
</file>
</activation>
<!--对应profile的扩展属性列表。Maven属性和Ant中的属性一样,可以用来存放一些值。这些值可以在POM中的任何地方使用标记${X}来使用,这里X是指属性的名称。-->
<!--属性有五种不同的形式,并且都能在settings.xml文件中访问。 -->
<!--1. env.X: 在一个变量前加上"env."的前缀,会返回一个shell环境变量。例如,"env.PATH"指代了$path环境变量(在Windows上是%PATH%)。 -->
<!--2. project.x:指代了POM中对应的元素值。 -->
<!--3. settings.x: 指代了settings.xml中对应元素的值。 -->
<!--4. Java System Properties: 所有可通过java.lang.System.getProperties()访问的属性都能在POM中使用该形式访问, -->
<!-- 如/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre。 -->
<!--5. x: 在<properties/>元素中,或者外部文件中设置,以${someVar}的形式使用。 -->
<properties>
<!-- 如果这个profile被激活,那么属性${user.install}就可以被访问了 -->
<user.install>usr/local/winner/jobs/maven-guide</user.install>
</properties>
<!--远程仓库列表,它是Maven用来填充构建系统本地仓库所使用的一组远程项目。 -->
<repositories>
<!--包含需要连接到远程仓库的信息 -->
<repository>
<!--远程仓库唯一标识 -->
<id>codehausSnapshots</id>
<!--远程仓库名称 -->
<name>Codehaus Snapshots</name>
<!--如何处理远程仓库里发布版本的下载 -->
<releases>
<!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 -->
<enabled>false</enabled>
<!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:-->
<!--always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 -->
<updatePolicy>always</updatePolicy>
<!--当Maven验证构件校验文件失败时该怎么做:-->
<!--ignore(忽略),fail(失败),或者warn(警告)。 -->
<checksumPolicy>warn</checksumPolicy>
</releases>
<!--如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。-->
<!--例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素 -->
<snapshots>
<enabled />
<updatePolicy />
<checksumPolicy />
</snapshots>
<!--远程仓库URL,按protocol://hostname/path形式 -->
<url>http://snapshots.maven.codehaus.org/maven2</url>
<!--用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。-->
<!--Maven 2为其仓库提供了一个默认的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 -->
<layout>default</layout>
</repository>
</repositories>
<!--发现插件的远程仓库列表。仓库是两种主要构件的家。第一种构件被用作其它构件的依赖。这是中央仓库中存储的大部分构件类型。另外一种构件类型是插件。-->
<!--Maven插件是一种特殊类型的构件。由于这个原因,插件仓库独立于其它仓库。pluginRepositories元素的结构和repositories元素的结构类似。-->
<!--每个pluginRepository元素指定一个Maven可以用来寻找新插件的远程地址。 -->
<pluginRepositories>
<!--包含需要连接到远程插件仓库的信息.参见profiles/profile/repositories/repository元素的说明 -->
<pluginRepository>
<releases>
<enabled />
<updatePolicy />
<checksumPolicy />
</releases>
<snapshots>
<enabled />
<updatePolicy />
<checksumPolicy />
</snapshots>
<id />
<name />
<url />
<layout />
</pluginRepository>
</pluginRepositories>
<!--手动激活profiles的列表,按照profile被应用的顺序定义activeProfile。 该元素包含了一组activeProfile元素,每个activeProfile都含有一个profile id。-->
<!--任何在activeProfile中定义的profile id,不论环境设置如何,其对应的 profile都会被激活。-->
<!--如果没有匹配的profile,则什么都不会发生。例如,env-test是一个activeProfile,则在pom.xml(或者profile.xml)中对应id的profile会被激活。-->
<!--如果运行过程中找不到这样一个profile,Maven则会像往常一样运行。 -->
<activeProfiles>
<activeProfile>env-test</activeProfile>
</activeProfiles>
</profile>
</profiles>
</settings>

install package deploy区别

1
2
3
maven package:打包到本项目,一般是在项目target目录下。如果a项目依赖于b项目,打包b项目时,只会打包到b项目下target下,编译a项目时就会报错。
maven install:打包到本地仓库,如果没有设置过maven本地仓库,一般在用户/.m2目录下。如果a项目依赖于b项目,那么install b时,会在本地仓库同时生成pom文件和jar文件,可以看install b的日志:
maven deploy:打包上传到远程仓库,如:私服nexus等,需要配置pom文件

mvn package

“在使用mvn package进行编译、打包时,Maven会执行src/test/java中的JUnit测试用例,有时为了跳过测试,会使用参数-DskipTests和-Dmaven.test.skip=true,这两个参数的主要区别是:
-DskipTests,不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下。
-Dmaven.test.skip=true,不执行测试用例,也不编译测试用例类。”

1
mvn clean package # 依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段

package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库

mvn install

mvn clean install # 依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8个阶段

install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库

mvn deploy

mvn clean deploy # 依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9个阶段

deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库

maven命令行参数

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
mvn -v # –version 显示版本信息;
mvn -V # –show-version 显示版本信息后继续执行Maven其他目标;
mvn -h # –help 显示帮助信息; mvn -e, –errors 控制Maven的日志级别,产生执行错误相关消息;
mvn -X # –debug 控制Maven的日志级别,产生执行调试信息;
mvn -q # –quiet 控制Maven的日志级别,仅仅显示错误;
mvn -Pxxx # 激活 id 为 xxx的profile (如有多个,用逗号隔开);
mvn -Dxxx=yyy # 指定Java全局属性;
mvn -o # –offline 运行offline模式,不联网更新依赖;
mvn -N # –non-recursive 仅在当前项目模块执行命令,不构建子模块;
mvn -pl # –module_name 在指定模块上执行命令;
mvn -ff # –fail-fast 遇到构建失败就直接退出;
mvn -fn # –fail-never 无论项目结果如何,构建从不失败;
mvn -fae # –fail-at-end 仅影响构建结果,允许不受影响的构建继续;
mvn -C # –strict-checksums 如果校验码不匹配的话,构建失败;
mvn -c # –lax-checksums 如果校验码不匹配的话,产生告警;
mvn -U # 强制更新snapshot类型的插件或依赖库(否则maven一天只会更新一次snapshot依赖);
mvn -npu # –no-plugin-updates 对任何相关的注册插件,不进行最新检查(使用该选项使Maven表现出稳定行为,该稳定行为基于本地仓库当前可用的所有插件版本);
mvn -cpu # –check-plugin-updates 对任何相关的注册插件,强制进行最新检查(即使项目POM里明确规定了Maven插件版本,还是会强制更新);
mvn -up # –update-plugins [mvn -cpu]的同义词;
mvn -B # –batch-mode 在非交互(批处理)模式下运行(该模式下,当Mven需要输入时,它不会停下来接受用户的输入,而是使用合理的默认值);
mvn -f # –file 强制使用备用的POM文件; mvn -s, –settings 用户配置文件的备用路径;
mvn -gs # –global-settings 全局配置文件的备用路径;
mvn -emp # –encrypt-master-password 加密主安全密码,存储到Maven settings文件里;
mvn -ep # –encrypt-password 加密服务器密码,存储到Maven settings文件里;
mvn -npr # –no-plugin-registry 对插件版本不使用~/.m2/plugin-registry.xml(插件注册表)里的配置

Maven单独构建多模块项目中的单个模块

场景:

多模块项目各自引用,那么单独编译子模块的pom.xml文件会直接报错,如果编译父项目,那么可能会造成编译时间很慢,其中有些项目也不需要编译

解决方法:

Maven选项:

1
2
3
4
5
6
-pl, --projects
Build specified reactor projects instead of all projects
-am, --also-make
If project list is specified, also build projects required by the list
-amd, --also-make-dependents
If project list is specified, also build projects that depend on projects on the list

单独构建模块jsoft-web,同时会构建jsoft-web模块依赖的其他模块

1
mvn install -pl jsoft-web -am

单独构建模块jsoft-common,同时构建依赖模块jsoft-common的其他模块

1
mvn install -pl jsoft-common -am -amd

pom.xml文件

Maven项目的核心是pom.xml,pom(Project Object Model项目对象模型
pom.xml文件定义了项目的基本信息,项目构建,项目依赖等。

1
2
3
4
5
6
7
8
9
<project xmlns = " http://maven.apache.org/POM/4.0.0 " xmlns:xsi = " http://www.w3.org/2001/XMLSchema-instance "
xsi:schemaLocation = " http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fz.shiro</groupId>
<artifactId>ShiroTest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>ShiroTest Maven Webapp</name>
</project>

porject:是所有元素的根元素
以下元素(groupId,artifactId,packaging,version)是maven的坐标,他们唯一标识了一个项目
modelVersion:指定了当前模型的版本,对于Maven2和Maven3来说,它只能说4.0.0
groupId:定义了项目属于哪个组,假如你在github上建立一个demo项目,那groupId应该com.github.demo。如果你的公司是百度,有个helloword的项目。那groupId应该为com.baidu.helloword如果你的helloword项目有很多模块,则按模块化分。com.baidu.helloword.模块名称
artifactId:定义了当前maven项目在组中的唯一ID,假如你的项目为myapp,groupId为com.baid.myapp。那你的artifactId可以按模块划分。例如当前编写的是myapp项目中的工具类,则artifactId可以为myapp-utils
packaging:表示打包后项目的类型(默认是jar),web项目为war
version:指定了当前项目的版本,SNAPSHOT意为快照,表示正在开发中,不是稳定版本。
name:声明了一个对于用户更为友好的项目名称

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
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">

<!-- 父项目的坐标。如果项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值。
坐标包括group ID,artifact ID和 version。 -->
<parent>
<!-- 被继承的父项目的构件标识符 -->
<artifactId>xxx</artifactId>

<!-- 被继承的父项目的全球唯一标识符 -->
<groupId>xxx</groupId>

<!-- 被继承的父项目的版本 -->
<version>xxx</version>

<!-- 父项目的pom.xml文件的相对路径。相对路径允许你选择一个不同的路径。默认值是../pom.xml。
Maven首先在构建当前项目的地方寻找父项目的pom,其次在文件系统的这个位置(relativePath位置),
然后在本地仓库,最后在远程仓库寻找父项目的pom。 -->
<relativePath>xxx</relativePath>
</parent>

<!-- 声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的,
这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。 -->
<modelVersion> 4.0.0 </modelVersion>

<!-- 项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成,
如com.mycompany.app生成的相对路径为:/com/mycompany/app -->
<groupId>xxx</groupId>

<!-- 构件的标识符,它和group ID一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的artifact ID
和groupID;在某个特定的group ID下,artifact ID也必须是唯一的。构件是项目产生的或使用的一个东西,Maven
为项目产生的构件包括:JARs,源码,二进制发布和WARs等。 -->
<artifactId>xxx</artifactId>

<!-- 项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型 -->
<packaging> jar </packaging>

<!-- 项目当前版本,格式为:主版本.次版本.增量版本-限定版本号 -->
<version> 1.0-SNAPSHOT </version>

<!-- 项目的名称, Maven产生的文档用 -->
<name> xxx-maven </name>

<!-- 项目主页的URL, Maven产生的文档用 -->
<url> http://maven.apache.org </url>

<!-- 项目的详细描述, Maven 产生的文档用。 当这个元素能够用HTML格式描述时(例如,CDATA中的文本会被解析器忽略,
就可以包含HTML标签), 不鼓励使用纯文本描述。如果你需要修改产生的web站点的索引页面,你应该修改你自己的
索引页文件,而不是调整这里的文档。 -->
<description> A maven project to study maven. </description>

<!-- 描述了这个项目构建环境中的前提条件。 -->
<prerequisites>
<!-- 构建该项目或使用该插件所需要的Maven的最低版本 -->
<maven></maven>
</prerequisites>

<!-- 项目的问题管理系统(Bugzilla, Jira, Scarab,或任何你喜欢的问题管理系统)的名称和URL,本例为 jira -->
<issueManagement>
<!-- 问题管理系统(例如jira)的名字, -->
<system> jira </system>

<!-- 该项目使用的问题管理系统的URL -->
<url> http://jira.baidu.com/banseon </url>
</issueManagement>

<!-- 项目持续集成信息 -->
<ciManagement>
<!-- 持续集成系统的名字,例如continuum -->
<system></system>

<!-- 该项目使用的持续集成系统的URL(如果持续集成系统有web接口的话)。 -->
<url></url>

<!-- 构建完成时,需要通知的开发者/用户的配置项。包括被通知者信息和通知条件(错误,失败,成功,警告) -->
<notifiers>
<!-- 配置一种方式,当构建中断时,以该方式通知用户/开发者 -->
<notifier>
<!-- 传送通知的途径 -->
<type></type>

<!-- 发生错误时是否通知 -->
<sendOnError></sendOnError>

<!-- 构建失败时是否通知 -->
<sendOnFailure></sendOnFailure>

<!-- 构建成功时是否通知 -->
<sendOnSuccess></sendOnSuccess>

<!-- 发生警告时是否通知 -->
<sendOnWarning></sendOnWarning>

<!-- 不赞成使用。通知发送到哪里 -->
<address></address>

<!-- 扩展配置项 -->
<configuration></configuration>
</notifier>
</notifiers>
</ciManagement>

<!-- 项目创建年份,4位数字。当产生版权信息时需要使用这个值。 -->
<inceptionYear />

<!-- 项目相关邮件列表信息 -->
<mailingLists>
<!-- 该元素描述了项目相关的所有邮件列表。自动产生的网站引用这些信息。 -->
<mailingList>
<!-- 邮件的名称 -->
<name> Demo </name>

<!-- 发送邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 -->
<post> banseon@126.com </post>

<!-- 订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 -->
<subscribe> banseon@126.com </subscribe>

<!-- 取消订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 -->
<unsubscribe> banseon@126.com </unsubscribe>

<!-- 你可以浏览邮件信息的URL -->
<archive> http:/hi.baidu.com/banseon/demo/dev/ </archive>
</mailingList>
</mailingLists>

<!-- 项目开发者列表 -->
<developers>
<!-- 某个项目开发者的信息 -->
<developer>
<!-- SCM里项目开发者的唯一标识符 -->
<id> HELLO WORLD </id>

<!-- 项目开发者的全名 -->
<name> banseon </name>

<!-- 项目开发者的email -->
<email> banseon@126.com </email>

<!-- 项目开发者的主页的URL -->
<url></url>

<!-- 项目开发者在项目中扮演的角色,角色元素描述了各种角色 -->
<roles>
<role> Project Manager </role>
<role> Architect </role>
</roles>

<!-- 项目开发者所属组织 -->
<organization> demo </organization>

<!-- 项目开发者所属组织的URL -->
<organizationUrl> http://hi.baidu.com/xxx </organizationUrl>

<!-- 项目开发者属性,如即时消息如何处理等 -->
<properties>
<dept> No </dept>
</properties>

<!-- 项目开发者所在时区, -11到12范围内的整数。 -->
<timezone> -5 </timezone>
</developer>
</developers>

<!-- 项目的其他贡献者列表 -->
<contributors>
<!-- 项目的其他贡献者。参见developers/developer元素 -->
<contributor>
<!-- 项目贡献者的全名 -->
<name></name>

<!-- 项目贡献者的email -->
<email></email>

<!-- 项目贡献者的主页的URL -->
<url></url>

<!-- 项目贡献者所属组织 -->
<organization></organization>

<!-- 项目贡献者所属组织的URL -->
<organizationUrl></organizationUrl>

<!-- 项目贡献者在项目中扮演的角色,角色元素描述了各种角色 -->
<roles>
<role> Project Manager </role>
<role> Architect </role>
</roles>

<!-- 项目贡献者所在时区, -11到12范围内的整数。 -->
<timezone></timezone>

<!-- 项目贡献者属性,如即时消息如何处理等 -->
<properties>
<dept> No </dept>
</properties>
</contributor>
</contributors>

<!-- 该元素描述了项目所有License列表。 应该只列出该项目的license列表,不要列出依赖项目的 license列表。
如果列出多个license,用户可以选择它们中的一个而不是接受所有license。 -->
<licenses>
<!-- 描述了项目的license,用于生成项目的web站点的license页面,其他一些报表和validation也会用到该元素。 -->
<license>
<!-- license用于法律上的名称 -->
<name> Apache 2 </name>

<!-- 官方的license正文页面的URL -->
<url> http://www.baidu.com/banseon/LICENSE-2.0.txt </url>

<!-- 项目分发的主要方式:
repo,可以从Maven库下载
manual, 用户必须手动下载和安装依赖 -->
<distribution> repo </distribution>

<!-- 关于license的补充信息 -->
<comments> A business-friendly OSS license </comments>
</license>
</licenses>

<!-- SCM(Source Control Management)标签允许你配置你的代码库,供Maven web站点和其它插件使用。 -->
<scm>
<!-- SCM的URL,该URL描述了版本库和如何连接到版本库。欲知详情,请看SCMs提供的URL格式和列表。该连接只读。 -->
<connection>
scm:svn:http://svn.baidu.com/banseon/maven/banseon/banseon-maven2-trunk(dao-trunk)
</connection>

<!-- 给开发者使用的,类似connection元素。即该连接不仅仅只读 -->
<developerConnection>
scm:svn:http://svn.baidu.com/banseon/maven/banseon/dao-trunk
</developerConnection>

<!-- 当前代码的标签,在开发阶段默认为HEAD -->
<tag></tag>

<!-- 指向项目的可浏览SCM库(例如ViewVC或者Fisheye)的URL。 -->
<url> http://svn.baidu.com/banseon </url>
</scm>

<!-- 描述项目所属组织的各种属性。Maven产生的文档用 -->
<organization>
<!-- 组织的全名 -->
<name> demo </name>

<!-- 组织主页的URL -->
<url> http://www.baidu.com/banseon </url>
</organization>

<!-- 构建项目需要的信息 -->
<build>
<!-- 该元素设置了项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对
于pom.xml的相对路径。 -->
<sourceDirectory></sourceDirectory>

<!-- 该元素设置了项目脚本源码目录,该目录和源码目录不同:绝大多数情况下,该目录下的内容会
被拷贝到输出目录(因为脚本是被解释的,而不是被编译的)。 -->
<scriptSourceDirectory></scriptSourceDirectory>

<!-- 该元素设置了项目单元测试使用的源码目录,当测试项目的时候,构建系统会编译目录里的源码。
该路径是相对于pom.xml的相对路径。 -->
<testSourceDirectory></testSourceDirectory>

<!-- 被编译过的应用程序class文件存放的目录。 -->
<outputDirectory></outputDirectory>

<!-- 被编译过的测试class文件存放的目录。 -->
<testOutputDirectory></testOutputDirectory>

<!-- 使用来自该项目的一系列构建扩展 -->
<extensions>
<!-- 描述使用到的构建扩展。 -->
<extension>
<!-- 构建扩展的groupId -->
<groupId></groupId>

<!-- 构建扩展的artifactId -->
<artifactId></artifactId>

<!-- 构建扩展的版本 -->
<version></version>
</extension>
</extensions>

<!-- 当项目没有规定目标(Maven2 叫做阶段)时的默认值 -->
<defaultGoal></defaultGoal>

<!-- 这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,这些资源被包含在
最终的打包文件里。 -->
<resources>
<!-- 这个元素描述了项目相关或测试相关的所有资源路径 -->
<resource>
<!-- 描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。
举个例子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为
org/apache/maven/messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。 -->
<targetPath></targetPath>

<!-- 是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素
里列出。 -->
<filtering></filtering>

<!-- 描述存放资源的目录,该路径相对POM路径 -->
<directory></directory>

<!-- 包含的模式列表,例如**/*.xml. -->
<includes>
<include></include>
</includes>

<!-- 排除的模式列表,例如**/*.xml -->
<excludes>
<exclude></exclude>
</excludes>
</resource>
</resources>

<!-- 这个元素描述了单元测试相关的所有资源路径,例如和单元测试相关的属性文件。 -->
<testResources>
<!-- 这个元素描述了测试相关的所有资源路径,参见build/resources/resource元素的说明 -->
<testResource>
<!-- 描述了测试相关的资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。
举个例子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为
org/apache/maven/messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。 -->
<targetPath></targetPath>

<!-- 是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素
里列出。 -->
<filtering></filtering>

<!-- 描述存放测试相关的资源的目录,该路径相对POM路径 -->
<directory></directory>

<!-- 包含的模式列表,例如**/*.xml. -->
<includes>
<include></include>
</includes>

<!-- 排除的模式列表,例如**/*.xml -->
<excludes>
<exclude></exclude>
</excludes>
</testResource>
</testResources>

<!-- 构建产生的所有文件存放的目录 -->
<directory></directory>

<!-- 产生的构件的文件名,默认值是${artifactId}-${version}。 -->
<finalName></finalName>

<!-- 当filtering开关打开时,使用到的过滤器属性文件列表 -->
<filters></filters>

<!-- 子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本
地配置都会覆盖这里的配置 -->
<pluginManagement>
<!-- 使用的插件列表 。 -->
<plugins>
<!-- plugin元素包含描述插件所需要的信息。 -->
<plugin>
<!-- 插件在仓库里的group ID -->
<groupId></groupId>

<!-- 插件在仓库里的artifact ID -->
<artifactId></artifactId>

<!-- 被使用的插件的版本(或版本范围) -->
<version></version>

<!-- 是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,只有在真需要下载时,该
元素才被设置成enabled。 -->
<extensions>true/false</extensions>

<!-- 在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。 -->
<executions>
<!-- execution元素包含了插件执行需要的信息 -->
<execution>
<!-- 执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标 -->
<id></id>

<!-- 绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段 -->
<phase></phase>

<!-- 配置的执行目标 -->
<goals></goals>

<!-- 配置是否被传播到子POM -->
<inherited>true/false</inherited>

<!-- 作为DOM对象的配置 -->
<configuration></configuration>
</execution>
</executions>

<!-- 项目引入插件所需要的额外依赖 -->
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>

<!-- 任何配置是否被传播到子项目 -->
<inherited>true/false</inherited>

<!-- 作为DOM对象的配置 -->
<configuration></configuration>
</plugin>
</plugins>
</pluginManagement>

<!-- 该项目使用的插件列表 。 -->
<plugins>
<!-- plugin元素包含描述插件所需要的信息。 -->
<plugin>
<!-- 插件在仓库里的group ID -->
<groupId></groupId>

<!-- 插件在仓库里的artifact ID -->
<artifactId></artifactId>

<!-- 被使用的插件的版本(或版本范围) -->
<version></version>

<!-- 是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,只有在真需要下载时,该
元素才被设置成enabled。 -->
<extensions>true/false</extensions>

<!-- 在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。 -->
<executions>
<!-- execution元素包含了插件执行需要的信息 -->
<execution>
<!-- 执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标 -->
<id></id>

<!-- 绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段 -->
<phase></phase>

<!-- 配置的执行目标 -->
<goals></goals>

<!-- 配置是否被传播到子POM -->
<inherited>true/false</inherited>

<!-- 作为DOM对象的配置 -->
<configuration></configuration>
</execution>
</executions>

<!-- 项目引入插件所需要的额外依赖 -->
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>

<!-- 任何配置是否被传播到子项目 -->
<inherited>true/false</inherited>

<!-- 作为DOM对象的配置 -->
<configuration></configuration>
</plugin>
</plugins>
</build>

<!-- 在列的项目构建profile,如果被激活,会修改构建处理 -->
<profiles>
<!-- 根据环境参数或命令行参数激活某个构建处理 -->
<profile>
<!-- 构建配置的唯一标识符。即用于命令行激活,也用于在继承时合并具有相同标识符的profile。 -->
<id></id>

<!-- 自动触发profile的条件逻辑。Activation是profile的开启钥匙。profile的力量来自于它能够
在某些特定的环境中自动使用某些特定的值;这些环境通过activation元素指定。activation元
素并不是激活profile的唯一方式。 -->
<activation>
<!-- profile默认是否激活的标志 -->
<activeByDefault>true/false</activeByDefault>

<!-- 当匹配的jdk被检测到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本
不是以1.4开头的JDK。 -->
<jdk>jdk版本,如:1.7</jdk>

<!-- 当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。 -->
<os>
<!-- 激活profile的操作系统的名字 -->
<name> Windows XP </name>

<!-- 激活profile的操作系统所属家族(如 'windows') -->
<family> Windows </family>

<!-- 激活profile的操作系统体系结构 -->
<arch> x86 </arch>

<!-- 激活profile的操作系统版本 -->
<version> 5.1.2600 </version>
</os>

<!-- 如果Maven检测到某一个属性(其值可以在POM中通过${名称}引用),其拥有对应的名称和值,Profile
就会被激活。如果值字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹
配属性值字段 -->
<property>
<!-- 激活profile的属性的名称 -->
<name> mavenVersion </name>

<!-- 激活profile的属性的值 -->
<value> 2.0.3 </value>
</property>

<!-- 提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活
profile。另一方面,exists则会检查文件是否存在,如果存在则激活profile。 -->
<file>
<!-- 如果指定的文件存在,则激活profile。 -->
<exists> /usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/ </exists>

<!-- 如果指定的文件不存在,则激活profile。 -->
<missing> /usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/ </missing>
</file>
</activation>

<!-- 构建项目所需要的信息。参见build元素 -->
<build>
<defaultGoal />
<resources>
<resource>
<targetPath></targetPath>
<filtering></filtering>
<directory></directory>
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
</resource>
</resources>
<testResources>
<testResource>
<targetPath></targetPath>
<filtering></filtering>
<directory></directory>
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
</testResource>
</testResources>
<directory></directory>
<finalName></finalName>
<filters></filters>
<pluginManagement>
<plugins>
<!-- 参见build/pluginManagement/plugins/plugin元素 -->
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<extensions>true/false</extensions>
<executions>
<execution>
<id></id>
<phase></phase>
<goals></goals>
<inherited>true/false</inherited>
<configuration></configuration>
</execution>
</executions>
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<goals></goals>
<inherited>true/false</inherited>
<configuration></configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- 参见build/pluginManagement/plugins/plugin元素 -->
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<extensions>true/false</extensions>
<executions>
<execution>
<id></id>
<phase></phase>
<goals></goals>
<inherited>true/false</inherited>
<configuration></configuration>
</execution>
</executions>
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
<goals></goals>
<inherited>true/false</inherited>
<configuration></configuration>
</plugin>
</plugins>
</build>

<!-- 模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的
相对路径 -->
<modules>
<!--子项目相对路径-->
<module></module>
</modules>

<!-- 发现依赖和扩展的远程仓库列表。 -->
<repositories>
<!-- 参见repositories/repository元素 -->
<repository>
<releases>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</releases>
<snapshots>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</snapshots>
<id></id>
<name></name>
<url></url>
<layout></layout>
</repository>
</repositories>

<!-- 发现插件的远程仓库列表,这些插件用于构建和报表 -->
<pluginRepositories>
<!-- 包含需要连接到远程插件仓库的信息.参见repositories/repository元素 -->
<pluginRepository>
<releases>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</releases>
<snapshots>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</snapshots>
<id></id>
<name></name>
<url></url>
<layout></layout>
</pluginRepository>
</pluginRepositories>

<!-- 该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的
仓库中下载。要获取更多信息,请看项目依赖机制。 -->
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>

<!-- 不赞成使用. 现在Maven忽略该元素. -->
<reports></reports>

<!-- 该元素包括使用报表插件产生报表的规范。当用户执行“mvn site”,这些报表就会运行。 在页面导航栏能看
到所有报表的链接。参见reporting元素 -->
<reporting></reporting>

<!-- 参见dependencyManagement元素 -->
<dependencyManagement>
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
</dependencyManagement>

<!-- 参见distributionManagement元素 -->
<distributionManagement>
</distributionManagement>

<!-- 参见properties元素 -->
<properties />
</profile>
</profiles>

<!-- 模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径 -->
<modules>
<!--子项目相对路径-->
<module></module>
</modules>

<!-- 发现依赖和扩展的远程仓库列表。 -->
<repositories>
<!-- 包含需要连接到远程仓库的信息 -->
<repository>
<!-- 如何处理远程仓库里发布版本的下载 -->
<releases>
<!-- true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 -->
<enabled><enabled>

<!-- 该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),
daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 -->
<updatePolicy></updatePolicy>

<!-- 当Maven验证构件校验文件失败时该怎么做:ignore(忽略),fail(失败),或者warn(警告)。 -->
<checksumPolicy></checksumPolicy>
</releases>

<!-- 如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,
为每种类型的构件采取不同的策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素 -->
<snapshots>
<enabled><enabled>
<updatePolicy></updatePolicy>
<checksumPolicy></checksumPolicy>
</snapshots>

<!-- 远程仓库唯一标识符。可以用来匹配在settings.xml文件里配置的远程仓库 -->
<id> banseon-repository-proxy </id>

<!-- 远程仓库名称 -->
<name> banseon-repository-proxy </name>

<!-- 远程仓库URL,按protocol://hostname/path形式 -->
<url> http://192.168.1.169:9999/repository/ </url>

<!-- 用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认
的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 -->
<layout> default </layout>
</repository>
</repositories>

<!-- 发现插件的远程仓库列表,这些插件用于构建和报表 -->
<pluginRepositories>
<!-- 包含需要连接到远程插件仓库的信息.参见repositories/repository元素 -->
<pluginRepository>
</pluginRepository>
</pluginRepositories>

<!-- 该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。
要获取更多信息,请看项目依赖机制。 -->
<dependencies>
<dependency>
<!-- 依赖的group ID -->
<groupId> org.apache.maven </groupId>

<!-- 依赖的artifact ID -->
<artifactId> maven-artifact </artifactId>

<!-- 依赖的版本号。 在Maven 2里, 也可以配置成版本号的范围。 -->
<version> 3.8.1 </version>

<!-- 依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外。一个类型可以被映射成另外一个扩展
名或分类器。类型经常和使用的打包方式对应,尽管这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。
如果设置extensions为 true,就可以在plugin里定义新的类型。所以前面的类型的例子不完整。 -->
<type> jar </type>

<!-- 依赖的分类器。分类器可以区分属于同一个POM,但不同构建方式的构件。分类器名被附加到文件名的版本号后面。例如,
如果你想要构建两个单独的构件成JAR,一个使用Java 1.4编译器,另一个使用Java 6编译器,你就可以使用分类器来生
成两个单独的JAR构件。 -->
<classifier></classifier>

<!-- 依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。
- compile :默认范围,用于编译
- provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath
- runtime: 在执行时需要使用
- test: 用于test任务时使用
- system: 需要外在提供相应的元素。通过systemPath来取得
- systemPath: 仅用于范围为system。提供相应的路径
- optional: 当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用 -->
<scope> test </scope>

<!-- 仅供system范围使用。注意,不鼓励使用这个元素,并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件
系统上的路径。需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径,例如${java.home}。 -->
<systemPath></systemPath>

<!-- 当计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件集。即告诉maven你只依赖指定的项目,不依赖项目的
依赖。此元素主要用于解决版本冲突问题 -->
<exclusions>
<exclusion>
<artifactId> spring-core </artifactId>
<groupId> org.springframework </groupId>
</exclusion>
</exclusions>

<!-- 可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。
可选依赖阻断依赖的传递性。 -->
<optional> true </optional>
</dependency>
</dependencies>

<!-- 不赞成使用. 现在Maven忽略该元素. -->
<reports></reports>

<!-- 该元素描述使用报表插件产生报表的规范。当用户执行“mvn site”,这些报表就会运行。 在页面导航栏能看到所有报表的链接。 -->
<reporting>
<!-- true,则,网站不包括默认的报表。这包括“项目信息”菜单中的报表。 -->
<excludeDefaults />

<!-- 所有产生的报表存放到哪里。默认值是${project.build.directory}/site。 -->
<outputDirectory />

<!-- 使用的报表插件和他们的配置。 -->
<plugins>
<!-- plugin元素包含描述报表插件需要的信息 -->
<plugin>
<!-- 报表插件在仓库里的group ID -->
<groupId></groupId>
<!-- 报表插件在仓库里的artifact ID -->
<artifactId></artifactId>

<!-- 被使用的报表插件的版本(或版本范围) -->
<version></version>

<!-- 任何配置是否被传播到子项目 -->
<inherited>true/false</inherited>

<!-- 报表插件的配置 -->
<configuration></configuration>

<!-- 一组报表的多重规范,每个规范可能有不同的配置。一个规范(报表集)对应一个执行目标 。例如,
有1,2,3,4,5,6,7,8,9个报表。1,2,5构成A报表集,对应一个执行目标。2,5,8构成B报
表集,对应另一个执行目标 -->
<reportSets>
<!-- 表示报表的一个集合,以及产生该集合的配置 -->
<reportSet>
<!-- 报表集合的唯一标识符,POM继承时用到 -->
<id></id>

<!-- 产生报表集合时,被使用的报表的配置 -->
<configuration></configuration>

<!-- 配置是否被继承到子POMs -->
<inherited>true/false</inherited>

<!-- 这个集合里使用到哪些报表 -->
<reports></reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>

<!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖
(必须描述group ID和artifact ID信息),如果group ID和artifact ID以外的一些信息没有描述,则通过
group ID和artifact ID匹配到这里的依赖,并使用这里的依赖信息。 -->
<dependencyManagement>
<dependencies>
<!-- 参见dependencies/dependency元素 -->
<dependency>
</dependency>
</dependencies>
</dependencyManagement>

<!-- 项目分发信息,在执行mvn deploy后表示要发布的位置。有了这些信息就可以把网站部署到远程服务器或者
把构件部署到远程仓库。 -->
<distributionManagement>
<!-- 部署项目产生的构件到远程仓库需要的信息 -->
<repository>
<!-- 是分配给快照一个唯一的版本号(由时间戳和构建流水号)?还是每次都使用相同的版本号?参见
repositories/repository元素 -->
<uniqueVersion />
<id> banseon-maven2 </id>
<name> banseon maven2 </name>
<url> file://${basedir}/target/deploy </url>
<layout></layout>
</repository>

<!-- 构件的快照部署到哪里?如果没有配置该元素,默认部署到repository元素配置的仓库,参见
distributionManagement/repository元素 -->
<snapshotRepository>
<uniqueVersion />
<id> banseon-maven2 </id>
<name> Banseon-maven2 Snapshot Repository </name>
<url> scp://svn.baidu.com/banseon:/usr/local/maven-snapshot </url>
<layout></layout>
</snapshotRepository>

<!-- 部署项目的网站需要的信息 -->
<site>
<!-- 部署位置的唯一标识符,用来匹配站点和settings.xml文件里的配置 -->
<id> banseon-site </id>

<!-- 部署位置的名称 -->
<name> business api website </name>

<!-- 部署位置的URL,按protocol://hostname/path形式 -->
<url>
scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web
</url>
</site>

<!-- 项目下载页面的URL。如果没有该元素,用户应该参考主页。使用该元素的原因是:帮助定位
那些不在仓库里的构件(由于license限制)。 -->
<downloadUrl />

<!-- 如果构件有了新的group ID和artifact ID(构件移到了新的位置),这里列出构件的重定位信息。 -->
<relocation>
<!-- 构件新的group ID -->
<groupId></groupId>

<!-- 构件新的artifact ID -->
<artifactId></artifactId>

<!-- 构件新的版本号 -->
<version></version>

<!-- 显示给用户的,关于移动的额外信息,例如原因。 -->
<message></message>
</relocation>

<!-- 给出该构件在远程仓库的状态。不得在本地项目中设置该元素,因为这是工具自动更新的。有效的值
有:none(默认),converted(仓库管理员从Maven 1 POM转换过来),partner(直接从伙伴Maven
2仓库同步过来),deployed(从Maven 2实例部署),verified(被核实时正确的和最终的)。 -->
<status></status>
</distributionManagement>

<!-- 以值替代名称,Properties可以在整个POM中使用,也可以作为触发条件(见settings.xml配置文件里
activation元素的说明)。格式是<name>value</name>。 -->
<properties>
<name>value</name>
</properties>
</project>

基本配置parent和继承结构

Maven项目的继承

Maven项目之间不仅存在多模块的聚合关系,而且Maven项目之间还可以存在相互继承的关系。

Maven项目之间的继承关系通过表示,在子Maven项目的POM中配置示例如下:

1
2
3
4
5
6
<parent>
<groupId>com.mycompany.cat</groupId>
<artifactId>cat-bundle</artifactId>
<version>2.0</version>
<relativePath>../cat-bundle</relativePath>
</parent>

说明:给出被继承的父项目的具体信息。

其中的relativePath给出父项目相对于子项目的路径,这样在构件子项目时首先从该相对路径查找父项目,如果没有才会从本地库或进而远程库中查找父项目。

子项目能够继承父项目的配置
1
2
3
4
5
6
7
- dependencies
- developers
- contributors
- plugin lists
- reports lists
- plugin executions with matching ids
- plugin configuration
Maven的Super POM

类似于Java中的java.lang.Object类,所有Java类都继承自该类。在Maven中也存在一个特殊的POM,被称为Super POM。任何Maven项目的POM都继承自Super POM。

在Super POM中,设置如下:

1
2
3
4
5
- Maven的central库
- Maven的central插件库
- build的基本参数和4个插件(maven-antrun-plugin、maven-assembly-plugin、maven-dependency-plugin和maven-release-plugin)
- reporting的基本目录
- 一个profile(id=release-profile)

配置build

在Maven的pom.xml文件中,存在如下两种

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<!-- "Project Build" contains elements of the BaseBuild set and the Build set-->
<build>...</build>

<profiles>
<profile>
<!-- "Profile Build" contains elements of the BaseBuild set only -->
<build>...</build>
</profile>
</profiles>
</project>

一种被称为Project Build,即是的直接子元素。另一种被称为Profile Build,即是的直接子元素。

Profile Build包含了基本的build元素,而Project Build还包含两个特殊的元素,即各种<…Directory>和

Profile Build和Project Build共用的基本build元素

example:

1
2
3
4
5
6
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
...
</build>

说明:

1
2
3
- defaultGoal,执行构建时默认的goal或phase,如jar:jar或者package等
- directory,构建的结果所在的路径,默认为${basedir}/target目录
- finalName,构建的最终结果的名字,该名字可能在其他plugin中被改变
resources:

资源往往不是代码,无需编译,而是一些properties或XML配置文件,构建过程中会往往会将资源文件从源路径复制到指定的目标路径。

给出各个资源在Maven项目中的具体路径。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<build>
...
<filters>
<filter>filters/filter1.properties</filter>
</filters>
<resources>
<resource>
<targetPath>META-INF/plexus</targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/plexus</directory>
<includes>
<include>configuration.xml</include>
</includes>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
<testResources>
...
</testResources>
...
</build>

说明:

1
2
3
4
5
6
7
8
- resources,build过程中涉及的资源文件
- targetPath,资源文件的目标路径
- filtering,构建过程中是否对资源进行过滤,默认false
- directory,资源文件的路径,默认位于${basedir}/src/main/resources/目录下
- includes,一组文件名的匹配模式,被匹配的资源文件将被构建过程处理
- excludes,一组文件名的匹配模式,被匹配的资源文件将被构建过程忽略。同时被includes和excludes匹配的资源文件,将被忽略。
- filters,给出对资源文件进行过滤的属性文件的路径,默认位于${basedir}/src/main/filters/目录下。属性文件中定义若干键值对。在构建过程中,对于资源文件中出现的变量(键),将使用属性文件中该键对应的值替换。
- testResources,test过程中涉及的资源文件,默认位于${basedir}/src/test/resources/目录下。这里的资源文件不会被构建到目标构件中
plugins:

给出构建过程中所用到的插件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<extensions>false</extensions>
<inherited>true</inherited>
<configuration>
<classifier>test</classifier>
</configuration>
<dependencies>...</dependencies>
<executions>...</executions>
</plugin>
</plugins>
</build>

说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
- groupId
- artifactId
- version
- extensions,是否加载该插件的扩展,默认false
- inherited,该插件的configuration中的配置是否可以被(继承该POM的其他Maven项目)继承,默认true
- configuration,该插件所需要的特殊配置,在父子项目之间可以覆盖或合并
- dependencies,该插件所特有的依赖类库
- executions,该插件的某个goal(一个插件中可能包含多个goal)的执行方式。一个execution有如下设置:
- id,唯一标识
- goals,要执行的插件的goal(可以有多个),如<goal>run</goal>
- phase,插件的goal要嵌入到Maven的phase中执行,如verify
- inherited,该execution是否可被子项目继承
- configuration,该execution的其他配置参数
pluginManagement:
1
在<build>中,<pluginManagement>与<plugins>并列,两者之间的关系类似于<dependencyManagement>与<dependencies>之间的关系。<pluginManagement>中也配置<plugin>,其配置参数与<plugins>中的<plugin>完全一致。只是,<pluginManagement>往往出现在父项目中,其中配置的<plugin>往往通用于子项目。子项目中只要在<plugins>中以<plugin>声明该插件,该插件的具体配置参数则继承自父项目中<pluginManagement>对该插件的配置,从而避免在子项目中进行重复配置。

Project Build特有的<…Directory>

往往配置在父项目中,供所有父子项目使用。示例如下:

1
2
3
4
5
6
7
8
9
  <build>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
...
</build>
</project>

目录可以使用绝对路径,如示例所示。如果使用相对路径,则所有的相对路径都是在${basedir}目录下。

Project Build特有的extensions

1
2
3
<extensions>是执行构建过程中可能用到的其他工具,在执行构建的过程中被加入到classpath中。
也可以通过<extensions>激活构建插件,从而改变构建的过程。
通常,通过<extensions>给出通用插件的一个具体实现,用于构建过程。

的使用示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
  <build>
...
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>1.0-alpha-3</version>
</extension>
</extensions>
...
</build>
</project>
阅读全文
Linux包管理
apt | yum

查看软件包安装情况

1
2
3
4
5
6
7
8
9
#rpm包安装的,可以用rpm -qa看到,如果要查找某软件包是否安装,用 rpm -qa | grep “软件或者包的名字”。
rpm -qa | grep ruby
#以deb包安装的,可以用dpkg -l能看到。如果是查找指定软件包,用dpkg -l | grep “软件或者包的名字”;
dpkg -l | grep ruby
#yum方法安装的,可以用yum list installed查找,如果是查找指定包,命令后加 | grep “软件名或者包名”;
yum list installed | grep ruby
#如果是以源码包自己编译安装的,例如.tar.gz或者tar.bz2形式的,这个只能看可执行文件是否存在了,
#上面两种方法都看不到这种源码形式安装的包。如果是以root用户安装的,可执行程序通常都在/sbin:/usr/bin目录下。
#其中rpm yum Redhat系linux的软件包管理命令,dpkg debian系列的软件包管理命令

apt

安装

1
2
3
4
5
6
#安装 example.rpm 包
rpm -i example.rpm
#安装 example.rpm 包并在安装过程中显示正在安装的文件信息
rpm -iv example.rpm
#安装 example.rpm 包并在安装过程中显示正在安装的文件信息及安装进度
rpm -ivh example.rpm

查看安装完成的软件

1
2
3
 rpm -qa | grep jdk
java-1.6.0-openjdk-1.6.0.0-1.66.1.13.0.el6.i686
java-1.7.0-openjdk-1.7.0.45-2.4.3.3.el6.i686

卸载软件

1
rpm -e --nodeps 要卸载的软件包

question

现象:E: Unable to locate package xxx

原因:apt源缺失

1
2
3
4
5
sudo add-apt-repository main
sudo add-apt-repository universe
sudo add-apt-repository restricted
sudo add-apt-repository multiverse
sudo apt-get update

yum

yum查找提供此功能的的软件包

yum provides semanage

安装docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#docker安装-安装软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
#docker安装-设置稳定的仓库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#docker安装---列出并排序存储库中可用的docker版本
yum list docker-ce --showduplicates | sort -r
#read version
yum install docker-ce-19.03.5 docker-ce-cli-19.03.5 containerd.io
#docker安装---查看当前docker的版本信息
docker version
#docker安装---启动docker
systemctl start docker

# 安装较旧版本时需要指定完整的rpm包名,并加上--setopt=obsoletes=0
yum install -y --setopt=obsoletes=0 docker-ce-17.03.2.ce-1.el7.centos.x86_64 docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch

# 安装较新版本时加上rpm包名的版本号部分
sudo yum install docker-ce-18.03.0.ce

安装chrome

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 配置yum源
# 在目录 /etc/yum.repos.d/ 下新建文件 google-chrome.repo
cd /etc/yum.repos.d/
vim google-chrome.repo
# 编辑google-chrome.repo,内容如下,编辑后保存退出(:wq)
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
# 安装google chrome浏览器
yum -y install google-chrome-stable
# Google官方源可能在中国无法使用,导致安装失败或者在国内无法更新,可以添加以下参数来安装:
yum -y install google-chrome-stable --nogpgcheck

# 没有--no-sandbox选项谷歌浏览器不能在root用户特权下运行。
# 打开/opt/google/chrome/google-chrome文件,在最后一行添加上--no-sandbox
vim /opt/google/chrome/google-chrome
# 在最后一行添加
--no-sandbox

安装CentOS7 Gnome GUI

在系统下使用命令安装gnome图形界面程序
在安装Gnome包之前,需要检查一下安装源(yum)是否正常,因为需要在yum命令来安装gnome包。
第一步:先检查yum 是否安装了,以及网络是否有网络。如果这两者都没有,先解决网络,在解决yum的安装。
第二步:在命令行下 输入下面的命令来安装Gnome包。

1
yum groupinstall "GNOME Desktop" "Graphical Administration Tools"

第三步:更新系统的运行级别。

1
ln -sf /lib/systemd/system/runlevel5.target /etc/systemd/system/default.target

第四步:重启机器。启动默认进入图形界面。

1
reboot
阅读全文
Algolia