[Maven da entrada ao tutorial de combate real] Capítulo 8 Divisão, herança, agregação do projeto Maven, caso abrangente de suporte ao Maven

1. Divisão, herança, agregação do projeto Maven

1.1 Problemas no desenvolvimento de projetos tradicionais

    Projetos de engenharia desenvolvidos com tecnologia Java, seja um sistema de processamento de dados ou um site Web, com desenvolvimento contínuo do projeto, refinamento contínuo e adição de requisitos, cada vez mais códigos no projeto e estruturas de pacotes cada vez mais complexas . Quando o andamento do projeto encontrará vários problemas:

    1. Em um projeto tradicional, todos os serviços serão gravados em um projeto e implantados com um servidor de aplicativos da web. Neste momento, se uma determinada operação comercial fizer com que o servidor fique inativo, todos os serviços do projeto não poderão ser acessados.

    2. Os códigos em diferentes aspectos são acoplados entre si. Neste momento, quando ocorre um problema em um sistema, é difícil localizar a causa do problema. Mesmo que o problema seja localizado, é difícil corrigir o problema , e mais problemas podem ser introduzidos quando o problema for corrigido.

    3. Muitos aspectos do código estão concentrados em uma estrutura geral. É difícil para novos desenvolvedores ter uma sensação intuitiva para o projeto geral, o que aumenta o custo para os novatos intervirem no desenvolvimento. Um desenvolvedor familiarizado com o projeto inteiro é necessários para manter a estrutura de todo o projeto (isso geralmente é difícil de fazer quando o projeto é grande e o tempo de desenvolvimento é longo).

    4. Os limites de código pelos quais os desenvolvedores são responsáveis ​​por si mesmos ou por outros são muito vagos, o que é mais fácil de encontrar em projetos complexos. O resultado é que os desenvolvedores podem facilmente modificar os códigos pelos quais outros são responsáveis ​​sem a pessoa responsável pelo código sabendo disso Rastreamento de responsabilidade Muito problemático.

    Dividir um projeto complexo em vários módulos é uma maneira importante de resolver os problemas acima. A divisão de vários módulos pode reduzir o acoplamento entre os códigos (desde o acoplamento em nível de classe até o acoplamento em nível de pacote jar), e cada módulo pode ser auto - explicativo (pelo nome do módulo ou pela documentação do módulo). Os módulos também regulam a divisão dos limites do código. Os desenvolvedores podem facilmente determinar pelo que são responsáveis ​​por meio dos módulos.

1.2 Divisão do projeto Maven

    Eu me pergunto se você já pensou em por que um bom projeto maven deve ser dividido? Diante da indústria de Internet + de hoje, os projetos de software estão se tornando maiores e mais complexos, o que aumenta muito o custo de desenvolvimento e gerenciamento. A divisão de projetos pode realizar desenvolvimento e teste de submódulos, bem como desenvolvimento e gerenciamento multi-thread, o que não apenas melhora a reutilização de códigos de engenharia, mas também melhora a velocidade e a eficiência do desenvolvimento de software.

    Por exemplo, um projeto crm completo desenvolvido anteriormente precisa ser dividido usando o projeto maven. Neste momento, a camada dao pode ser desmontada para formar um projeto independente. O mesmo vale para a camada de serviço e a camada da web.
    
    Link para o texto original da explicação do conceito e fotos: https://blog.csdn.net/yerenyuan_pku/article/details/103680220

 Entenda os benefícios da divisão de projetos:

    Como pode ser visto na figura acima, há um problema.Se houver um bug na camada dao no projeto crm e precisar ser reparado, a camada dao no projeto erp e o projeto oa também devem ser modificados de acordo. Repetir coisas como esta precisa ser feito três vezes! Não é desejável, então como resolvê-lo?

    Neste momento, a camada dao no projeto crm pode ser desmontada para formar um projeto independente e, em seguida, cada projeto pode reutilizar esse projeto independente.

     Divida o projeto em projetos individuais e apenas importe suas coordenadas quando precisar delas no futuro, o que é um pouco como construir blocos.

     Construir blocos em vários projetos:

    Para um projeto de grande escala, se o desenvolvermos diretamente como um projeto, só podemos desenvolvê-lo por um grupo de pessoas do começo ao fim devido à dependência mútua, caso contrário, haverá uma situação caótica onde muitas pessoas se desenvolvem e mudam uns aos outros. Dividimos o projeto horizontalmente e verticalmente.

    A chamada divisão horizontal é o que costumamos chamar de arquitetura de três camadas, que divide o projeto em camada web, camada de serviço e camada dao (a camada web também é chamada de camada de apresentação, a camada de serviço também é chamada de camada de negócios camada, e a camada dao também é chamada de camada de persistência. ), que pode ser entendida como a divisão dos diferentes processos de chamada de um módulo de função na direção horizontal.

    A chamada divisão vertical é a divisão de vários módulos funcionais de um projeto. Após a divisão horizontal, cada módulo funcional foi desenvolvido de forma independente. Quando o projeto é integrado, é necessário ter um projeto que possa integrar esses projetos ou módulos. Engenharia, este é o significado da chamada engenharia agregada.

