ある記事では、Maven に習熟すること、従来の Java および JavaWeb プロジェクトから Maven プロジェクトにすばやく切り替えること、および Maven の実用的なケースのチュートリアルについて説明しています。

1.Mavenのコンセプト

1.1 Maven の紹介

Maven は、プロジェクト オブジェクト モデル (プロジェクト オブジェクト モデル)、一連の標準コレクション、プロジェクト ライフ サイクル (プロジェクト ライフサイクル)、依存関係管理システム (依存関係管理システム) を含むプロジェクト管理ツールであり、定義を実行するために使用されます。ライフサイクル フェーズのプラグイン ゴールのロジック。Maven を使用する場合、明確に定義されたプロジェクト オブジェクト モデルを使用してプロジェクトを記述すると、Maven は一連の共有 (またはカスタム) プラグインから横断的ロジックを適用できます。

Maven は「エキスパート」、「エキスパート」と訳されています。Maven は、Apache の下で純粋に Java で開発されたオープン ソース プロジェクトで、Maven を使用して Java プロジェクトを構築および管理できるプロジェクト管理ツールです。現在 Maven を使用しているプロジェクトの数は増え続けています。

Maven公式サイト:https://maven.apache.org/

Maven 機能: クリーニング、コンパイル、テスト (ユニット テストを自分で作成)、レポート、パッケージング (エクスポート jar、戦争)、展開。

1.2 プロジェクト構築とは

    プロジェクトの構築は、ソース コードの記述から、コンパイル、テスト、パッケージ化、デプロイ、および実行までのプロジェクトのプロセスです。

1.2.1 従来のプロジェクト構築プロセス

Eclipse を使用してプロジェクトを構築する従来のプロセスは次のとおりです。

     構築プロセスは次のとおりです。  
        1. Eclipse で JavaWeb プロジェクトを作成します。
        2. プロジェクトにソース コードと構成ファイルを書き込みます。
        3. ソース コードをコンパイルし、Java ファイルをクラス ファイルにコンパイルします。
        4. Junit 単体テストを実行します。
        5. プロジェクトを war パッケージにし、Tomcat にデプロイして実行します。

1.2.2 Maven プロジェクトの構築プロセス

    Maven は、プロジェクト構築のプロセスを標準化します。各段階は 1 つのコマンドで完了します。次の図は、構築プロセスのいくつかの段階を示しています。次の章では、各段階を詳細に紹介します。一般的な概要は次のとおりです。

    上の図のいくつかの段階に対応するコマンドは次のとおりです。
        cleanup 段階に対応する Maven コマンドは clean で、出力クラス ファイルをクリーンアップします。
        コンパイル フェーズに対応する Maven コマンドは compile で、Java コードをクラス ファイルにコンパイルします。
        パッケージ化フェーズに対応する Maven コマンドは package であり、Java プロジェクトは jar パッケージにパッケージ化でき、web プロジェクトは war パッケージにパッケージ化できます。
        Maven プロジェクト (Web プロジェクト) を実行するには、コマンド tomcat:run が必要です。

    Maven プロジェクトの構築の利点:
        1. 1 つのコマンドで構築と操作が完了するため、便利で高速です。
        2. Maven は各構築フェーズを調整します。これは、大規模なチームの共同開発に非常に役立ちます。

1.3 依存関係管理とは

    依存関係とは何ですか? Java プロジェクトを実行するには、いくつかのサード パーティの jar パッケージを使用する必要がある場合があるため、この Java プロジェクトはこれらのサード パーティの jar パッケージに依存していると言えます。例: crm システム、そのアーキテクチャーは SSH フレームワーク、crm プロジェクトは SSH フレームワークに依存します。具体的には、Hibernate、Spring、Struts2 関連の jar パッケージに依存します。

    依存関係管理とは何ですか? これは、プロジェクトのすべての依存 jar パッケージの標準化された管理です。

1.3.1 従来のプロジェクトの依存関係管理

    従来のプロジェクト エンジニアリングが依存する jar パッケージは、完全に手動で管理されています. プログラマーは、下の図に示すように、インターネットから jar パッケージをダウンロードして、プロジェクト プロジェクトに追加します: プログラマーは、Hibernate、Struts2、 Spring を WEB-INF/lib ディレクトリに移動します。

     jar パッケージを手動でコピーしてプロジェクトに追加する場合の問題点は次のとおりです。
        1. jar パッケージのバージョンの統一された管理がないため、バージョンの競合が容易に発生する可能性があります。
        2.インターネットからjarパッケージを見つけるのは非常に不便で、見つからないjarもあります。
        3. jar パッケージがプロジェクトに追加され、プロジェクトが大きすぎます。

1.3.2 Maven プロジェクトの依存関係管理

    Maven プロジェクト管理が依存する jar パッケージは、jar パッケージを手動でプロジェクトに追加する必要はなく、pom で jar パッケージの座標を追加するだけで済みます。

     Maven 依存関係管理を使用して jar を追加する利点:
        1. pom.xml ファイルによる jar パッケージのバージョンの統合管理により、バージョンの競合を回避できます。
        2. Maven チームは、現在使用されている jar パッケージを含む非常に完全な Maven ウェアハウスを維持しています. Maven プロジェクトは、Maven ウェアハウスから jar パッケージを自動的にダウンロードできます.これは非常に便利です.

1.4 Mavenの概念モデル

    上記の概念では、Maven はプロジェクト管理ツールであり、プロジェクト オブジェクト モデル (プロジェクト オブジェクト モデル)、一連の標準コレクション、プロジェクト ライフ サイクル (プロジェクト ライフサイクル)、依存関係管理システム (依存関係管理システム) が含まれています。 )、およびライフサイクル フェーズ (フェーズ) で定義されたプラグインの目標を実行するために使用されるロジック。

1.4.1 プロジェクト オブジェクト モデル

    Maven Project Object Model (POM) は、プロジェクトの構築、レポート、文書化を小さな記述情報で管理できるプロジェクト管理ツール ソフトウェアです。

    Maven は、プログラム構築機能を備えているだけでなく、高度なプロジェクト管理ツールも提供します。Maven のデフォルトのビルド ルールは再利用性が高いため、2 行または 3 行の Maven ビルド スクリプトで単純なプロジェクトをビルドできることがよくあります。 

    Maven プロジェクトには pom.xml ファイルがあり、pom.xml ファイルを通じてプロジェクトの座標、プロジェクトの依存関係、プロジェクト情報、プラグインの目標などを定義します。

最初に pom.xml を見てみましょう。

<?xml version="1.0" encoding="UTF-8"?>

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.maven</groupId>
    <artifactId>maven-helloworld</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>第一个maven工程</name>
    <description>第一个maven工程</description>

    <!-- 添加依赖: servlet-api,jsp-api,junit单元测试 -->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <!-- 配置了很多插件 -->
        <plugins>
            <!--jdk编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>

            <!--引入tomcat7的插件-->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <!--端口号-->
                    <port>9090</port>
                    <!--path就相当于部署项目时候的ContextPath-->
                    <path>/mgr</path>
                    <uriEncoding>UTF-8</uriEncoding>
                    <server>tomcat7</server>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

その1:プロジェクトの基本情報

<modelVersion>4.0.0</modelVersion>
<groupId>com.maven</groupId>
<artifactId>maven-helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>第一个maven工程</name>
<description>第一个maven工程</description>

2 番目の部分: 依存関係に囲まれているのは、プロジェクトで使用する必要がある jar パッケージです。

<!-- 添加依赖: servlet-api,jsp-api,junit单元测试 -->
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

3 番目の部分: build で囲まれているのは、プロジェクトで使用する必要があるプラグインです。

<build>
    <!-- 配置了很多插件 -->
    <plugins>
        <!--jdk编译插件-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>utf-8</encoding>
            </configuration>
        </plugin>

        <!--引入tomcat7的插件-->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <!--端口号-->
                <port>9090</port>
                <!--path就相当于部署项目时候的ContextPath-->
                <path>/mgr</path>
                <uriEncoding>UTF-8</uriEncoding>
                <server>tomcat7</server>
            </configuration>
        </plugin>
    </plugins>
</build>

    上記で詳しく紹介しましたが、次の 3 つの部分に分かれています。
        1. プロジェクト自体に関する情報。
        2. プロジェクト操作が依存する jar パッケージ情報。    
        3. jdk、Tomcat 情報などのプロジェクトの動作環境情報。

1.4.2 依存関係管理システム

    Maven の依存関係管理により、プロジェクトが依存する jar パッケージが一元的に管理されます。このプロジェクトは、pom.xml で依存関係を定義することにより、jar パッケージを管理します。

    写真の中央は中央倉庫を指し、b2b は遠隔倉庫を指し、ローカルはローカル倉庫を指します. ここでは、依存関係を構成する 3 つの部分に焦点を当てます: 1. 会社組織の名前
        .
        2. プロジェクト名。
        3. バージョン番号。

特定の依存関係を分析してみましょう。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

    ここで、javax.servlet は会社組織 (親プロジェクト) の名前、javax.servlet-api はプロジェクト名、3.0.1 はバージョン番号です。

    依存関係管理を行う理由
        依存関係の管理:
            1. インターネットに接続して自動的にダウンロードできます。
            2. 自社開発モジュールの依存関係管理を行います。

1.4.3 プロジェクトのライフサイクル

    図の下部にあるビルド ライフサイクルは Maven のライフ サイクルを指し、下のプラグインはプラグインを指します。つまり、各 Maven コマンドは Maven の基になるプラグインに対応します。

    プロジェクトの構築は、クリーニング、コンパイル、テスト、展開など、Maven によって完了します。Maven は、これらのプロジェクトをライフサイクルに標準化します。

     Maven は、いくつかの簡単なコマンドを実行することで、上記のライフサイクル プロセスを実現できます。

1.4.4 標準セットのセット

    Maven は、プロジェクト管理プロセス全体の一連の標準を定義します。たとえば、Maven 構築プロジェクトには、標準のディレクトリ構造、標準のライフ サイクル ステージ、および依存関係管理のための標準の座標定義があります。
    
    Maven は、共通の標準ディレクトリ構造の使用を提唱しています。これにより、さまざまな開発者のコ​​ラボレーションが容易になり、いくつかの統一された自動化スクリプトの実装が容易になります。

    以前に作成した Java プロジェクト:
        src -> ソース コード ディレクトリですが、これは標準ではなく、気軽にフォルダを作成してソース コード ディレクトリにすることができます。
        libs -> サードパーティの jar パッケージですが、ディレクトリは任意の名前にすることができます。 
    
    以前に作成した Web プロジェクト:
        src -> ソース コード ディレクトリ。
        web -> 静的リソース、構成ファイル、およびサードパーティの jar を格納するために IDEA ツールによって作成されるディレクトリ。
        WebContent/WebRoot -> 静的リソース、構成ファイル、およびサードパーティの jar を格納するために Eclipse ツールによって作成されるディレクトリ。

    以前作成したプロジェクトには、標準がありませんでした。

1.4.5 プラグインの目標

    Maven は、プラグインに基づいてプロジェクトのライフサイクルを管理します。

1.5 Maven を使用する理由

    1. プロジェクトはプロジェクト プロジェクト
        が非常に大きい場合、パッケージを使用してモジュールを分割するのは適切ではありません. 各モジュールをプロジェクトに対応させた方が、分業とコラボレーションに役立ちます. Maven の助けを借りて、プロジェクトを複数のプロジェクトに分割できます。

    2.プロジェクトで使用されるjarパッケージは、プロジェクトのlibに「コピー」して「貼り付ける」必要があり、管理が不便です.プロジェクトが比較的大きい場合、大きなプロジェクトを多くの小さなプロジェクトに分割します
        .各小規模プロジェクト数名の開発者が担当例えばeコマースのプロジェクトは、アカウント関連、注文関連、商品関連のプロジェクトに分かれるが、構造は似ており、使用技術も異なる同じ: SSM (Spring 、Springmvc、Mybatis)、そして各プロジェクトは、これらの jar のコピーを独自のプロジェクト ディレクトリにコピーする必要があります. 最後の 10 個のプロジェクトは、jar の 10 個のコピーのみをコピーしました. 後で、いくつかの jar がプロジェクトをアップグレードする必要がありました. 交換します. このとき、10 個のアイテムを順番に交換する必要がありますが、これもかなりの苦痛です.
        Maven の助けを借りて、jar パッケージを「倉庫」に保存できます。どのプロジェクトにいても、参照を使用するだけです。

    3. jar パッケージが必要な場合は、自分で準備するか、公式 Web サイトからダウンロードする必要があります.
        たとえば、プロジェクトで fastjson を使用する必要があります.このとき、Baidu に移動して fastjson 関連の jar を検索しますパッケージをダウンロードし、プロジェクトの lib の下に配置します。 、プロジェクトのクラスパスに追加し、それを使用して、この jar のバージョンが古すぎて、必要なものではないことを確認してから調べます。繰り返しますが、それは苦痛です。
        Maven は、各 jar に一意のフラグを定義します。これは、maven ではプロジェクトの座標と呼ばれ、使用する必要がある jar パッケージの任意のバージョンを見つけることができます。

    4. jar パッケージのバージョンが一致しないリスク
        . a.jar はプロジェクトで使用され、a.jar は c.jar のバージョン 1.5 に依存します. 次に、これら 2 つの jar をプロジェクトにコピーし、b.jar を後で使用しますが、 b.jar も c.jar の 1.0 バージョンに依存しています. このとき、b.jar と c-1.0.jar をインポートすると、c.jar の 2 つのバージョンが競合し、エラーが発生することがわかります。この場合、jar 競合の問題を解決するために開始する必要があり、これも非常に苦痛です。
        Maven は、異なるバージョン間の jar の競合を簡単に解決できます。

    5. jar パッケージは他の jar パッケージに依存しており、手動でプロジェクトに追加する必要があります.
        一般に、jar パッケージは独立して存在しません. 一般に、一部の jar は他の jar も使用します. たとえば、spring-aop.jar は spring を使用します-core .jar、この依存関係は比較的単純な場合があり、a.jar は b.jar に依存し、b.jar は c.jar に依存し、c.jar は d.jar に依存するなど、いくつかの依存関係には多くのレベルがある場合があります。 、使用する場合 a.jar に関しては、他の 3 つを含める必要があるため、jar を使用する場合は、これらの jar がどの jar に依存するかを明確に把握し、それらをすべてインポートする必要があります。通常の運用では、プロジェクトが大量の jar を使用している場合、どの jar が欠落しているかを判断するのは困難です.プロジェクトの実行プロセス中にエラーが報告された場合にのみわかります.これも非常に苦痛であり、多くの無駄があります.時間の。
        Maven は jar の依存関係の問題を自動的に解決します. たとえば、a-1.0.jar を使用していて、a-1.0.jar が b-1.1.jar と c-1.5.jar に依存している場合、a-1.0.jar を導入すると、その後、b-1.1.jar と c-1.5.jar が自動的にインポートされます。

    6. 統合されたプロジェクト構造
        昔、Eclipse を使用してプロジェクトをビルドしたとき、Java ソース コードの場所、リソース ファイルの場所、テスト ファイルの場所、静的リソースの場所、およびコンパイルされたクラス ファイルの場所はすべて自由に配置できます , これらは、それぞれの会社のアーキテクトがプロジェクトをビルドするときに決定し、経験に従って定義されます. 結果として、各会社は異なるプロジェクト構造を持つ場合があります.どこがどこにあるのかを知るには人間の指導が必要であり、目に見えないコストがかかります.ある仕様に従って、全員が同じプロジェクト構造を採用できれば、非常に便利ではないでしょうか?誰もが特定の合意に従い、プロジェクトは同じ構造を使用します.たとえば: Javaファイル、リソースファイル、テストケース、静的リソース、コンパイルされたクラス、パッケージ化後のjarの場所など、さまざまなファイルの場所、これらのこと、Java開発を行うすべての企業が同意する場合、このようなプロジェクトを取得した後、多くのものを保存します。
        Maven を使用して構築されたプロジェクト構造は、同じ構造に従う必要があります.Java ソース ファイル、リソース ファイル、テスト ケース クラス ファイル、および静的リソース ファイルはすべて合意されています.誰もがこの合意に従います.プロジェクトが Maven によって作成されている場合は、新しい人を募集しますMaven を理解していれば、トレーニングはまったく必要なく、プロジェクトが立ち上がったときにプロジェクト全体の構造を理解できます。

    7. クロスプラットフォーム
        Maven はクロスプラットフォームであり、Windows と Linux で使用できます。

