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">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.zwwhnly<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mybatis-action<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.0-SNAPSHOT<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</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">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.zwwhnly<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mybatis-action<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.0-SNAPSHOT<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">properties</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">project.build.sourceEncoding</span>&gt;</span>UTF-8<span class="hljs-tag">&lt;/<span class="hljs-name">project.build.sourceEncoding</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">properties</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.mybatis<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mybatis<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.3.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>mysql<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mysql-connector-java<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.1.38<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>junit<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>junit<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>4.12<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.slf4j<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>slf4j-api<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.7.12<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.slf4j<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>slf4j-log4j12<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.7.12<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>log4j<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>log4j<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.2.17<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">build</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">plugins</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>maven-compiler-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">source</span>&gt;</span>1.6<span class="hljs-tag">&lt;/<span class="hljs-name">source</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">target</span>&gt;</span>1.6<span class="hljs-tag">&lt;/<span class="hljs-name">target</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">plugins</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">build</span>&gt;</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>
&lt;typeAliases&gt;
    &lt;package name="com.zwwhnly.mybatisaction.model"/&gt;
&lt;/typeAliases&gt;

&lt;environments default="development"&gt;
    &lt;environment id="development"&gt;
        &lt;transactionManager type="JDBC"&gt;
            &lt;property name="" value=""/&gt;
        &lt;/transactionManager&gt;
        &lt;dataSource type="UNPOOLED"&gt;
            &lt;property name="driver" value="com.mysql.jdbc.Driver"/&gt;
            &lt;property name="url" value="jdbc:mysql://localhost:3306/mybatis_action_db"/&gt;
            &lt;property name="username" value="root"/&gt;
            &lt;property name="password" value=""/&gt;
        &lt;/dataSource&gt;
    &lt;/environment&gt;
&lt;/environments&gt;

&lt;mappers&gt;
    &lt;mapper resource="com/zwwhnly/mybatisaction/mapper/CountryMapper.xml"/&gt;
&lt;/mappers&gt;

</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&lt;Country&gt; 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&lt;Country&gt; 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 从入门到精通》

IntelliJ IDEA 中创建 xml 文件

原创不易,如果觉得文章能学到东西的话,欢迎点个赞、评个论、关个注,这是我坚持写作的最大动力。

如果有兴趣,欢迎添加我的微信:zwwhnly,等你来聊技术、职场、工作等话题(PS:我是一名奋斗在上海的程序员)。