JavaWeb学习笔记之——Maven

Maven

文章目录

  • Maven
    • 1、Maven 概述
      • 1.1、Maven 的优势举例
    • 2、Maven 的两个经典作用
      • 2.1、Maven 的依赖管理
      • 2.2、项目的一键构建
    • 3、Maven 的使用
      • 3.1、Maven 的安装
        • 下载
        • 安装
      • 3.2、Maven 仓库
        • 3.2.1、Maven 仓库的分类
        • 3.2.2、全局 setting 与用户 setting
      • 3.3、Maven 工程的认识
        • 3.3.1、Maven 工程的目录结构
    • 4、Maven 常用命令
      • 4.1、clean
      • 4.2、compile
      • 4.3、test
      • 4.4、package
      • 4.5、install
    • 5、Maven 指令的生命周期
    • 6、maven 的概念模型
    • 7、IDEA 开发 maven 项目
      • 7.1、idea 的 maven 配置
      • 7.2、使用骨架创建 maven 的 java 工程
      • 7.3、不使用骨架创建 maven 的 java 工程
      • 7.4、使用骨架创建 maven 的 web 工程
    • 8、maven 对 web 工程的一些操作
      • 8.1、导入项目依赖的 jar 包
      • 8.2、jar 包冲突解决
      • 8.3、maven 工程环境的修改
    • 9、maven 的 java 工程取 mysql 数据库数据
      • 9.1、数据库数据
      • 9.2、配置 pom.xml
      • 9.2、创建一个实体类
      • 9.3、创建 Dao 类
      • 9.4、测试

1、Maven 概述

