手机版 欢迎访问it开发者社区(www.mfbz.cn)网站

当前位置: > 开发

JDBC+事务+Maven

时间:2021/5/31 2:56:03|来源:|点击: 次

1.JDBC(Database Transaction)

1.1概述

  • JDBC: Java DataBase Connectivity --java数据库连接
    即利用java语言连接数据库的规范
    另外连接数据库的方式 CMD命令窗口和Navicat/Sqlylog等可视化数据库软件
  • 实际开发中更多是通过java程序来连接数据库,比如Mybatis/Hibernate/DBUtils/Spring JdbcTemplate等框架底层也是在通过JDBC来连接数据库
    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.xmlWeb应用的核心配置文件
target/classes源码目录中的文件经过编译后会输出到classes目录
pom.xmlMaven项目的配置文件

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>

Copyright © 2002-2019 某某自媒体运营 版权所有