2. Maven のインストールと設定

2.1 JDK のインストールと JDK 環境変数の構成

    Maven のインストールは、JAVA_HOME 構成の環境変数に基づいている必要があります。

    システム変数:
        変数名: JAVA_HOME
        変数値: JDKインストールルートパス (C:\Java\jdk1.8.0_311)

    パス パスのインポート:
        %JAVA_HOME%\bin

    注: Maven3.3+ バージョン、jdk は少なくとも 1.7 以上

2.2 Maven のインストール

2.2.1 Maven のダウンロード

    Maven の公式 Web サイトのダウンロード アドレス: https://maven.apache.org/download.cgi、最新バージョンをダウンロードできます。
        
    注: Maven には最新バージョンは必要ありませんが、少なくともバージョン 3.3+ は必要です。

2.2.2 Maven のインストール

    Maven自体はインストール不要のグリーン版で、解凍するだけ。中国語とスペースを含まないディレクトリに Maven を解凍します。

2.2.3 Maven 環境変数の設定

    1. コンピューターを右クリック -> プロパティ -> システムの詳細設定 -> 詳細タブ -> 環境変数。    

    2. 新しいシステム変数を作成します:
        変数名: MAVEN_HOME
        変数値: D:\Tools\apache-maven-3.8.5 (Maven 解凍パス)

     3. %MAVEN_HOME%\bin を Path システム変数に追加します。

2.2.4 テスト

    cmd コマンド ライン ウィンドウを開き、 mvn -version コマンドを実行して、構成が成功したかどうかをテストします。

2.3 Maven ディレクトリ分析

    bin ディレクトリ: Maven によって実行されるスクリプト。
        mvn (実行モードでプロジェクトを実行)
        mvnDebug (デバッグ モードでプロジェクトを実行)

    ブート ディレクトリ: Maven の実行に必要なクラス ローダー。

    conf ディレクトリ:
        settings.xml、Maven ツール全体のコア構成ファイル。 

    lib ディレクトリ: Maven は、依存する jar パッケージを実行します。

2.4 グローバル設定とユーザー設定

    Maven ウェアハウス アドレス、プライベート サーバー、およびその他の構成情報は、settings.xml ファイルで構成する必要があります。このファイルは、グローバル構成とユーザー構成に分かれています。

    Maven インストール ディレクトリに conf/settings.xml ファイルがあり、この settings.xml ファイルはすべての Maven プロジェクトで使用され、Maven のグローバル構成として使用されます。

    パーソナライズされた構成が必要な場合は、ユーザー構成で設定する必要があります。ユーザー構成のsetting.xmlファイルのデフォルトの場所は次のとおりです: ${user.home}/.m2/settings.xmlディレクトリ、${user. home} は、Windows ユーザー ディレクトリを指します。(個人的なおすすめ)

    Maven は最初にユーザー構成を見つけます。見つかった場合はユーザー構成ファイルが優先され、そうでない場合はグローバル構成ファイルが使用されます。

    役割: Maven のローカル倉庫の場所、中央倉庫のミラーリング、およびその他の構成。

    Maven グローバル構成ファイル settings.xml の詳細な説明: https://cloud.tencent.com/developer/article/1014577

2.5 Alibaba Cloud ミラー ウェアハウスの構成

    Maven を使用してビルドされたすべてのプロジェクトは Maven ウェアハウスからダウンロードされますが、次の 2 つの問題があります。
        1. ダウンロード速度が遅すぎる。
        2. 公式のミラー ノード ブラックリスト メカニズム。
    
    注: 外部アクセスの IP アドレス ip138.com を確認してください。

    上記の問題に基づいて、国内のミラー ノードを構成する必要があり、Alibaba Cloud ミラーを使用することをお勧めします (デフォルトのミラー ノードをコメントアウトすることを忘れないでください)。

    注: 「ミラーリングは、ファイル ストレージの形式であり、冗長性の一種です。1 つのディスク上のデータは、ミラーである別のディスク上に同一のコピーを持ちます。」

方法 1: グローバル構成

    Alibaba Cloud のイメージを maven の setting.xml 構成に追加すると、毎回 pom にミラー ウェアハウスの構成を追加し、ミラー ノードの下にサブノードを追加する必要がなくなります。

<mirrors>
    <!-- mirror
     | Specifies a repository mirror site to use instead of a given repository. The repository that
     | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
     |
    <mirror>
      <id>mirrorId</id>
      <mirrorOf>repositoryId</mirrorOf>
      <name>Human Readable Name for this Mirror.</name>
      <url>http://my.repository.com/repo/path</url>
    </mirror>
     -->

    <!--
    <mirror>
      <id>maven-default-http-blocker</id>
      <mirrorOf>external:http:*</mirrorOf>
      <name>Pseudo repository to mirror external repositories initially using HTTP.</name>
      <url>http://0.0.0.0/</url>
      <blocked>true</blocked>
    </mirror>
 	-->

    <!-- 配置阿里云镜像节点 -->
    <mirror> 
        <id>alimaven</id> 
        <name>aliyun maven</name> 
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url> 
        <mirrorOf>central</mirrorOf>
    </mirror> 
</mirrors>

方法 2: ユーザー構成

    conf/settings.xml を .m2 フォルダーにコピーします。

    注: .m2 フォルダーの作成に失敗した場合は、コマンド ラインを使用してフォルダーを作成し、ユーザー ディレクトリを入力して、mkdir .m2 を実行することを検討してください。

注:必ずミラー構成を<mirrors>以下に配置してください

2.6 Maven のアンインストール

    Maven は、インストール中に解凍され、環境変数が構成され、ローカル ウェアハウスが設定されるだけなので、アンインストールも非常に簡単です。
        1.解凍したmavenフォルダを削除;
        2.設定した環境変数MAVEN_HOMEを削除し、パスに追加された「%MAVEN_HOME%\bin;」を削除;
        3.ローカルウェアハウスを削除;

3. Maven 契約

Java プロジェクトと JavaWeb プロジェクトでは、src はソース コード ディレクトリです。

    Maven プロジェクトには、次の 4 つのソース コード ディレクトリがあります。
        src/main/java: プロジェクトのソース コード (.java) ファイルを格納します。
        src/main/resources: プロジェクト構成リソース ファイルと、Spring、Mybatis 構成ファイル、db.properties データベース リソース ファイルなどのリソース ファイルを格納します。
        src/test/java: Junit テスト クラスなどのテスト コードを格納します。
        src/test/resources: テストで使用される設定ファイルを保存します。

src/main/webapp: Maven Web プロジェクトのディレクトリ。Eclipse の Web プロジェクトの WebContent/WebRoot ディレクトリに似ています。

target: プロジェクトの出力場所。コンパイルされたクラス ファイルはこのディレクトリに出力されます。

pom.xml: 現在のプロジェクトの構成管理、依存関係管理、およびプラグイン管理。

構造は次のとおりです。

プロジェクト
    |---src
    |----|---main
    |----|----|---java プロジェクトの.javaファイルを保存
    |----|----| -- -resources spring や hibernate 構成ファイルなどのプロジェクト リソース ファイルを保存します
    |----|----|---webapp webapp ディレクトリは Web プロジェクトのメイン ディレクトリです
    |----|-- --|--- |---WEB-INF
    |----|----|---|---web.xml
    |----|---test
    |----| ----|- --java は、JUnit テスト クラスなどのすべてのテスト .java ファイルを保存します
    |----|----|---リソース テスト リソース ファイル
    |---ターゲット ターゲット ファイルの出力場所.class、.jar、.war ファイル
    |---pom.xml Maven プロジェクト コア構成ファイル

4. Maven プロジェクトの実装を手動でビルドする

4.1 Maven Java プロジェクトを手動でビルドする

    知っておくべきこと: Maven 自体はプラットフォームに依存しないオープン ソース プロジェクトです。 Eclipse と IDEA、Maven を直接実行して、プロジェクトの jar ファイル サポートを提供することもできます。

    次に、独立した Maven プロジェクトを手動で作成、コンパイル、および実行し、このプロジェクトを通じて、Maven 自体に関するその他の知識ポイントを追加します。

4.1.1 Maven プロジェクトのフォルダー ディレクトリを作成する

まず、ディレクトリ構造を見てみましょう。

MavenProjectName:
    |---src
    |----|---main |
    ----|----|---java
    |----|----|---resources
    |-- --|---テスト
    |----|----|---Java
    |----|----|---リソース
    |---pom.xml

    次に、この最も単純な構造に従い、Maven プロジェクトの Java ファイルとテスト ファイルを保存するためのフォルダー構造を独自のディスクに手動で作成し、このフォルダーにコードを記述し、POM ファイルを追加し、このプロジェクトを徐々にインストールしてコンパイルして実行します。

4.1.2 Maven プロジェクトの pom.xml ファイルを構成する

    The pom.xml file of the Maven project is the soul of the Maven project. すべての重要な情報と Maven プロジェクトの jar ファイルのサポートは、このファイルを通じて構成されます. pom.xml ファイルを手動で構成しましょう (エンコード形式に注意してください)。

1. プロジェクトのルート フォルダーの下に pom.xml 構成ファイルを作成し、次の基本構造を作成します。

<?xml version="1.0" encoding="UTF-8"?>

<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">
    <modelVersion>4.0.0</modelVersion>

</project>

上記の構成は、Maven プロジェクトの pom.xml ファイルの基本的な構成方法に属します。

    <modelVersion></modelVersion> タグ: 現在の Maven プロジェクトで使用されている記述仕様のバージョン番号を示します。このラベルについて心配する必要はありません.主流の Maven プロジェクトで使用されている記述仕様のバージョン番号はバージョン 4.0.0 です。

2. pom.xml ファイルでプロジェクト座標を構成します。

    Maven はこれらの構成情報に基づいてプロジェクトの特定の場所を決定するため、各 Maven プロジェクトは pom.xml ファイルで次のコンテンツを構成する必要があります。したがって、以下で構成する情報はプロジェクトのプロジェクト座標とも呼ばれます。

    プロジェクトの座標を理解する方法: 実際の生活では、座標の概念は非常に人気があります.Yang Guofu Malatang で注文した同じ食事ですが、外国のコードの兄弟は、他の人の手ではなく、あなたの部分を正確に届けることができるのはなぜですか? 座標を使用するだけです。実生活では、都道府県、市区町村、地区、通り、地区、建物、ユニット、フロア、番地などの情報を使用して独自の座標を特定するため、テイクアウトの兄弟はこれに従ってテイクアウトを正しく配達できます。 「コーディネート」 .

    同様に、私たちのコンピューターの 1 つで、同時に複数の Java プロジェクトが存在する場合があります。Maven はこれらのプロジェクトをどのように区別するのでしょうか? プロジェクト座標も使用されるため、プロジェクト座標は Maven ソフトウェアが Java プロジェクトを識別するために使用する一意の識別子であると言われています。

    スパイシーなスープを食べるときにイカのボールを追加する必要があり、コリアンダーを食べないのと同じように、Maven ソフトウェアは、プロジェクトの座標に従って、このプロジェクトに必要な jar ファイルと不要な jar ファイルも識別します。

    OK!これで、プロジェクト座標の意味が理解できるはずですよね? それでは、Maven プロジェクトのプロジェクト座標を構成する方法を紹介しましょう。まず、説明しましょう。プロジェクト座標は、pom.xml ファイルの <project></project> タグの下で直接構成されます。

アイテムの座標を記述するための標準的な構造は次のとおりです。

<project>
    <groupId></groupId>
    <artifactId></artifactId>
    <version></version>
    <packaging></packaging>
    <classifier></classifier>
</project>