一个对 Maven 比较正式的定义是这么说的: Maven 是一个项目管理工具,它包含了一个项目对象模型 (POM: Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑

maven 能解决什么问题?

  • 我们需要引用各种 jar 包,尤其是比较大的工程,引用的 jar 包往往有几十个乃至上百个, 每用到一种 jar 包,都需要手动引入工程目录,而且经常遇到各种让人抓狂的 jar 包冲突,版本冲突。
  • 我们辛辛苦苦写好了 Java 文件,可是只懂 0 和 1 的白痴电脑却完全读不懂,需要将它编译成二进制字节码。好歹现在这项工作可以由各种集成开发工具帮我们完成, Eclipse、 IDEA 等都可以将代码即时编译。当然,如果你嫌生命漫长,何不铺张,也可以用记事本来敲代码,然后用 javac 命令一个个地去编译,逗电脑玩。
  • 世界上没有不存在 bug 的代码, 计算机喜欢 bug 就和人们总是喜欢美女帅哥一样。为了追求美为了减少 bug,因此写完了代码,我们还要写一些单元测试,然后一个个的运行来检验代码质量。
  • 再优雅的代码也是要出来卖的。我们后面还需要把代码与各种配置文件、资源整合到一起,定型打包,如果是 web 项目,还需要将之发布到服务器,供人访问。

试想,如果现在有一种工具,可以把你从上面的繁琐工作中解放出来,能帮你构建工程管理 jar 包编译代码,还能帮你自动运行单元测试打包生成报表,甚至能帮你部署项目,生成 Web 站点,你会心动吗? Maven 就可以解决上面所提到的这些问题。

1.1、Maven 的优势举例

前面我们通过 Web 阶段项目,要能够将项目运行起来,就必须将该项目所依赖的一些 jar 包添加到工程中,否则项目就不能运行。 试想如果具有相同架构的项目有十个,那么我们就需要将这一份 jar 包复制到十个不同的工程中。 我们一起来看一个 CRM 项目的工程大小。

使用传统 Web 项目构建的 CRM 项目如下:

JavaWeb学习笔记之——Maven_第1张图片

原因主要是因为上面的 WEB 程序要运行,我们必须将项目运行所需的 Jar 包复制到工程目录中,从而导致了工程很大。

同样的项目,如果我们使用 Maven 工程来构建,会发现总体上工程的大小会少很多。如下图:

JavaWeb学习笔记之——Maven_第2张图片

小结: 可以初步推断它里面一定没有 jar 包,继续思考,没有 jar 包的项目怎么可能运行呢?

JavaWeb学习笔记之——Maven_第3张图片


2、Maven 的两个经典作用

2.1、Maven 的依赖管理

Maven 的一个核心特性就是依赖管理。当我们涉及到多模块的项目(包含成百个模块或者子项目),管理依赖就变成一项困难的任务。 Maven 展示出了它对处理这种情形的高度控制。

传统的 WEB 项目中,我们必须将工程所依赖的 jar 包复制到工程中,导致了工程的变得很大。那么 maven 工程是如何使得工程变得很少呢?分析如下:

JavaWeb学习笔记之——Maven_第4张图片

通过分析发现:maven 工程中不直接将 jar 包导入到工程中,而是通过在 pom.xml 文件中添加所需 jar 包的坐标,这样就很好的避免了 jar 直接引入进来,在需要用到 jar 包的时候,只要查找 pom.xml 文件,再通过 pom.xml 文件中的坐标,到一个专门用于 ”存放 jar 包的仓库”(maven 仓库)中根据坐标从而找到这些 jar 包,再把这些 jar 包拿去运行。

那么问题来了:

第一:”存放 jar 包的仓库” 长什么样?

第二:通过读取 pom.xml 文件中的坐标,再到仓库中找到 jar 包,会不会很慢?从而导致这种方式不可行!

第一个问题:存放 jar 包的仓库长什么样,这一点我们后期会分析仓库的分类,也会带大家去看我们的本地的仓库长什么样。

第二个问题:通过 pom.xml 文件配置要引入的 jar 包的坐标,再读取坐标并到仓库中加载 jar 包,这样我们就可以直接使用 jar 包了,为了解决这个过程中速度慢的问题, maven 中也有索引的概念,通过建立索引,可以大大提高加载 jar 包的速度,使得我们认为 jar 包基本跟放在本地的工程文件中再读取出来的速度是一样的。这个过程就好比我们查阅字典时,为了能够加快查找到内容,书前面的目录就好比是索引,有了这个目录我们就可以方便找到内容了,一样的在 maven 仓库中有了索引我们就可以认为可以快速找到 jar 包。

2.2、项目的一键构建

我们的项目,往往都要经历编译、 测试、 运行、 打包、 安装 ,部署等一系列过程。

什么是构建指的是项目从编译、测试、运行、打包、安装 ,部署整个过程都交给 maven 进行管理,这个过程称为构建

一键构建指的是整个构建过程,使用 maven 一个命令可以轻松完成整个工作

Maven 规范化构建流程如下:

JavaWeb学习笔记之——Maven_第5张图片


3、Maven 的使用

3.1、Maven 的安装

  • 下载

    Apache-maven-3.5.2 下载地址: http://archive.apache.org/dist/maven/maven-3/

  • 安装

    Maven 下载后,将 Maven 解压到一个没有中文没有空格的路径下,比如 D:\software\maven 下面。

JavaWeb学习笔记之——Maven_第6张图片

3.2、Maven 仓库

3.2.1、Maven 仓库的分类

maven 的工作需要从仓库下载一些 jar 包,如下图所示,本地的项目 A、项目 B 等都会通过 maven 软件从远程仓库(可以理解为互联网上的仓库)下载 jar 包并存在本地仓库,本地仓库就是本地文件夹,当第二次需要此 jar 包时则不再从远程仓库下载,因为本地仓库已经存在了,可以将本地仓库理解为缓存,有了本地仓库就不用每次从远程仓库下载了。

下图描述了 maven 中仓库的类型:

JavaWeb学习笔记之——Maven_第7张图片

  • 本地仓库:用来存储从远程仓库或中央仓库下载的插件和 jar 包,项目使用一些插件或 jar 包,优先从本地仓库查找

    默认本地仓库位置在 ${user.dir}/.m2/repository${user.dir} 表示 windows 用户目录。

    自定义本地仓库的位置:

    MAVE_HOME/conf/settings.xml 文件中配置本地仓库位置(maven 的安装目录下):

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
      
    	
        
    	<localRepository>G:\maven_repositorylocalRepository>
    
  • 远程仓库:如果本地需要插件或者 jar 包,本地仓库没有, 默认去远程仓库下载。远程仓库可以在互联网内也可以在局域网内。

  • 中央仓库:在 maven 软件中内置一个远程仓库地址 https://repo1.maven.org/maven2 ,它是中央仓库,服务于整个互联网,它是由 Maven 团队自己维护,里面存储了非常全的 jar 包,它包含了世界上大部分流行的开源项目构件。

3.2.2、全局 setting 与用户 setting

maven 仓库地址、私服等配置信息需要在 setting.xml 文件中配置,分为全局配置和用户配置。

在 maven 安装目录下的有 conf/setting.xml 文件,此 setting.xml 文件用于 maven 的所有 project 项目,它作为 maven 的全局配置。

如需要个性配置则需要在用户配置中设置,用户配置的 setting.xml 文件默认的位置在: ${user.dir} /.m2/settings.xml 目录中,${user.dir} 指 windows 中的用户目录。

maven 会先找用户配置,如果找到则以用户配置文件为准,否则使用全局配置文件。

3.3、Maven 工程的认识

3.3.1、Maven 工程的目录结构

JavaWeb学习笔记之——Maven_第8张图片

作为一个 maven 工程,它的 src 目录和 pom.xml 是必备的。

进入 src 目录后,我们发现它里面的目录结构如下:

JavaWeb学习笔记之——Maven_第9张图片

注意:如果是普通的 java 项目,那么就没有 webapp 目录。



4、Maven 常用命令

我们可以在 cmd 中通过一系列的 maven 命令来对我们的 maven-helloworld 工程进行编译、测试、运行、打包、安装、部署。

4.1、clean

clean 是 maven 工程的清理命令,执行 clean 会删除 target 目录及内容。

4.2、compile

compile 是 maven 工程的编译命令,作用是将 src/main/java 下的文件编译为 class 文件输出到 target 目录下。

4.3、test

test 是 maven 工程的测试命令 mvn test,会执行 src/test/java 下的单元测试类。

不仅仅会编译 src/test/java 下的代码,同样会编译 src/main/java 下的代码。

4.4、package

package 是 maven 工程的打包命令,对于 java 工程执行 package 打成 jar 包,对于 web 工程打成 war 包(在 target 目录下)。

4.5、install

install 是 maven 工程的安装命令,执行 install 将 maven 打成 jar 包或 war 包发布到本地仓库。

从运行结果中,可以看出:

当后面的命令执行时,前面的操作过程也都会自动执行。


5、Maven 指令的生命周期

JavaWeb学习笔记之——Maven_第10张图片

maven 对项目构建过程分为三套相互独立的生命周期,请注意这里说的是 “三套”,而且 “相互独立”,这三套生命周期分别是:

  • 清理生命周期(Clean Lifecycle):在进行真正的构建之前进行一些清理工作
  • 默认生命周期(Default Lifecycle):构建的核心部分,编译,测试,打包,部署等等
  • 站点生命周期(Site Lifecycle):生成项目报告,站点,发布站点

6、maven 的概念模型

Maven 包含了一个项目对象模型(Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。

JavaWeb学习笔记之——Maven_第11张图片

  • 项目对象模型(Project Object Model)

    一个 maven 工程都有一个 pom.xml 文件,通过 pom.xml 文件定义项目的坐标项目依赖项目信息插件目标等。

  • 依赖管理系统(Dependency Management System)

    通过 maven 的依赖管理对项目所依赖的 jar 包进行统一管理。

    比如:项目依赖 junit4.9,通过在 pom.xml 中定义 junit4.9 的依赖即使用 junit4.9,如下所示是 junit4.9 的依赖定义:

    
    <dependencies>
    	
    	<dependency>
    		
    		<groupId>junitgroupId>
    		
    		<artifactId>junitartifactId>
    		
    		<version>4.9version>
    		
    		<scope>testscope>
    	dependency>
    dependencies>	
    
  • 一个项目生命周期(Project Lifecycle)

    使用 maven 完成项目的构建,项目构建包括:清理、编译、测试、部署等过程, maven 将这些过程规范为一个生命周期。

    maven 通过执行一些简单命令即可实现上边生命周期的各个过程,比如执行 mvn compile 执行编译、执行 mvn clean 执行清理。

  • 一组标准集合

    maven 将整个项目管理过程定义一组标准,比如:通过 maven 构建工程有标准的目录结构,有标准的生命周期阶段、依赖管理有标准的坐标定义等。

  • 插件(plugin)目标(goal)

    maven 管理项目生命周期过程都是基于插件完成的。


7、IDEA 开发 maven 项目

7.1、idea 的 maven 配置

JavaWeb学习笔记之——Maven_第12张图片

7.2、使用骨架创建 maven 的 java 工程

JavaWeb学习笔记之——Maven_第13张图片

点击下一步:

JavaWeb学习笔记之——Maven_第14张图片

创建完之后的 java 工程:

JavaWeb学习笔记之——Maven_第15张图片

目录并不完整,需要我们手动添加资源目录:

JavaWeb学习笔记之——Maven_第16张图片

7.3、不使用骨架创建 maven 的 java 工程

JavaWeb学习笔记之——Maven_第17张图片

创建 java 工程后的目录结构:

JavaWeb学习笔记之——Maven_第18张图片

7.4、使用骨架创建 maven 的 web 工程

JavaWeb学习笔记之——Maven_第19张图片

点击下一步:

JavaWeb学习笔记之——Maven_第20张图片

创建 web 工程后的目录结构:

JavaWeb学习笔记之——Maven_第21张图片

目录结构仍然不完整,需要我们手动添加:

JavaWeb学习笔记之——Maven_第22张图片


8、maven 对 web 工程的一些操作

8.1、导入项目依赖的 jar 包

在 pom.xml 中导入项目运行所需要的 jar 包:


<dependency>
	<groupId>javax.servletgroupId>
	<artifactId>javax.servlet-apiartifactId>
	<version>4.0.1version>
dependency>

新建一个 Servlet 取名为 MyServlet:

JavaWeb学习笔记之——Maven_第23张图片

添加依赖需要指定依赖 jar 包的坐标,但是很多情况我们是不知道 jar 包的的坐标,可以通过如下方式查询:

https://mvnrepository.com/

MySevlet 代码为:

@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("hello.jsp").forward(request, response);
    }
}

