文章目录
MyBatis简介
MyBaits的前生是IBATIS 是Clinton Begin在2001年发起的一个开源项目 最初侧重于密码软件的开发 后来发展成为一款基于Java的持久层框架,Clinton将iBATIS的名字和源码捐献给了Apache软件基金会,随后开源软件发生了巨大的变化,数据库技术都彻底改变了,2010年,核心团队决定离开Apache软件基金会,并且将iBATIS改名为MyBatis
MyBatis是一款优秀的支持自定义SQL查询、存储过程和高级映射的持久层框架,消除了几乎所有的JDBC代码和参数的手动设置以及结果集的检索。MyBatis可以使用XML或注解进行配置和映射,MyBatis通过将参数映射到配置的SQL形成最终执行的SQL语句,最后将执行SQL的结果映射成Java对象返回。
与其他的ORM(对象关系映射)框架不同,MyBatis并没有将Java对象与数据库表关联起来,而是将Java方法与SQL语句关联。MyBatis允许用户充分利用数据库的各种功能,例如存储过程、视图、各种复杂的查询以及某数据库的专有特性。如果要对遗留数据库、不规范的数据库进行操作,或者要完全控制SQL的执行,MyBatis将会是一个不错的选择。
与JDBC相比,MyBatis简化了相关代码,SQL语句在一行代码中就能执行。MyBatis提供了一个映射引擎,声明式地将SQL语句的执行结果与对象树映射起来。通过使用一种内建的类XML表达式语言,SQL语句可以被动态生成。
MyBatis支持声明式数据缓存(declarative data caching)。当一条SQL语句被标记为“可缓存”后,首次执行它时从数据库获取的所有数据会被存储在高速缓存中,后面再执行这条语句时就会从高速缓存中读取结果,而不是再次命中数据库。MyBatis 提供了默认情况下基于 Java HashMap的缓存实现,以及用于与OSCache、Ehcache、Hazelcast和Memcached连接的默认连接器,同时还提供了API供其他缓存实现使用。
主要学习
- MyBatis-3:Mybatis源码
- generator:代码生成器,可以生成一些常见的基本方法,提高工作效率
- ehcache-cache:默认集成Ehcache的缓存实现
- spring:方便和Spring集成的工具类
- Mybatis-Spring-Boot:方便和Spring Boot集成的工具类
初步了解MyBatis
创建Maven项目
Maven是一个优秀的项目构建和管理的工具,后面要学习的内容都会在Maven构建的项目基础上进行讲解和测试 使用的工具是IDEA作为开发工具
在IDEA中创建一个基本的Maven项目,按照以下步骤进行操作即可.
在IDEA中打开File–>New–>Project–>Maven->Next
选择Name框输入项目名称 Location选择存储的地址 -->Finish
完成以上操作后,稍等片刻,一个基于Maven的基本结构就创建完成了,得到的Mevan项目的目录结构
配置Maven
打开Maven项目的配置文件pom.xml,可以看到如下配置
<?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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>untitled</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
以上是Maven项目的基本配置信息,我们还需要为它添加一些常用配置,首先源代码编写方式为UTF-8,配置如下
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
接下来,我们来设置编译源代码的JDK版本,为了增大兼容范围,我使用的是JDK1.8,各位客官按照自己的JDK来进行配置
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
至此,基本的Maven配件就完成了
配置MyBatis
以上我们配置完了Maven,但还需要在配件文件中添加一些依赖才能使我们接下来做的事情顺利,首先,不要忘记最重要的MyBatis依赖,在pom.xml文件中添加MyBatis的依赖坐标,配置如下
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
</dependencies>
我们也可以通过Maven存储库来查询依赖坐标
接着,我们还需要添加会用到的Log4j, Junit和MySQL以及Lombok的驱动依赖,
<!-- 测试单元Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- Mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- Log4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>Log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
最终的Pom.xml文件内容如下
<?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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.bulid.sourceEncoding>UTF-8</project.bulid.sourceEncoding>
</properties>
<dependencies>
<!-- 引入Mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!--测试单元Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- Mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- Log4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>Log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
当对Meven的配置进行修改后,还需要在项目上点击Mevan刷新图标
完成以上步骤后,MyBatis的基本开发环境就已经准备好了
让MyBatis跑起来
这里通过一个MyBatis的简单例子让各位客官对MyBatis有一个初步的了解,在操作过程中如果客官已经了解各项配置之间的关系,可以按照自己的习惯的方式对配置进行调整,如果还不了解,请客官跟着我的操作来
准备数据库
首先创建一个数据库,编码方式设置为UTF-8,可以使用MySQL客户端工具Navicat来实现M,通过执行下面的SQL语句创建一个名为MyBatis的数据库
CREATE DATABASE mybatis DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
然后在创建一个名为country的表并插入一些简单的数据,代码如下
use mybatis;
CREATE TABLE `country` (
`id` int NOT NULL AUTO_INCREMENT ,
`countryname` varchar(255) NULL ,
`countrycode` varchar(255) NULL ,
PRIMARY KEY (`id`)
);
insert country(`countryname`, `countrycode`)
values (’中国’, 'CN'), (’美国’, 'US'), (’俄罗斯’, 'RU'),
(’英国’, 'GB'), (’法国’, 'FR');
准备好表和简单的数据后,继续来配置MyBatis
配置MyBatis
配置MyBatis有多种方式,本节使用最基础最常用的XML进行配置
注意 !!!!
除XML方式以外,在后面还会介绍和Spring集成时使用Spring bean方式进行配置,另外还可以通过Java编码方式来进行配置
使用XML形式进行配置,首先在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>
<!-- settings中的logImpl的属性配置指定使用LOG4J输出日志 -->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- typeAliases 元素下面配置了一个包的别名,
通常确定一个类的时候需要使用类的全限定名称
例如: tk.mybatis.simple.model.Country,在MyBatis中需要频繁用到类的全限定名称
为了方便使用,所以配置了tk.mybatis.simple.model包,这样配置后,在使用类的时候不需要写包名的部分
只使用Country即可-->
<typeAliases>
<package name="com.lz.mybatis.model"/>
</typeAliases>
<!-- environments环境配置 主要配置了数据库链接,
数据库的包为:com.mysql.cj.jdbc.Driver 注意:如果MySQL版本是8.0以下的 不需要加cj
数据库的URL为 jdbc:mysql://localhost:3306/mybatis
使用的是本机MySQL的mybatis数据库
后面的username和password分别是数据库的用户名和密码 请对应自己的进行修改
-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- mappers配置了一个包含完整路径的CountryMapper.xml
这是一个MyBatis的SQL语句和映射配置文件
这个XML文件后面会描述的-->
<mappers>
<mapper resource="com/lz/mybatis/mapper/CountryMapper.xml"/>
</mappers>
</configuration>
其中也简单的讲解了一下配置
创建实体类和Mapper.xml文件
MyBatis是一个结果映射框架,这里创建的实体类实际上是一个数据值对象(Data Value Object),在实际应用中,一个表一般会对应一个实体,用于 INSERT UPDATE DELETE和简单的SELECT操作,所以姑且称这个简单的对象为实体类
提示!
关于Mapper的命名方式,在MyBatis中,根据MyBatis官方的习惯,一般用Mapper作为XML和接口类名的后缀,这里的Mapper和我们常用的DAO后缀类似,只是一种习惯而已,接下来全部使用Mapper后缀,通常称为Mapper.XML文件,称接口为Mapper接口,在实际的开发中可以根据自己的需求来定义命名方式!
在src/main/java下创建一个基础的包com.lz.mybatis,在这个包下创建model包
根据数据库表country,在model包下创建实体类Country,代码如下
/**
* 这里使用了Lombok中的@Data注解
* 解释说明:
* @Data 包含了 @ToString、@EqualsAndHashCode、
* @Getter / @Setter和@RequiredArgsConstructor的功能
* 这样就无需声明Get/Set/toString/Constructor...方法了
*/
@Data
public class Country {
private Long id;
private String countryname;
private String countrycode;
}
在src/main/resources下面创建com.lz.mybatis.mapper目录,再在该目录下面创建CountryMapper.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">
<!--mapper XML的根元素 属性namespace定义了当前XML的命名空间-->
<mapper namespace="com.lz.mybatis.mapper.CountryMapper">
<!-- select元素 我们所定义的一个SELECT查询
id 属性:定义了当前SELECT查询的唯一一个ID
resultType:定义了当前查询的返回值类型,此处就是指实体类Country
前面配置中提到的别名主要用于这里,如果没有设置别名,此处就需要写成
resultType="tk.mybatis.simple.model.Country"-->
<select id="selectAll" resultType="Country">
-- select id ..:查询SQL语句
select id,countryname,countrycode from country
</select>
</mapper>
其中也对了一些配置进行了解释说明
配置Log4j以便查看MyBatis操作数据库的过程
在src/main/resources中添加log4.properties配置文件,输入以下内容
# 全局设置
log4j.rootLogger=ERROR , stdout
#MyBatis日志配置
log4j.logger.com.lz.mybatis.mapper=TRACE
#控制太输出配置
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n%
日志注意事项!!!
用过 Log4j 日志组件的人可能都会知道,配置中的 log4j.logger.com.lz.mybatis.mapper对应的是tk.mybatis.simple.mapper包,但是在这个例子中,Java目录下并没有这个包名,只在资源目录下有mapper目录。
在MyBatis的日志实现中,所谓的包名实际上是XML配置中的namespace属性值的一部分。后面章节中介绍结合接口使用的相关内容时,由于 namespace 属性值必须和接口全限定类名相同,因此才会真正对应到Java中的包。当使用纯注解方式时,使用的就是纯粹的包名。
MyBatis日志的最低级别是 TRACE,在这个日志级别下,MyBatis会输出执行 SQL过程中的详细信息,这个级别特别适合在开发时使用。
配置好log4j后,接下来就可以编写测试代码让MyBatis跑起来了 GOGOGOGO
编写测试代码让MyBatis跑起来
首先在src/text/java 中创建 com.lz.mybatis.mapper包,然后创建CountryMapperTest测试类,
代码如下
package com.lz.mybatis.mapper;
import com.lz.mybatis.model.Country;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
public class CountryMapperTest {
private static SqlSessionFactory sqlSessionFactory;
// @BeforeClass 表示在类中的任意public static void方法执行之前执行
@BeforeClass
public static void init() {
try {
// 通过Resources工具类将mybatis-config.xml配置文件读入Reader
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
// 通过SqlSessionFactoryBuilder建造类使用Reader创建SqlSessionFactory工厂对象
// 在创建SqlSessionFactory对象的过程中,首先解析mybatis-config.xml配置文件,
// 读取配置文件中的mapper配置后读取全部的Mapper.xml进行具体方法的解析,在这些解析完毕后
// SqlSessionFactory就包含了所有的属性配置和执行SQL的信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
@Test
public void testSelectAll() {
// 使用时通过SqlSessionFactory工厂对象获取一个SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
// 通过SqlSession的selectList方法查找到CountryMapper.xml中id="selectAll"的方法
// 执行SQL查询
// MyBatis底层使用JDBC执行SQL,获得查询结果集ResultSet后,根据resultType的配置将结果映射为Country类型的集合,返回查询结果。
List<Country> selectAll = sqlSession.selectList("selectAll");
// 这样就得到了最后的查询结果countryList,简单将结果输出到控制台。
printCountryList(selectAll);
} finally {
// 最后一定不要忘记关闭 SqlSession,否则会因为连接没有关闭导致数据库连接数过多,造成系统崩溃。
sqlSession.close();
}
}
private void printCountryList(List<Country> selectAll) {
for (Country country : selectAll) {
System.out.printf("%-4d%4s%4s\n",
country.getId(), country.getCountryname() ,country.getCountrycode());
}
}
}
上面的测试代码成功执行后,会输出如下日志
DEBUG [main] - ==> Preparing: -- select id ..:查询SQL语句 select id,countryname,countrycode from country
%DEBUG [main] - ==> Parameters:
%TRACE [main] - <== Columns: id, countryname, countrycode
%TRACE [main] - <== Row: 1, 中国, CN
%TRACE [main] - <== Row: 2, 美国, US
%TRACE [main] - <== Row: 3, 英国, GB
%TRACE [main] - <== Row: 4, 俄罗斯, RU
%TRACE [main] - <== Row: 5, 法国, FR
%DEBUG [main] - <== Total: 5
%1 中国 CN
2 美国 US
3 英国 GB
4 俄罗斯 RU
5 法国 FR
从日志中可以看到完整的SQL输出和结果输出,从日志对应的级别可以发现SQL、参数、结果数都是DEBUG级别,具体的查询结果列和数据都是TRACE级别。
通过一系列的操作,我们让一个简单的 MyBatis 例子跑了起来,相信各位客官现在对 MyBatis已经有了初步的了解。
总结
在本节中,我们对MyBatis有了一个简单的认识,学习了如何创建一个使用Maven管理的项目,涉及了一些MyBatis的简单配置以及使用方法,并让一个简单的MyBatis项目跑了起来。在后面,我会与各位客官继续深入地学习MyBatis的各项配置以及各种常见的、复杂的用法。