これらのラベルの構成情報の意味は次のとおりです。

    <groupId> タグ: プロジェクト組織の一意の識別子。通常、それは会社や組織の名前、または大規模なプロジェクトの名前ですが、通常、ドメイン名は反転されており、倉庫にインストールされている第 1 レベルのディレクトリ構造に影響を与えます。
        例:
            サーブレット関連の jar、その groupId は javax.servlet、javax.servlet は大きなプロジェクトの名前 (親プロジェクト名) です。
            Mybatis 関連の jar、その groupId は org.mybatis、org.mybatis は会社名または組織名です。
    
    <artifactId> タグ: プロジェクトの一意の識別子。通常、ウェアハウスにインストールされるサブディレクトリ構造とパッケージの名前に影響を与えるのは、プロジェクト名またはサブプロジェクト名またはモジュール名です。<artifactId> タグの値には、現在のプロジェクト (モジュール) の実際の名前を使用することをお勧めします。
    
    groupId と artifactId は、プロジェクトの一意性を確保するために、まとめて「座標」と呼ばれます。プロジェクトを Maven ローカル ウェアハウスに取得する場合、プロジェクトを見つけたい場合は、これら 2 つの ID に従って検索する必要があります。groupId は通常、複数のセクションに分割されます。ここでは 2 つのセクションのみを説明します。最初のセクションはドメインで、2 番目のセクションは会社名です。ドメインはorg、com、cnなどに分かれており、orgは非営利団体、comは営利団体です。Apache 社の tomcat プロジェクトの例を見てみましょう。このプロジェクトの groupId は org.apache、ドメインは org (tomcat は非営利プロジェクトであるため)、会社名は apache、artifactId は tomcat です。

    <version> タグ: 現在のプロジェクトのバージョン番号を示します。これは、ウェアハウスにインストールされる最終的なディレクトリ構造とパッケージの名前に影響します。

    <packaging> タグ: 現在のプロジェクトのパッケージ化方法を示します. 一般的な値 "jar" に加えて, 現在のプロジェクトが war ファイルとしてパッケージ化されていることを意味する値 "war" を取ることもできます. オプションの jar:は、パッケージが .jar
        ファイル Pack としてパッケージ化されていることを意味します。
        オプションの war: パッケージが .war ファイルとしてパッケージ化されていることを示します。
        オプションの pom: 現在のプロジェクトが管理プロジェクトであることを示します。
        デフォルトはjarです。
    
    <classifier> タグ: 現在のプロジェクトがパッケージ化されて生成されるときに生成されるいくつかの添付ファイルを示すために使用されます。
        詳細:
    
    https://www.cnblogs.com/love-kimi/archive/2012/10/09/2716507.html はどうですか、タグがたくさんありますね。しかし、実際に Maven プロジェクトを作成すると、それほど多くの座標はまったく必要なく、Maven プロジェクトに必要な座標ラベルは最初の 3 つだけです。
    
    現在のプロジェクトの座標を設定する方法を見てみましょう: 次のタグの内容を、以前に作成した pom.xml ファイルの <project></project> タグにコピーします。

<groupId>com.maven</groupId>
<artifactId>MavenTest</artifactId>
<version>0.0.1-SNAPSHOT</version>

上記の構成を pom.xml ファイルにコピーした後、そのような pom.xml ファイルの内容を取得します。

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <!-- 当前Maven项目使用的描述规范版本号 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- 配置当前Maven项目的项目坐标 -->
    <!-- 项目组织唯一的标识符 -->
    <groupId>com.maven</groupId>
    <!-- 项目的唯一的标识符 -->
    <artifactId>MavenTest</artifactId>
    <!-- 项目的版本号 -->
    <version>0.0.1-SNAPSHOT</version>
    <!-- 当前项目的打包方式 -->
    <packaging>jar</packaging>

</project>

    ここまでで、プロジェクト座標の構成が完了しました。

プロジェクトのバージョン番号に関する注意:

    Maven プロジェクトの <version> タグで使用されるバージョン番号には、デジタル バージョン番号 0.0.1 に加えて、バージョン タイプもあります。SNAPSHOT という単語は、スナップショット バージョンを意味します。では、プロジェクトのバージョンの種類は何ですか?
    1. スナップショット: スナップショット バージョン、つまり開発バージョン. このバージョンのプロジェクトは開発段階にあり、機能が不完全でエラーが多いため使用できません. Eclipse と IDEA は Maven を作成するときにデフォルトでこのバージョンを使用します.プロジェクト。
    2. alpha: 内部テスト バージョン. このバージョンのプログラムは推奨されません. このバージョンのプログラムは、開発者がバグを見つけて変更するための内部テストに使用されます.
    3. ベータ版: 外部テスト バージョン。ユーザー グループ向けにリリースされたテスト バージョンです。使用することはできますが、まだ不安定でバグが多いため、使用することはお勧めしません。
    4. リリース: リリース バージョン。公式が推奨する、より包括的な機能と安定した動作を備えたバージョンを意味しますが、いくつかのバグがある可能性があり、正常に使用できます。
    5. 安定版: リリース版をベースに、ほとんどのバグを取り除き、一部の機能を最適化した安定版です。
    6. current: 最新バージョン, 必ずしも安定バージョンではありませんが, 最新の機能を備えています. 対応するリリースまたは安定バージョンがある場合, 最初の2つを使用することをお勧めします.
    7. eval: 評価版で、1 か月または一定期間使用できます。
    さらに、ここでは詳しく説明しませんが、pre、RC、GA、およびその他のバージョンがあります。

3. pom.xml ファイルに jar ファイルの依存関係を追加します。

    Maven を学習する目的は、Maven がプロジェクトに必要な jar ファイルを自動的に追加および管理できるようにすることです。

    現在の Maven プロジェクトのすべての依存関係は <dependencies> タグで構成され、各依存関係は依存 jar の座標である <dependency> タグでラップされます。

    また、プロジェクトに必要な jar ファイルの依存関係の構成を pom.xml ファイルに追加する方法を紹介する前に、ここでは詳しく説明しません。

    現在のプロジェクトのテストを容易にするために、 pom.xml ファイルに junit-4.12 バージョンの jar ファイルの依存関係を追加します。

<!--
    所有jar文件依赖的声明都放在<dependencies>标签下的子标签<dependency>当中
    每一个依赖单独创建一个<dependency>子标签
-->
<dependencies>
    <!-- 对junit-4.12版本的jar文件依赖声明 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

上記の構成コンテンツを pom.xml ファイルに追加すると、より包括的なバージョンの pom.xml ファイルが得られます。

<?xml version="1.0" encoding="UTF-8"?>
<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">
	<!-- 当前Maven项目使用的描述规范版本号 -->
    <modelVersion>4.0.0</modelVersion>
	
	<!-- 配置当前Maven项目的项目坐标 -->
	<!-- 项目组织唯一的标识符 -->
	<groupId>com.maven</groupId>
	<!-- 项目的唯一的标识符 -->
    <artifactId>MavenTest</artifactId>
	<!-- 项目的版本号 -->
    <version>0.0.1-SNAPSHOT</version>
	<!-- 当前项目的打包方式 -->
    <packaging>jar</packaging>
	
	<!--
    所有jar文件依赖的声明都放在<dependencies>标签下的子标签<dependency>当中
    每一个依赖单独创建一个<dependency>子标签
	-->
	<dependencies>
		<!-- 对junit-4.12版本的jar文件依赖声明 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

    ここまでで、Maven プロジェクト全体の pom.xml 構成ファイルが完成したので、Java コードをいくつか書きましょう。

4.1.3 Maven プロジェクトで Java コードを書く

    Maven プロジェクトでは、Java ソース コードとテスト コードを厳密に区別しています. これらのコードは別の場所に格納されます. また、コンパイルと実行の過程で Maven が Java ソース コードとテスト コードをコンパイルしてコンパイルすることもわかります. 実行もかなり異なります. .

1. Java ソース コードを記述します。

    Maven プロジェクトのすべての Java ソース コードは src/main/java フォルダーに格納されているため、このフォルダーの下に次の Java ソース ファイルとコードを作成します。

こんにちはMaven.java:

package com.maven;

public class HelloMaven {
	
	private String msg = "Hello Maven!";
	
	public void sayHi() {
		System.out.println(msg);
	}	
	
}

2. テスト コードを記述します。

    Maven プロジェクトのすべてのテスト コードは src/test/java フォルダーに格納されるため、このフォルダーに次のテスト クラスとテスト コードを作成します。

こんにちはMavenTest.java:

package com.maven;

import org.junit.Test;

public class HelloMavenTest {
	
	@Test
	public void test1() {
		HelloMaven hm = new HelloMaven();
		hm.sayHi();
	}	

}

    ここまでで、Maven プロジェクトの Java コードが作成されましたが、上記の手順で注目する必要があるのは、Maven プロジェクト内の Java ソース コードとテスト コードの格納パスの場所です。

4.1.4 Maven プロジェクトのコンパイルと実行

    Maven プロジェクトを作成したら、プロジェクトを手動でコンパイルする必要があります。また、Java原本コードで作成したHelloMaven型をテストコードで使用するため、以下の順序でプロジェクトをコンパイルする必要があり
        ます
        。 src/test/java フォルダーの下のコード

    この順序でコンパイルすることによってのみ、テスト コードを正常に実行できます。

1. Java ソース コードをコンパイルします。

    まず、Maven プロジェクトのルート ディレクトリに入り、次のコマンドを使用して Maven プロジェクトのソース コードをコンパイルします。

mvn compile

    注: 初めて Maven プロジェクトをコンパイルする場合、Maven は必要な jar ファイルをリモートの中央ウェアハウスからローカル ウェアハウスにダウンロードします。

    ミラーを使用してダウンロードするように構成した場合、ダウンロード プロセスははるかに高速になります (デモンストレーションのために、ダウンロードしたすべての jar ファイルをローカル ウェアハウスに削除しました...)。

 プロジェクトが正常にコンパイルされると、次の結果が得られます。

    まず、コマンド コンソールに次の結果が表示されます。

     次に、src フォルダーの下に、target という名前の新しいフォルダーが表示されます。このフォルダーには、現在コンパイルされているすべての Java ファイルのバイトコード ファイルが保存されます。

 2. テスト コードをコンパイルして実行します。

    同じコマンドを使用して、Maven プロジェクトでテスト コードをコンパイルおよび実行します。

mvn test

    つまり、上記のコマンドを実行すると、Maven は次の 3 つの操作を同時に実行します
        。 xml 構成ファイル. 倉庫内.
        2. テスト コードをコンパイルし、対応するバイトコード ファイルを生成します。
        3. テスト クラスでテスト メソッドを直接実行し、テスト結果を出力します。

jar ファイルをローカル ウェアハウスにダウンロードするプロセス:

 テスト ファイルをコンパイルし、テスト メソッドを実行して実行結果を取得します。

 3. Maven プロジェクトをクリーンアップします。

    コンパイルおよび生成された Java ソース コードとテスト コードのバイトコード ファイルをクリアする必要がある場合は、次のコマンドを使用できます。

mvn clean

Maven はプロジェクトをクリーニングしています:

 クリーンアップ完了:

 このコマンドを実行すると、Maven はプロジェクトのルート ディレクトリにあるターゲット フォルダーを自動的に削除します。

     ここまでで、Maven プロジェクトを手動で作成、構成、コンパイル、および実行する操作はすべて終了しました。

4.2 Maven Web プロジェクトを手動でビルドする

    Maven Web プロジェクトは、Maven Java プロジェクトよりもいくつか構造が多く、Maven 規則に従ってビルドできます。

4.2.1 Web ディレクトリの作成

    src/main ディレクトリの下に webapp ディレクトリを作成します。webapp ディレクトリは、Web プロジェクトのメイン ディレクトリです。

    後はWebプロジェクトに合わせて運用することなので繰り返しません。 

4.2.2 HelloServletの作成

    src/main/java ディレクトリの下に com.maven.servlet パッケージを作成し、その下に HelloServlet クラスを定義します。

HelloServlet クラスのコードは次のとおりです。

package com.maven.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().write("Hello.................");
	}

}

4.2.3 構成の依存関係と動作環境 (詳細は後述)

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.newcapec</groupId>
  <artifactId>HelloMaven</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  
  <build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>
	
	<!-- 添加servlet-api,jsp-api -->
	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.0</version>
			<scope>provided</scope>
		</dependency>
		
	</dependencies>
  
</project>

4.2.4 テストの実行    

    データで HelloMaven を開き、テストを実行します。

    Maven プロジェクト ディレクトリ (現在のディレクトリには pom.xml ファイルがあります) に入り、mvn tomcat:run コマンドを実行します。

    上記のプロンプト情報に従って、ブラウザから http://localhost:8080/HelloMaven/HelloServlet にアクセスします。

4.2.5  Maven Web プロジェクトのエラー処理

    質問 1: jar パッケージの競合が発生している可能性があります。
        解決策: jsp とサーブレットの依存関係に <scope>provided</scope> を追加します。

    質問 2: Maven に組み込まれている Tomcat は 6.0 で、このバージョンは jdk1.8 をサポートしていません。
        tomcat7 プラグインを構成し、maven コンパイル環境を 1.8 に構成します。
        mvn tomcat7:run コマンドを実行して、サービスを開始します。tomcat:run を使い続けると、Maven の Tomcat6 を使い続けることになり、間違いを犯し続けることになります...

<plugins>
    <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>
            <source>1.8</source>
            <target>1.8</target>
            <encoding>UTF-8</encoding>
        </configuration>
    </plugin>
</plugins>

4.3 コマンドテスト

cmd コマンド ラインを開き、hello プロジェクトのルート ディレクトリを入力し、次のコマンドを実行してルート ディレクトリの変更を表示します。

#编译:
mvn compile

#清空:
mvn clean

#测试:
mvn test

#打包:在打包之前先执行test命令,经过测试发现,并不会打包测试文件
mvn package

#把项目安装到本地仓库,在安装之前先执行package命令:
mvn install

ファイブ、Maven 倉庫とコーディネート

5.1 Maven リポジトリの概要

    Maven ウェアハウスの分類:
        ローカル ウェアハウス: ローカル ホスト上のウェアハウス。
        リモート ウェアハウス: プラグインまたは jar パッケージがローカルに必要であるが、ローカル ウェアハウスにない場合は、デフォルトでリモート ウェアハウスに移動してダウンロードします。リモート ウェアハウスは、インターネット上またはローカル エリア ネットワーク上にあります。

    Maven の作業には、ウェアハウスからいくつかの jar パッケージをダウンロードする必要があります. 下の図に示すように、ローカルの Maven プロジェクトは、Maven ソフトウェアとストアを介して、リモートのウェアハウス (インターネット上のウェアハウスとして理解できる) から jar パッケージをダウンロードします。それらはローカル倉庫にあります. ローカル倉庫はローカルファイルです. フォルダー, jar パッケージが 2 回目に必要になると、ローカル倉庫が既に存在し、ローカル倉庫ができるため、リモート倉庫からダウンロードされなくなります.ローカルウェアハウスを使えば、リモートウェアハウスから毎回ダウンロードする必要がありません。