8.2、jar 包冲突解决

A 依赖 B,需要在 A 的 pom.xml 文件中添加 B 的坐标,添加坐标时需要指定依赖范围,依赖范围包括:

  • compile:编译范围,指 A 在编译时依赖 B,此范围为默认依赖范围。 编译范围的依赖会用在编译、测试、运行,由于运行时需要所以编译范围的依赖会被打包。
  • provided: provided 依赖只有在当 JDK 或者一个容器已提供该依赖之后才使用, provided 依赖在编译和测试时需要,在运行时不需要,比如: servlet api 被 tomcat 容器提供。
  • runtime: runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。 比如: jdbc 的驱动包。由于运行时需要所以 runtime 范围的依赖会被打包。
  • test: test 范围依赖 在编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用,比如: junit。由于运行时不需要所以 test 范围依赖不会被打包。
  • system: system 范围依赖与 provided 类似,但是你必须显式的提供一个对于本地系统中 JAR 文件的路径, 需要指定 systemPath 磁盘路径, system依赖不推荐使用。

在 maven-web 工程中测试各各 scop。测试总结:

  • 默认引入的 jar 包 ------- compile【默认范围可以不写】(编译、测试、运行 都有效 )
  • servlet-api 、jsp-api ------- provided(编译、测试有效, 运行时无效防止和 tomcat 下 jar 冲突)
  • jdbc 驱动 jar 包 ---- runtime(测试、运行有效)
  • junit ----- test(测试有效)

