1.JDBC(Database Transaction)
1.1概述
- JDBC: Java DataBase Connectivity --java数据库连接
即利用java语言连接数据库的规范
另外连接数据库的方式 CMD命令窗口和Navicat/Sqlylog等可视化数据库软件 - 实际开发中更多是通过java程序来连接数据库,比如Mybatis/Hibernate/DBUtils/Spring JdbcTemplate等框架底层也是在通过JDBC来连接数据库
1.2如何通过JDBC连接到数据库
- JDBC只是一种规范(说明书)无实质性代码,对数据库的增删改查操作都存在于驱动中,如Mysql Driver即 jar包,jar包中包含很多class文件,由Java程序编译而来,是mysql厂商提供,利用jar包中的类可操作数据库,不同数据库操作方法不同,学习成本高
- 因此Sun公司提供了一套规范(API),即大量接口,所有不同类都实现统一接口,操作数据库的方法归于一致.也就是**面向接口编程,**开发人员只需要学会这套接口
- JDBC中主要包含 java.sql 和 javax.sql 这两个包, 且java中已经包含这两个包,所以使用JDBC无需导包只需导入mysql.Driver等对应的数据库驱动包即可.
1.3 通过JDBC实现对数据的增删改查
1.3.1 通过JDBC实现数据查询
1️⃣准备数据,创建项目导入mysql驱动包.
Eclipse: New—>Folder(lib)—>将驱动包复制到此目录下—>右键jar包—>BuildPath—>Add to Build Path
Idea: File—>ProjectStructrue—>Modules—Dependencies—>+JARs or directories
2️⃣ 创建测试类在main方法中编写程序
//1.注册数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
- **反射中的方法(类加载器),**用于加载一个类,加载进来自动注册,将驱动交给JDBC Driver Manager管理
//2.获取数据库连接
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai",
"root", "root");
//3.获取传输器
Statement stat = conn.createStatement();
- JDBC与数据库通讯协议默认为TCP协议,TCP为面向连接的协议,构建通讯需要先建立连接,
- Java程序获取与数据库的连接(即建立通道),此连接作为对象返回,父接口Connection接受子类对象.
- 通过连接对象创建 Statement 传输器,使用 Statement 传输器发送Sql语句到Mysql服务器执行,再通过传输器返回数据.
//4.发送SQL到服务器执行并返回结果集rs
String sql = "select * from account";
ResultSet rs = stat.executeQuery( sql );
- executeQuery 执行的是查询方法
//5.处理结果(将rs对象中的数据遍历)
while( rs.next() ) {
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id+" : "+name+" : "+money);
}
- 根据表中的**数据类型和字段(列名)**获取每一行的数据
- ResultSet 接口 extends WRapper 表示数据库结果集的数据表,通常通过执行查询数据库的语句生成,ResultSet对象(rs)中 有获取查询结果的方法,和指向其当前数据行的光标,
- 最开始光标指向表头,要想获得下一行数据需要调用rs.next()方法, 调用一次光标下移一行,利用rs.getInt(“id”)rs.getString(“name”)等方法获取需要的数据
- rs.next()方法有返回值,调用时,若指向当前行有数据则返回true,当前行为空则返回false
- 以下三行获取数据都为重复操作,面对大量数据时可以使用循环遍历,rs.next()作为循环条件,调用rs.next()既会让光标指向下一行,还可以返回true/false作为循环的条件以此判断是否结束循环.
//6.释放资源
rs.close();
stat.close();
conn.close();
System.out.println("TestJdbc.main()....");
- 将以上用到的对象需要关闭,遵循后进先出原则
- 对象长时间存在于内存中会占用空间,所以需要释放,类似于IO流.
public class JdbcDemo1 {
public static void main(String[] args) throws Exception {
//1.注册数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取数据库连接
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai",
"root", "root");
//3.获取传输器
Statement stat = conn.createStatement();
//4.发送SQL到服务器执行并返回结果集
String sql = "select * from account";
ResultSet rs = stat.executeQuery( sql );
//5.处理结果(将rs对象中的数据遍历)
while( rs.next() ) {
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id+" : "+name+" : "+money);
}
//6.释放资源
rs.close();
stat.close();
conn.close();
System.out.println("TestJdbc.main()....");
}
}
1.3.2 通过JDBC实现数据的增删改操作
- Tips: @Test可以添加在一些符合规则的方法上,在不添加main方法的情况下也可以运行程序,不选中任何方法名运行(Runs)则运行所有测试,单元测试有自己的运行顺序,不是按照书写顺序
- 增删改数据库返回的是一个数值,表示增删改操作完成后影响的行数
1️⃣新增表记录
-
SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层与应用层之间对网络连接进行加密。
-
int rows = stat.executeUpdate(sql);
该方法的返回值为int类型的数值,表示影响的行数
//释放资源
stat.close();
conn.close();
- 不需要释放rs,没有使用ResultSet 结果集对象
/* 1、新增:往account表中添加一个id为null(主键自增)名称为john、money为3500的记录 */
@Test
public void testAddd() {
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
Connection conn = DriverManager.getConnection(
"jdbc:mysql:///jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai&userSSL=false",
"root", "root");
//获取传输器
Statement stat = conn.createStatement();
//发送sql语句到服务器执行,并返回执行结果
String sql = "insert into account values(null, 'john', 3500)";
int rows = stat.executeUpdate(sql);
//处理结果
System.out.println("影响行数: " + rows);
//释放资源
stat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
2️⃣修改和删除只需要改变sql语句即可,其他无需变动
/* 2、修改:将account表中名称为john的记录,money修改为1500 */
@Test
public void testUpdate() {
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai",
"root", "root");
//获取传输器
Statement stat = conn.createStatement();
//发送sql语句到服务器执行,并返回执行结果
String sql = "update account set money=1500 where name='john'";
int rows = stat.executeUpdate(sql);
//处理结果
System.out.println("影响行数: " + rows);
//释放资源
stat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
1.4 JDBC连接数据库的优点和缺点
- 优点:
使用JDBC连接并访问数据库 相比使用第三方的框架连接访问数据库速度要快一些!因为这是最为传统,最为底层的方法;框架包装了很多层容易报错. - 缺点:
1️⃣JDBC中包含大量重复的代码(比如每次连接数据库都需要 注册驱动、获取连接、获取传输器、处理结果、释放资源等),后期难以维护
2️⃣JDBC自身没有连接池,而底层遵循TCP协议,需要获取连接才能与数据库通讯,而框架(mybatis自带连接池)自带连接池,当需要连接直接从连接池中获取,用完连接不用关闭,再还回连接池中,这样可以提高执行效率!连接池就是将连接对象置于池中,随用随取,用完返还.
3️⃣ JDBC中执行select查询语句的结果需要开发人员自己手动处理, 如果是非常复杂的数据(比如查询的结果中列数非常多或者查询的数据来自多张表)处理起来是非常麻烦的,但框架可以帮我们处理
如:String s1 = "abc"
String s2= "abc"
第一次声明常量池中没有’abc’对象,则在常量池中创建’abc’的对象,声明s2对象时即可直接调用
1.5 连接池概念
- 如果不使用连接池:
用户每次需要连接访问数据库时, 都需要创建一个连接(Connection), 基于这个连接去访问数据库中的数据, 用完连接(Connection)后会将连接关闭(close), 其实每次创建连接和关闭连接(相比使用连接)需要消耗大量的时间和资源,导致程序的执行效率低下(特别是高并发的时候,比如京东618) - 如果使用连接池:
可以在程序一启动之后,就创建一批连接放在一个池中(容器Container 如数组集合等), 当用户需要连接时, 不用自己创建, 而是从连接池中获取一个连接对象, 再基于这个连接对象去访问数据库, 用完连接后, 不用将连接关闭, 而是还回连接池中。这样一来,用户使用的都是池中的这一批连接,可以减少连接创建和关闭的次数,提高程序的执行效率!
2.数据库事务(Database Transaction)
2.1 事务的概念
事务就是将一堆SQL语句绑定在一起执行, 执行结果是: 所有SQL都执行成功了才算成功, 但凡有一条失败, 就按全失败来处理(比如即使执行成功的语句,也会进行回滚,就是撤销当前的执行)
- 以转账为例: A、B账户各有1000元,A给B转账100元
A账户减去100元:update account set money=money-100 where name=‘A’;
B账户加上100元:update account set money=money+100 where name=‘B’;
如果上面两条语句执行时,没有事务,如果第一条成功,但第二条失败了! 钱丢了
反之,如果第一条失败了,但第二条成功了! 钱多了
所以如果想保证上面的两条SQL语句同时成功或者同时失败,可以将这两条SQL添加到一个事务中。
2.2 事务的四大特征(面试题)
1️⃣ 原子性:即事务不可被分割, 事务中的所有SQL是一个整体。不存在一部分SQL执行成功,而另一部分SQL执行失败,都执行成功才算成功,有一条失败就算失败!
2️⃣一致性:在事务执行前后(不管事务最后是提交还是回滚)的业务数据之和是保持一致的!
- 转账前后AB账户金额之和保持不变
3️⃣隔离性:在事务并发时, 一个事务理论上看不到另外一个事务的状态, 也就是说事务之间是相互隔离开来的.即事务开启后到事务结束前,Sql语句并未生效.
- 在两个事务同时执行并且访问相同数据时,事物之间不可见(打开两个mysql命令窗口执行sql互不影响) ,一个事务只能看到另一个事务没开始之前的数据状态,或只能看到另一个事务结束后的数据状态
4️⃣ 持久性:一旦事务提交之后, 事务中对数据的更新操作会持久的保存到数据库中(最终是更新到硬盘的数据文件里)
反过来说, 在事务提交之前, 对数据的更新操作只是一个临时的数据, 没有真正的去修改数据库。
– 开启事务:
A减去100元: update account set money=money-100 where name=‘A’; 900元
B加上100元: update account set money=money+100 where name=‘B’; 1100元
– 结束事务(提交,回滚)
持久存储:数据存储在硬盘上
非持久存储:数据信息存储在内存中,比如在事务未执行完成时(提交或回滚),比如Radis缓存数据
2.3 Mysql的事务操作
- 在默认情况下, mysql中每执行一条SQL语句,都是一个单独的事务,即使不开启事务, 每执行一条SQL之前, 自动开启事务, 执行完这条立即提交事务
- 如果需要在一个事务中包含多条SQL语句, 那么就需要手动开启事务, 和手动结束事务
开启事务: begin; | start transaction;
结束事务: 提交(commit), 回滚(rollback)
案例: 左边命令框未提交事务,右边命令框看不到数据的改变!
MariaDB [jt_db]> begin;
Query OK, 0 rows affected (0.000 sec)
MariaDB [jt_db]> -- A账户减去100元
MariaDB [jt_db]> update acc set money=money-100 where name='A';
Query OK, 1 row affected (0.000 sec)
MariaDB [jt_db]> -- B账户加上100元
MariaDB [jt_db]> update acc set money=money+100 where name='B';
Query OK, 1 row affected (0.000 sec)
3.Maven
3.1Maven简介
Maven: 翻译为"专家"、“内行”,是Apache下的一个纯Java开发的一个开源项目。
Maven是一个项目管理工具,使用Maven开发,可以简化项目配置,统一项目结构。使用Maven可以来管理企业级的Java项目开发及依赖的管理。
🔺通过Maven创建Maven项目,通过Maven帮我们下载和管理项目中所需要的依赖
🔺依赖:比如前面创建的JDBC项目中引用了一个mysql驱动包,如果将这个Jar包从项目中移除会导致项目无法运行,此时我们说这个项目依赖于mysql驱动包(也就是依赖于这个jar包)
而所谓的依赖管理,其实就是对项目中所有依赖的jar包进行规范化管理。
3.2Maven下载,安装,配置
3.2.1下载安装Maven
1️⃣官方下载地址:http://maven.apache.org/download.cgi
2️⃣下载绿色版,解压之后就可以使用
3️⃣若要下载旧版本Maven,可以访问:https://archive.apache.org/dist/maven/maven-3/
3.2.2 配置Maven本地仓库
1️⃣什么是本地仓库:
本地仓库:其实就是本地硬盘上的某一目录,该目录中会包含maven项目中所需要的所有jar包及插件。如果不配置本地仓库,maven会使用一个默认路劲作为本地仓库:
c:/uses/{当前用户}/.m2/repository
如果没有这个目录,maven会再第一次使用时自动创建以上目录
2️⃣如何配置本地仓库
**[maven的安装目录]**找到[MAVEN_HOME]/conf/目录中的配置文件settings.xml,修改maven仓库的路径
<localRepository>D:/JavaDevelop/localRepo</localRepository>
3.2.3配置Maven远程仓库
1️⃣什么是远程仓库
如果不配置远程仓库,默认连接中央仓库下载所需要的jar包,中央仓库是maven团队维护的jar包仓库,其中包含了全世界几乎所有的jar包,中央仓库面向的是全球用户,所以在下载jar包时,速度可能会比较慢,效率会比较低。
总结:如果不配置远程仓库,默认连接中央仓库下载所需的jar包和插件,保存到本地仓库中!
2️⃣如何配置远程仓库
配置连接阿里云远程仓库
配置方法:找到maven安装目录找到[MAVEN_HOME]/conf/目录中的配置文件settings.xml–标签
配置连接阿里云远程仓库:
<mirror>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<mirrorOf>central</mirrorOf>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
3.2.4配置Maven的JDK版本
通过 Maven创建的工程,JDK版本默认是JDK1.5,每次都需要手动改为更高的版本。
配置方式为:打开 {maven根目录}/conf/settings.xml
文件并编辑,在 settings.xml文件内部的 <profiles>
标签内部添加如下配置:
<profile>
<id>development</id>
<activation>
<jdk>1.8</jdk>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
🔺以上的本地仓库配置,远程仓库配置和jdk配置在新的maven软件中是没有的,需要自己添加
3.2.5将Maven整合到eclipse
将Maven工具配置到Eclipse中,就可以通过Eclipse和自己安装的Maven创建Maven项目了。
1.window右键–> Preferences
2.点击Maven选项,在右侧选项中勾选 "Download Artifact Sources"
3.点击add将自己安装的Maven添加进来
4.添加自己安装的Maven目录
5.将默认的maven切换为自己配置的maven
6.设置maven的settings文件的位置
7.测试是否配置成功:window—> show view —> other中搜索"maven"–>Maven Repositories.
在弹出的窗口中,查看自己配置的本地仓库和远程仓库镜像:
🔸一定要注意:自己安装的Maven不要放在桌面上(容易丢失,并且路径中往往有空格),**maven的安装路径中也不要包含中文和空格!!
3.3 Maven项目的构建
通过Maven构建Java项目分为两种方式:
(1)使用简单方式创建:可以创建Maven的简单Java项目以及创建Maven的简单Web项目
(2)使用模板方式创建:创建使用模板的Java项目以及创建使用模板的Web项目
这里我们选择第一种方式
3.3.1 通过Maven创建Java项目
1️⃣空白处右键New —> Maven Project
2️⃣在弹出的窗口中,勾选前面的框,创建一个简单工程(即不使用骨架),进入下一步
3️⃣在弹出的窗口中,填写内容(Package选择jar,即创建java工程),点击完成即可。
在上述内容中,必填的内容有四项:
(1)Group Id – 组的名称,通常填写公司名称(比如com.tedu)或者组织名称(org.apache…)
(2)Artifact Id – 项目名称或者模块名称
(3)Version – 项目的版本,创建的项目默认是0.0.1-SNAPSHOT快照,也叫非正式版,正式版是RELEASE)
(4)Package – 项目的类型:jar表示创建的是Java工程,war表示创建的是web工程,pom表示创建的是父工程(当然相对的还有子工程)或者聚合工程,pom目前我们不讨论。
填写完毕后,点击完成即可完成创建简单Java工程
3.3.2通过Maven创建Web项目
1、空白处右键New —> Maven Project:
2、在弹出的窗口中,勾选前面的框,创建一个简单工程(即不使用骨架),进入下一步。
3、在弹出的窗口中,填写内容(Package选择war,即创建web工程),点击完成即可。
4、创建完成后pom.xml文件会报错,说找不到web.xml文件,例如:
解决方法:在[Package Explorer]视图窗口中,在Web项目上右键 ==》选择:JavaEE Tools ==》选择:Generate Deployment…,webapp目录下就会生成WEB-INF目录和web.xml文件
5、创建Servlet程序,测试运行环境。
上面的错误是因为运行环境中缺少Servlet的jar包,将tomcat运行环境添加过来即可!
!!缺少Servlet运行环境解决方案:
在项目上点击鼠标右键,选择 “Build Path” —> “Add Libraries…”,再选择 “Server RunTime”,选中下图中的 “Apache Tomcat v8.5”,最后点击 Finish 完成即可!
或者,在项目中的pom.xml文件中的根标签下添加Servlet的jar包的坐标,引入Servlet的jar包,如下:
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
添加后保存pom文件。若还报错,在项目上右键选择 “Maven” —> “UpdateProject…” 更新工程即可!
6、测试访问:打开浏览器访问地址:http://localhost:8080/MavenSimpleProJavaWeb/HelloServlet
3.3.3 Maven项目的目录结构
以 CGB-Maven-Web01 项目为例来进行说明:
目录 | 说明 |
---|---|
src/main/java(源码目录) | 存放主程序/项目里的Java源文件(.java文件) |
src/main/resources(源码目录) | 存放项目所需要的配置文件(比如.xml,.properties.yml.yaml) |
src/test/java(源码目录) | 存放测试相关的java源文件 |
src/test/resources(源码目录) | 存放测试程序所需要的配置文件 |
src/main/webapp (相当于web应用目录) | 存放web资源文件(html/css/js/jsp/图片等…) |
src/main/webapp/WEB-INF/web.xml | Web应用的核心配置文件 |
target/classes | 源码目录中的文件经过编译后会输出到classes目录 |
pom.xml | Maven项目的配置文件 |
3.4Maven的依赖管理
3.4.1在Maven项目中引入依赖
❓如何在maven项目中引入mysql驱动包?
在项目的pom.xml文件中添加jar包的坐标标签(GroupID, ArtifactID, Version) 即可将jar包引进项目中,之后就可以在项目中使用所引入的jar包了。
在pom.xml文件中,添加mysql驱动包的坐标如下:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
</dependencies>
❓引入到maven项目中的依赖存放在哪个位置
存放在本地仓库中,具体位置[本地仓库位置+当前jar包的坐标]
如:在项目的pom文件中引入了mysql 8.0.11的驱动包,而本地仓库的位置是D:\JavaDevelop\localRepo
那么mysql80.011的jar文件位置是:D:\JavaDevelop\localRepo\mysql\mysql-connector-java\8.0.11
❓本地仓库的jar包来源:
3.4.2 Maven三种仓库的联系
1️⃣本地仓库:就是本地硬盘上的一个目录,用于存放[远程仓库]或者[中央仓库]下载下来的jar文件
2️⃣远程仓库:通常是由公司或团队搭建,服务于公司或团队的内部远程仓库,远程仓库刚搭建完毕时,内部几乎没有jar包,其中的jar包是从中央仓库下载下来并保存到远程仓库中
3️⃣中央仓库:中央仓库也叫做公服,在maven软件中内置了一个仓库地址(http://repo1.maven.org/maven2)它就是中央仓库,服务于整个互联网,由Maven团队自己搭建并维护,里面存储了非常全的jar包,它包含了世界上大部分流行的开源项目的jar包。
3.4.3添加jar包的两种方式
手动添加依赖需要指定所依赖jar包的坐标,大部分情况下,我们是不知道jar包的坐标的。可以通过访问如下网址,在互联网上搜索查询:
http://mvnrepository.com
http://maven.ityuan.com/
3.5Maven项目常见问题
3.5.1常见环境问题
1️⃣问题描述1:
-
创建Maven项目时报如下错误:
-
或者创建Maven项目目录结构不全(比如只有src目录),如下图:
-
导入已有的Maven项目,项目运行不了(jar没有下载完全)
此时是因为maven的环境被破坏了,导致Maven基础运行环境不全,无法创建Maven项目,或者无法下载所需要的jar包。解决方法:
1)确保当前网络环境是否能连接上所配置的远程仓库,接着进行第2步。(若不在达内教室,是无法连接达内的远程仓库;又或者使用手机热点网络将无法连接阿里云的远程仓库等)
2)在项目的pom文件中敲一个空白行,再保存文件。(目的是让maven检测到pom文件发生了变化,再根据pom文件中的配置,到本地仓库中寻找对应的jar包,如果没有相应的jar包,maven会重新下载),
3)接着在项目上,右键—> Maven —> Update Project…,在弹出的窗口中勾选下方的 “[]Force Update…”,即强制更新项目,此时maven也会检查pom文件,下载没有引入的相关依赖。
4)如果以上操作还是不行,到本地仓库的目录下,将本地仓库中所有的目录都删除,删除时,由于eclipse正在使用本地仓库中的资源文件,所以会阻止删除,此时将eclipse关闭,再将本地仓库中的所有目录删除,重启eclipse。
5)启动eclipse后,再将上面的第(1)步和第(2)步再做一遍!
6)如果还是不行,就使用老师下发的本地仓库替换你的本地仓库!
2️⃣问题描述2:
每天第一次打开Eclipse发现之前创建的Maven工程报错(比如项目上有叉号或者叹号,但项目之前是OK的),解决方法:在菜单栏中找到 Project —> Clean…
或者是:在报错的项目上鼠标右键 --> Maven --> Update Project:
3.5.2找不到jar包问题
在项目中通过坐标引入了jar包(或者插件),并且本地仓库中也存在对应的jar包,但是项目还是报错,提示内容说找不到。
解决方法:如果引入的jar包,在本地仓库中存在,但是还是提示找不到,可以将本地仓库中jar包或插件的所在目录整个删除(如果删除时提示文件正在被占用,关闭eclipse再删除即可),重新保存pom.xml文件,并更新工程,让maven再次下载上面的jar包即可!
3.6Maven的依赖范围
下面添加了一个 jsp-api 的依赖,maven就会去下载 jsp-api 的jar包及它依赖的一些jar包。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
依赖配置中有一个scope标签,它就是依赖范围。
1、什么是依赖范围:就是指定你这个jar包在哪个阶段时才有效。
- compile - 编译依赖范围。默认的范围,可以不填,表示在所有过程中都有效,如编译期、测试过程中、运行期间等。
- provided - 已提供依赖范围。这个范围表示只提供编译和测试阶段有效,运行期间不需要,像tomcat等容器本身已经提供的 servlet-api、jsp-api 等依赖。
- runtime - 运行时依赖范围。这个范围表示只有在运行和测试期间才有效,编译期间不需要,像连接数据库的jdbc驱动程序等。
- test - 测试依赖范围。这个范围只有测试阶段有效,编译和运行不需要,像单元测试提供的junit包。
- system - 系统依赖范围。这个范围表示不依赖本地仓库,jar在其他的目录,需要通过systemPath指定路径,这个不建议使用。
- import - 引用依赖范围。Maven2.0.9之后新增的范围,只能用在中,并且导入的type为pom类型的父工程配置,一般用来解决多继承问题。
2、什么是依赖传递:
依赖的传递通过继承和聚合的方式可以达到,通过继承的方式可以轻松的从父项目继承过来,通过聚合的方式也可以间接的传递过来。
继承:A继承B,A就可以继承B的依赖(dependencies)
聚合:A依赖C,C依赖D,那么A就要依赖D自然也就获取了D的依赖。
3、什么是依赖排除:
在依赖传递过程中,如 A 依赖 B、S2.0,B 依赖C、S1.0,这样A就有了S1.0和S2.0两个依赖,这样某些情况下会造成冲突需要手动把B间接传递过来的依赖排除掉,就是不依赖B带过来的S1.0的包。
<dependency>
<groupId>org.testgroupId>
<artifactId>B</artifactId>
<version>1.0</version>
<!-- 排除B传递过来的S依赖 -->
<exclusions>
<exclusion>
<groupId>com.test</groupId>
<artifactId>S</artifactId>
</exclusion>
</exclusions>
</dependency>
或者直接设置 排除所有间接依赖:
<dependency>
<groupId>org.testgroupId>
<artifactId>B</artifactId>
<version>1.0</version>
<!-- 排除B传递过来的所有依赖 -->
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>