次の図は、maven のウェアハウスのタイプを示しています。

5.2 中央倉庫

    元のローカル ウェアハウスは空であるため、Maven コマンドの実行時に必要なビルドをダウンロードするために、Maven は少なくとも 1 つの使用可能なリモート ウェアハウスを認識している必要があります。

    セントラル ウェアハウスは Maven のデフォルトのリモート ウェアハウスであり、インターネット全体にサービスを提供します. これは Maven チーム自身によって維持され、世界で人気のあるオープン ソース プロジェクト コンポーネントのほとんどを含む非常に完全な jar パッケージを格納します.

    中央倉庫のアドレスは https://repo.maven.apache.org/maven2 です。

    Maven のインストール ファイルには、デフォルトで中央ウェアハウスの構成が付属しています。これは、構成されている MAVEN_HOME/lib/maven-model-builder.jar、org\apache\maven\model\pom-4.0.0.xml にあります。中央倉庫の住所で。

<repositories>
    <repository>
        <id>central</id>
        <name>Central Repository</name>
        <url>https://repo.maven.apache.org/maven2</url>
        <layout>default</layout>
        <snapshots>
        <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

5.3 個人倉庫

    主にチームのコラボレーションと開発のために、ローカルエリアネットワークに設定された倉庫である特別な種類のリモート倉庫であり、プライベートサーバーとも呼ばれる自社の倉庫として理解できます。

    Alibaba Cloud ミラーを構成する. Alibaba Cloud ミラーは、実際には Ali のプライベート ウェアハウスであり、誰もが使用できるようになっています。

<mirror>
    <id>alimaven</id>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>
</mirror>

プライベート サーバーを使用する利点:

    独自の外部ネットワーク帯域幅を節約: プライベート サーバーを確立すると、組織自体の費用を削減できます, 外部のリモート倉庫に対する多数の繰り返し要求は、多くの帯域幅を消費します. プライベートサーバーを使用して外部倉庫をプロキシした後, 外部の繰り返しコンポーネントつまり、外部ネットワーク帯域幅のプレッシャーをなくすことができます。

    Maven の構築を加速する: 外部ウェアハウスを継続的に要求するのは間違いなく時間がかかりますが、Maven の一部の内部メカニズム (スナップショット検出など) では、ビルドの実行時に Maven がリモート ウェアハウスのデータを継続的にチェックする必要があります。したがって、多くのリモート ウェアハウスが構成されている場合、ビルドの速度は大幅に低下します。プライベート サーバーを使用すると、この問題をうまく解決できます。

    サードパーティ コンポーネントの展開: 特定のコンポーネントを外部のリモート ウェアハウスからダウンロードできない場合はどうすればよいですか? 組織内で生成されたプライベート コンポーネントを外部ウェアハウスから取得してはならない、Oracle の JDBC ドライバーは著作権上の理由で外部ネットワーク上の中央ウェアハウスにリリースできないなど、多くの例があります。プライベート サーバーが確立されたら、これらのコンポーネントをローカルのプライベート サーバーにデプロイして、内部の Maven プロジェクトで使用できます。

    安定性の向上と制御の強化: Maven ビルドはリモート ウェアハウスに依存しているため、インターネットが不安定な場合、Maven ビルドも不安定になるか、ビルドに失敗することさえあります。
プライベート サーバーを使用すると、一時的にインターネットに接続できなくても、Maven は正常に実行できます。これは、プライベート サーバーに多数のコンポーネントがキャッシュされているためです。さらに、一部のプライベート サーバー ソフトウェア (Nexus など) は、権利管理、RELEASE/SNAPSHOT の区別など、多くの追加機能も提供します。管理者は、ウェアハウスに対してより高度な制御を実行できます。

    中央ウェアハウスの負荷を軽減します。数百万のリクエストと数テラバイトのデータのストレージには、かなりの財務リソースが必要です。プライベート サーバーを使用すると、中央倉庫への多くの繰り返し要求を回避できます。

5.4 ローカル倉庫

    Maven がコンパイルまたはテストを実行するとき、ローカル リポジトリの依存関係を使用する必要がある場合は、座標に基づいて常にそれらを使用します。デフォルトでは、Linux または Windows に関係なく、各ユーザーには、独自のユーザー ディレクトリの下に .m2/respository/ という名前のリポジトリ ディレクトリがあります。

    jar パッケージと Maven 情報を中央倉庫または専用倉庫からダウンロードするか、jar パッケージの依存倉庫を自分で構築します。

    デフォルトの場所: ~/.m2/repository

    ローカル倉庫の場所を変更します: MAVE_HOME/conf/settings.xml ファイルでローカル倉庫の場所を構成します。

<localRepository>D:\maven\repository</localRepository>

5.4 Maven座標

    Maven ウェアハウスには多数の依存 jar パッケージがあり、統一された仕様を構築するために一意に識別する必要があります。統一された仕様により、Maven リポジトリから必要な依存関係を正確に見つけることができます。

<dependency>
    <!-- Maven依赖的坐标GAV -->
    <groupId></groupId>
    <artifactId></artifactId>
    <version></version>
</dependency>

6. Eclipse で Maven を使用する

6.1 Maven プラグインのインストール

    Eclipse を開き、メニューの [ヘルプ] -> [新しいソフトウェアのインストール] をクリックし、[追加] ボタンをクリックします。
        名前: m2e 
        場所: http://download.eclipse.org/technology/m2e/releases

注: 新しいバージョンの eclipse には Maven が直接統合されているため、m2eclipse プラグインをインストールする必要はありません。

6.2 Eclipse で Maven を構成する

    1. Eclipse を開き、メニューの [ウィンドウ] -> [設定] をクリックし、[Maven] -> [インストール] を見つけて、デフォルトの Maven を変更し、[追加] をクリックして独自の Maven を追加します。

    注: 組み込みの Maven バージョンが 3.3 以降の場合は、この手順を省略してデフォルトの手順を使用できます。もちろん、自分でインストールした Maven を使用することもできます。

    2. [ユーザー設定] をクリックし、ユーザー設定ファイルとローカル リポジトリ パスを再度選択します。

    注: 通常、Eclipse はデフォルトでユーザー ディレクトリの .m2 フォルダーの下にある settings/xml を使用し、settings.xml ファイルの構成情報を自動的に認識します。

     3. jar パッケージのソース コードとドキュメントを構成してダウンロードします (必要な場合)。
    
    注: 以下の 2 項目にチェックを入れると、依存関係をダウンロードする際に、依存関係に対応するソースコードとドキュメントが一緒にダウンロードされます (個人的には、チェックすることはお勧めしません)。

6.3 Eclipse で Maven プロジェクトを作成する

6.3.1 Maven Java プロジェクトの作成

    1. [ファイル] -> [新規] -> [プロジェクト] をクリックし、[Maven] -> [Maven プロジェクト] を見つけます。

     2. [次へ] をクリックし、[Maven archetype (prototype)] を選択します。

     3. カタログのデフォルトの選択は、すべてのプロトタイプを意味するすべてのカタログです。カタログで [内部] を選択して、Maven の組み込みタイプを示します (公式 Web サイトで提供されます)。
    
        Maven Java プロジェクトの場合は、maven-archetype-quickstart を選択します。
        Maven Web プロジェクトの場合は、maven-archetype-webapp を選択します。

     4. Maven 座標を入力します。
        グループ ID: 会社のドメイン名の反転。
        アーティファクト ID: プロジェクト名。
        バージョン: バージョン番号。
        パッケージ: 必要に応じて定義します。

    5. Maven は、プロジェクトに必要な依存パッケージを自動的にダウンロードし、完了後にプロジェクト構造を再構築します。

    注: eclipse によってデフォルトで導入された junit 依存関係のバージョンは 3.8 であり、4.12 として定義されています。

     6. 自動生成された App.java と AppTest.java を削除し、プロジェクト コードを記述します。

プロジェクトのソース コード Student.java:

package com.maven;

public class Student {
    private int id;
    private String name;
    private String sex;
    private double score;

    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Student(int id, String name, String sex, double score) {
        super();
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.score = score;
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", score=" + score + "]";
    }

}

プロジェクト テスト コード StudentTest.java:

package com.maven;

import org.junit.Test;

public class StudentTest {

	@Test
	public void test1() {
		Student stu = new Student(101, "张三", "男", 22);
		System.out.println(stu);
	}
}

    7. コードを記述したら、プロジェクトの Run As を右クリックして、実行する Maven コマンドを選択します。

 Maven テストを実行します。

     注: Eclipse には Maven パッケージ コマンドがないことがわかりました.Maven ビルドを介して Eclipse でコマンド構成インターフェイスを呼び出すことができ、このプラグインで実行ターゲットを自分で構成できます。

6.3.2 Maven Web プロジェクトの作成

    1、按照之前的步骤,在选择Maven archetype(原型)的时候选择选择maven-archetype-webapp,创建Maven Web项目。

 建立Maven Web项目后目录结构如下:

    在搭建好Maven项目之后,项目上会出现一个小红叉,通过观察这个JSP文件中报错位置的提示信息我们发现,实际上这是因为我们的项目中没有导入Java EE的相关JAR文件导致的。
    
    在接下来的操作中,我们有两种选择:
        1.1 通过Build Path手动导入Java EE相关Jar包。
        1.2 通过Maven的pom.xml文件配置这些Jar包的相关依赖。

    我们使用的可是Maven项目!手动导入Jar包,多丢人啊!妥妥的选择使用Maven配置依赖啊!

    2、需要手动创建src/main/java,src/test/java,src/test/resources等源码目录。
    
    注意:src/main/webapp为存放web的根目录,类似于WebContent目录。但其中的index.jsp和WEB-INF目录下的web.xml因版本过早,需要删除重建。

     3、通过Maven的pom.xml文件配置这些Jar包的相关依赖。
        打开:https://mvnrepository.com,并搜索javaee关键字,选择使用最多的一个选项:

     接下来选择基于Java 8版本的Java EE类库:

     将其中的依赖声明代码复制到项目的pom.xml文件中:

或者单独配置:

<!-- jsp -->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
    <scope>provided</scope>
</dependency>

<!-- servlet -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

<!-- jstl -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

本地tomcat部署Maven Web项目:

     https://www.cnblogs.com/noyitela/p/10386455.html

Maven Web プロジェクトをデプロイする Maven コマンド:

    tomcat7-maven-plugin プラグインを pom.xml に追加します。
    
    注: バージョンが tomcat7-maven-plugin 2.0 の場合、jdk 1.8 をサポートしていないため、単に tomcat7-maven-plugin 2.2 に置き換えてください。

<build>
    <finalName>maven-web-eclipse</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
        </plugin>
    </plugins>
</build>

    このようにして、構成が完了します。目標を tomcat7:run に変更することを忘れないでください。

6.4 Maven コマンド エラーを実行するための解決策

Maven コマンドを実行し、エラーを報告します。

    エラーの原因: Eclipse の実行環境はデフォルトで jre であり、Maven の実行環境には jre ではなく JDK が必要です。

    1. [ウィンドウ] -> [設定] -> [Java] -> [インストール済みの JRES] -> [追加] -> [標準 VM] -> インストールした JDK を選択します。

     2. 現在のプロジェクトの [プロパティ] -> [Java ビルド パス] -> [ライブラリ] -> [ライブラリの追加] -> [JRE システム ライブラリ] -> [ワークスペースのデフォルト JRE] を確認します。

     その他の解決策: https://blog.csdn.net/weixin_44405634/article/details/100837978

7. IDEA で Maven を使用する

7.1 IDEA には独自の Maven プラグインがあり、インストールする必要はありません

7.2 IDEA で Maven を構成する

    1. IDEA を開き、メニューの [ファイル] -> [設定] をクリックし、[ビルド]、[実行]、[デプロイ] -> [ビルド ツール] -> [Maven] を見つけて、デフォルトの Maven を変更します。

    注: 組み込みの Maven バージョンが 3.3 以降の場合は、この手順を省略してデフォルトの手順を使用できます。もちろん、自分でインストールした Maven を使用することもできます。

    2. Build, Execution, Deployment -> Build Tools -> Maven -> Importing で、自動的にダウンロードされる jar パッケージのソース コード、ドキュメント、および注釈を設定します。

    注: 以下の 2 項目にチェックを入れると、依存関係をダウンロードする際に、依存関係に対応するソースコードとドキュメントが一緒にダウンロードされます (個人的には、チェックすることはお勧めしません)。

7.3 IDEA で Maven プロジェクトを作成する

7.3.1 Maven Java プロジェクトの作成

    1. File -> New -> Project をクリックし、Maven を見つけ、Create from archetype をチェックし、必要な archetype を選択します。quickstart は Java プロジェクトをビルドし、webapp は JavaWeb プロジェクトをビルドします。

     2. Maven座標、グループID:会社名、artifactID:プロジェクト名、version:バージョン番号を記入し、完成まで次のステップ。

     3. Maven は、プロジェクトに必要な依存パッケージを自動的にダウンロードし、完了後にプロジェクト構造を再構築します。

    4. Maven アグリーメントに従ってプロジェクト構造を完成させます。
        メインディレクトリの下にリソースフォルダーを作成し、ディレクトリを「リソースルート」としてマークします。
        テスト ディレクトリの下にリソース フォルダーを作成し、ディレクトリを「テスト リソース ルート」としてマークします。

    注: 新しいバージョンの IDEA では、リソースを作成すると、対応するプロンプトが表示されます。

    5. 自動生成された App.java と AppTest.java を削除し、プロジェクト コードを記述します。

    6. コードを記述したら、Maven Projects ウィンドウを IDEA の右側に折りたたみ、Lifecycle の下のコマンドを選択し、Run ボタンをクリック (コマンドをダブルクリック) して実行します。

    注: 右側に Maven プロジェクトの折りたたみウィンドウがない場合は、[表示] -> [外観] -> [ツール ウィンドウ バー] をクリックします。