依赖范围由强到弱的顺序是: compile > provided > runtime > test

只在运行时起作用:

<dependency>
	<groupId>javax.servletgroupId>
	<artifactId>javax.servlet-apiartifactId>
	<version>4.0.1version>
	<scope>providedscope>
dependency>

只在测试时起作用:

<dependency>
	<groupId>junitgroupId>
	<artifactId>junitartifactId>
	<version>4.11version>
	<scope>testscope>
dependency>

8.3、maven 工程环境的修改

<plugin>
	<groupId>org.apache.tomcat.mavengroupId>
	<artifactId>tomcat9-maven-pluginartifactId>
	<version>2.2version>
plugin>
<plugin>
	<groupId>org.apache.maven.pluginsgroupId>
	<artifactId>maven-compiler-pluginartifactId>
	<configuration>
		<source>1.8source>
		<target>1.8target>
		<encoding>UTF-8encoding>
	configuration>
plugin>

9、maven 的 java 工程取 mysql 数据库数据

9.1、数据库数据

JavaWeb学习笔记之——Maven_第24张图片

我们作为示例,取 192.168.1.1 数据库服务器 db4 数据库 user 表中的 id 和 username 字段。

9.2、配置 pom.xml

我们需要数据库连接的 jar 包和单元测试的 jar 包。

