> 文档中心 > 项目管理与SSM框架——Maven

项目管理与SSM框架——Maven

Maven学习+案例练习


文章目录

  • 一、Maven介绍
    • 1.Maven简介
    • 2.Maven的作用
    • 3.Maven的安装
    • 4.Maven工程的类型和结构
    • 5.Maven项目的生命周期
    • 6.Maven常用命令
    • 7.Maven仓库类型
    • 8.Maven配置文件
  • 二、Maven工程开发
    • 1.IDEA配置Maven插件
    • 2.建构Maven工程
    • 3.pom文件配置
    • 4.Maven依赖范围
  • 三、Maven工程测试
    • 1.测试概述
    • 2.Junit使用步骤
    • 3.Junit结果判定
    • 4.@Before、@After
  • 四、依赖冲突调解
    • 1.最短路径优先原则
    • 2.最先声明原则
    • 3.排除依赖
    • 4.锁定版本
  • 五、Maven聚合开发
    • 1.聚合关系
    • 2.继承关系
  • 六、Maven聚合案例
    • 1.搭建父工程
    • 2.搭建dao模块
    • 3.搭建service模块
    • 4.搭建web模块
    • 5.运行项目
    • 6.依赖传递失效及解决方案

一、Maven介绍

1.Maven简介

Maven是一个项目管理工具。它可以帮助程序员构建工程,管理jar包,编译代码,完成测试,项目打包等等。

●Maven工具是基于POM(Project Object Model,项目对象模型)实现的。在Maven的管理下每个项目都相当于是一个对象。
●Maven标准化了项目的构建。即对项目结构,构建命令等进行了标准化定义。
●Maven提供了一个免费的中央仓库,在其中几乎可以找到任何的流行开源类库。
●Maven是跨平台的,在Windows、Linux、Mac上,都可以使用同样的命令。

2.Maven的作用

一键构建
我们的项目往往都要经历编译、测试、运行、打包、安装 ,部署等一系列过程,这些过程称之为构建。通过Maven工具,可以使用简单的命令轻松完成构建工作。

依赖管理
传统的Web项目中,我们必须将工程所依赖的jar包复制到工程中,导致了工程的变得很大。如果一个公司具有相同架构的项目有十个,那么就需要将这一份jar包复制到十个不同的工程中,非常浪费资源。

同样的项目内容,传统Web项目大小如下:

在这里插入图片描述

而使用Maven构建的项目大小如下:

在这里插入图片描述

这说明了传统Web项目中大部分磁盘空间是被jar包占据,而Maven项目中一定没有jar包,那没有jar包的项目是怎么运行的呢?

在这里插入图片描述

maven工程中不直接将jar包导入到工程中,而是有一个专门存放jar包的仓库,仓库中的每个jar包都有自己的坐标。maven工程中只要配置jar包坐标即可,运行项目需要使用jar包时,根据坐标即可从maven仓库中拿到jar包即可运行。

3.Maven的安装

下载
https://maven.apache.org/download.cgi

image-20211111163834866

安装
解压下载好的安装文件,解压后目录结构如下:

项目管理与SSM框架——Maven

●bin:存放maven的命令
●boot:存放maven本身的引导程序,如类加载器等
●conf:存放maven的配置文件
●lib:存放maven本身运行所需的jar包

配置环境变量
由于Maven是由Java语言开发的,运行时依赖Java环境,所以要在计算机的环境变量中配置JAVA_HOME

在这里插入图片描述

为了更方便的使用Maven命令,需要在环境变量中配置MAVEN_HOMEPath

在这里插入图片描述

项目管理与SSM框架——Maven

查看版本
打开CMD命令窗口,输入mvn -v,显示Maven版本和Java版本,证明安装成功