7.3.2 Maven のデフォルト JDK コンパイル環境の変更

    Maven によって作成されたプロジェクトのデフォルトの JDK コンパイル環境は 1.5 です. pom で Maven コンパイル プラグインを使用するか、グローバル構成を通じてプロジェクトの JDK バージョンを変更できます。バージョンが指定されていない場合、バージョンの不一致の問題が発生しやすく、コンパイルに失敗する問題が発生する可能性があります。

方法 1: プロジェクト レベルの pom.xml を変更する

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

    上記の構成は、現在のプロジェクト (モジュール) に対してのみ有効です。

方法 2: Maven の settings.xml ファイルを変更する (グローバル)

<profile>    
    <id>jdk-1.8</id>    
    <activation>    
        <activeByDefault>true</activeByDefault>    
        <jdk>1.8</jdk>    
    </activation>    
    <properties>    
        <maven.compiler.source>1.8</maven.compiler.source>    
        <maven.compiler.target>1.8</maven.compiler.target>    
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>    
    </properties>    
</profile> 

    上記の構成はグローバル レベルです。つまり、現在の Maven 環境に基づいて作成されたプロジェクト (モジュール) が有効になります。

7.3.3 Maven Web プロジェクトの作成

    1. 前の手順に従って、Maven Web プロジェクトを作成します。

 Maven Web プロジェクトを作成すると、ディレクトリ構造は次のようになります。

    2. src/main/java、src/mian/resources、src/test/java、src/test/resources などのソース コード ディレクトリを手動で作成し、最初にディレクトリ (通常のディレクトリ) を作成します。

    注: 新しいバージョンの IDEA が指定された名前のディレクトリを作成すると、直接プロンプトが表示されます。これは非常に使いやすいです。

     3. ディレクトリを右クリックし、[Mark Directory as] を選択して、ディレクトリを対応するソース コード ディレクトリに変換します。ソース ルートは src/main/java ディレクトリに対応し、テスト ソース ルートは src/test/java ディレクトリに対応し、リソース ルートは src/main/resources ディレクトリに対応し、テスト リソース ルートは src/test/resources ディレクトリに対応します。ディレクトリ

     4. src/main/webapp は、WebContent ディレクトリと同様に、Web を格納するためのルート ディレクトリです。ただし、WEB-INF ディレクトリの index.jsp と web.xml はバージョンが古いため、削除して再構築する必要があります。

jsp テンプレート:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Hello Maven!</h1>
</body>
</html>

web.xml テンプレート:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

    5. 展開してテストします。
        ローカルの tomcat が Maven Web プロジェクトをデプロイします。
        Maven Web プロジェクトをデプロイするための Maven コマンド。

8.Mavenの依存範囲

    前に作成した Maven Web プロジェクトに基づいて、Web 開発で一般的に使用される依存関係を追加します。
        1.mysql ドライバー
        2.サーブレット
        3.jsp
        4.jstl
        5.gson など

ディレクトリ構造は次のとおりです。

Student クラスのコードは次のとおりです。

package com.maven.entity;

/**
 * 学生实体类
 */
public class Student {
    private Integer id;
    private String name;
    private String gender;
    private double score;

    public Student(){}

    public Student(Integer id, String name, String gender, double score) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.score = score;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", score=" + score +
                '}';
    }
}

GsonServlet クラスのコードは次のとおりです。

package com.maven.servlet;

import com.google.gson.Gson;
import com.maven.entity.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 测试Gson的Servlet
 */
@WebServlet("/gsonServlet")
public class GsonServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建Gson对象(如果没有引入gson的jar包或依赖,肯定会报错)
        Gson gson = new Gson();

        //创建集合来存储学生对象
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student(101,"Tom","boy",89));
        studentList.add(new Student(102,"Jerry","boy",56.2));
        studentList.add(new Student(103,"HanMeiMei","girl",44));
        studentList.add(new Student(104,"LiLei","boy",100));

        //把studentList转换为json字符串响应出去
        String json = gson.toJson(studentList);
        resp.getWriter().write(json);
    }
}

StudentTest クラスのコードは次のとおりです。

package com.maven.entity;

import org.junit.Test;

/**
 * 学生类单元测试
 */
public class StudentTest {
    @Test
    public void test1() {
        Student student = new Student(101, "张三", "男", 12);
        System.out.println(student);
    }
}

pom.xml ファイルは、次のものに依存します。

<dependencies>
    <!-- 引入junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

    <!-- 引入mysql驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.49</version>
    </dependency>

    <!-- 引入jsp -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>

    <!-- 引入servlet -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>

    <!-- 引入jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <!-- 引入gson -->
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.5</version>
    </dependency>
</dependencies>

    エンティティ クラス、サーブレット、およびテスト クラス コードについては説明する必要はありませんが、依存関係を導入すると、依存関係にはスコープ タグが含まれるものと含まれないものがあることがわかります。

    <scope> タグは、依存要素の使用範囲を制御するためのものです。簡単に言えば、Jar パッケージをロードして使用するスコープを制御することです。

8.1 依存範囲の概要

3 つのクラスパスの理解:

    1. コンパイル クラスパス: ターゲット ディレクトリの下の classes ディレクトリに対応し、src/main ディレクトリの下のコンパイルされたコンテンツのみが格納されます。
        src/main/java: コンパイル後に生成されたバイトコード ファイルは、(パッケージ構造で) classes ディレクトリに配置されます。
        src/main/resources: コンパイルされず、classes ディレクトリに直接配置されます。

    2. テスト クラスパス: ターゲット ディレクトリの下の test-classes ディレクトリに対応し、src/test ディレクトリの下のコンパイルされたコンテンツのみが格納されます。
        src/test/java: コンパイル後に生成されたバイトコード ファイルは、test-classes ディレクトリ (パッケージ構造) に配置されます。
        src/test/resources: コンパイルされず、test-classes ディレクトリに直接配置されます。
    
    3. 実行中のクラスパス: プロジェクト実行時のバイトコード ファイル格納ディレクトリ。たとえば、Web プロジェクトの /WEB-INF/classes ディレクトリです。
    
    注:
        1. resources ディレクトリの下にパッケージを作成することはできず、フォルダーのみを作成できます.com.maven.servlet フォルダーを作成すると、com.maven.servlet というフォルダーのみが作成されます。
        2. resources ディレクトリ配下には、main ディレクトリ配下と同様のディレクトリ構造を定義できます。
        3. リソースディレクトリ配下にメインディレクトリ配下と同じファイルを定義することはできません。
        4. resources ディレクトリにある Java ソース コードはコンパイルされないため、Java ソース コードを resources ディレクトリに置くことはお勧めしません。

     Maven プロジェクトのさまざまな段階でクラスパスに導入される依存関係は異なります。
        コンパイル時に、Maven はコンパイル関連の依存関係をクラスパスに導入します。
        テスト時に、Maven はテスト関連の依存関係をクラスパスに導入します。
        実行時に、Maven は実行時関連の依存関係をクラスパスに導入します。
    
    依存関係のスコープは、クラスパスのコンパイル、クラスパスのテスト、およびクラスパスの実行に依存する 3 つのクラスパスの使用を制御するために使用されます。

8.2 スコープの値に応じて

    Maven のライフ サイクルには、これらのプロセスのコンパイル、テスト、および実行が含まれるため、当然のことながら、junit などのテストにのみ使用される依存関係もあれば、コンパイルには使用されず、実行時にのみ使用できる依存関係もあります。 mysql はコンパイル時に使用されます (JDBC インターフェースはコンパイル時に使用されます) が、実行時には使用されます。コンパイル時に使用される依存関係がいくつかありますが、実行時に提供する必要はありません。 Tomcat では既に提供されているので、必要なのはコンパイル時に提供することだけです。まとめると、POM 4 では、主に依存関係の展開を管理する <dependency> にも <scope> が導入されています。大まかにコンパイル、提供、ランタイム、テスト、システムなどがあります。
        
    compile: 依存関係のスコープをコンパイルします。
    test: 依存関係のスコープをテストします。
    提供: 依存関係のスコープが提供されます。
    runtime: ランタイムの依存関係のスコープ。(インターフェースと実装の分離)
    system: システム依存のスコープ。ローカル以外の倉庫からインポートされ、システムの特定のパスに保存された jar。(通常は使用されません)
    import: 依存スコープをインポートします。dependencyManagement を使用すると、依存関係の構成をインポートできます。(後で説明)

依存範囲 クラスパスを有効にコンパイルする テスト クラスパスは有効です クラスパスの実行は機能します
コンパイル スプリングクロー
テスト N N ジュニット
提供された N サーブレット API
ランタイム N jdbc

コンパイル (デフォルト)

    意味: compile がデフォルト値です。スコープ値が指定されていない場合、この要素のデフォルト値は compile です。依存プロジェクトは、現在のプロジェクトのコンパイル、テスト、パッケージ化、実行、およびその他の段階に参加する必要があります。依存プロジェクトは通常、パッケージ化時に含まれます。

    デモンストレーション: gson のスコープ値はデフォルトのコンパイルです。test に変更すると、コンパイル中に gson が見つからず、エラーが報告されます。

提供された

    意味: 依存プロジェクトは、理論的にはコンパイル、テスト、および操作の段階に参加できますが、これはコンパイルと同等ですが、除外のアクションは再パッケージ段階で実行されます。 

    該当するシナリオ: たとえば、Web アプリケーションを開発している場合、コンパイル時に servlet-api.jar に依存する必要がありますが、実行時に jar パッケージは必要ありません。この jar パッケージはアプリケーションによって提供されているためです。サーバー、この時点で、範囲の変更のために指定された使用が必要です。

    デモンストレーション: gson のスコープ値を provided に変更します。コンパイルとテストには問題はありませんが、アプリケーション サーバーが gson の jar パッケージを提供していないため、実行時にエラーが報告されます。

ランタイム

    意味: 依存プロジェクトがプロジェクトのコンパイルに参加する必要はありませんが、プロジェクトのテストと実行には参加することを示します。コンパイルと比較して、依存プロジェクトはプロジェクトのコンパイルに参加する必要はありません。

    該当するシナリオ: たとえば、コンパイル時には JDBC API jar パッケージは必要ありませんが、実行時には JDBC ドライバー パッケージのみが必要です。

テスト

    意味: 依存プロジェクトが、テスト コードのコンパイルや実行など、テスト関連の作業にのみ参加することを示します。

    該当するシナリオ: Junit テストなど。

    デモ: src/main/java で単体テストを使用できません。

システム

    意味: system 要素は提供された要素に似ていますが、依存アイテムは Maven ウェアハウスから検索されず、ローカル システムから取得されます。systemPath 要素は、ローカル システム内の jar ファイルのパスを指定するために使用されます。 . 例えば:

<dependency>
    <groupId>org.open</groupId>
    <artifactId>open-core</artifactId>
    <version>1.5</version>
    <scope>system</scope>
    <systemPath>${basedir}/WebContent/WEB-INF/lib/open-core.jar</systemPath>
</dependency>

インポート(理解)

    <dependencyManagement> でのみ使用されます。これは、たとえば、他の pom から依存関係の構成をインポートすることを意味します (B プロジェクトは A プロジェクトのパッケージ構成をインポートします)。

    おそらく、SpringBoot アプリケーションを実行しているときは、次のコードが作成されます。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.3.RELEASE</version>
</parent>

    親モジュールを継承し、対応する依存関係を導入します。

    継承したくない、複数継承したい、という場合はどうすればいいですか?Maven の継承は、Java の継承と同様に、多重継承を実現できないことがわかっています.10、20、またはそれ以上のモジュールが同じモジュールから継承されている場合、以前の慣行によれば、この親モジュールの依存関係管理には多数の依存が含まれます。より明確な管理のためにこれらの依存関係を分類したい場合、それは不可能であり、スコープの依存関係をインポートすることでこの問題を解決できます。依存関係を管理するために特別に使用される別の pom に依存関係管理を配置し、依存関係を使用する必要があるモジュールのインポート スコープの依存関係を介して依存関係管理をインポートできます。たとえば、依存関係管理のためにそのような pom を作成できます。

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.test.sample</groupId>
    <artifactId>base-parent1</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0-SNAPSHOT</version>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactid>junit</artifactId>
                <version>4.8.2</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactid>log4j</artifactId>
                <version>1.2.16</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

次に、非継承により、この依存関係管理構成を導入できます。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.test.sample</groupId>
            <artifactid>base-parent1</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
 
<dependency>
    <groupId>junit</groupId>
    <artifactid>junit</artifactId>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactid>log4j</artifactId>
</dependency>

注: インポート スコープは、dependencyManagement でのみ使用できます。

    このようにして、親モジュールの pom は非常にクリーンになり、依存関係は pom として特別なパッケージングによって管理されます。これは、オブジェクト指向設計の単一責任の原則にも準拠しています。さらに、そのような依存関係管理 pom を複数作成して、より詳細な方法で依存関係を管理することができました。このプラクティスは、オブジェクト指向設計で継承の代わりに構成を使用することにも幾分似ています。

    では、このメソッドを使用して SpringBoot の継承の問題を解決するにはどうすればよいでしょうか?

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.3.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

    この構成により、独自のプロジェクトは SpringBoot のモジュールを継承する必要がなくなり、独自のプロジェクトのモジュールを継承できます。

9. Maven 依存関係の配信

9.1 依存関係の転送

誰もが問題を理解する必要があります: Maven ウェアハウス内のすべての jar は、本質的には実際には Java プロジェクトですが、jar パッケージにパッケージ化され、Maven ウェアハウスに配置されているだけです. Java プロジェクトであるため、このプロジェクトは使用することもできますサードパーティの jar パッケージ。

特定の jar パッケージを導入すると、これらの jar パッケージが依存する jar パッケージも導入されます。これが依存関係の転送です。

    たとえば、Commons-logging プロジェクトがあり、プロジェクト Spring-core は Commons-logging に依存し、プロジェクト user-service は Spring-core に依存しています。次に、ユーザーサービスも Commons-logging に依存していると言えます。つまり、依存関係は次のとおりです。user-service—>Spring-core—>Commons-logging

    プロジェクトのユーザー サービスを実行すると、依存関係の推移性であるユーザー サービス プロジェクトの jar パッケージ フォルダーに Spring-core と Commons-logging が自動的にダウンロードされてインポ​​ートされます。