1.3 Agregação do projeto Maven

    O desenvolvimento do projeto geralmente é desenvolvido em grupos e módulos. Após a conclusão do desenvolvimento de cada módulo, cada módulo precisa ser agregado e executado em conjunto para executar o projeto inteiro. Por exemplo, os três projetos de dao, serviço e web serão eventualmente empacotado como um pacote de guerra independente.

    Tome como exemplo um projeto de CRM completo desenvolvido no início. Depois de desmontar o projeto de CRM em vários submódulos, a execução de cada módulo independentemente não pode atender aos requisitos do projeto de software. Somente integrando todos eles, o trabalho pode ser concluído por meio da divisão de trabalho e cooperação. Portanto, o projeto pai é necessário para gerenciar cada submódulo e executá-los juntos, ou seja, empacotar os três projetos crm_dao, crm_service e crm_web em um pacote war executável independente.

     É um pouco como pegar as peças de um carro e montá-las em um carro que pode dirigir. Abaixo está um monte de várias partes do carro.

     Junte as várias partes do carro para transformá-lo em um carro que pode correr.

     Atenção deve ser dada ao estabelecimento do projeto de agregação:
        1. O próprio projeto de agregação também é um projeto Maven e deve ter seu próprio POM.
        2. Sua forma de embalagem deve ser: pom.
        3. Um novo elemento é introduzido: módulos---módulo.
        4. Versão: A versão do módulo agregado é consistente com a versão do módulo agregado.
        5. parentePath: O valor de cada módulo é um diretório relativo do POM atual.
            Especifica o caminho (relativo) para localizar o pom.xml deste projeto pai. Ordem padrão: parentePath > armazém local > armazém remoto.
            Nenhuma tag parentPath é equivalente a .../pom.xml, ou seja, ela é encontrada no diretório superior do arquivo pom atual por padrão.
        6. Nome do diretório: Para localizar rapidamente o conteúdo de forma conveniente, o diretório onde o módulo está localizado deve ser consistente com seu artefatoId (acordo Maven em vez de um requisito rígido). Resumindo, o diretório onde o módulo está localizado deve ser o igual ao diretório onde o <module>module está localizado</module > Consistent.
        7. Conteúdo reduzido do módulo de agregação: o conteúdo do módulo de agregação é apenas um arquivo pom.xml, que não contém src/main/java, src/test/java e outros diretórios, pois é apenas uma ferramenta para ajudar outros módulos constroem, em si Não há conteúdo real.
        8. Diretórios de módulos e submódulos de agregação: podem ser classes pai-filho, ou estruturas paralelas Claro, se estruturas paralelas forem usadas, o POM do módulo de agregação também precisa ser alterado de acordo.
        9. Caso o submódulo do projeto de agregação seja excluído após sua criação, ele deve ser excluído na aba módulos no pom.xml do projeto de agregação.

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

Resumir:

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

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

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

1.4 Herança de projetos Maven

    Semelhante à herança de classes em Java, tudo para eliminar a duplicação. A subclasse herda a classe pai, e os métodos e propriedades na classe pai não precisam ser definidos e implementados na subclasse, bastando chamar diretamente a classe pai ao usá-la. Depois de dividirmos o projeto crm, haverá um projeto pai (como crm) e vários subprojetos (como crm_dao, crm_service, crm_web), e as dependências a serem usadas nos subprojetos podem estar no arquivo pom. xml do projeto pai Com o gerenciamento de dependências, não há necessidade de definir a versão quando os subprojetos serão desenvolvidos no futuro, o objetivo é facilitar o gerenciamento.

    Além de evitar duplicações, a herança também tem a vantagem de tornar o projeto mais seguro.

    Observação ao herdar:
        1. Quando se trata de herança, deve ser uma estrutura pai-filho, então criamos um projeto pai no projeto de agregação.
        2. <embalagem>: Como o POM do módulo pai, seu tipo de embalagem também deve ser POM.
        3. Estrutura: O módulo pai serve apenas para nos ajudar a eliminar a duplicação, portanto não precisa de diretórios como src/main/java, src/test/java, etc.
        4. Um novo elemento: <parent>, que é usado em submódulos.
        5. Atributos do elemento <parent>: <relativePath>: Indica o caminho relativo do módulo pai POM. Ao compilar, o Maven primeiro verificará o pai POM de acordo com o parentePath. Se não conseguir encontrá-lo, ele procurará no armazém local.
        6. O valor padrão de relativoPath: ../pom.xml.
        7. Submódulo omite groupId e versão: GroupId e versão não podem ser declarados em um submódulo que usa herança, e o submódulo herdará implicitamente esses dois elementos do módulo pai.

