【Maven入門から実戦までのチュートリアル】第8章 Mavenプロジェクトの分割、継承、集約、対応Maven総合ケース

1. Maven プロジェクトの分割、継承、集約

1.1 従来のプロジェクト開発の問題点

    データ処理システムであろうと Web サイトであろうと、Java テクノロジを使用して開発されたエンジニアリング プロジェクト。プロジェクトの継続的な開発、要件の継続的な改良と追加、プロジェクト内のコードの増加、パッケージ構造の複雑化が伴います。 . プロジェクトの進行にさまざまな問題が発生する場合:

    1. 従来のプロジェクトでは、すべてのサービスが 1 つのプロジェクトに書き込まれ、Web アプリケーション サーバーで展開されます。このとき、何らかの業務によりサーバーがダウンすると、プロジェクトのすべてのサービスにアクセスできなくなります。

    2. さまざまな側面のコードが相互に結合している このとき、システムに問題が発生した場合、問題の原因を突き止めることは困難です. 問題が突き止められたとしても、問題を修正することは困難です. 、問題が修正されると、さらに問題が発生する可能性があります。

    3. コードの多くの側面が全体構造に集中している. 新人開発者はプロジェクト全体を直感的に把握することが難しく, 初心者が開発に介入するコストが高くなる. プロジェクト全体に精通している開発者はプロジェクト全体の構造を維持するために必要です (プロジェクトが大きく、開発時間が長い場合、これはしばしば困難です)。

    4. 開発者が責任を負うコードの境界は非常に曖昧であり、これは複雑なプロジェクトで最も遭遇しやすい. その結果、開発者は、コードの担当者なしで、他の人が担当するコードを簡単に変更できます.責任追跡 非常に面倒です。

    複雑なプロジェクトを複数のモジュールに分割することは、上記の問題を解決するための重要な方法です. 複数のモジュールを分割することで、コード間の結合 (クラスレベルの結合から jar パッケージレベルの結合まで) を減らすことができます. -説明 (モジュール名またはモジュールのドキュメントによる). モジュールはまた、コード境界の分割を規制します. 開発者は、モジュールを通じて自分が何を担当しているかを簡単に判断できます.

1.2 Maven プロジェクトの分割

    優れた Maven プロジェクトを分割する必要がある理由について考えたことはありますか? 今日のインターネット + 業界に直面して、ソフトウェア プロジェクトは大規模かつ複雑になり、開発と管理のコストが大幅に増加しています。プロジェクトの分割により、サブモジュールの開発とテスト、およびマルチスレッドの開発と管理を実現できます。これにより、エンジニアリング コードの再利用が向上するだけでなく、ソフトウェア開発の速度と効率も向上します。

    例えば、完全な初期開発の crm プロジェクトは、maven プロジェクトを使用して分割する必要があります. この時点で、dao 層を分解して独立したプロジェクトを形成できます. サービス層と Web 層についても同様です. 分割.
    
    概念説明と写真の原文へのリンク: https://blog.csdn.net/yerenyuan_pku/article/details/103680220

 プロジェクト分割の利点を理解する:

    上記の図からわかるように、問題があります.crm プロジェクトの dao 層にバグがあり、修復する必要がある場合は、erp プロジェクトと oa プロジェクトの dao 層もそれに応じて変更する必要があります。このようなことを 3 回繰り返す必要があります。望ましくないので、どうすれば解決できますか?

    このとき、crm プロジェクトの dao レイヤーを分解して独立したプロジェクトを形成し、各プロジェクトでこの独立したプロジェクトを再利用できます。

     プロジェクトを個々のプロジェクトに分割し、将来必要になったときに座標をインポートするだけです。これはビルディング ブロックに少し似ています。

     ブロックをさまざまなプロジェクトに構築します。

    大規模なプロジェクトの場合、直接プロジェクトとして開発すると、相互依存のために最初から最後まで数人のグループでしか開発できません。プロジェクトを水平方向と垂直方向に分割します。

    いわゆる水平分割は、通常、プロジェクトを Web レイヤー、サービス レイヤー、DAO レイヤーに分割する 3 層アーキテクチャと呼ばれるものです (Web レイヤーはプレゼンテーション レイヤーとも呼ばれ、サービス レイヤーはビジネス レイヤーとも呼ばれます)。層であり、dao 層は永続化層とも呼ばれます。)、これは、関数モジュールの異なる呼び出しプロセスを水平方向に分割すると理解できます。

    いわゆる縦分割とは、プロジェクトの複数の機能モジュールを分割することで、横分割後は各機能モジュールが独立して開発されており、プロジェクトを統合する際には、これらのプロジェクトまたはモジュールを統合できるプロジェクトが必要です。工学、これはいわゆる集合工学の意味です。