依存関係の完全な構造:

<dependencies>
    <dependency>
        <groupId>组织/父项目名称</groupId>
        <artifactId>项目名称</artifactId>
        <version>项目版本号</version>
        <type>依赖的类型,对应项目的packaging,默认是jar</type>
        <scope>依赖范围</scope>
        <systemPath>配合 scope=system 时使用</systemPath>
        <optional>标记是否为可选依赖</optional>
        <exclusions>
            <!-- 用来排除传递性依赖 -->
            <exclusion>
                <groupId>组织/父项目名称</groupId>
        		<artifactId>项目名称</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

    <optional>true</optional> を設定すると、依存関係がオプションであり、依存関係によって渡されないことを意味します。

検証例:

    依存関係の spring-core を導入します。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.18.RELEASE</version>
</dependency>

結果は次のとおりです。

    注意深い観察の結果、この時点で「依存」を伴う commons-logging:commons-logging:1.2 がより多く存在することもわかりました。

    A jar パッケージが B jar パッケージのクラスを使用する必要がある場合、A は B に依存していると言えます。現在のプロジェクトは、ローカルの倉庫に移動して、座標に従って依存する jar パッケージを見つけます。

    Maven ウェアハウスを通じて、spring-core はコンパイル時に 5 つの jar に依存していることがわかりますが、オプションのタグが構成されているため、依存関係として渡されるのは 1 つだけです。

    注: 依存関係を使用したくない場合、オプションのタグは独自のプロジェクトでのみ設定でき、継承されません (プロジェクトを jar パッケージとしてパッケージ化する場合、プロジェクトの一部の依存関係は継承されません)。他のプロジェクトから渡された場合、依存推移的除外を使用できます。

9.2 推移的な依存関係からの除外

    プログラムが正しいことを確認するために、繰り返される可能性のある間接的な依存関係を除外できる場合があります。

    依存関係の転送の除外 除外には 2 つのタイプがあります。
        1. 構成ファイルを介して依存関係を除外します。
        2. Maven は、重複する依存関係を自動的に除外します。

 例: C -> B -> A、C を実行したくないときに A をダウンロードしたくない場合は、<exclusions> タグを使用できます。

<dependencies>
    <dependency>
        <groupId>B</groupId>
        <artifactId>B</artifactId>
        <version>0.0.1</version>
        <exclusions>
            <exclusion>
                <!--被排除的依赖包坐标-->
                <groupId>A</groupId>
                <artifactId>A</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

    一般に、特別な状況がない限り、依存関係の除外を自分で作成することはありません。

    junit が依存する hamcrest-core:1.3 にバージョンの問題があり、junit が依存する hamcrest-core:1.3 が必要ない場合は、除外によって除外できます。

<!-- 引入junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency></dependency>注:依存関係を最初にエクスポートした元のパッケージと同じスコープ内にある必要があります。

    hamcrest-core の除外に頼った後、junit に問題があるはずです。バージョンに問題のない hamcrest-core を見つけて導入する必要があります。

<!-- 引入hamcrest-core -->
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-core</artifactId>
    <version>2.2</version>
</dependency>

除外に依存するシナリオ:

    1. プロジェクト A はプロジェクト B に依存しているが、プロジェクト A がプロジェクト B に完全に依存していない場合、つまり、プロジェクト A はプロジェクト B の機能の一部のみを使用しており、プロジェクトの機能のこの部分の実現はたまたま行われています。 B はプロジェクト C に依存する必要はありません。このとき、プロジェクト A はプロジェクト C への依存を除外する必要があります。

    2. バージョンの不一致: 渡された jar パッケージと実際に使用される jar の間にバージョンの不一致があり、プロジェクトが異常に実行されます。

    3. 公開モジュールをカプセル化する: 特定の jar で API を使用します。この jar に不要な推移的な依存関係がある場合は、依存関係を除外して渡すことができます。