Dois, caso abrangente do Maven

    Para um projeto de grande porte, na maioria dos casos, vários módulos funcionais de um projeto são divididos. Após a divisão, cada módulo funcional é desenvolvido de forma independente. Quando o projeto é integrado, é necessário ter um A engenharia desses projetos ou módulos é o significado da chamada engenharia de agregação.

    Não escrevemos tantos módulos agora, mas dividimos um módulo de aluno em módulos de acordo com a função da classe (arquitetura de três camadas) e, em seguida, experimentamos a divisão, herança e agregação de projetos.

2.1 Construir a estrutura do projeto

2.1.1 Criar e gerenciar projeto pai

    1. Crie um projeto pai de gerenciamento (maven-student), e o método de empacotamento dos projetos de gerenciamento Maven é pom. O projeto pai da classe de gerenciamento é apenas uma ferramenta para ajudar na construção de outros módulos, e não tem nenhum conteúdo real em si.Você pode deletar o diretório src.

     2. Após a conclusão da criação, faça a seguinte configuração:
        2.1 Modifique o método de empacotamento do projeto para pom.
        2.2 Gerenciamento de versão de dependência.
        2.3 Gerenciamento de dependências

<?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 Criar subprojeto de classe de ferramenta

    1. Crie um subprojeto de ferramenta (maven-student-util).

    Nota: Ao criar um subprojeto, um Módulo é criado. Clique com o botão direito do mouse no projeto pai -> Novo -> Módulo, Módulo também é um projeto Maven.

     2. O arquivo pom.xml do submódulo maven-student-util adicionará automaticamente a tag pai para identificar o projeto pai ou o módulo pai do módulo atual. E os módulos serão adicionados automaticamente ao arquivo pom.xml do projeto pai para identificar os módulos agregados.

<!-- 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. Apresente as dependências necessárias para o módulo atual.

<?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 Criar subprojetos de classe de entidade

    Crie um subprojeto de classe de entidade (maven-student-entity) e introduza as dependências necessárias para o módulo atual.

<?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 Criar subprojeto de camada de persistência

    Crie um subprojeto de camada de persistência (maven-student-dao) e introduza as dependências necessárias para o módulo atual.

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

    O gerenciamento de dependências é realizado em módulos próprios no projeto pai, não sendo necessário definir versões em submódulos.

<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 Criar um subprojeto de camada de negócios

    Crie um subprojeto de camada de negócios (maven-student-service) e introduza as dependências necessárias para o módulo atual.

<?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 Criar subprojeto de apresentação

    1. Crie um subprojeto de camada de apresentação (maven-student-web) e modifique o método de empacotamento do projeto para war.

    2. Apresente as dependências necessárias para o módulo atual

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

Finalmente, o conteúdo do arquivo pom.xml do projeto pai:

<?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 sobre módulos

    módulos podem ser adicionados ou não. Mas os módulos têm uma vantagem: após definir os módulos, executamos o ciclo de vida através do projeto pai, e todos os submódulos executarão o ciclo de vida correspondente.

    Nota: Se não tivermos dependências entre os módulos, execute-os na ordem de configuração da agregação; se houver dependências, as dependentes devem ser construídas primeiro.

Compilar via projeto pai:

2.2 Implementação de back-end do projeto

2.2.1 Criar tabela de alunos

    Crie uma tabela de alunos na biblioteca de teste do banco de dados MySQL. Os campos da tabela de alunos são os seguintes:

2.2.2 Implementação da classe de ferramentas DBUtils

    Crie o pacote com.maven.util no subprojeto de classe de ferramenta e crie a classe de ferramenta DBUtils.

O código DBUtils é o seguinte:

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 Implementação de classe de entidade estudantil

    Crie o pacote com.maven.entity no subprojeto de classe de entidade e crie a classe de entidade StudentEntity.

O código StudentEntity é o seguinte:

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 Implementação da Camada de Persistência do Aluno

    Crie o pacote com.maven.dao no subprojeto da camada de persistência e crie a interface StudentDao.

    Crie o pacote com.maven.dao.impl no subprojeto da camada de persistência e crie a classe de implementação StudentDaoImpl.

    Observação: Implementamos apenas um conjunto simples de CRUD.

O código da interface StudentDao é o seguinte:

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

O código da classe de implementação StudentDaoImpl é o seguinte:

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 Implementação da camada de negócios do aluno

    Crie um pacote com.maven.service no subprojeto da camada de negócios e crie uma classe StudentService.

O código da classe StudentService é o seguinte:

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 Implementação do Servlet da Camada de Apresentação do Aluno

Servlet para consultar todos os alunos:

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

    }
}

Consultar o Servlet do aluno de acordo com o 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);

    }
}

Adicione o servlet do aluno:

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 para remoção de alunos:

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

Modifique o servlet do aluno:

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 Implementação de front-end do projeto

A estrutura de diretórios é a seguinte:

2.3.1 Implementação da página inicial do projeto

<%@ 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 Implementação da página de lista de alunos

<%@ 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 Modificar a implementação da página do aluno

<%@ 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 Adicionar implementação da página do aluno

<%@ 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>

Acho que você gosta

Origin blog.csdn.net/ligonglanyuan/article/details/123988147
Recomendado
Clasificación