1.3 Maven プロジェクトの集約

    プロジェクト開発は通常、グループとモジュールで開発されます. 各モジュールの開発が完了したら, プロジェクト全体を実行するために各モジュールを集約して一緒に実行する必要があります. たとえば, dao, service, web の 3 つのプロジェクトは最終的には独立した war パッケージとしてパッケージ化されています。

    初期に開発された完全な crm プロジェクトを例にとると、crm プロジェクトを複数のサブモジュールに分解した後、各モジュールを単独で実行することは、ソフトウェア プロジェクトの要件を満たすことができません.それらをすべて統合することによってのみ、分業によって作業を完了することができます.と協力。したがって、親プロジェクトは、各サブモジュールを管理し、それらを一緒に実行する必要があります。つまり、3 つのプロジェクト crm_dao、crm_service、および crm_web を独立した実行可能な war パッケージにパッケージ化する必要があります。

     これは、車の部品を組み合わせて、運転できる車にするようなものです。以下は、車のさまざまな部分の束です。

     車の各パーツを組み立てて、走れる車に変身させます。

     集約プロジェクトの確立には注意が必要です。
        1. 集約プロジェクト自体も Maven プロジェクトであり、独自の POM が必要です。
        2. パッケージング方法は、pom である必要があります。
        3. モジュール --- モジュールという新しい要素が導入されました。
        4. バージョン: 集約モジュールのバージョンは、集約モジュールのバージョンと一致しています。
        5. relativePath: 各モジュールの値は、現在の POM の相対ディレクトリです。
            この親プロジェクトの pom.xml を見つけるための (相対) パスを指定します。デフォルトの順序: relativePath > ローカル倉庫 > リモート倉庫。
            .../pom.xml に相当する relativePath タグはありません。つまり、デフォルトでは現在の pom ファイルの上位ディレクトリから検索されます。
        6. ディレクトリ名: コンテンツを便利にすばやく見つけるために、モジュールが配置されているディレクトリは、artifactId と一致している必要があります (厳格な要件ではなく、Maven の合意) 要するに、モジュールが配置されているディレクトリは、 <module>モジュールが置かれているディレクトリと同じ</module > 一貫性があります。
        7. 集約モジュールのコンテンツの削減: 集約モジュールのコンテンツは pom.xml ファイルのみであり、src/main/java、src/test/java およびその他のディレクトリは含まれていません。これは単なる支援ツールであるためです。他のモジュールがビルドされ、それ自体には実際のコンテンツはありません。
        8. 集約モジュールとサブモジュールのディレクトリ: 親子クラスまたは並列構造にすることができます. もちろん、並列構造を使用する場合は、集約モジュールの POM もそれに応じて変更する必要があります.
        9. 集計プロジェクトのサブモジュールを作成後に削除する場合は、集計プロジェクトの pom.xml のモジュール タブで削除する必要があります。

<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,这么做主要是为了方便。

1.4 Maven プロジェクトの継承

    Java でのクラスの継承と同様に、すべては重複を排除するためのものです。サブクラスは親クラスを継承し、親クラスのメソッドとプロパティをサブクラスで定義して実装する必要はなく、使用時に親クラスを直接呼び出すだけで十分です。crm プロジェクトを分割すると、親プロジェクト (crm など) といくつかのサブプロジェクト (crm_dao、crm_service、crm_web など) ができ、サブプロジェクトで使用される依存関係は pom に含めることができます。親プロジェクトの xml ファイル 依存関係管理により、将来サブプロジェクトを開発する際にバージョンを定義する必要がなくなり、管理が容易になります。

    継承には、重複を避けるだけでなく、プロジェクトをより安全にするという利点もあります。

    継承時の注意事項
        1. 継承に関しては親子構造でなければならないので、集約プロジェクトに親プロジェクトを作成します。
        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 を宣言することはできず、サブモジュールは親モジュールのこれら 2 つの要素を暗黙的に継承します。

二、Maven総合ケース

    大規模なプロジェクトでは、ほとんどの場合、プロジェクトの複数の機能モジュールが分割されます.分割後、各機能モジュールは独立して開発されます.プロジェクトが統合されると、これらのプロジェクトまたはモジュールのエンジニアリングが必要になります.いわゆるアグリゲーションエンジニアリングの意味です。

    今はそれほど多くのモジュールを書くことはありませんが、学生のモジュールをクラスの機能に応じてモジュールに分割し (3 層アーキテクチャ)、プロジェクトの分割、継承、および集約を経験します。

2.1 プロジェクト構造の構築

2.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>

2.1.2 ツール クラス サブプロジェクトの作成

    1. ツール サブプロジェクト (maven-student-util) を作成します。

    注: サブプロジェクトを作成すると、モジュールが作成されます。親プロジェクトを右クリック->新規->モジュール、モジュールもMavenプロジェクトです。

     2. maven-student-util サブモジュールの pom.xml ファイルは、現在のモジュールの親プロジェクトまたは親モジュールを識別する親タグを自動的に追加します。また、モジュールは親プロジェクトの pom.xml ファイルに自動的に追加され、集約されたモジュールを識別します。

<!-- 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>

2.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>

2.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>

2.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>

2.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>

2.1.7 モジュールについて

    モジュールを追加することも、追加しないこともできます。ただし、モジュールには利点があります. モジュールを定義した後、親プロジェクトを通じてライフサイクルを実行し、すべてのサブモジュールが対応するライフサイクルを実行します.

    注: モジュール間に依存関係がない場合は、集約構成の順序でそれらを実行します。依存関係がある場合は、依存関係を最初に構築する必要があります。

親プロジェクト経由でコンパイル:

2.2 プロジェクトのバックエンド実装

2.2.1 生徒テーブルの作成

    MySQL データベースのテスト ライブラリの下に、student テーブルを作成します。student テーブルのフィールドは次のとおりです。

2.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("连接关闭失败!");
            }
        }
    }
}

2.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 + '\'' +
                '}';
    }
}

2.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);
    }
}

2.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;
    }
}

2.2.6 Student Presentation Layer のサーブレット実装

すべての生徒にクエリを実行するサーブレット:

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 に従って生徒のサーブレットを照会します。

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);

    }
}

学生のサーブレットを追加します。

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);
    }
}

学生を削除するためのサーブレット:

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);
    }
}

学生のサーブレットを変更します。

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);
    }
}

2.3 プロジェクトのフロントエンド実装

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

2.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>

2.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>

2.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>

2.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/123988147