9.3 依存関係の競合と解決

    依存関係の競合: プロジェクト A は、異なる依存関係配信パスを通じて X に依存しています.異なるパスで配信された X のバージョンが異なる場合、A は X パッケージのどのバージョンをインポートする必要がありますか?

    依存コンテンツには複数のバージョンがあるため、特定の POM が複数のバージョンに依存している場合、依存関係の競合と呼ばれます。


        依存関係の競合は、次の    2 つの原則に従います。
        2. 最初に宣言することが優先されます (POM.xml では、依存コンテンツ宣言の依存関係が先に来る方が優先されます。

検証例:

    次の依存関係を導入します。

<!-- spring核心包 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.18.RELEASE</version>
</dependency>
<!-- spring beans包 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.3.18.RELEASE</version>
</dependency>
<!-- spring环境包 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.18.RELEASE</version>
</dependency>

    我们会发现,我们引入了spring-core,但是beans、context以及context里面的aop等都依赖传递了spring-core。那么项目中会引入多个jar吗? 

    答案是否定的。实际上Maven只引入了一个spring-core。

 冲突解决方案:

    1、如果依赖路径的长度不同,则采取最短路径原则:
        A—>B—>C—>D—>E—>X(version 0.0.2)
        A—>F—>X(version 0.0.1)
        则A依赖于X(version 0.0.1)。

    2、依赖路径长度相同情况下,则采取最先申明原则:
        A—>E—>X(version 0.0.1)
        A—>F—>X(version 0.0.2)
        则在项目A的<depencies></depencies>中,E、F哪个先声明则A依赖哪条路径的X。

十、Maven生命周期

Maven的生命周期就是对所有的构建过程进行抽象和统一。包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。

Maven的生命周期是抽象的,即生命周期不做任何实际的工作,实际任务由插件完成,类似于设计模式中的模板方法。

10.1 三个生命周期

    Maven有三套相互独立的生命周期,分别是clean、default和site。
        1、clean:Clean Lifecycle在进行真正的构建之前进行一些清理工作。

        2. default: Default Lifecycle は、コンパイル、テスト、パッケージ化、展開などのコア部分を構築します。

        3. サイト: サイト ライフサイクルは、プロジェクト レポート、サイト、およびリリース サイトを生成します。

    各ライフサイクルにはいくつかのフェーズが含まれており、これらのフェーズは連続しており、後のフェーズは前のフェーズに依存し、ユーザーと Maven の間の最も直接的な対話はこれらのライフサイクルフェーズを呼び出します。

    ライフ サイクル ステージの前後の依存関係と比較して、3 つのライフ サイクル自体は互いに独立しており、ユーザーはクリーン ライフ サイクルの特定のステージのみを呼び出すか、デフォルト ライフ サイクルの特定のステージのみを呼び出すことができます。その他のライフ サイクル。

10.2 クリーンライフサイクル

    次の段階を含むクリーニング ライフ サイクル:
        1. 事前クリーニング: クリーニングの前に完了する必要があるいくつかの作業を実行します。

        2. clean: 以前のビルドで生成されたすべてのファイルを削除します。

        3. 清掃後: 清掃直後に完了する必要があるいくつかの作業を実行します。

    mvn clean の clean は上記の clean です. ライフサイクルでは, 特定のステージが実行されると, それ以前のすべてのステージが実行されます. つまり, mvn clean が実行されると, 次の 2 つのライフサイクルステージが実行されます. :
        pre -clean, clean
        
    mvn post-clean を実行すると、次の 3 つのライフ サイクル フェーズが実行されます:
        pre-clean、clean、post-clean
        
    これは Maven の非常に重要なルールであり、コマンドの入力を大幅に簡素化できますライン。

10.3 デフォルトのライフサイクル

これは、アプリケーションの構築に使用される Maven の主要なライフサイクルであり、次の 23 フェーズで構成されています。

ライフサイクル段階 説明
検証する (検証する) プロジェクトが正しく、プロジェクトのビルド プロセスを完了するために必要なすべての情報が含まれていることを確認します。
初期化(初期化) プロパティ値の設定など、ビルド状態を初期化します。
generate-sources (ソースコードの生成) コンパイル フェーズに含まれるソース コードを生成します。
プロセスソース (プロセスソースコード) たとえば、ソース コードを処理し、任意の値をフィルター処理します。
generate-resources (リソース ファイルの生成) プロジェクト バンドルに含まれるリソース ファイルを生成します。
process-resources (プロセス リソース ファイル) リソースをターゲット ディレクトリにコピーして処理します。これは、パッケージ化フェーズに最適な準備です。
コンパイル(コンパイル) プロジェクトのソース コードをコンパイルします。
process-classes (処理クラス ファイル) Java クラス ファイルのバイトコードの改善と最適化など、コンパイルによって生成されたファイルを処理します。
generate-test-sources (テスト ソース コードの生成) コンパイル フェーズに含まれるテスト ソース コードを生成します。
process-test-sources (プロセス テスト ソース) たとえば、テスト ソース コードを処理して、任意の値をフィルタリングします。
generate-test-resources (テスト リソース ファイルの生成) テスト用のリソース ファイルを作成します。
process-test-resources (プロセス テスト リソース ファイル) テスト リソースをターゲット ディレクトリにコピーして処理します。
test-compile (テスト ソース コードのコンパイル) テスト ソース コードをテスト ターゲット ディレクトリにコンパイルします。
process-test-classes (プロセス テスト クラス ファイル) テスト ソース コードをコンパイルして生成されたファイルを処理します。
テスト (テスト) 適切な単体テスト フレームワークを使用してテストを実行します (Juint はその 1 つです)。
prepare-package (パッケージの準備) 実際の梱包の前に、必要な操作を行って梱包の準備を行います。
パッケージ コンパイルされたコードを、JAR、WAR、または EAR ファイルなどの配布可能な形式のファイルにパッケージ化します。
pre-integration-test (統合テスト前) 統合テストを実行する前に、必要なアクションを実行します。たとえば、必要な環境を構築します。
統合テスト (統合テスト) プロジェクトを処理し、統合テストを実行できる環境にデプロイします。
post-integration-test (統合テスト後) 統合テストの実行が完了したら、必要なアクションを実行します。たとえば、統合テスト環境をクリーンアップします。
確認する (確認する) 任意のチェックを実行して、プロジェクト パッケージが有効であり、品質基準を満たしていることを確認します。
インストール プロジェクト パッケージをローカル リポジトリにインストールして、プロジェクト パッケージを他のローカル プロジェクトの依存関係として使用できるようにします。
配備 最終的なプロジェクト パッケージをリモート リポジトリにコピーして、他の開発者やプロジェクトと共有します。

重要な段階は次のとおりです。

ステージ 対処する 説明
検証する 検証プロジェクト プロジェクトが正しいこと、およびすべての必要な関連リソースが利用可能であることを確認します。これには、pom.xml ファイル ツリーの検証が含まれます。
コンパイル コンパイル コンパイルを実行 ソースコードのコンパイルはこの段階で行われます。
テスト テスト テスト JUnit などの適切な単体テスト フレームワークを使用してテストを実行します。これらのテストでは、パッケージ化と展開は必要ありません。
包装パッケージ パック pom.xml に記載されているパッケージで定義されているように、JAR/WAR パッケージを作成します。
確認する 診る パッケージが有効で、品質基準を満たしていることを確認するために、すべてのチェックが実行されます。
インストール インストール インストール 他のプロジェクトで使用するために、パッケージ化されたプロジェクトをローカル リポジトリにインストールします。
展開する 配備 最終的なプロジェクト パッケージをリモート ウェアハウスにコピーして、他の開発者やプロジェクトと共有します。

    任意のステージを実行すると、その前のすべてのステージが実行されます。これが、mvn install を実行すると、コードがコンパイル、テスト、およびパッケージ化される理由です。さらに、Maven のプラグイン メカニズムは Maven のライフ サイクルに完全に依存しているため、ライフ サイクルを理解することは非常に重要です。

実験:

    Maven Java プロジェクトを jar パッケージにパッケージ化し、それを別の Maven プロジェクトにインポートします。

    1. Maven Java プロジェクトで install を実行すると、Maven Java が jar パッケージにパッケージ化され、ローカル ウェアハウスにインストールされます。

    2. プロジェクト座標を通じて、ローカル倉庫にインストールされている jar をインポートします。

知らせ:

    両方のプロジェクトがプロジェクト レベルにあり、相互に依存する場合は、パッケージ化後に依存関係を介してインポートする必要があります。ただし、2 つのプロジェクトのモジュール レベルを直接インポートできる場合は、後で説明します。

2 つのライフサイクル フェーズを同時に実行します。

    mvn クリーン インストール

    Maven は最初に clean コマンドを実行し、次に install コマンドを実行します。

10.4 サイトのライフサイクル

    site生命周期的目的是建立和发布项目站点,Maven能够基于POM所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息。该生命周期包含如下阶段:
        1、pre-site:执行一些需要在生成站点文档之前完成的工作。

        2、site:生成项目的站点文档。

        3、post-site: 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备。

        4、site-deploy:将生成的站点文档部署到特定的服务器上。

十一、Maven项目拆分、继承、聚合

11.1 传统项目开发的问题

    使用Java技术开发的工程项目,无论是数据处理系统还是Web网站,随着项目的不断发展,需求的不断细化与添加,工程项目中的代码越来越多,包结构也越来越复杂这时候工程的进展就会遇到各种问题:

    1、传统的项目中,会将全部的业务都写到一个项目中,用一台Web应用服务器来部署。此时如果某一个业务操作造成服务器宕机,则全部的项目业务都不能访问。

    2、不同方面的代码之间相互耦合,这时候一系统出现问题很难定位到问题的出现原因,即使定位到问题也很难修正问题,可能在修正问题的时候引入更多的问题。

    3、多方面的代码集中在一个整体结构中,新入的开发者很难对整体项目有直观的感受,增加了新手介入开发的成本,需要有一个熟悉整个项目的开发者维护整个项目的结构(通常在项目较大且开发时间较长时这是很难做到的)。

    4、开发者对自己或者他人负责的代码边界很模糊,这是复杂项目中最容易遇到的,导致的结果就是开发者很容易修改了他人负责的代码且代码负责人还不知道,责任追踪很麻烦。

    将一个复杂项目拆分成多个模块是解决上述问题的一个重要方法,多模块的划分可以降低代码之间的耦合性(从类级别的耦合提升到jar包级别的耦合),每个模块都可以是自解释的(通过模块名或者模块文档),模块还规范了代码边界的划分,开发者很容易通过模块确定自己所负责的内容。

11.2 Maven项目拆分

    不知你有没有想过,一个好好的maven工程为什么要进行拆分呢?面对当今互联网+的行业,软件项目变得越来越庞大,复杂程度越来越高,这大大地提高了开发与管理的成本。而工程的拆分可以实现分模块开发与测试,亦可实现多线程开发与管理,在提高工程代码复用度的同时也提高了软件的开发速度与效率。

    例如,一个完整的早期开发好的crm项目,现在要使用maven工程对它进行拆分,这时候就可以将dao层拆解出来,形成一个独立的工程,同样service层以及web层也都进行这样的拆分。
    
    概念讲解和配图原文链接:https://blog.csdn.net/yerenyuan_pku/article/details/103680220

 理解工程拆分的好处:

    从上图可以看出,出现了一个问题,如果crm项目中dao层一旦出现bug需要修复时,erp项目与oa项目中的dao层也要做相应的修改,像这样重复的事情需要做三遍!实在是不可取,那怎么解决呢?

    这时,就可以将crm项目中的dao层拆解出来了,并形成一个独立的工程,然后每个项目都来复用这个独立的工程。

     把工程拆分成一个个独立的工程,将来要用到的时候就把它们的坐标给引进来就行了,这就有点类似于搭积木一样。

     把积木搭建成各种项目:

    对于一个大型的项目,如果我们直接作为一个工程开发,由于相互之间的依赖我们只能从头到尾由一组人开发,否则就会出现一个类好多人开发,相互更改的混乱局面,这个时候我们就将项目进行了横向和纵向的拆分。

    所谓的横向的拆分就是我们平常说的三层架构,将项目分成了web层,service层、dao层(web层也被叫做表现层,service层也被叫做业务层,dao层也被持久层),可以理解为将一个功能模块的不同调用过程进行了水平方向的拆分。

    所谓的纵向拆分就是将一个项目的多个功能模块进行了拆分,横向拆分后,每个功能模块进行了单独的开发之后,项目整合的时候就需要有一个能够整合这些项目或者模块的工程,这就是所谓聚合工程的意义。

11.3 Maven项目聚合

    项目开发通常是分组分模块开发的,每个模块开发完成后,要运行整个工程需要将每个模块聚合在一起运行,比如,dao、service以及web这三个工程最终会打一个独立的war包运行。

    就拿一个完整的早期开发好的crm项目来说,把crm项目拆成多个子模块后,独立运行各个模块是无法完成软件项目的要求的,只有把它们都整合起来,分工合作才能完成工作。因此需要父工程来管理各个子模块,把它们聚合在一起运行,即把crm_dao、crm_service以及crm_web这三个工程打成一个独立的可运行的war包。

     这有点像把汽车的各个零部件组装起来,变成一辆可以行驶的车。以下是一堆的汽车各个零部件。

     将汽车的各个零部件组装起来,可以变成一辆可以行驶的车。

     建立聚合工程需要注意:
        1、该聚合项目本身也做为一个Maven项目,它必须有自己的POM。
        2、它的打包方式必须为:pom。
        3、引入了新的元素:modules---module。
        4、版本:聚合模块的版本和被聚合模块版本一致。
        5、relativePath:每个module的值都是一个当前POM的相对目录。
            指定查找该父项目pom.xml的(相对)路径。默认顺序:relativePath > 本地仓库 > 远程仓库。
            没有relativePath标签等同…/pom.xml, 即默认从当前pom文件的上一级目录找。
        6、目录名称:为了方便的快速定位内容,模块所处的目录应当与其artifactId一致(Maven约定而不是硬性要求),总之,模块所处的目录必须和<module>模块所处的目录</module>相一致。
        7、聚合模块减少的内容:聚合模块的内容仅仅是一个pom.xml文件,它不包含src/main/Java、src/test/java等目录,因为它只是用来帮助其它模块构建的工具,本身并没有实质的内容。
        8、聚合模块和子模块的目录:他们可以是父子类,也可以是平行结构,当然如果使用平行结构,那么聚合模块的POM也需要做出相应的更改。
        9、如果聚合项目的子模块新建完成后进行了删除操作,一定要在聚合项目中pom.xml中的modules选项卡中将这个子模块进行删除

<modules>
    <module>../maven-util</module>
    <module>../maven-entity</module>
    <module>../maven-dao</module>
    <module>../maven-service</module>
    <module>../maven-web</module>
</modules>

总结:

	对于聚合模块来说,它知道有哪些被聚合的模块,而对于被聚合的模块来说,它们不知道被谁聚合了,也不知道它的存在

	对于继承关系的父POM来说,它不知道自己被哪些子模块继承了,对于子POM来说,它必须知道自己的父POM是谁

	在一些最佳实践中我们会发现:一个POM既是聚合POM,又是父POM,这么做主要是为了方便。

11.4 Maven项目的继承

    类似Java中类的继承,都是为了消除重复。子类继承父类,父类里有的方法和属性在子类中就不需要再定义和实现了,使用的时候直接调用父类的就可以了。我们把crm项目拆分后,将会有一个父工程(例如crm)和若干个子工程(例如crm_dao、crm_service、crm_web),子工程中要用到的依赖都可以在父工程的pom.xml文件中进行依赖管理,将来子工程在开发的时候就不需要再定义版本了,这样做的目的是为了方便管理。

    继承除了能够避免重复,还有一个好处就是让项目更加安全。

    继承时需要注意:
        1、说到继承肯定是一个父子结构,那么我们在聚合项目中来创建一个parent project。
        2、<packaging>: 作为父模块的POM,其打包类型也必须为POM。
        3、结构:父模块只是为了帮助我们消除重复,所以它也不需要src/main/java、src/test/java等目录。
        4、新的元素:<parent>,它是被用在子模块中的。
        5.<parent>元素的属性:<relativePath>: 表示父模块POM的相对路径,在构建的时候,Maven会先根据relativePath检查父POM,如果找不到,再从本地仓库查找。
        6、relativePath的默认值:../pom.xml。
        7、子模块省略groupId和version: 使用了继承的子模块中可以不声明groupId和version, 子模块将隐式的继承父模块的这两个元素。

十二、Maven综合案例

    对于一个大型的项目,大部分情况下都是将一个项目的多个功能模块进行了拆分,拆分后,每个功能模块进行了单独的开发之后,项目整合的时候就需要有一个能够整合这些项目或者模块的工程,这就是所谓聚合工程的意义。

    我们现在不写那么多模块,把一个学生模块按照类的功能(三层架构)拆分成一个个模块,然后来体会项目的拆分、继承、聚合。

12.1 搭建项目结构

12.1.1 创建管理父项目

    1、创建管理父项目(maven-student),Maven管理类项目的打包方式为pom。管理类父项目只是用来帮助其它模块构建的工具,本身并没有实质的内容,可以删除src目录。

     2、创建完成之后,做如下配置:
        2.1 修改项目打包方式为pom。
        2.2 依赖版本管理。
        2.3 依赖管理

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.maven</groupId>
    <artifactId>maven-student</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 1、修改为管理项目,packaging为pom -->
    <packaging>pom</packaging>

    <!-- 2、依赖版本管理:对项目中所有的依赖的版本进行管理 -->
    <properties>
        <!-- properties里面可以定义自定义标签 -->
        <servlet.version>3.0.1</servlet.version>
        <jsp.version>2.1</jsp.version>
        <jstl.version>1.2</jstl.version>
        <junit.version>4.12</junit.version>
        <mysql.version>5.1.49</mysql.version>
    </properties>

    <!-- 3、依赖管理:对项目中所有的依赖进行管理 -->
    <!-- 依赖管理不会引入依赖 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <!-- maven表达式获取版本 -->
                <version>${servlet.version}</version>
                <scope>provided</scope>
            </dependency>

            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>${jsp.version}</version>
                <scope>provided</scope>
            </dependency>

            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>${jstl.version}</version>
            </dependency>

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>
</project>

12.1.2 创建工具类子项目

    1、创建工具类子项目(maven-student-util)。

    注意:创建子项目的时候,创建的是一个Module。父项目右键 -> New -> Module,Module也是Maven项目。

     2、maven-student-util子模块的pom.xml文件里面会自动添加parent标签,标识当前模块的父项目或父模块。并且父项目的pom.xml文件中会自动添加modules,标识聚合的模块。

<!-- Maven继承:子模块中的parent表示当前模块的父项目或父模块 -->
<parent>
    <artifactId>maven-student</artifactId>
    <groupId>com.maven</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<!-- 父项目管理的子模块列表:聚合 -->
<modules>
    <module>maven-student-util</module>
    <module>maven-student-entity</module>
</modules>

    3、引入当前模块需要用到的依赖。

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <!-- Maven继承:子模块中的parent表示当前模块的父项目或父模块 -->
    <parent>
        <artifactId>maven-student</artifactId>
        <groupId>com.maven</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <!-- 子模块可以继承groupId和version等,但是artifactId不能继承 -->
    <artifactId>maven-student-util</artifactId>

    <!-- 配置当前模块的依赖 -->
    <dependencies>
        <!-- 子模块中配置依赖无需再配置版本,都是参照父项目的版本号 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

12.1.3 创建实体类子项目

    创建实体类子项目(maven-student-entity),并引入当前模块需要用到的依赖。

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>maven-student</artifactId>
        <groupId>com.maven</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>maven-student-entity</artifactId>

    <!-- 配置当前模块的依赖 -->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

12.1.4 创建持久层子项目

    创建持久层子项目(maven-student-dao),并引入当前模块需要用到的依赖。

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>maven-student</artifactId>
        <groupId>com.maven</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>maven-student-dao</artifactId>

    <!-- 配置当前模块的依赖 -->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 持久层需要用到工具类,那么就需要引入自己的模块,无需安装 -->
        <!-- 这里没有定义版本,是因为在父项目中对自己的模块进行依赖管理了 -->
        <dependency>
            <groupId>com.maven</groupId>
            <artifactId>maven-student-util</artifactId>
        </dependency>
        <dependency>
            <groupId>com.maven</groupId>
            <artifactId>maven-student-entity</artifactId>
        </dependency>
    </dependencies>

</project>

    在父项目中对自己的模块进行依赖管理,子模块中就不需要定义版本。

<dependency>
    <groupId>com.maven</groupId>
    <artifactId>maven-student-util</artifactId>
    <!-- Maven表达式中的对象project -->
    <version>${project.version}</version>
</dependency>

<dependency>
    <groupId>com.maven</groupId>
    <artifactId>maven-student-entity</artifactId>
    <version>${project.version}</version>
</dependency>

12.1.5 创建业务层子项目

    创建业务层子项目(maven-student-service),并引入当前模块需要用到的依赖。

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>maven-student</artifactId>
        <groupId>com.maven</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>maven-student-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.maven</groupId>
            <artifactId>maven-student-dao</artifactId>
        </dependency>
    </dependencies>

</project>

12.1.6 创建表现层子项目

    1、创建表现层子项目(maven-student-web),修改项目打包方式为war。

    2、引入当前模块需要用到的依赖

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>maven-student</artifactId>
        <groupId>com.maven</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>maven-student-web</artifactId>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>com.maven</groupId>
            <artifactId>maven-student-service</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
    </dependencies>

</project>

最后,父项目的pom.xml文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.maven</groupId>
    <artifactId>maven-student</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 父项目管理的子模块列表:聚合 -->
    <modules>
        <module>maven-student-util</module>
        <module>maven-student-entity</module>
        <module>maven-student-dao</module>
        <module>maven-student-service</module>
        <module>maven-student-web</module>
    </modules>
    <!-- 1、修改为管理项目,packaging为pom -->
    <packaging>pom</packaging>

    <!-- 2、依赖版本管理:对项目中所有的依赖的版本进行管理 -->
    <properties>
        <!-- properties里面可以定义自定义标签 -->
        <servlet.version>3.0.1</servlet.version>
        <jsp.version>2.1</jsp.version>
        <jstl.version>1.2</jstl.version>
        <junit.version>4.12</junit.version>
        <mysql.version>5.1.38</mysql.version>
    </properties>

    <!-- 3、依赖管理:对项目中所有的依赖进行管理 -->
    <!-- 依赖管理不会引入依赖 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <!-- maven表达式获取版本 -->
                <version>${servlet.version}</version>
                <scope>provided</scope>
            </dependency>

            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>${jsp.version}</version>
                <scope>provided</scope>
            </dependency>

            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>${jstl.version}</version>
            </dependency>

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <dependency>
                <groupId>com.maven</groupId>
                <artifactId>maven-student-util</artifactId>
                <!-- Maven表达式中的对象project -->
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>com.maven</groupId>
                <artifactId>maven-student-entity</artifactId>
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>com.maven</groupId>
                <artifactId>maven-student-dao</artifactId>
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>com.maven</groupId>
                <artifactId>maven-student-service</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

12.1.7 关于modules

    modules可以加,也可以不加。但是modules有一个好处,当定义modules之后,我们通过父项目执行生命周期,所有的子module都会执行对应的生命周期。

    注意:我们如果模块之间没有依赖,那么按照聚合配置的顺序来执行;如果有了依赖,肯定是被依赖的先构建。

通过父项目执行编译:

12.2 项目后端实现

12.2.1 创建学生表

    在MySQL数据库的test库下创建学生表,学生表字段如下:

12.2.2 DBUtils工具类实现

    在工具类子项目中创建com.maven.util包,创建DBUtils工具类。

DBUtils代码如下:

package com.maven.util;

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

/*
 * JDBC工具类的高度封装
 * */
public class DBUtils {
    /*
     * private 为了不让外部调用
     * static 因为要在static代码块或方法中使用
     * final 不允许修改
     * */
    private static final String driverName = "com.mysql.jdbc.Driver";
    private static final String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8";
    private static final String userName = "root";
    private static final String userPwd = "root";
    private static Connection connection;
    private static PreparedStatement preparedStatement;
    private static ResultSet resultSet;

    /*
     * 注册数据库驱动,注册驱动只需要执行一次即可
     *   static静态代码块,在类加载的时候有且仅执行一次
     * */
    static {
        try {
            Class.forName(driverName);
        } catch (ClassNotFoundException e) {
            System.out.println("数据库驱动加载失败!");
        }
    }

    /*
     * 获取连接
     * */
    public static Connection getConnection() {
        try {
            connection = DriverManager.getConnection(url, userName, userPwd);
        } catch (SQLException throwables) {
            System.out.println("数据库连接获取失败!");
        }
        return connection;
    }

    /*
     * 查询数据的方法
     *   参数:
     *       String sql,要执行的sql语句
     *       List list,sql的参数
     *   返回值:
     *       不能返回ResultSet,因为资源释放之后,结果集不能在操作
     *       把结果集里面的数据用另外一种形式返回即可 List<Map<String,String>>
     * */
    public static List<Map<String, String>> query(String sql, List list) {
        List<Map<String, String>> resultList = new ArrayList<>();
        // 每次执行查询,都要获取得到连接
        getConnection();

        // 获取执行SQL语句的PrepareStatement对象
        try {
            preparedStatement = connection.prepareStatement(sql);
            // 给sql设置参数
            for (int i = 0; i < list.size(); i++) {
                // 因为不知道参数的类型,所以我们直接使用setObject(占位符索引,值); 占位符索引从1开始
                preparedStatement.setObject(i + 1, list.get(i));
            }

            // 执行查询
            resultSet = preparedStatement.executeQuery();

            // 获取结果集对应的结构
            ResultSetMetaData metaData = resultSet.getMetaData();

            // 把resultSet转换为List<Map<String,String>>
            while (resultSet.next()) {
                // resultSet里面每有一条数据,就创建一个Map集合
                Map<String, String> map = new HashMap<>();
                // map里面的key是列名,value是列对应的值
                // 结果集里面有多少列,就向map里面存储多少对值
                for (int i = 1; i <= metaData.getColumnCount(); i++) {
                    map.put(metaData.getColumnName(i), resultSet.getString(i));
                }
                // 把map存储到list中
                resultList.add(map);
            }

        } catch (SQLException throwables) {
            System.out.println("SQL语句异常");
        } finally {
            close();
        }
        return resultList;
    }

    /*
     * 增删改的方法
     *   返回值: int类型,表示增、删、改的条目数
     *   参数:
     *       String sql,要执行的sql语句
     *       List list,sql的参数
     * */
    public static int update(String sql, List list) {
        int count = 0;
        // 每次执行更改操作,都要获取得到连接
        getConnection();

        // 获取执行SQL语句的PrepareStatement对象
        try {
            preparedStatement = connection.prepareStatement(sql);
            // 给sql设置参数
            for (int i = 0; i < list.size(); i++) {
                // 因为不知道参数的类型,所以我们直接使用setObject(占位符索引,值); 占位符索引从1开始
                preparedStatement.setObject(i + 1, list.get(i));
            }

            count = preparedStatement.executeUpdate();

        } catch (SQLException throwables) {
            System.out.println("SQL语句异常");
        } finally {
            close();
        }
        return count;
    }


    /*
     * 释放资源
     * */
    public static void close() {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                System.out.println("结果集关闭失败");
            }
        }

        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException throwables) {
                System.out.println("Statement关闭失败");
            }
        }

        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException throwables) {
                System.out.println("连接关闭失败!");
            }
        }
    }
}

