文章目录
Maven
什么是Maven
由于Jar包的错综复杂,多一个Jar包少一个Jar包就有可能导致抛出各种各样的异常,以往的程序员经常需要花费很多精力在构建Jar包上,而Maven就是一款帮助程序员构建项目的工具,我们只需要告诉Maven需要哪些Jar 包,它会帮助我们下载所有的Jar,极大提升开发效率。
Maven下载安装
Maven基本命令
-
-v:查询Maven版本
本命令用于检查maven是否安装成功。
Maven安装完成之后,在命令行输入mvn -v,若出现maven信息,则说明安装成功。 -
compile:编译
将java源文件编译成class文件 -
test:测试项目
执行test目录下的测试用例 -
package:打包
将项目打成jar包 -
clean:删除target文件夹
-
install:安装
Jar包“坐标”
- groupId:所需Jar包的项目名
- artifactId:所需Jar包的模块名
- version:所需Jar包的版本号
<dependency>
<groupId>cn.missbe.web.search</groupId>
<artifactId>resource-search</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
</dependency>
Maven项目目录结构
- main : 该目录下存放的是该项目的主要代码文件,下面有三个文件夹,分别用来存放:
java:该目录用来存放 java 的源代码文件
resources:该目录主要用来存放项目的一些配置文件(比如 spring 的 xml 配置文件)。
webapp:该目录相当于 web 项目下 webcontent 的目录,用来存放 jsp、web.xml 等文件. - test :该目录用来存放项目的测试文件
java:该目录主要存放该项目的测试所用的 java 源代码。
resources:该目录存放测试使用的资源文件。 - pom.xml
pom.xml详解
POM ( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个 XML 文件,pom.xml是Maven的核心,你的项目需要什么Jar包就在pom.xml里面配置。当编译项目时Maven读取该文件,并从仓库中下载相应的Jar包。
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd">
<!--父项目的坐标。如果项目中没有规定某个元素的值,
那么父项目中的对应值即为项目的默认值。
坐标包括group ID,artifact ID和 version。-->
<parent>
<!--被继承的父项目的构件标识符-->
<artifactId/>
<!--被继承的父项目的全球唯一标识符-->
<groupId/>
<!--被继承的父项目的版本-->
<version/>
</parent>
<!--声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,
但它仍然是必不可少的,这是为了当Maven引入了新的特性或者其他模型变更的时候,
确保稳定性。-->
<modelVersion>4.0.0</modelVersion>
<!--项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。
并且构建时生成的路径也是由此生成, 如com.mycompany.app生成的相对路径为:
/com/mycompany/app-->
<groupId>cn.missbe.web</groupId>
<!-- 构件的标识符,它和group ID一起唯一标识一个构件。换句话说,
你不能有两个不同的项目拥有同样的artifact ID和groupID;在某个
特定的group ID下,artifact ID也必须是唯一的。构件是项目产生的或使用的一个东西,
Maven为项目产生的构件包括:JARs,源码,二进制发布和WARs等。-->
<artifactId>search-resources</artifactId>
<!--项目产生的构件类型,例如jar、war、ear、pom。插件可以创建
他们自己的构件类型,所以前面列的不是全部构件类型-->
<packaging>war</packaging>
<!--项目当前版本,格式为:主版本.次版本.增量版本-限定版本号-->
<version>1.0-SNAPSHOT</version>
<!--项目的名称, Maven产生的文档用-->
<name>search-resources</name>
<!--项目主页的URL, Maven产生的文档用-->
<url>http://www.missbe.cn</url>
<!-- 项目的详细描述, Maven 产生的文档用。 当这个元素能够用HTML格式描述时
(例如,CDATA中的文本会被解析器忽略,就可以包含HTML标 签),
不鼓励使用纯文本描述。如果你需要修改产生的web站点的索引页面,
你应该修改你自己的索引页文件,而不是调整这里的文档。-->
<description>A maven project to study maven.</description>
<!--描述了这个项目构建环境中的前提条件。-->
<prerequisites>
<!--构建该项目或使用该插件所需要的Maven的最低版本-->
<maven/>
</prerequisites>
<!--构建项目需要的信息-->
<build>
<!--该元素设置了项目源码目录,当构建项目的时候,
构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。-->
<sourceDirectory/>
<!--该元素设置了项目脚本源码目录,该目录和源码目录不同:
绝大多数情况下,该目录下的内容 会被拷贝到输出目录(因为脚本是被解释的,而不是被编译的)。-->
<scriptSourceDirectory/>
<!--该元素设置了项目单元测试使用的源码目录,当测试项目的时候,
构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。-->
<testSourceDirectory/>
<!--被编译过的应用程序class文件存放的目录。-->
<outputDirectory/>
<!--被编译过的测试class文件存放的目录。-->
<testOutputDirectory/>
<!--使用来自该项目的一系列构建扩展-->
<extensions>
<!--描述使用到的构建扩展。-->
<extension>
<!--构建扩展的groupId-->
<groupId/>
<!--构建扩展的artifactId-->
<artifactId/>
<!--构建扩展的版本-->
<version/>
</extension>
</extensions>
<!--这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,
这些资源被包含在最终的打包文件里。-->
<resources>
<!--这个元素描述了项目相关或测试相关的所有资源路径-->
<resource>
<!-- 描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。举个例 子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为org/apache/maven /messages。
然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。-->
<targetPath/>
<!--是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,
文件在filters元素里列出。-->
<filtering/>
<!--描述存放资源的目录,该路径相对POM路径-->
<directory/>
<!--包含的模式列表,例如**/*.xml.-->
<includes/>
<!--排除的模式列表,例如**/*.xml-->
<excludes/>
</resource>
</resources>
<!--这个元素描述了单元测试相关的所有资源路径,例如和单元测试相关的属性文件。-->
<testResources>
<!--这个元素描述了测试相关的所有资源路径,参见build/resources/resource元素的说明-->
<testResource>
<targetPath/>
<filtering/>
<directory/>
<includes/>
<excludes/>
</testResource>
</testResources>
<!--构建产生的所有文件存放的目录-->
<directory/>
<!--产生的构件的文件名,默认值是${artifactId}-${version}。-->
<finalName/>
<!--当filtering开关打开时,使用到的过滤器属性文件列表-->
<filters/>
<!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。
给定插件的任何本地配置都会覆盖这里的配置-->
<pluginManagement>
<!--使用的插件列表 。-->
<plugins>
<!--plugin元素包含描述插件所需要的信息。-->
<plugin>
<!--插件在仓库里的group ID-->
<groupId/>
<!--插件在仓库里的artifact ID-->
<artifactId/>
<!--被使用的插件的版本(或版本范围)-->
<version/>
<!--是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,
只有在真需要下载时,该元素才被设置成enabled。-->
<extensions/>
<!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。-->
<executions>
<!--execution元素包含了插件执行需要的信息-->
<execution>
<!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标-->
<id/>
<!--绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段-->
<phase/>
<!--配置的执行目标-->
<goals/>
<!--配置是否被传播到子POM-->
<inherited/>
<!--作为DOM对象的配置-->
<configuration/>
</execution>
</executions>
<!--项目引入插件所需要的额外依赖-->
<dependencies>
<!--参见dependencies/dependency元素-->
<dependency>......</dependency>
</dependencies>
<!--任何配置是否被传播到子项目-->
<inherited/>
<!--作为DOM对象的配置-->
<configuration/>
</plugin>
</plugins>
</pluginManagement>
<!--使用的插件列表-->
<plugins>
<!--参见build/pluginManagement/plugins/plugin元素-->
<plugin>
<groupId/>
<artifactId/>
<version/>
<extensions/>
<executions>
<execution>
<id/>
<phase/>
<goals/>
<inherited/>
<configuration/>
</execution>
</executions>
<dependencies>
<!--参见dependencies/dependency元素-->
<dependency>......</dependency>
</dependencies>
<goals/>
<inherited/>
<configuration/>
</plugin>
</plugins>
</build>
<!--模块(有时称作子项目) 被构建成项目的一部分。
列出的每个模块元素是指向该模块的目录的相对路径-->
<modules/>
<!--发现依赖和扩展的远程仓库列表。-->
<repositories>
<!--包含需要连接到远程仓库的信息-->
<repository>
<!--如何处理远程仓库里发布版本的下载-->
<releases>
<!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 -->
<enabled/>
<!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。-->
<updatePolicy/>
<!--当Maven验证构件校验文件失败时该怎么做:ignore(忽略),fail(失败),或者warn(警告)。-->
<checksumPolicy/>
</releases>
<!-- 如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,
POM就可以在每个单独的仓库中,为每种类型的构件采取不同的 策略。
例如,可能有人会决定只为开发目的开启对快照版本下载的支持。
参见repositories/repository/releases元素 -->
<snapshots>
<enabled/>
<updatePolicy/>
<checksumPolicy/>
</snapshots>
<!--远程仓库唯一标识符。可以用来匹配在settings.xml文件里配置的远程仓库-->
<id>banseon-repository-proxy</id>
<!--远程仓库名称-->
<name>banseon-repository-proxy</name>
<!--远程仓库URL,按protocol://hostname/path形式-->
<url>http://192.168.1.169:9999/repository/</url>
<!-- 用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认的布局;然 而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。-->
<layout>default</layout>
</repository>
</repositories>
<!--发现插件的远程仓库列表,这些插件用于构建和报表-->
<pluginRepositories>
<!--包含需要连接到远程插件仓库的信息.参见repositories/repository元素-->
<pluginRepository>......</pluginRepository>
</pluginRepositories>
<!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。
它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。-->
<dependencies>
<dependency>
<!--依赖的group ID-->
<groupId>org.apache.maven</groupId>
<!--依赖的artifact ID-->
<artifactId>maven-artifact</artifactId>
<!--依赖的版本号。 在Maven 2里, 也可以配置成版本号的范围。-->
<version>3.8.1</version>
<!-- 依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外
。一个类型可以被映射成另外一个扩展名或分类器。类型经常和使用的打包方式对应,
尽管这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。
如果设置extensions为 true,就可以在 plugin里定义新的类型。所以前面的类型的例子不完整。-->
<type>jar</type>
<!-- 依赖的分类器。分类器可以区分属于同一个POM,但不同构建方式的构件。
分类器名被附加到文件名的版本号后面。例如,如果你想要构建两个单独的构件成 JAR,
一个使用Java 1.4编译器,另一个使用Java 6编译器,你就可以使用分类器来生成两个单独的JAR构件。-->
<classifier/>
<!--依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。
- compile :默认范围,用于编译
- provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath
- runtime: 在执行时需要使用
- test: 用于test任务时使用
- system: 需要外在提供相应的元素。通过systemPath来取得
- systemPath: 仅用于范围为system。提供相应的路径
- optional: 当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用-->
<scope>test</scope>
<!--仅供system范围使用。注意,不鼓励使用这个元素,
并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件系统上的路径。
需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径,例如${java.home}。-->
<systemPath/>
<!--当计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件集。
即告诉maven你只依赖指定的项目,不依赖项目的依赖。此元素主要用于解决版本冲突问题-->
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
<!--可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。可选依赖阻断依赖的传递性。-->
<optional>true</optional>
</dependency>
</dependencies>
<!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,
而是当子项目声明一个依赖(必须描述group ID和 artifact ID信息),
如果group ID和artifact ID以外的一些信息没有描述,
则通过group ID和artifact ID 匹配到这里的依赖,并使用这里的依赖信息。-->
<dependencyManagement>
<dependencies>
<!--参见dependencies/dependency元素-->
<dependency>......</dependency>
</dependencies>
</dependencyManagement>
<!--项目分发信息,在执行mvn deploy后表示要发布的位置。
有了这些信息就可以把网站部署到远程服务器或者把构件部署到远程仓库。-->
<distributionManagement>
<!--部署项目产生的构件到远程仓库需要的信息-->
<repository>
<!--是分配给快照一个唯一的版本号(由时间戳和构建流水号)?
还是每次都使用相同的版本号?参见repositories/repository元素-->
<uniqueVersion/>
<id>banseon-maven2</id>
<name>banseon maven2</name>
<url>file://${basedir}/target/deploy</url>
<layout/>
</repository>
<!--构件的快照部署到哪里?如果没有配置该元素,默认部署到repository元素配置的仓库,
参见distributionManagement/repository元素-->
<snapshotRepository>
<uniqueVersion/>
<id>banseon-maven2</id>
<name>Banseon-maven2 Snapshot Repository</name>
<url>scp://svn.baidu.com/banseon:/usr/local/maven-snapshot</url>
<layout/>
</snapshotRepository>
<!--部署项目的网站需要的信息-->
<site>
<!--部署位置的唯一标识符,用来匹配站点和settings.xml文件里的配置-->
<id>banseon-site</id>
<!--部署位置的名称-->
<name>business api website</name>
<!--部署位置的URL,按protocol://hostname/path形式-->
<url>scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web</url>
</site>
<!--项目下载页面的URL。如果没有该元素,用户应该参考主页。
使用该元素的原因是:帮助定位那些不在仓库里的构件(由于license限制)。-->
<downloadUrl/>
<!-- 给出该构件在远程仓库的状态。不得在本地项目中设置该元素,
因为这是工具自动更新的。有效的值有:none(默认),
converted(仓库管理员从 Maven 1 POM转换过来),partner(直接从伙伴Maven 2仓库同步过来),deployed(从Maven 2实例部 署),verified(被核实时正确的和最终的)。-->
<status/>
</distributionManagement>
<!--以值替代名称,Properties可以在整个POM中使用,也可以作为触发条件(见settings.xml配置文件里activation元素的说明)。格式是<name>value</name>。-->
<properties/>
</project>
传递依赖和排除依赖
传递依赖:如果我们的项目引用了一个 jar 包,而该 jar 包又引用了其他 jar 包,那么在默认情况下项目编译时,Maven 会把直接引用和间接引用的 jar 包都下载到本地。
排除依赖:如果我们只想下载直接引用的 jar 包,那么需要在 pom.xml 中做如下配置:(将需要排除的 jar 包的坐标写在其中)
<exclusions>
<exclusion>
<groupId>cn.missbe.web.search</groupId>
<artifactId>resource-search</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
</exclusion>
</exclusions>
依赖冲突
若项目中多个Jar同时引用了相同的Jar时,会产生依赖冲突,但Maven采用了两种避免冲突的策略,因此在Maven中是不存在依赖冲突的。
- 短路优先
本项目——>A.jar——>B.jar——>X.jar
本项目——>C.jar——>X.jar
若本项目引用了A.jar,A.jar又引用了B.jar,B.jar又引用了X.jar,并且C.jar也引用了X.jar。
在此时,Maven只会引用引用路径最短的Jar。(即C.jar)
- 声明优先
若引用路径长度相同时,在pom.xml中谁先被声明,就使用谁。
聚合
将多个项目同时运行就称为聚合。
在pom中作如下配置即可实现聚合:
<modules>
<module>web-connection-pool</module>
<module>web-java-crawler</module>
</modules>
继承
在聚合多个项目时,如果这些被聚合的项目中需要引入相同的Jar,那么可以将这些Jar写入父pom中,各个子项目继承该pom即可。
- 父pom配置:将所需要继承的Jar包放入标签即可
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.missbe.web.search</groupId>
<artifactId>resource-search</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
- 子pom配置:
<parent>
<groupId>父pom所在项目的groupId</groupId>
<artifactId>父pom所在项目的artifactId</artifactId>
<version>父pom所在项目的版本号</version>
</parent>
<parent>
<artifactId>resource-search</artifactId>
<groupId>cn.missbe.web.search</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
Mybatis
Mybatis简介
MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。
它支持定制化 SQL、存储过程以及高级映射。
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
MyBatis 应用程序大都使用 SqlSessionFactory 实例,SqlSessionFactory 实例可以通过 SqlSessionFactoryBuilder 获得,而 SqlSessionFactoryBuilder 则可以从一个 XML 配置文件或者一个预定义的配置类的实例获得。
注:持久层指的是Dao层、Service层、Controller层等完成持久化工作的代码块,层界限十分明显
第一个Mybatis程序
- 搭建数据库
CREATE DATABASE mybatis;
use mybatis;
CREATE TABLE user(
id INT(20) not null PRIMARY KEY,
name VARCHAR(30) DEFAULT NULL,
pwd VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO user (id,name,pwd) VALUES
(1,‘狂神’,‘123456’),
(2,‘张三’,‘123456’),
(3,‘李四’,‘123890’)
- 创建maven项目
- 导入junit,mysql,Mybatis依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
- src /main /resources 下创建核心配置文件 mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration核心配置文件-->
<configuration>
<!--设置别名简化 resultType 书写,该标签必须在 environments 前-->
<typeAliases>
<!--1、单个别名的定义: alias:别名,type:别名映射的类型-->
<typeAlias type="com.mybatis.entity.User" alias="User"/>
<!--2、批量别名定义:指定包路径,自动扫描包下边的类,定义别名,别名默认为类名(首字母小写或大写)
<package name="com.mybatis.entity"/> -->
</typeAliases>
<!--environments配置环境组-->
<!--default默认环境-->
<!-- 配置开发环境,可以配置多个,在具体用时再做切换 -->
<environments default="test">
<!--environment单个环境-->
<environment id="test">
<!--transactionManager配置事务管理器-->
<!-- 事务管理类型:JDBC、MANAGED -->
<transactionManager type="JDBC"></transactionManager>
<!--配置连接池-->
<!-- 数据源类型:POOLED、UNPOOLED、JNDI -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/example?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&allowMultiQueries=true"/>
<property name="username" value="root"/>
<property name="password" value="****"/>
</dataSource>
</environment>
</environments>
<!--每一个Mapper.xml需要在Mybatis核心配置文件中注册-->
<mappers>
<!-- 路径用 斜线(/) 分割,而不是用 点(.) -->
<mapper resource="UserMapper.xml"></mapper>
</mappers>
</configuration>
- 编写 MyBatis 工具类
package com.mybatis.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 获取 SqlSessionFactory 实例
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// SqlSessionFactory,顾名思义,可以从中获得 SqlSession 的实例
// SqlSession 包含了面向数据库执行 SQL 命令所需的所有方法。
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
6.编写代码
实体类
package entity;
public class User {
private int id;
private String name;
private String pwd;
public User() {
}
public User(int id, String username, String password) {
this.id = id;
this.name = username;
this.pwd = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public String getPwd() {
return pwd;
}
public void setName(String name) {
this.name = name;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
dao层接口
package dao;
import entity.User;
import java.util.List;
public interface UserDao {
List<User> getUserList();
User getUserById(int id);
int addUser(User user);
int updateUser(User user);
int deleteUserById(int id);
}
创建映射文件UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--指定唯一 namespace ,一般习惯为接口的包路径名-->
<mapper namespace="UserDao">
<!-- 查询功能,resultType 设置返回值类型 -->
<select id="getUserList" resultType="User">
<!-- 书写 SQL 语句 -->
SELECT * FROM user;
</select>
<select id="getUserById" parameterType="int" resultType="User">
SELECT *
FROM user
WHERE id = #{id};
<!--parameterType 是简单类型( java 8 种原始数据类型加 string ),占位符 #{} 变量名任取-->
</select>
<!--以实体来封装参数 -->
<insert id="addUser" parameterType="User">
INSERT INTO user (id, name, pwd)
VALUES (#{id}, #{name}, #{pwd});
<!--parameterType 是对象或 map,占位符 #{} 变量名为对象属性或 map 的 key 值-->
</insert>
<update id="updateUser" parameterType="User">
UPDATE user
set name=#{name},
pwd=#{pwd}
WHERE id = #{id};
</update>
<delete id="deleteUserById" parameterType="integer">
DELETE
FROM user
WHERE id = #{id};
</delete>
</mapper>
注:一般情况下将所对应的Mapper和Java代码放到一层,但需要进行pom的配置,或者直接将其放入resources包内
pom.xml中进行配置
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
创建测试类
import entity.User;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
import static util.MyBatisUtil.getSqlSession;
public class TestUserDao {
@Test
public void testGetUserList() {
SqlSession sqlSession = getSqlSession();
List<User> userList = sqlSession.selectList("getUserList");
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
@Test
public void testGetUserByUserId() {
SqlSession sqlSession = getSqlSession();
User user = sqlSession.selectOne("getUserById", 1);
System.out.println(user);
sqlSession.close();
}
@Test
public void testAddUser() {
SqlSession sqlSession = getSqlSession();
User user = new User(6, "Lihua", "1234");
int res = sqlSession.insert("addUser", user);
if (res > 0) {
System.out.println("插入成功");
}
// 进行 insert,update,delete 操作时,需要手动提交,否则 res > 0 但数据库没有更新数据
sqlSession.commit();
sqlSession.close();
}
@Test
public void testUpdateUser() {
SqlSession sqlSession = getSqlSession();
User user = new User(6, "Lihua", "3456");
int res = sqlSession.update("updateUser", user);
if (res > 0) {
System.out.println("更新成功");
}
sqlSession.commit();
sqlSession.close();
}
@Test
public void testDeleteUserById() {
SqlSession sqlSession = getSqlSession();
int res = sqlSession.delete("deleteUserById", 1);
if (res > 0) {
System.out.println("删除成功");
}
sqlSession.commit();
sqlSession.close();
}
}
Log4j
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件
我们也可以控制每一条日志的输出格式
通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
建立依赖
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
resources下创建log4j.properties
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%5p] [%c]%m%n
#文件输出的相关设置
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/mxt.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}] [%5p] [%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
mybatis-config.xml解析
配置文件中,各个标签要按照以下顺序进行配置,因为mybatis 加载配置文件的源码中是按照这个顺序进行解析的
<configuration> 配置
<!-- 配置顺序如下
properties 属性
settings 设置
typeAliases 类型别名
typeHandlers 类型处理器
objectFactory 对象工厂
plugins 插件
environments 环境配置
environment 环境变量
transactionManager 事务管理器
dataSource 数据源
mappers 映射器
-->
</configuration>
关于各个标签的作用在这里不再赘述
生命周期
动态SQL
根据不同条件生成不同SQL语句
- if
<select id="find" parameterType="User" resultType="User" >
SELECT * FROM tb_person WHERE id >= 2
<if test="username != null and username != ''">
AND username like concat("%", #{username}, "%");
</if>
</select>
- choose( when,otherwise) 类似 switch
<select id="queryUserChoose" parameterType="map" resultType="User">
select * from tb_person
<where>
<choose>
<when test="username !=null">
username=#{username}
</when>
<when test="password !=null">
and password=#{password}
</when>
<otherwise>
and id=#{id}
</otherwise>
</choose>
</where>
</select>
- set
<update id="updateUser" parameterType="map">
update tb_person
<set>
<if test="username !=null">
username=#{username},
</if>
<if test="password !=null">
password=#{password}
</if>
</set>
where id=#{id}
</update>
- trim
trim代替where
<trim prefix="WHERE" prefixOverrides="AND | OR">
...
</trim>
- foreach
遍历list
<select id="batchFindUser" parameterType="list" resultType="user" >
SELECT * FROM student WHERE id in
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
- sql
将重复的 SQL 片段(尽量只有 if )提取出来,然后在需要的地方,使用 < include > 标签进行引用
<sql id="if-username-password">
<if test="username != null">
username = #{username}
</if>
<if test="password != null">
and password = #{password}
</if>
</sql>
<select id="queryUserIf" parameterType="map" resultType="User">
SELECT * FROM tb_person
<where>
<include refid="if-username-password"></include>
</where>
</select>