maven依赖学习

前两篇博客分别学习了maven环境搭建,手动创建maven工程,配置eclipse下的maven环境,今天学习maven的依赖关系。

我们现在已经知道使用maven来管理项目,我们可以方便的分模块来开发,这里我创建一个用户管理系统,并且分模块的来开发,并且配置依赖关系,来深入理解maven的依赖关系。

创建maven工程

这里我首先创建一个核心模块,打开eclipse->new->maven project
这里写图片描述
这里选择”maven-archetype-quickstart”
这里写图片描述
这里需要填写工程中pom.xml文件需要的基本内容:
groupId
artifactId
package
完成之后,maven会自动帮我们创建好目录已经pom.xml文件。
这里写图片描述

依赖的查询

在工程中总是要用到其他的一些包,在maven中所有的依赖都是通过坐标来表示的,也就是我们前面提到的(groupId,artifactId,version)通过这三个坐标描述的值,就可以确定一个唯一的依赖。

仓库查询的网站

http://mvnrepository.com/
这里我们需要用到hibernate的core模块,进入该网站搜索hibernate,选择hibernate-core,这里我选择4.1.0
这里写图片描述
如图,将上边的依赖复制到我们的pom.xml中的dependencies标签中,就可以添加hibernate4.0的核心包以及其依赖的所有包。如下图:
这里写图片描述

添加实体类和映射文件

创建Users.java

在”src/main/java”中创建实体类:Users.java

package com.test.user.user_core;

public class Users {

    private int uid;
    private String uname;
    private double uage;

    public Users(){}

    public Users(String uname, double uage) {
        this.uname = uname;
        this.uage = uage;
    }

    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public double getUage() {
        return uage;
    }
    public void setUage(double uage) {
        this.uage = uage;
    }   
}

创建Users.hbm.xml

在maven中所有的资源都是存放在”src/main/resources”文件夹中的,所以我们在该文件夹中新创建一个com.test.user.user_core包,并将Users.hbm.xml放到该包下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.test.user.user_core.Users">
        <id name="uid">
            <generator class="increment"/>
        </id>

        <property name="uname"/>
        <property name="uage"/>

    </class>
</hibernate-mapping>    

创建hibernate.cfg.xml

同样hibernate.cfg.xml也属于资源文件,因此我们同样将其放到”src/main/resources”目录下。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">root</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">true</property>
        <mapping resource="com/test/user/user_core/Users.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

记得要在hibernate.cfg.xml中配置该映射文件:

<mapping resource="com/test/user/user_core/Userinfo.hbm.xml"/>

注意,这里使用到了mysql,所以需要添加mysql的依赖
这里写图片描述

创建实体类对应的表

到目前为止所有的实体类和映射文件都已经写好了,现在需要生成实体类对应的表,运行下面这段代码:

Configuration cfg = new Configuration().configure();
SchemaExport exp = new SchemaExport(cfg);
exp.create(true, true);

编写测试类

在maven中所有的测试类代码都是存放在”src/test/java”文件夹中的,我们在该文件夹中新建UserTest.java,这里我只测试一个添加的方法。

package com.test.user.user_core;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class UserTest {

    @Test
    public void testAdd() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory(); 
        Session session = factory.openSession();                
        try {
            session.beginTransaction();                             
            Users u = new Users("444",13);
            session.save(u);                                        
            session.getTransaction().commit();                      
        } catch (HibernateException e) {
            e.printStackTrace();
            session.getTransaction().rollback();                    
        }

        session.close();                        
    }


}

使用maven编译测试

到现在为止,测试方法已经写好了,我们可以测试添加user的方法了。
1.右键pom.xml文件
2.run as
3.maven build
此时会出现如下界面:
这里写图片描述

注意,此时运行可能会出现如下错误:

-Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment variable and mvn script match.

解决办法

可以设一个环境变量M2_HOME指向你的maven安装目录
M2_HOME=D:\Apps\apache-maven-3.3.1
然后在Window->Preference->Java->Installed JREs->Edit
在Default VM arguments中设置
-Dmaven.multiModuleProjectDirectory=$M2_HOME
这里写图片描述