12.2.3 学生实体类实现

    在实体类子项目中创建com.maven.entity包,创建StudentEntity实体类。

StudentEntity代码如下:

package com.maven.entity;

/**
 * 学生实体类
 */
public class StudentEntity {
    private Integer id;
    private String name;
    private String sex;
    private String major;

    public StudentEntity() {
    }

    public StudentEntity(Integer id, String name, String sex, String major) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.major = major;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }

    @Override
    public String toString() {
        return "StudentEntity{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", major='" + major + '\'' +
                '}';
    }
}

12.2.4 学生持久层实现

    在持久层子项目中创建com.maven.dao包,创建StudentDao接口。

    在持久层子项目中创建com.maven.dao.impl包,创建StudentDaoImpl实现类。

    注:我们仅仅实现简单的一套CRUD即可。

StudentDao接口代码如下:

package com.maven.dao;

import com.maven.entity.StudentEntity;

import java.util.List;
import java.util.Map;

/*
 * 学生DAO接口
 */
public interface StudentDao {
    /*
     * 新增学生的方法
     * @param studentEntity 包含新增学生的信息实体类
     * @return int 实际插入的数量
     */
    public abstract int insert(StudentEntity studentEntity);

    /*
     * 删除学生的方法
     * @param id 删除学生的id
     * @return int 实际删除的数量
     */
    public abstract int delete(Integer id);

    /*
     * 修改学生的方法
     * @param studentEntity 包含修改学生的信息实体类
     * @return int
     */
    public abstract int update(StudentEntity studentEntity);

    /*
     * 根据id查询学生的方法
     * @param id 查询学生的id
     * @return StudentEntity 查询到的学生信息
     */
    public abstract List<Map<String, String>> query(Integer id);

    /*
     * 查询所有学生的方法
     * @return List<StudentEntity> 查询到的所有数据
     */
    public abstract List<Map<String, String>> queryAll();
}

StudentDaoImpl实现类代码如下:

package com.maven.dao.impl;

import com.maven.dao.StudentDao;
import com.maven.entity.StudentEntity;
import com.maven.util.DBUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 学生DAO接口实现类
 */
public class StudentDaoImpl implements StudentDao {

    @Override
    public int insert(StudentEntity studentEntity) {
        String sql = "insert into student(name,sex,major) values (?,?,?)";
        List list = Arrays.asList(studentEntity.getName(), studentEntity.getSex(), studentEntity.getMajor());
        return DBUtils.update(sql, list);
    }

    @Override
    public int delete(Integer id) {
        String sql = "delete from student where id = ?";
        List list = Arrays.asList(id);
        return DBUtils.update(sql, list);
    }

    @Override
    public int update(StudentEntity studentEntity) {
        String sql = "update student set name = ?,sex=?,major=? where id = ?";
        List list = Arrays.asList(studentEntity.getName(), studentEntity.getSex(), studentEntity.getMajor(),studentEntity.getId());
        return DBUtils.update(sql, list);
    }

    @Override
    public List<Map<String, String>> query(Integer id) {
        String sql = "select * from student where id = ?";
        List list = Arrays.asList(id);
        return DBUtils.query(sql,list);
    }

    @Override
    public List<Map<String, String>> queryAll() {
        String sql = "select * from student";
        List list = new ArrayList();
        return DBUtils.query(sql,list);
    }
}

12.2.5 学生业务层实现

    在业务层子项目中创建com.maven.service包,创建StudentService类。

StudentService类代码如下:

package com.maven.service;

import com.maven.dao.StudentDao;
import com.maven.dao.impl.StudentDaoImpl;
import com.maven.entity.StudentEntity;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 学生的业务逻辑层
 */
public class StudentService {
    //创建DAO实现类对象
    private StudentDao studentDao = new StudentDaoImpl();

    public int insert(StudentEntity studentEntity) {
        return studentDao.insert(studentEntity);
    }

    public int delete(Integer id) {
        return studentDao.delete(id);
    }

    public int update(StudentEntity studentEntity) {
        return studentDao.update(studentEntity);
    }

    public StudentEntity query(Integer id) {
        StudentEntity studentEntity = null;
        List<Map<String, String>> query = studentDao.query(id);
        if (query.size() > 0) {
            Map<String, String> stringMap = query.get(0);
            studentEntity = new StudentEntity();
            studentEntity.setId(Integer.parseInt(stringMap.get("id")));
            studentEntity.setName(stringMap.get("name"));
            studentEntity.setSex(stringMap.get("sex"));
            studentEntity.setMajor(stringMap.get("major"));
        }

        return studentEntity;
    }

    public List<StudentEntity> queryAll() {
        List<StudentEntity> list = new ArrayList<>();
        List<Map<String, String>> query = studentDao.queryAll();
        for (int i = 0; i < query.size(); i++) {
            Map<String, String> stringMap = query.get(0);
            StudentEntity studentEntity = new StudentEntity();
            studentEntity.setId(Integer.parseInt(stringMap.get("id")));
            studentEntity.setName(stringMap.get("name"));
            studentEntity.setSex(stringMap.get("sex"));
            studentEntity.setMajor(stringMap.get("major"));
            list.add(studentEntity);
        }
        return list;
    }
}

12.2.6 学生表现层Servlet实现

查询所有学生的Servlet:

package com.maven.servlet;

import com.maven.entity.StudentEntity;
import com.maven.service.StudentService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * 查询所有学生的Servlet
 */
@WebServlet("/student/list")
public class StudentQueryAllServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        StudentService studentService = new StudentService();
        List<StudentEntity> list = studentService.queryAll();
        System.out.println(list);
        req.setAttribute("stuList", list);
        System.out.println(req.getServletContext().getContextPath());
        //在请求转发中,/表示项目根目录
        req.getRequestDispatcher("/student/list.jsp").forward(req, resp);

    }
}

根据id查询学生的Servlet:

package com.maven.servlet;

import com.maven.entity.StudentEntity;
import com.maven.service.StudentService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 根据学生id查询学生的Servlet
 */
@WebServlet("/student/query")
public class StudentQueryServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        //获取查询学生的id
        int id = Integer.parseInt(req.getParameter("id"));

        StudentService studentService = new StudentService();
        StudentEntity studentEntity = studentService.query(id);

        req.setAttribute("editStudentInfo", studentEntity);
        req.getRequestDispatcher("/student/edit.jsp").forward(req, resp);

    }
}

添加学生的Servlet:

package com.maven.servlet;

import com.maven.entity.StudentEntity;
import com.maven.service.StudentService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 添加学生的Servlet
 */
@WebServlet("/student/add")
public class StudentAddServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        String name = req.getParameter("name");
        String sex = req.getParameter("sex");
        String major = req.getParameter("major");

        StudentEntity studentEntity = new StudentEntity(null, name, sex, major);

        StudentService studentService = new StudentService();
        int i = studentService.insert(studentEntity);

        if (i > 0) {
            req.setAttribute("msg", "添加成功!");
        } else {
            req.setAttribute("msg", "添加失败!");
        }

        req.getRequestDispatcher("/student/list").forward(req, resp);
    }
}

删除学生的Servlet:

package com.maven.servlet;

import com.maven.entity.StudentEntity;
import com.maven.service.StudentService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 删除学生的Servlet
 */
@WebServlet("/student/delete")
public class StudentDeleteServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        //获取删除学生的id
        int id = Integer.parseInt(req.getParameter("id"));
        System.out.println("删除学生的id:"+id);

        StudentService studentService = new StudentService();
        int i = studentService.delete(id);

        if (i > 0) {
            req.setAttribute("msg", "删除成功!");
        } else {
            req.setAttribute("msg", "删除失败!");
        }

        req.getRequestDispatcher("/student/list").forward(req, resp);
    }
}

修改学生的Servlet:

package com.maven.servlet;

import com.maven.entity.StudentEntity;
import com.maven.service.StudentService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 修改学生的Servlet
 */
@WebServlet("/student/update")
public class StudentUpdateServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        int id = Integer.parseInt(req.getParameter("id"));
        String name = req.getParameter("name");
        String sex = req.getParameter("sex");
        String major = req.getParameter("major");

        StudentEntity studentEntity = new StudentEntity(id, name, sex, major);
        System.out.println(studentEntity);

        StudentService studentService = new StudentService();
        int i = studentService.update(studentEntity);

        if (i > 0) {
            req.setAttribute("msg", "修改成功!");
        } else {
            req.setAttribute("msg", "修改失败!");
        }

        req.getRequestDispatcher("/student/list").forward(req, resp);
    }
}

12.3 项目前端实现

目录结构如下:

12.3.1 项目首页实现

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>这里是项目首页</h1>
    <a href="${pageContext.request.contextPath}/student/list">查询所有学生信息</a>
</body>
</html>

12.3.2 学生列表页实现

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
    <style>
        table, td, th {
            border: 1px solid black;
            border-collapse: collapse;
        }

        table {
            width: 600px;
        }

        tr {
            height: 40px;
        }
    </style>
</head>
<body>
    <h2>所有学生的信息: ${msg}</h2>
    <table>
        <tr>
            <th>学号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>专业</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${stuList}" var="stu">
            <tr>
                <td>${stu.id}</td>
                <td>${stu.name}</td>
                <td>${stu.sex}</td>
                <td>${stu.major}</td>
                <td>
                    <a href="${pageContext.request.contextPath}/student/delete?id=${stu.id}">删除</a>
                        <%--先根据id查询学生信息,然后跳转到修改页面--%>
                    <a href="${pageContext.request.contextPath}/student/query?id=${stu.id}">修改</a>
                </td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

12.3.3 修改学生页面实现

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>修改学生信息</h2>
    <form action="${pageContext.request.contextPath}/student/update" method="post">
        <p>
            学号: <input type="text" name="id" value="${editStudentInfo.id}" readonly>
        </p>
        <p>
            姓名: <input type="text" name="name" value="${editStudentInfo.name}">
        </p>
        <p>
            性别:
            <c:if test="${editStudentInfo.sex == '男'}">
                <input type="radio" name="sex" value="男" checked> 男
                <input type="radio" name="sex" value="女"> 女
            </c:if>
            <c:if test="${editStudentInfo.sex == '女'}">
                <input type="radio" name="sex" value="男"> 男
                <input type="radio" name="sex" value="女" checked> 女
            </c:if>
        </p>
        <p>
            专业: <input type="text" name="major" value="${editStudentInfo.major}">
        </p>
        <p>
            <button type="submit">修改</button>
        </p>
    </form>
</body>
</html>

12.3.4 添加学生页面实现

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>添加学生信息</h2>
    <form action="${pageContext.request.contextPath}/student/add" method="post">
        <p>
            姓名: <input type="text" name="name">
        </p>
        <p>
            性别:
            <input type="radio" name="sex" value="男" checked> 男
            <input type="radio" name="sex" value="女"> 女

        </p>
        <p>
            专业: <input type="text" name="major">
        </p>
        <p>
            <button type="submit">新增</button>
        </p>
    </form>
</body>
</html>

おすすめ

転載: blog.csdn.net/ligonglanyuan/article/details/123988592