maven高级
一 Maven基础知识回顾
1 介绍
maven 是一个项目管理工具,主要作用是在项目开发阶段对Java项目进行依赖管理和项目构建。
依赖管理:就是对jar包的管理。通过导入maven坐标,就相当于将仓库中的jar包导入了当前项目中。
项目构建:通过maven的一个命令就可以完成项目从清理、编译、测试、报告、打包,部署整个过程。
2 仓库类型
1.本地仓库
2.远程仓库
- maven中央仓库(地址:http://repo2.maven.org/maven2/)
- 镜像
- maven私服(公司局域网内的仓库,需要自己搭建)
- 其他公共远程仓库(例如apache提供的远程仓库,地址:http://repo.maven.apache.org/maven2/)
开发中一般会配置一个阿里云镜像,可以更快的将jar包从中央仓库中下载到本地
3 常用命令
- clean: 清理 清理target目录
- compile:主要编译main目录下的java代码
- test: 编译和测试 会把项目中所有代码都编译,并且会运行test包下的java代码
- package: 打包 将我们的项目打成war或者jar包,也会执行test中操作,包中不包含测试代码
- install:安装 将项目进行打包,且安装到本地仓库中
- deploy:部署 将项目进行导包,安装到本地仓库中,且还会将包安装到私服中
maven的三套生命周期
- 清理生命周期:clean,清理项目
- 默认生命周期: compile test package install deploy
- 站点生命周期:site
4 坐标书写规范
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
<scope>compile</scope>
</dependency>
5 依赖范围
依赖范围 | 对于编译classpath有效 | 对于测试classpath有效 | 对于运行时classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | - | Y | - | Junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | JDBC驱动 |
system | Y | Y | - | 导入本地的,maven仓库之外的类库(几乎用不上) |
切记:servlet和jsp依赖范围需要配置为provided
6 jdk版本配置
maven中自带jdk5,可以通过插件或properties进行配置jdk8
maven中自带tomcat6,一般不用,也可以通过插件配置tomcat7
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
7 镜像
下载jar包的时候若本地没有(若有私服,私服上也没有的话),会去中央仓库的默认地址上下载 , 中央仓库在国外,下载的时候比较慢,在实际开发中我们一般会配置阿里的镜像.只需要去maven的setting.xml中的mirrors中配置即可
https://help.aliyun.com/document_detail/102512.html?spm=a2c40.aliyun_maven_repo.0.0.36183054hGGQov
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
二 Maven的依赖传递
1 什么是依赖传递
在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B以及项目C。假设A依赖B,B依赖C,那么我们可以根据maven项目依赖的特征不难推出项目A也依赖C。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RCiiqDqY-1623738297698)(maven高级.assets/图片3.png)]
通过下面的图可以看到,我们的web项目直接依赖了spring-webmvc,而spring-webmvc依赖了sping-aop、spring-beans等。最终的结果就是在我们的web项目中间接依赖了spring-aop、spring-beans等。
2 什么是依赖冲突
由于依赖传递现象的存在, spring-webmvc 依赖 spirng-beans-4.2.4,spring-aop 依赖 spring-beans-5.1.5,但是发现 spirng-beans-4.2.4 加入到了工程中,而我们希望 spring-beans-5.1.5 加入工程。这就造成了依赖冲突。
3 如何解决依赖冲突
- 使用maven提供的依赖调解原则
- 第一声明者优先原则
- 路径近者优先原则
- 排除依赖
- 锁定版本
4 依赖调解原则(了解)
第一声明者优先原则
在 pom 文件中定义依赖,以先声明的依赖为准。
其实就是根据坐标导入的顺序来确定最终使用哪个传递过来的依赖。
路径近者优先原则
在pom 文件定义依赖,以路径近者为准。
**还是上述情况:**spring-aop和spring-webmvc都传递过来了spring-beans,那如果直接把spring-beans的依赖直接写到pom文件中,那么项目就不会再使用其他依赖传递过来的spring-beans,因为自己直接在pom 中定义 spring-beans要比其他依赖传递过来的路径要近。
5 排除依赖
可以使用exclusions标签将传递过来的依赖排除出去。
例如:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
</dependencies>
6 锁定版本
采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中经常使用。
我们可以把版本号提取出来,使用properties标签设置成变量
<properties>
<!--自定义maven坐标的版本号-->
<spring.version>5.1.5.RELEASE</spring.version>
</properties>
第一步:在dependencyManagement标签中锁定依赖的版本
<!--
jar包的版本锁定
<dependencyManagement> 并不会实现依赖的导入操作,只是版本的声明锁定
如果我们项目中需要导入坐标 还是来用dependencies
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
第二步:在dependencies标签中声明需要导入的maven坐标
<!--
导入坐标 依赖管理
我们开发者只需要通过 <dependencies> 标签
导入坐标的 <groupId> 和 <artifactId> 即可,这样也不会出现依赖冲突的问题
-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
</dependencies>
三 Maven构建工程
需求基于maven构建 SSM工程,规范依赖管理 , 拆分spring的配置文件 , 每层都有自己的配置文件。
场景:查询所有账户信息
1 创建web工程
名字叫:ssm-account-maven
2 通过版本锁定,导入依赖
<properties>
<spring.version>5.1.5.RELEASE</spring.version>
<mybatis.version>3.5.1</mybatis.version>
<mysql.version>5.1.32</mysql.version>
<mybatis-spring.version>1.3.2</mybatis-spring.version>
<druid.version>1.0.9</druid.version>
<aspectjweaver.version>1.9.2</aspectjweaver.version>
<junit.version>4.12</junit.version>
<jackson.version>2.9.9</jackson.version>
</properties>
<!--锁定依赖版本-->
<dependencyManagement>
<dependencies>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- springMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!--添加依赖-->
<dependencies>
<!-- Mybatis和mybatis与spring的整合 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!-- MySql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- spring相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectjweaver.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- springMVC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!--servlet和jsp-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<!--工具类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 设置编译版本为1.8 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
3 搭建mybatis环境
Account实体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
private Integer id;
private String name;
private Double money;
}
applicationContext-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--加载配置文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 让spring管理sqlsessionfactory 使用mybatis和spring整合包中的 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 实体类型别名 -->
<property name="typeAliasesPackage" value="com.itheima.domain"/>
</bean>
<!-- mapper扫描器 :用来产生代理对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mapper"/>
</bean>
</beans>
4 搭建spring环境
AccountService接口和实现
applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.itheima.service"/>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--事务运行规则-->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--aop配置-->
<aop:config>
<aop:pointcut id="pc" expression="execution(* com.itheima.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
</aop:config>
</beans>
5 搭建springMVC环境
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启组件扫描-->
<context:component-scan base-package="com.itheima.web"/>
<!--开启mvc注解支持-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--静态资源放行-->
<mvc:default-servlet-handler/>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 监听器监听其他的spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
四 分模块构建Maven工程
1 什么是分模块构建
在现实生活中,汽车厂家进行汽车生产时,由于整个生产过程非常复杂和繁琐,工作量非常大,所以车场都会将整个汽车的部件分开生产,最终再将生产好的部件进行组装,形成一台完整的汽车。
在企业项目开发过程中,由于项目规模庞大,业务复杂,参与的人员比较多,一般会通过合理的模块拆分将一个大型的项目拆分为N多个小模块,分别进行开发。而且拆分出的模块可以非常容易的被其他模块复用。
常见的拆分方式有两种:
第一种:按照业务模块进行拆分,每个模块拆分成一个maven工程,例如将一个项目分为用户模块、订单模块、购物车模块等,每个模块对应就是一个maven工程
第二种:按照层进行拆分,例如持久层、业务层、表现层等,每个层对应就是一个maven工程
不管是上面哪种拆分方式,通常都会提供一个父工程,将一些公共的代码和配置提取到父工程中进行统一管理和配置。
2 maven工程继承
在Java语言中,类之间是可以继承的,通过继承,子类就可以引用父类中非private的属性和方法。
同样,在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。继承的目的是为了消除重复代码。
父工程不知道自己的孩子是谁
子工程知道自己的父亲是谁
在子工程中通过parent标签确定
最终会在子模块的pom中通过parent标签声明当前模块的父模块
3 maven工程聚合
通过父工程进行统一的操作.
父工程知道有哪些孩子
子工程不知道自己的父工程是谁
通过在父工程使用moudles和moudle标签确定的
五 Mybatis逆向工程
Mybatis是目前非常流行的持久层框架,其逆向工程更是大大缩减了我们的开发时间。所谓mybatis逆向工程,就是Mybatis会根据我们设计好的数据表,自动生成pojo(实体)、mapper(接口)以及mapper.xml(映射)
官网地址:https://mybatis.org/generator/
1 导入工程
把资料中的工程导入到工作空间中
使用插件生成
注意:创建不要多次点击,否则会重复生成代码,追加到文件中,执行报错!!!
2 方法介绍
CRUD
条件查询
> gt
= eq
< lt
* 条件说明
* criteria.andXxxIsNull 添加字段xxx为null的条件
* criteria.andXxxIsNotNull 添加字段xxx不为null的条件
* criteria.andXxxEqualTo(value) 添加xxx字段等于value条件
* criteria.andXxxNotEqualTo(value) 添加xxx字段不等于value条件
* criteria.andXxxGreaterThan(value) 添加xxx字段大于value条件
* criteria.andXxxGreaterThanOrEqualTo(value) 添加xxx字段大于等于value条件
* criteria.andXxxLessThan(value) 添加xxx字段小于value条件
* criteria.andXxxLessThanOrEqualTo(value) 添加xxx字段小于等于value条件
* criteria.andXxxIn(List<?>) 添加xxx字段值在List<?>条件
* criteria.andXxxNotIn(List<?>) 添加xxx字段值不在List<?>条件
* criteria.andXxxLike("%"+value+"%") 添加xxx字段值为value的模糊查询条件
* criteria.andXxxNotLike("%"+value+"%") 添加xxx字段值不为value的模糊查询条件
* criteria.andXxxBetween(value1,value2) 添加xxx字段值在value1和value2之间条件
* criteria.andXxxNotBetween(value1,value2) 添加xxx字段值不在value1和value2之间条件
@ContextConfiguration("classpath:spring/applicationContext-dao.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class TestDao {
@Autowired
AccountMapper accountMapper;
@Test
//条件查询
public void testSelect() {
AccountExample accountExample = new AccountExample();
//获取具体条件对象
AccountExample.Criteria criteria = accountExample.createCriteria();
//添加条件
//criteria.andNameEqualTo("jack");
criteria.andNameLike("%a%");
criteria.andMoneyGreaterThan(1000);
//排序操作
accountExample.setOrderByClause("id desc");
List<Account> list = accountMapper.selectByExample(accountExample);
System.out.println(list);
}
@Test
public void testFindById() {
Account account = accountMapper.selectByPrimaryKey(1);
System.out.println(account);
}
@Test
public void testInsert() {
Account account = new Account();
account.setMoney(200);
//int i = accountMapper.insert(account);
int i = accountMapper.insertSelective(account);
System.out.println(i);
}
@Test
public void testUpdate() {
Account account = new Account();
account.setId(5);
//account.setMoney(500);
account.setName("张大拿");
//accountMapper.updateByPrimaryKey(account);
accountMapper.updateByPrimaryKeySelective(account);
}
@Test
public void testDelete() {
accountMapper.deleteByPrimaryKey(4);
}
}