还可能会有如下错误

Unknown system variable ‘language’
解决办法

这是因为我使用的依赖mysql的jar文件是mysql-connector-java-5.1.36.jar,这个版本太高了,改用mysql-connector-java-5.1.24.jar版本即可

此时运行”Maven build”,已经成功将数据插入到数据库了。
这里写图片描述

完整的工程结构如下图:

这里写图片描述

打包工程

运行clean install命令打包该工程,需要注意的是,运行该命令的时候,maven会自动运行clean test package install这几个命令
此时会在target目录下生成user-core-0.0.1-SNAPSHOT.jar的包,并且会打包到本地仓库中:
这里写图片描述

依赖的传递性

接下来在创建一个”user-dao”工程来说明”依赖的传递性”
在该工程中,引入user-core的依赖

<dependency>
    <groupId>com.test.user</groupId>
    <artifactId>user-core</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

这里写图片描述
可以看到,user-dao并没有添加hibernate和mysql的依赖,却自动拥有这些jar文件,这是因为user-dao依赖于user-core,而user-core模块又依赖于hibernate和mysql,这就是依赖的传递性。
注意:依赖传递性的范围默认是基于scope是”compile”的,如果是其他的则默认是不会传递的

依赖的范围

依赖的范围分为以下几点:
1.test:只会在测试返回有效,在编译和打包时候,都不会使用该依赖
2.compile:在编译范围有效,在编译和打包时候,都会使用
3.provided:在编译和测试的过程有效,在最后生成war包时候,不会加入。
4.runtime:在运行的时候依赖,在编译的时候不依赖。
默认的依赖范围是compile

依赖传递性的冲突问题

试想如果出现如下现象:
user-core工程依赖于hibernate4.1版本
user-dao 工程依赖于hibernate5.1版本
那么此时,当user-service工程依赖既依赖于”user-core”又依赖于”user-dao”这两个工程,那么根据依赖的传递性,此时”user-service”到底依赖于hibernate4.1版本还是hibernate5.1版本呢??
分两种情况

当依赖的路径长度相同的时候

a->b1.0
c->b1.1
d->a,c
可以看到此时对于d来说依赖于a和c,依赖的路径长度是相同的,那么此时在d的pom.xml依赖当中,那么依赖先写,就优先依赖那个版本。
比如在d的pom.xml中是这样写的

<dependencies>
        <dependency>
            <groupId>c</groupId>
            ...
        </dependency>

        <dependency>
            <groupId>a</groupId>
            ...
        </dependency>
    </dependencies>

可以看到此时c的依赖关系是在a的依赖关系之前的,那么此时d会首先依赖c的依赖,也就是b1.0版本。

当依赖的路径长度不同的时候

  1. a->b1.0
  2. c->b1.2
  3. d->a,c (a的依赖在c的前面,所以此时d依赖于b1.0)
  4. f->d,c

可以看到此时f->c->b1.2有两级路径 ,而f->d->a->b1.0有三级路径,此时,虽然在pom.xml文件当中,d的依赖在c的依赖前面配置,但是优先会选择路径较短的依赖,所以此时f依赖的是b1.2版本。

自定义依赖关系

对于上面提到的两种默认的依赖传递策略,如果我们想要更改也是可以的,比如对于
a->b1.0
c->b1.1
d->a,c

<dependencies>
        <dependency>
            <groupId>c</groupId>
            ...
        </dependency>

        <dependency>
            <groupId>a</groupId>
            ...
        </dependency>
    </dependencies>

这样的依赖,可以看到此时”d默认是依赖于b1.1”,那么,如果需要让”d依赖于b1.0”,只需要做如下配置即可。

<dependencies>
        <dependency>
            <groupId>c</groupId>
            ...
            <exclusions>
                <exclusion>
                    <groupId>b1.1的groupId</groupId>
                    <artifactId>b1.1的artifactId</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>a</groupId>
            ...
        </dependency>
    </dependencies>

源码下载

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值