![在这里插入图片描述](https://img-blog.csdnimg.cn/d54a3ed3963f404085fc1f661477de3e.png?x-oss-process=

4.Maven工程的类型和结构

Maven工程类型

●POM工程
POM工程是逻辑工程,Maven并不会对该类型工程做打包处理,这些工程往往不包含具体的业务,而是用来整合其他工程的。

●JAR工程
普通Java工程,在打包时会将项目打成jar包。

●WAR工程
JAVA Web工程,在打包时会将项目打成war包。

Maven工程结构
接下来我们通过一个WAR工程学习Maven工程的结构

文件目录结构:
项目管理与SSM框架——Maven
●src:源代码
●target:编译生成的文件
●pom.xml:Maven工程配置文件,如坐标信息等。

项目结构:
在这里插入图片描述
●src/main/java:存放项目的java 文件
●src/main/resources:存放项目资源文件,如配置文件
●src/test/java:存放项目的测试文件
●src/test/resources:存放测试时的资源文件

5.Maven项目的生命周期

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

项目管理与SSM框架——Maven

生命周期 所做工作
验证 validate 验证项目是否正确
编译 compile 源代码编译
测试 Test 使用适当的单元测试框架(例如junit)运行测试。
打包 package 创建JAR/WAR包
检查 verify 对集成测试的结果进行检查,以保证质量达标。
安装 install 安装打包的项目到本地仓库,以供其他项目使用。
部署 deploy 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程。

maven有三套相互独立的生命周期。分为是构建生命周期,clean生命周期(清理构建后的文件)、site生命周期(生成项目报告)。作为开发人员一般重点学习构建生命周期。

6.Maven常用命令

在Maven构建项目的每一步都可以使用一句简单的命令完成,接下来我们学习这些命令:

命令 作用
mvn clean 清除编译的class文件,即删除target目录。
mvn validate 验证项目是否正确
mvn compile 编译maven项目
mvn test 编译maven项目及运行测试文件
mvn package 编译maven项目及运行测试文件,并打包
mvn install 编译maven项目及运行测试文件并打包,并发布到本地仓库
mvn deploy 部署项目到远程仓库
mvn tomcat7:run 使用tomcat运行项目

Maven依赖插件来执行命令,比如clean、validate等命令是maven自带的,tomcat7命令是引入的第三方插件。

7.Maven仓库类型

本地仓库
本地仓库指用户计算机中的文件夹。用来存储从远程仓库或中央仓库下载的jar包,只有下载到本地仓库的jar包才能使用,项目使用jar包时优先从本地仓库查找。

远程仓库
远程仓库一般指私服,它是架设在局域网的仓库服务,可以从中央仓库下载资源,供局域网使用,从而减少每个程序员都从中央仓库下载浪费的带宽。

如果项目需要的jar包本地仓库没有,则会去远程仓库下载,下载到本地仓库即可使用。

远程仓库不是必须配置的,如果本地仓库没有jar包,也没有配置远程仓库,则会直接从中央仓库下载。

中央仓库
中央仓库是互联网上的服务器,是Maven提供的最大的仓库,里面拥有最全的jar包资源。

如果项目需要的jar包,本地仓库和远程仓库都没有,则会去中央仓库下载,下载到本地仓库使用。

Maven中央仓库访问页面:https://mvnrepository.com/

中央仓库访问速度较慢,我们一般都会配置镜像代理中央仓库的下载请求,如阿里镜像、华为镜像等。

8.Maven配置文件

本地仓库的默认位置是${user.dir}/.m2/repository${user.dir}表示 windows用户目录,我们可以通过修改${MAVEN_HOME}\conf\settings.xml,修改本地仓库的位置。

配置本地仓库
中添加如下标签:

<!-- 本地仓库路径 --><localRepository>F://repository</localRepository>

配置镜像
由于中央仓库访问速度较慢,可以配置镜像代理中央仓库的下载请求。在下的中添加如下标签即可配置镜像:

<mirror>      <!-- 指定镜像ID -->    <id>nexus-aliyun</id>      <!-- 匹配中央仓库。-->    <mirrorOf>central</mirrorOf>    <!-- 指定镜像名称 --> <name>Nexus aliyun</name>      <!-- 指定镜像路径 --><url>http://maven.aliyun.com/nexus/content/groups/public</url>  </mirror>

配置JDK版本
创建maven项目的时候,默认使用的JDK是1.5版本,验证语法、编译、运行时都会按照JDK1.5操作,这样就有很多语法无法使用。若本机安装的JDK是JDK11,可以配置maven按照JDK11创建项目。

下的中添加如下标签即可配置JDK版本:

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

二、Maven工程开发

1.IDEA配置Maven插件

File-Settings-搜索maven-配置Maven home directory:下载的maven所在路径,User settings file:maven的settings.xml文件所在路径,Local repository:repository本地仓库路径

在这里插入图片描述
在这里插入图片描述

2.建构Maven工程

打开 idea,选择创建一个新工程

在这里插入图片描述

选择Maven工程,并使用maven的web工程模板

在这里插入图片描述

点击 Next 填写项目信息
项目管理与SSM框架——Maven
Name:项目名 Location:项目保存路径 GroupId:公司或组织名 ArtifactId:项目名 Version:版本号

后续完成创建即可

需手动添加src/main/java目录,此时该目录还不能写Java代码。

将src/main/java目录在Mark Directory as设置为Sources Root。

3.pom文件配置

pom文件最上方是项目基本信息:

groupId
groupId一般定义项目组名,命名规则使用反向域名。

artifactId
artifactId一般定义项目名,命名使用小写字母。项目发布后,它的坐标是groupId+artifactId。

version
version定义版本号。版本号一般有三段,第一段:革命性的产品升级。第二段:新功能版本。第三段:修正一些bug。

packaging
packaging定义打包方式。

中定义一些配置信息:
在这里插入图片描述

中定义依赖的jar包坐标:

由于项目是web项目,需要写Servlet和JSP,所以需要引入Servlet和JSP的依赖。查找依赖坐标的网站:
https://mvnrepository.com/

在这里插入图片描述
配置示例:

1<dependencies>2    <dependency>3 <groupId>junit</groupId>4 <artifactId>junit</artifactId>5 <version>4.11</version>6 <scope>test</scope>7    </dependency>8    <!-- jsp -->9    <dependency>10 <groupId>javax.servlet.jsp</groupId>11 <artifactId>jsp-api</artifactId>12 <version>2.2</version>13    </dependency>14    <!-- servlet -->15    <dependency>16 <groupId>javax.servlet</groupId>17 <artifactId>javax.servlet-api</artifactId>18 <version>3.0.1</version>19    </dependency>20</dependencies>

中定义第三方插件:

web项目依赖tomcat运行,所以添加tomcat7插件

示例:

1<plugins>2    <!-- tomcat插件 -->3    <plugin>4 <groupId>org.apache.tomcat.maven</groupId>5 <artifactId>tomcat7-maven-plugin</artifactId>6 <version>2.1</version>7 <configuration>8     <port>8080</port>9     <path>/</path>10     <uriEncoding>UTF-8</uriEncoding>11     <server>tomcat7</server>12 </configuration>13    </plugin>14</plugins>

4.Maven依赖范围

由于我们项目中引入了Servlet和Jsp的jar包,而在项目运行时,Tomcat会使用它自带的Servlet和Jsp的jar包,这样就造成了jar包冲突。而如果项目不引入Servlet和Jsp的jar包,则项目会无法通过编译。

此时可以设置依赖的作用范围解决该问题,设置Servlet和Jsp的jar包只在编译期起作用,运行时不起作用,这样不仅可以通过编译,还能在运行时避免jar包冲突。

通过在中添加,可以设置依赖的作用范围,有以下取值:

compile
默认范围。表示该依赖在编译和运行时生效,项目打包时也会将该依赖打包进去。

provided
使用此依赖范围的Maven依赖,编译和测试时有效,但在运行时无效。典型的例子是servlet-api,在运行时Web容器已经提供依赖,就不需要Maven重复地引入一遍。

runtime
runtime范围表明编译时不需要生效,而只在运行时生效。典型的例子是JDBC驱动包,编译时只需要JDK的JDBC接口即可,只有运行项目时才需要具体的JDBC驱动。

test
test范围表明使用此依赖范围的依赖,只在编译和运行测试代码的时生效,程序的正常运行不需要此类依赖。典型的例子就是JUnit,它只有在编译测试代码及运行测试的时候才需要。

system
如果有些我们依赖的jar包没有Maven坐标的,它完全不在Maven体系中,这时候你可以把它下载到本地硬盘,然后通过system来引用。

所以我们可以将Servlet和Jsp依赖添加范围为provided即可。

1<dependency>2    <groupId>javax.servlet.jsp</groupId>3    <artifactId>jsp-api</artifactId>4    <version>2.2</version>5    <scope>provided</scope>6</dependency>7<dependency>8    <groupId>javax.servlet</groupId>9    <artifactId>javax.servlet-api</artifactId>10    <version>3.0.1</version>11    <scope>provided</scope>12</dependency>

重启项目,即可正常访问Servlet和Jsp

三、Maven工程测试

1.测试概述

测试即在交付前对写好的代码进行评测,分为黑盒测试和白盒测试:

黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。
白盒测试:需要写代码的。关注程序具体的执行流程。
在这里插入图片描述

单元测试是指对软件中的最小可测试单元进行检查和验证,Java里单元测试指一个类的功能。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

Junit是Java编程语言的单元测试框架,用于编写和运行可重复的自动化测试。从分类中属于白盒测试。

2.Junit使用步骤

在Maven项目中引入依赖

1<dependency>2    <groupId>junit</groupId>3    <artifactId>junit</artifactId>4    <version>4.12</version>5    <scope>test</scope>6</dependency>

定义被测试的类
我们定义一个计算器工具类。

1public class Calculator {2    // 加法3    public int add(int a,int b){4 return a+b;5    }6    // 除法7    public int div(int a,int b){8 return a/b;9    }10}

对定义的类进行测试
创建src/test/java包,并将改包设置为测试包。

在src/test/java中创建测试类的包,包名一般与被测试包名一致。

定义测试类,类名一般为被测试类+Test

在这里插入图片描述

测试类中编写测试方法。

1public class CalculatorTest {2    /**3     * 测试方法是可以独立运行的,写法如下:4     * 1.方法名一般为test+被测试方法名5     * 2.方法上方添加@Test6     * 3.测试方法没有参数和返回值7     */8    @Test9    public void testAdd(){10 Calculator calculator = new Calculator();11 int add = calculator.add(1, 2);12 System.out.println(add);13    }1415    @Test16    public void testDiv(){17 Calculator calculator = new Calculator();18 int div = calculator.div(2,0);19 System.out.println(div);20    }21}

3.Junit结果判定

点击测试方法边的三角运行测试方法,如果出现绿色对钩,证明方法能正常运行;如果出现红色感叹号,证明方法抛出异常,需要修改方法。
在这里插入图片描述

当然,不是能正常运行就代表方法一定没有问题,也有可能方法的结果和预期结果不一致,这时就需要使用断言操作。

1@Test2public void testAdd(){3    Calculator calculator = new Calculator();4    int add = calculator.add(1, 2);5    /**6     * 断言7     * 参数1:预期结果,参数2:实际结果8     */9    Assert.assertEquals(2,add);10}

如果真实结果和预期结果不一致,则会抛出以下异常:
在这里插入图片描述

4.@Before、@After

在测试类中,@Before修饰的方法会在测试方法之前自动执行,@After修饰的方法会在测试方法执行之后自动执行。比如,我们可以设置前置方法为获取资源,后置方法为释放资源。

1@Before2public void before(){3    System.out.println("开始测试");4}56@After7public void after(){8    System.out.println("结束测试");9}

四、依赖冲突调解

1.最短路径优先原则

依赖冲突产生的原因——依赖传递
假设你的项目依赖jar包A,jar包A又依赖jar包B。当添加jar包A时,Maven会把jar包B也自动加入到项目中。比如刚刚我们添加了junit依赖,junit又依赖hamcrest,所以Maven会将junit和hamcrest都加入项目中。

在这里插入图片描述

这时就可能会产生依赖冲突问题,比如依赖A会引入依赖C,依赖B也会引入依赖C。如果不进行调解则会引入两个依赖C,那么Maven是如何解决依赖冲突问题的呢?

依赖冲突调解
我们以Spring依赖为例,spring-webmvc依赖spring-aop,spring-context也依赖spring-aop,如果两个同时引入,会引入哪个版本的spring-aop呢?

测试代码:

1<dependency>2    <groupId>org.springframework</groupId>3    <artifactId>spring-context</artifactId>4    <version>5.2.12.RELEASE</version>5</dependency>67<dependency>8    <groupId>org.springframework</groupId>9    <artifactId>spring-webmvc</artifactId>10    <version>4.2.4.RELEASE</version>11</dependency>

Maven调解依赖冲突的第一原则是最短路径优先原则:

也就是说项目依赖关系树中路径最短的版本会被使用。例如,假设有几个jar包之间的依赖关系是:A->B->C->D(2.0)E->F->D(1.0),如果同时引入A和E,那么D(1.0)会被使用,因为E到D的路径更短。

查看依赖路径的方式如下:
在这里插入图片描述
spring-webmvc到spring-aop的路径如下:
在这里插入图片描述
spring-context到spring-aop的路径如下:
在这里插入图片描述
可以看到,spring-webmvc到spring-aop的路径为:
spring-webmvc -> spring-context ->spring-aop

而spring-context到spring-aop的路径为:
spring-context ->spring-aop

spring-context到spring-aop的路径更短,所以spring-aop会按照spring-context的版本引入。
在这里插入图片描述

2.最先声明原则

最短路径优先原则不能解决所有问题,比如这样的依赖关系:A–>B–>C(1.0)D–>E–>C(2.0),同时引入A和D之后,C(1.0)和C(2.0)的依赖路径长度都为2。此时第一原则将不能解决问题

Maven调解依赖冲突的第二原则是最先声明原则:
在依赖路径长度相等的前提下,在POM中依赖声明的顺序靠前的会被解析使用。比如:以上案例中,spring-webmvc和spring-context到spring-core的路径都为1。谁声明在上方,spring-core会按照谁的版本引入。(可参考上图。)

3.排除依赖

如果不想使用Maven默认的冲突调解方式,有两种方式可以手动进行冲突调解。

排除依赖
比如以上案例中,想使用spring-webmvc的spring-aop包,那么可以让spring-context引入时排除引入spring-aop包,这样就可以使用spring-webmvc的spring-aop包了,测试代码写法如下:

1<dependency>2    <groupId>org.springframework</groupId>3    <artifactId>spring-webmvc</artifactId>4    <version>4.2.4.RELEASE</version>5</dependency>6<dependency>7    <groupId>org.springframework</groupId>8    <artifactId>spring-context</artifactId>9    <version>5.2.12.RELEASE</version>10    <exclusions>11 <exclusion>12     <groupId>org.springframework</groupId>13     <artifactId>spring-aop</artifactId>14 </exclusion>15    </exclusions>16</dependency>

4.锁定版本

在Maven中为某个jar包配置锁定版本后,不考虑依赖的声明顺序和依赖路径,以锁定的版本的为准添加到工程中,此方法在企业开发中常用。以下可以直接配置spring-aop锁定的版本。

1<dependencyManagement>2    <dependencies>3 <dependency>4     <groupId>org.springframework</groupId>5     <artifactId>spring-aop</artifactId>6     <version>4.2.4.RELEASE</version>7 </dependency>8    </dependencies>9</dependencyManagement>

五、Maven聚合开发

1.聚合关系

假如我们现在写了两个项目分别是电商卖家端和电商买家端,两个项目都需要调用serive层查询订单的方法。原来的写法如下:
在这里插入图片描述
这样重复编码造成开发效率降低。

而使用maven后,我们可以把之前的项目按需拆分成一个个小项目,之后将小项目发布到仓库中,小项目之间也可以互相引用,并且在我们的项目中引入需要的小项目即可。
在这里插入图片描述

Maven将一个大项目分成一个个小项目开发,最后打包时会将这些小的项目打成一个完整的war包独立运行。

2.继承关系

Maven中的继承是针对于父工程和子工程。父工程定义的依赖和插件子工程可以直接使用。注意:父工程类型为POM类型工程。

多继承
在Maven中对于继承采用的也是单继承,也就是说一个子项目只能有一个父项目。但我们可以在配置多继承。写法如下:

1<dependencyManagement>2    <dependencies>3 <!--父项目a-->4 <dependency>5     <groupId>com.package</groupId>6     <artifactId>parent_a</artifactId>7     <version>1.0-SNAPSHOT</version*>8     <type>pom</type>9     <!-- 引入父项目,scope的值为import -->10     <scope>import</scope>11 </dependency>1213 <!--父项目b-->14 <dependency>15     <groupId>com.package</groupId>16     <artifactId>parent_b</artifactId>17     <version>1.0-SNAPSHOT</version>18     <type>pom</type>19     <scope>import</scope>20 </dependency>21    </dependencies>22</dependencyManagement>

六、Maven聚合案例

1.搭建父工程

在这里插入图片描述

1.创建一个Maven工程,创建时不需要选择模板。
在这里插入图片描述
2.由于父工程是虚拟工程,不需要写逻辑代码,所以删除父工程的src目录。

3.由于父工程的依赖和插件子工程都能继承,可以将需要的依赖和插件都配置在父工程中。

1<groupId>com.package</groupId>2<artifactId>maven_demo2</artifactId>3<version>1.0-SNAPSHOT</version>4<packaging>pom</packaging>56<properties>7    <maven.compiler.source>11</maven.compiler.source>8    <maven.compiler.target>11</maven.compiler.target>9</properties>1011<dependencies>12    <dependency>13 <groupId>junit</groupId>14 <artifactId>junit</artifactId>15 <version>4.12</version>16 <scope>test</scope>17    </dependency>18    <dependency>19 <groupId>javax.servlet.jsp</groupId>20 <artifactId>jsp-api</artifactId>21 <version>2.2</version>22 <scope>provided</scope>23    </dependency>24    <dependency>25 <groupId>javax.servlet</groupId>26 <artifactId>javax.servlet-api</artifactId>27 <version>3.0.1</version>28 <scope>provided</scope>29    </dependency>30    <!-- jdbc驱动 -->31    <dependency>32 <groupId>mysql</groupId>33 <artifactId>mysql-connector-java</artifactId>34 <version>8.0.27</version>35    </dependency>36    <!-- jstl -->37    <dependency>38 <groupId>org.apache.taglibs</groupId>39 <artifactId>taglibs-standard-spec</artifactId>40 <version>1.2.5</version>41    </dependency>42    <dependency>43 <groupId>org.apache.taglibs</groupId>44 <artifactId>taglibs-standard-impl</artifactId>45 <version>1.2.5</version>46    </dependency>47</dependencies>4849<build>50    <plugins>51 <!-- tomcat插件 -->52 <plugin>53     <groupId>org.apache.tomcat.maven</groupId>54     <artifactId>tomcat7-maven-plugin</artifactId>55     <version>2.1</version>56     <configuration>57  <port>8080</port>58  <path>/</path>59  <uriEncoding>UTF-8</uriEncoding>60  <server>tomcat7</server>61  <systemProperties>62<java.util.logging.SimpleFormatter.format>%1$tH:%1$tM:%1$tS %2$s%n%4$s: %5$s%6$s%n</java.util.logging.SimpleFormatter.format>63  </systemProperties>64     </configuration>65 </plugin>66    </plugins>67</build>

IDEA中工程和模块有什么区别?

没什么区别,只是新工程会占据一个新窗口,我们一般写父工程时定义为新工程,写子工程时定义为新模块。

2.搭建dao模块

dao子工程中一般写实体类和dao层:

1.在父工程下创建maven模块,不选择模板,创建时一定要选择父工程。
项目管理与SSM框架——Maven
2.子模块的pom文件中写入父工程证明继承成功。

3.准备数据库

1CREATE DATABASE `student`;2USE `student`;3DROP TABLE IF EXISTS `student`;4CREATE TABLE `student` (5  `id` int(11) NOT NULL AUTO_INCREMENT,6  `name` varchar(255) DEFAULT NULL,7  `sex` varchar(10) DEFAULT NULL,8  `address` varchar(255) DEFAULT NULL,9  PRIMARY KEY (`id`)10) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;1112insert  into `student`(`id`,`name`,`sex`,`address`) values (1,'小可爱','男','青青草原'),(2,'小淘气','女','海洋');

4.编写实体类

1public class Student {2    private int id;3    private String name;4    private String sex;5    private String address;6    7    // 省略getter/setter/tostring/构造方法8}

5.在resources中编写连接数据库的配置文件db.properties

1jdbc.url=jdbc:mysql:///student2jdbc.user=root3jdbc.password=root

6.编写dao方法

1public class StudentDao {2    // 查询所有学生3    public List<Student> findAll() throws Exception {4 // 读取配置文件5 Properties properties = new Properties();6 InputStream is = this.getClass().getClassLoader().getResourceAsStream("db.properties");7 properties.load(is);89 String url = properties.getProperty("jdbc.url");10 String user = properties.getProperty("jdbc.user");11 String password = properties.getProperty("jdbc.password");1213 // 查询数据库14 Connection connection = DriverManager.getConnection(url, user, password);15 Statement statement = connection.createStatement();16 ResultSet resultSet = statement.executeQuery("select * from student");1718 // 处理结果集19 List<Student> students = new ArrayList();20 while (resultSet.next()){21     int id = resultSet.getInt("id");22     String name = resultSet.getString("name");23     String sex = resultSet.getString("sex");24     String address = resultSet.getString("address");25     Student student = new Student(id, name, sex, address);26     students.add(student);27 }2829 // 释放资源30 resultSet.close();31 statement.close();32 connection.close();3334 return students;35    }36}

7.测试dao方法

1public class StudentDaoTest {2    // 测试findAll3    @Test4    public void testFindAll() throws Exception {5 StudentDao studentDao = new StudentDao();6 List<Student> all = studentDao.findAll();7 all.forEach(System.out::println);8    }9}

3.搭建service模块

service子工程中一般写service层的内容,也需要继承父工程,由于需要调用dao子工程的方法,所以需要导入dao子工程的依赖。

1.在父工程下创建maven模块,不选择模板,选择父工程。

2.在service模块的pom文件中引入dao子工程的依赖。

1<dependencies>2    <dependency>3 <groupId>/*同dao工程*/</groupId>4 <artifactId>/*同dao工程*/</artifactId>5 <version>1.0-SNAPSHOT</version>6    </dependency>7</dependencies>

3.编写Service方法

1public class StudentService {2    private StudentDao studentDao = new StudentDao();3    public List<Student> findAllStudent() throws Exception {4 return studentDao.findAll();5    }6}

4.测试service方法

1public class StudentServiceTest {2    // 测试findAllStudent3    @Test4    public void testFindAll() throws Exception {5StudentService studentService = new StudentService();6 List<Student> allStudent = studentService.findAllStudent();7 allStudent.forEach(System.out::println);8    }9}

4.搭建web模块

web子工程中一般要写控制器和前端页面的内容。它不是普通的java工程,而是一个web工程,需要继承父工程,导入service子工程的依赖。

1.在父工程下创建maven模块,选择web工程模板,选择父工程。

2.创建好后,添加父工程,删除pom文件中的jdk编译版本,删掉junit依赖(因为已经继承的父工程中有响应规范),引入service依赖。

1<parent>2    <artifactId>maven_demo2</artifactId>3    <groupId>/*same*/</groupId>4    <version>1.0-SNAPSHOT</version>5</parent>67<properties>8    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>9    <maven.compiler.source>11</maven.compiler.source>10    <maven.compiler.target>11</maven.compiler.target>11</properties>1213<dependencies>14    <dependency>15 <groupId>/*same*/</groupId>16 <artifactId>maven_demo2_service</artifactId>17 <version>1.0-SNAPSHOT</version>18    </dependency>19</dependencies>

3.编写控制器

1@WebServlet("/allStudent")2public class FindAllStudentServlet extends HttpServlet {3    @Override4    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {5 StudentService studentService = new StudentService();6 List<Student> allStudent = null;7 try {8     allStudent = studentService.findAllStudent();9 } catch (Exception e) {10     e.printStackTrace();11 }12 req.setAttribute("allStudent",allStudent);13 req.getRequestDispatcher("allStudent.jsp").forward(req,resp);14    }15}

4.编写JSP页面

1<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>2<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>3<html>4<head>5    <title>所有学生</title>6</head>7<body>8<table align="center" border="1" cellspacing="0" cellpadding="0" width="500px">9    <tr>10 <th>id</th>11 <th>姓名</th>12 <th>性别</th>13 <th>地址</th>14    </tr>15    <c:forEach items="${allStudent}" var="student">16 <tr>17     <td>${student.id}</td>18     <td>${student.name}</td>19     <td>${student.sex}</td>20     <td>${student.address}</td>21 </tr>22    </c:forEach>23</table>24</body>25</html>

5.运行项目

有以下两种方式可以运行项目:

1.配置tomcat插件运行父工程,此时会自动聚合运行项目。

点开配置tomcat7插件:
在这里插入图片描述

进行如下配置:
在这里插入图片描述
点击运行箭头即可访问http://localhost:8080/allStudent
项目管理与SSM框架——Maven

2.配置tomcat插件运行web子工程。

运行web子工程时会从本地仓库下载依赖的jar包,所以必须将dao模块和service模块发布到本地仓库,我们可以直接发布整个项目。
在这里插入图片描述
之后按照tomcat插件配置父工程的方式配置web工程即可:
在这里插入图片描述

点击运行箭头即可访问http://localhost:8080/allStudent

6.依赖传递失效及解决方案

之前的案例中,junit是在父工程当中引入的,如果在dao工程引入,service工程引入dao工程,即service --> dao --> junit。按照依赖的传递性,service工程也可以使用junit。可实际情况却是无法使用。这就是依赖传递失效问题。
在这里插入图片描述

Maven在定义依赖传递时,一些依赖范围的依赖无法传递,表格如下:
在这里插入图片描述

在实际开发中,不需要记这张表格,遇到依赖没有传递过来时,我们直接在本工程再次添加一遍依赖即可。

1<dependencies>2 <dependency>3     <groupId>/*same*/</groupId>4     <artifactId>maven_demo2_dao</artifactId>5     <version>1.0-SNAPSHOT</version>6 </dependency>7 <dependency>8     <groupId>junit</groupId>9     <artifactId>junit</artifactId>10     <version>4.12</version>11     <scope>test</scope>12 </dependency>13</dependencies>