目录
一、Maven概述
Maven是一个基于项目对象模型(Project Object Model,POM)的项目管理工具,其核心功能是描述项目间的依赖关系,通过pom.xml文件的配置获取jar包,而不用手动添加jar包。
如果要使用pom.xml文件的配置获取jar包,必须要创建为maven项目。
maven项目就是在java项目和web项目的基础上包裹了一层maven,本质还是java和web项目,只不过可以通过pom.xml文件的配置获取jar包了,还可以解决一些jar包之间的版本冲突问题。
1.1Maven的安装
官网地址:Maven – Welcome to Apache Maven
百度云地址:https://pan.baidu.com/s/1BVHrF8JMkKQlHy_lL0xycg (提取码:5l0k)
在安装maven前需要确保java安装成功,并创建好了JAVA_HOME的环境变量。
我们将压缩包解压到不含中文和空格的目录下,例如E:\apache-maven-3.5.2
配置系统环境变量MAVEN_HOME,
在系统变量Path中添加%MAVEN_HOME%\bin,
打开cmd,键入命令mvn -v,出现下图则证明安装成功。
1.2Maven依赖管理
传统的web工程,jar包会放置在项目中,而使用maven开发的web项目,jar包会被统一放置在jar包仓库,而不会占用项目的空间。
那么我们项目在运行和编译的时候,如何找到对应的jar包仓库中需要的jar包呢?
这就涉及到了maven的依赖管理功能,我们会在项目中根据需要jar包的坐标,去jar包仓库找到我们需要的jar包。当项目非常多时,如果使用传统的方法,将所有jar包放置在项目自己的目录下,会造成很多jar包重复占用空间,但是还不能随便删除;如果使用maven进行管理,那么所有的jar包都放置在仓库中,你需要就来拿,不会有重复的jar包出现。
简单来说,依赖管理就是maven工程对jar包的管理过程。
1.3Maven一键构建
我们的项目往往要经历编译、测试、运行、打包、安装和部署等一系列过程,这些过程都需要我们人为操作,比较繁琐。
而maven提供了一键构建的命令,一个命令完成编译、测试、运行、打包、安装和部署等一系列过程。我们通过一个Demo(提取码:6nea)来看一下如何快速构建web项目。
本机环境为 tomcat7+java1.8,Maven中的tomcat6可能会不支持java1.8,需要在 pom.xml 中添加tomcat7的插件,
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8080</port>
<path>/maven-helloworld</path>
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
我们在maven-helloworld项目的文件夹目录下打开cmd,键入命令mvn tomcat7:run,注意这里要键入tomcat7,如果用tomcat:run命令则还是会使用maven自己的tomcat6,
启动之后网址上输入地址即可访问web应用,
页面结果:
1.4Maven仓库种类及关系
在MAVEN_HOME\config\settings.xml文件中,Maven定义了仓库的路径,
所有的jar包都会在该路径(即本地仓库)下进行管理, 当我们启动一个项目时,maven会在这个本地仓库查找需要的jar包,如果我们刚安装maven,那么这个本地仓库是空的,此时本地仓库会请求中央仓库,下载项目需要的jar包以供项目使用。
而一般的公司会有一个远程仓库,该仓库放置了开发需要的大部分jar包,可以通过局域网连接获取,如果远程仓库没有找到需要的jar包,则会请求中央仓库进行下载。同时远程仓库也可以接受本地仓库上传的jar包。
因为maven默认的仓库是在C盘下,我们可以在settings.xml中修改仓库的地址:
<localRepository>修改后的本地仓库地址</localRepository>
我把仓库就放在了maven的安装目录(E:\apache-maven-3.5.2\repository)
1.5maven标准目录结构
一个开发完的项目一般有以下几部分组成:
- 核心代码部分
- 配置文件部分
- 测试代码部分
- 测试配置文件部分
我们一般在核心代码部分放不经常修改的,因为项目只要更新代码就要重新打jar包,这样对于频繁的更新部分,我们一般放在配置文件中。为了对核心代码进行单元测试,所以还有测试代码部分和测试配置文件部分。
传统的项目往往只有一个src目录,里面放置了上述的四个部分文件,所以只要修改更新就要重新打jar包比较繁琐。(用户可以自己创建config目录解决这个问题,但是往往名字不统一)。
Maven针对这个问题,定义了自己的标准目录结构:
- src
- main
- java:核心代码部分
- resources:配置文件部分
- webapp(web应用有该目录):放置页面资源(js、css、图片等)
- test
- java:测试代码部分
- resources:测试配置文件部分
- main
二、Maven常用命令及生命周期
2.1Maven常用命令和生命周期
mvn clean:清理项目编译的文件
mvn compile:编译src\main\java文件下的核心代码部分
mvn test:编译src\main\test文件下的测试代码部分(若核心代码未编译也会一起编译)
mvn package:打包项目(会按照pom.xml中定义的格式打包,同时会编译核心代码和测试代码部分)
mvn install:打包项目,并将项目安装到了本地仓库
mvn deploy:发布项目,需要先设定一些配置
按照上述命令,我们可以将Maven项目分为以下几个生命周期:
2.2Maven概念模型图
在Maven的概念模型中,很重要的一个就是项目对象模型(POM),该模型中主要包括以下信息:
- 项目自身信息
- 项目运行所需要的jar包信息
- 项目运行环境信息(比如jdk、tomcat等)
其中项目运行所依赖的jar包独立出来了一个依赖管理模型,这个模型中放置的都是jar包的坐标,用于maven在仓库中查找依赖的jar包文件,下述为经典的jar包坐标:
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
jar包坐标有以下几个部分信息组成:
- groupId:公司组织的名称
- artifactId:项目名
- version:版本号
图中依赖管理模型指向了三个箭头,这些都是数据库:central(中央仓库)、b2b(远程仓库)、local(本地仓库)。这些对应了我们1.4节中说明的仓库类型和之间的关系。
项目对象模型和依赖管理模型对应了Maven的第一个核心功能:依赖管理。
接着往下看,对应的是Build lifecycle & phases模块,就是一键构建模块。
不同的构建阶段也对应了不同的生命周期,常用的生命周期为默认生命周期:
compile, test, package, install, deploy
每一个构建项目的命令都对应了maven底层的插件。
三、IDEA实战
3.1IDEA集成maven插件
我们首先打开IDEA的settings,配置一下maven的路径,
再到Runner中添加一个VM启动命令:
-DarchetypeCatalog=internal
这样除了第一次使用原型archetype创建Maven项目时需要联网下载需要的插件,后面创建可以不联网直接用本地插件。
3.2创建java工程
3.2.1使用archetype创建java工程
archetype就是原型,也称为骨架。利用这些模板创建出来的工程可以直接运行,不过需要联网(如果配置了上述启动命令,除了第一次创建需要联网,后面就不需要了)
我们新建项目,左侧找到maven,勾选上Create from archetype允许从原型创建工程,找到quickstart原型,点击next,
然后我们填写jar包坐标中包含的三个信息,
然后是确认maven的配置信息是否正确,我们直接下一步,
然后是项目的名称和存放位置,修改过后直接点击finish。
创建出来的并没有配置文件resources的目录,我们需要在src\main的目录下新建resources目录,并右键目录,将目录标记为资源的根目录。(测试文件的配置resources目录同理)
至此一个java工程就已经创建完成了。
3.2.2不使用archetype创建java工程
我们还是新建一个maven项目,此次不勾选Create from archetype,直接点击next,
接着设置公司名和项目名:
然后是项目的位置,我们点finish即可。
使用框架和不使用框架的差异如下:
如果只是创建java工程,推荐不使用框架创建项目。
3.3创建web工程
web工程我们用框架来创建,首先还是新建项目,选择maven,勾选上从框架创建,找到webapp(注意有两个webapp框架,我们选择maven包下的),然后点击下一步,
然后填写好公司名,项目名和版本号,
接着都点击下一步,确认好项目的存放地址就行,我们创建好的目录下没有java目录,我们手动创建一个java目录,然后右键将目录设置为源文件根路径,
如果webapp路径下不能创建jsp文件,需要打开Project Structure设置,指定web资源包路径。
3.3Servlet跳转jsp页面
我们在java目录下新建一个servlet,让该servlet可以直接跳转到web资源上(例如jsp),新建之后发现缺少 javax.servlet 的包,因为我们新建的项目没有导入任何jar包,所有这里报错提示我们缺少包。
我们编辑pom.xml文件,告诉maven我们需要 javax.servlet 的包,maven会自动到仓库中查找该包。后续缺少项目运行依赖的jar包也是通过修改pom.xml文件的方法。
我们添加以下几个依赖,
<!--放置的都是项目运行所依赖的jar包-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
然后右键项目->maven->reimport更新一下maven项目,让他把根据依赖找到我们需要的jar包,接着就可以使用servlet了。我们直接在servlet中跳转jsp(我们简单写一个hello.jsp,页面输出hello maven),
public class TestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/hello.jsp").forward(request,response);//跳转hello.jsp界面
}
}
然后点击项目右侧的maven projects,
双击execute maven goal,输入tomcat:run启动命令,
运行打开网页时会发现报错, 这个是因为我们在maven的pom.xml中导入的包和tomcat中自身的包版本不对应冲突产生的,所以我们给pom.xml中导入的包添加一个作用域,让其仅在编译的时候有作用即可,我们修改dependency标签,在里面添加一个scope标签,值为provided。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
然后添加两个插件,使用tomcat7和jdk1.8,
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<target>1.8</target>
<source>1.8</source>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
然后使用命令tomcat7:run启动,访问地址http://localhost:8080/maven_JavaWebTest/testServlet
3.4连接mysql数据库
我们创建一个maven项目,看看如何将数据库中的user表数据查询显示出来,
我们先在pom.xml中导入mysql的包以及junit的包(用于测试),mysql设置依赖的范围为runtime,junit设置为test
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
以下为一些常用的依赖范围的设置及例子:
依赖范围 | 编译期间生效 | 测试期间生效 | 运行期间生效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | - | Y | - | Junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | JDBC驱动 |
system | Y | Y | - | 本地的,maven仓库之外的类库 |
首先我们定义一个实体类User,存放取出来的用户数据,
package domain;
public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
然后我们在数据访问层DAO实现访问数据的方法,
package dao;
import domain.User;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
interface UserDao {
public List<User> findAll() throws Exception;
}
public class UserDaoImpl implements UserDao {
public List<User> findAll() throws Exception {
List<User> list=new ArrayList<User>();
Connection connection = null;
PreparedStatement pst=null;
ResultSet resultSet =null;
try{
Class.forName("com.mysql.jdbc.Driver");//加载mysql驱动类
connection = DriverManager.getConnection("jdbc:mysql:///mydb1","root","3837");//获取connection对象
pst=connection.prepareCall("select * from user");//获取操作数据的对象
resultSet = pst.executeQuery();//执行查询操作,得到数据库结果集
while (resultSet.next()){//将结果集中的数据存储到list集合中
User user=new User();
user.setName(resultSet.getString("username"));//获取用户名
user.setPassword(resultSet.getString("password"));//获取用户密码
list.add(user);
}
}catch (Exception e){
e.printStackTrace();
}finally {//关闭资源连接
connection.close();
pst.close();//
resultSet.close();
}
return list;
}
}
然后我们在测试文件中写一个测试类,
package mysqlTest;
import dao.UserDao;
import dao.UserDaoImpl;
import domain.User;
import org.junit.Test;
import java.util.List;
public class UserTest {
@Test
public void findAll() throws Exception {
UserDao userDao=new UserDaoImpl();
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user.getName()+":"+user.getPassword());
}
}
}
运行查看结果: