MyBatis系列(一):MyBatis入门
1. MyBatis 简介
2001 年,Clinton Begin 发起了一个名为 iBATIS 的开源项目,最初侧重于密码软件的研发,后来发展成为一款基于 Java 的持久层框架。
2004 年,Clinton 将 iBATIS 的名字和源码捐赠给了 Apache 软件基金会。
2010 年,核心开发团队决定离开 Apache 软件基金会,并且将 iBATIS 改名为 MyBatis。
MyBatis 是一款优秀的支持自定义 SQL 查询、存储过程和高级映射的持久层框架,消除了几乎所有的 JDBC 代码和参数的手动设置以及结果集的检索。MyBatis 可以使用 XML 或注解进行配置和映射,MyBatis 通过将参数映射到配置的 SQL 形成最终执行的 SQL 语句,最后将执行 SQL 的结果映射成 Java 对象返回。
与其他的 ORM(对象关系映射)框架不同,MyBatis 并没有将 Java 对象与数据库表关联起来,而是将 Java 方法与 SQL 语句关联。
说明:以上内容了解下即可,因为按我的风格,特别不喜欢纯理论纯文字的东西,看过我以往博客的读者可能有这个意识,我更喜欢具体代码实战,比如如何使用一个新技术,某一段代码是为了解决什么问题……
2. 创建 Maven 项目
关于 Maven 的相关内容,大家可以参考我之前的博客Spring 入门 (四):使用 Maven 管理 Spring 项目。
我一直认为,理解一门技术最好的方式,是通过一个具体的例子,比如 Hello World,哈哈。
所以,首先我们要新建个 Maven 项目,使用 IDEA 新建 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>
<span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>com.zwwhnly<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>mybatis-action<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">version</span>></span>1.0-SNAPSHOT<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
</project>
首先,我们设置源代码的编码方式为 UTF-8:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
接着,设置编译源代码的 JDK 版本,这里暂时用 1.6,可根据自己的实际需要修改,比如修改成 1.8:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
然后,添加重要的 MyBatis 的依赖坐标和 mysql 驱动的依赖坐标:
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
</dependencies>
最后,添加下用到的 Log4j、JUnit 的依赖坐标,最终的 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>
<span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>com.zwwhnly<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>mybatis-action<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">version</span>></span>1.0-SNAPSHOT<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
<span class="hljs-tag"><<span class="hljs-name">properties</span>></span>
<span class="hljs-tag"><<span class="hljs-name">project.build.sourceEncoding</span>></span>UTF-8<span class="hljs-tag"></<span class="hljs-name">project.build.sourceEncoding</span>></span>
<span class="hljs-tag"></<span class="hljs-name">properties</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dependencies</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>org.mybatis<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>mybatis<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">version</span>></span>3.3.0<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>mysql<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>mysql-connector-java<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">version</span>></span>5.1.38<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>junit<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>junit<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">version</span>></span>4.12<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>org.slf4j<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>slf4j-api<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">version</span>></span>1.7.12<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>org.slf4j<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>slf4j-log4j12<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">version</span>></span>1.7.12<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>log4j<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>log4j<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">version</span>></span>1.2.17<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dependencies</span>></span>
<span class="hljs-tag"><<span class="hljs-name">build</span>></span>
<span class="hljs-tag"><<span class="hljs-name">plugins</span>></span>
<span class="hljs-tag"><<span class="hljs-name">plugin</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>maven-compiler-plugin<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">configuration</span>></span>
<span class="hljs-tag"><<span class="hljs-name">source</span>></span>1.6<span class="hljs-tag"></<span class="hljs-name">source</span>></span>
<span class="hljs-tag"><<span class="hljs-name">target</span>></span>1.6<span class="hljs-tag"></<span class="hljs-name">target</span>></span>
<span class="hljs-tag"></<span class="hljs-name">configuration</span>></span>
<span class="hljs-tag"></<span class="hljs-name">plugin</span>></span>
<span class="hljs-tag"></<span class="hljs-name">plugins</span>></span>
<span class="hljs-tag"></<span class="hljs-name">build</span>></span>
</project>
在 IDEA 中,如果没有特殊配置过,修改完 pom 文件,需要手动导入下,否则是下图这样的情况:
怎么手动导入呢?点击下 IDEA 右下角提示的 Import Changes 即可。
至此,Maven 项目创建完毕。
3. 简单示例
3.1 数据准备
首先执行如下语句创建数据库 mybatis_action_db:
CREATE DATABASE mybatis_action_db DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
然后执行如下语句创建表 country,并添加一些数据:
use mybatis_action_db;
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');
3.2 配置 MyBatis
首先在 src/main/resources 目录下创建 mybatis-config.xml 配置文件,为了后续更快速的创建 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> <setting name="logImpl" value="LOG4J"/> </settings>
<typeAliases> <package name="com.zwwhnly.mybatisaction.model"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"> <property name="" value=""/> </transactionManager> <dataSource type="UNPOOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis_action_db"/> <property name="username" value="root"/> <property name="password" value=""/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/zwwhnly/mybatisaction/mapper/CountryMapper.xml"/> </mappers>
</configuration>
配置简单讲解:
<settings>
节点中的 logImpl 属性配置指定使用 LOG4J 输出日志。<typeAliases>
元素下面配置了一个包名,通常确定一个类的时候需要使用类的全限定名称,例如 com.zwwhnly.mybatisaction.model.Country。在 MyBatis 中需要频繁用到类的全限定名称,为了方便使用,我们配置了 com.zwwhnly.mybatisaction.model 包,这样配置后,在使用类的时候不需要写包名的部分,只使用 Country 即可。<environments>
环境配置中主要配置了数据库连接,如这里我们使用的是本机 MySql 中的 mybatis_action_db 数据库,用户名为 root,没有密码(大家可根据自己的实际情况修改数据库及用户名和密码)。<mappers>
中配置了一个包含完整类路径的 CountryMapper.xml,这是一个 MyBatis 的 Sql 语句和映射配置文件。
3.3 创建实体类和 Mapper.xml 文件
在 src/main/java 下新建包:com.zwwhnly.mybatisaction,然后在这个包下再创建包:model。
在 model 包下创建数据库表 country 表对应的实体类 Country:
package com.zwwhnly.mybatisaction.model;
public class Country {
private Integer id;
<span class="hljs-keyword">private</span> String countryname;
<span class="hljs-keyword">private</span> String countrycode;
<span class="hljs-comment">// 按Alt+Insert快捷键生成get和set方法</span>
}
在 src/main/resources 下创建目录 com/zwwhnly/simple/mapper 目录,然后在该目录下创建 CountryMapper.xml 文件,为了后续更快速的创建 Mapper.xml 文件,我们可以参考上面的添加 mybatis-config.xml 模版的方法,这里不再赘述。
最终的 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 namespace="com.zwwhnly.mybatisaction.mapper.CountryMapper">
<select id="selectAll" resultType="Country">
SELECT id,countryname,countrycode from country
</select>
</mapper>
配置简单讲解:
- mapper:XML 的根元素,属性 namespace 定义了当前 XML 的命名空间。
- select:我们所定义的一个 Select 查询。
- id 属性:定义了当前 Select 查询的唯一 id。
- resultType:定义了当前查询的返回值类型,此处就是指实体类 Country,前面配置中提到的包名主要用于这里,如果没有设置包名,此处就需要写成 resultType="com.zwwhnly.mybatisaction.model.Country"。
- SELECT id,countryname,countrycode from country:查询 Sql 语句。
3.4 配置 Log4j 以便查看 MyBatis 操作数据库的过程
在 src/main/resources 下新建 log4j.properties 配置文件,输入如下内容:
log4j.rootLogger=ERROR, stdout
log4j.logger.com.zwwhnly.mybatisaction.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
3.5 编写测试代码
在 src/test/java 下创建包:com.zwwhnly.mybatisaction.mapper,然后创建测试类 CountryMapperTest 类,代码如下:
package com.zwwhnly.mybatisaction.mapper;
import com.zwwhnly.mybatisaction.mapper.model.Country;
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 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;
<span class="hljs-meta">@BeforeClass</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">init</span><span class="hljs-params">()</span> {
<span class="hljs-keyword">try</span> {
<span class="hljs-type">Reader</span> <span class="hljs-variable">reader</span> <span class="hljs-operator">=</span> Resources.getResourceAsReader(<span class="hljs-string">"mybatis-config.xml"</span>);
sqlSessionFactory = <span class="hljs-keyword">new</span> <span class="hljs-title class_">SqlSessionFactoryBuilder</span>().build(reader);
reader.close();
} <span class="hljs-keyword">catch</span> (IOException e) {
e.printStackTrace();
}
}
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testSelectAll</span><span class="hljs-params">()</span> {
<span class="hljs-type">SqlSession</span> <span class="hljs-variable">sqlSession</span> <span class="hljs-operator">=</span> sqlSessionFactory.openSession();
<span class="hljs-keyword">try</span> {
List<Country> countryList = sqlSession.selectList(<span class="hljs-string">"selectAll"</span>);
printCountryList(countryList);
} <span class="hljs-keyword">finally</span> {
sqlSession.close();
}
}
<span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">printCountryList</span><span class="hljs-params">(List<Country> countryList)</span> {
<span class="hljs-keyword">for</span> (Country country : countryList) {
System.out.printf(<span class="hljs-string">"%-4d%4s%4s\n"</span>, country.getId(), country.getCountryname(), country.getCountrycode());
}
}
}
运行测试代码,输出日志如下:
DEBUG [main] - ==> Preparing: 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, 俄罗斯, RU
TRACE [main] - <== Row: 4, 英国, GB
TRACE [main] - <== Row: 5, 法国, FR
DEBUG [main] - <== Total: 5
1 中国 CN
2 美国 US
3 俄罗斯 RU
4 英国 GB
5 法国 FR
4. 源码及参考
源码地址:https://github.com/zwwhnly/mybatis-action.git,欢迎下载。
刘增辉《MyBatis 从入门到精通》
原创不易,如果觉得文章能学到东西的话,欢迎点个赞、评个论、关个注,这是我坚持写作的最大动力。
如果有兴趣,欢迎添加我的微信:zwwhnly,等你来聊技术、职场、工作等话题(PS:我是一名奋斗在上海的程序员)。