<dependencies>
	<dependency>
		<groupId>mysqlgroupId>
		<artifactId>mysql-connector-javaartifactId>
		<version>5.1.15version>
		<scope>runtimescope>
	dependency>

	<dependency>
		<groupId>junitgroupId>
		<artifactId>junitartifactId>
		<version>4.12version>
		<scope>testscope>
	dependency>
dependencies>

配置完 pom.xml 一定要记得点击 “刷新”

9.2、创建一个实体类

package com.li;

public class Items {
    private Integer id;
    private String username;

    public Integer getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public String toString() {
        return "Items{" +
                "id=" + id +
                ", username='" + username + '\'' +
                '}';
    }
}

9.3、创建 Dao 类

package com.Dao;

import com.li.Items;

import java.util.List;

public interface ItemsDao {
    public List<Items> findAll();
}

接着创建一个实现类:

package com.Dao.impl;

import com.Dao.ItemsDao;
import com.li.Items;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class ItemsDaoImpl implements ItemsDao {
    @Override
    public List<Items> findAll() throws SQLException {
        //1. 先获取connection对象
        Connection connection = null;
        //2. 获取真正操作数据的对象
        PreparedStatement preparedStatement = null;
        //3. 执行数据库操作
        ResultSet resultSet = null;
        List<Items> list = new ArrayList<>();
        try{
            //加载驱动类
            Class.forName("com.mysql.jdbc.Driver");
            //1. 先获取connection对象
            connection = DriverManager.getConnection("jdbc:mysql://192.168.1.11/db4", "root", "Opfordream@0518");
            //2. 获取真正操作数据的对象
            preparedStatement = connection.prepareStatement("select id, username from user");
            //3. 执行数据库操作
            resultSet = preparedStatement.executeQuery();
            //4. 把数据库结果集转成java的List集合
            while (resultSet.next()){
                Items items = new Items();
                items.setId(resultSet.getInt("id"));
                items.setUsername(resultSet.getString("username"));
                list.add(items);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            connection.close();
            preparedStatement.close();
            resultSet.close();
        }

        return list;
    }
}

9.4、测试

package com.li.test;

import com.Dao.ItemsDao;
import com.Dao.impl.ItemsDaoImpl;
import com.li.Items;
import org.junit.Test;

import java.sql.SQLException;
import java.util.List;

public class ItemsTest {

    @Test
    public void findAll() throws SQLException {
        ItemsDao itemsDao = new ItemsDaoImpl();
        List<Items> itemsList = itemsDao.findAll();

        for (Items items:
             itemsList) {
            System.out.println(items);
        }
    }
}
Items{id=1, username='zhangsan'}
Items{id=2, username='lisi'}

你可能感兴趣的:(Java基础+JavaWeb,maven,intellij-idea,java)