# MyBatis教程 - 2 HelloWorld

在学习 MyBatis 的使用之前,首先要安装环境:

  • 开发工具:因为是 Java 项目,所以就使用 IDEA,最好用的,没什么好说的。
  • 数据库:MySql8.0

上面开发工具和数据库的安装这里就不介绍了。


下面来编写HelloWorld,这里是在普通 Maven 项目中集成 MyBatis。

暂时不使用 Spring 集成,后面再单独介绍。

# 2.1 准备数据库表

首先在数据库中创建一张用户表,后面好操作这张表,我这里叫:tb_user

CREATE TABLE `tb_user` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(32) NULL,
  `password` VARCHAR(32) NULL,
  `email` VARCHAR(64) NULL,
  `age` INT NULL,
  `create_time` DATETIME NULL,
  `update_time` DATETIME NULL,
  PRIMARY KEY (`id`)
) 
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4;
1
2
3
4
5
6
7
8
9
10
11
12

并准备几条数据:

INSERT INTO `tb_user` 
(`username`, `password`, `email`, `age`, `create_time`, `update_time`)
VALUES 
('doubi', '123456', 'doubi@foooor.com', 30, NOW(), NOW()),
('niubi', '1234qwer', 'niubi@foooor.com', 28, NOW(), NOW()),
('erbi', '88888888', 'erbi@foooor.com', 35, NOW(), NOW());
1
2
3
4
5
6

# 2.2 Maven集成MyBatis

# 1 创建Maven项目

使用 IDEA 创建一个项目即可,选择使用 Maven。

# 2 添加依赖

在项目的 pom.xml 添加依赖:mybatis依赖、mysql驱动依赖、单元测试依赖。

<?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>com.foooor</groupId>
    <artifactId>hello-mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <!-- mybatis 驱动 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.16</version>
        </dependency>

        <!-- 数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>

        <!-- Lombok,用于自动生成getter和setter等代码 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
      
        <!-- junit单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

添加完依赖,右键项目 -> Maven -> Reload project

# 3 创建MyBatis核心配置文件

核心配置文件用来配置数据库连接信息和 MyBatis 的一些全局配置。配置文件的名称是自定义的,但是一般建议名称为 mybatis.config.xml

src/main/resources 下创建 mybatis-config.xml 内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  
    <!-- 设置 -->
    <settings>
        <!-- 驼峰命名法 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
  
    <!-- 定义不同的环境配置,通过 default 属性指定默认使用的环境 -->
    <environments default="development">
        <!-- 定义一个名为 "development" 的环境配置 -->
        <environment id="development">
            <!-- 指定事务管理方式为 JDBC,表示 MyBatis 使用 JDBC 提供的事务管理 -->
            <transactionManager type="JDBC"/>
            <!-- 定义数据源配置,使用 POOLED 类型的数据源 -->
            <dataSource type="POOLED">
                <!-- 数据库的连接信息 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/foooor_db"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  • <settings> 用来进行一些配置,mapUnderscoreToCamelCase 表示驼峰规则,将数据库的 create_time 映射为 Java 实体类中的 createTime该配置默认为 false,如果不配置,会获取不到多个单词的字段数据
  • 配置了数据库连接的信息(驱动、地址、用户名、密码等信息),关于多环境配置(开发、测试、生产)后面再介绍。

# 4 创建实体类

创建和数据库映射的实体类。

先在项目下创建包 com.foooor.mybatis.pojo (自定义的),然后在其下创建实体类。

User.java

package com.foooor.mybatis.pojo;
import lombok.Data;

import java.util.Date;

@Data  // 使用lombok注解,自动生成getter、setter、equals、hashCode、toString等方法
public class User {

    private Integer id;
    private String username;
    private String password;
    private String email;
    private Integer age;
    private Date createTime;
    private Date updateTime;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

和数据库中的字段对应。

# 5 创建Mapper接口

在 MyBatis 中操作数据库需要使用 Mapper 接口,不需要使用实现类。

一般 Mapper 接口的命名都是 XxxMapper.java

例如先在项目下创建包 com.foooor.mybatis.mapper (自定义的),然后在包下创建一个 UserMapper.java 接口,我们通过使用 UserMapper.java 接口,来操作数据库的 tb_user 表。后面有多张表,每张表都对应一个 Mapper 接口。

UserMapper.java 接口:

package com.foooor.mybatis.mapper;

import com.foooor.mybatis.pojo.User;

import java.util.List;

public interface UserMapper {

    /**
     * 查询所有用户
     */
    List<User> selectAll();

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

上面定义了一个查询所有用户的接口。

# 6 创建和配置SQL映射文件

创建 SQL 映射文件,用于将 UserMapper.java 中的接口方法与 SQL 语句进行映射。这样调用接口中方法的时候,执行指定的 SQL,并将返回结果,转换为指定类型的 Java 对象。

一般 SQL 映射文件的名称遵循 XxxMapper.xml 的格式,和接口类保持一致。后面有多张表,每张表都对应一个 Mapper 映射文件。

先在 src/main/resources 下创建一个 com/foooor/mybatis/mapper 文件夹(要与XxxMappper.java的包名对应),然后在文件夹下创建一个 UserMapper.xml

需要注意,创建完成 resources 下的 com/foooor/mybatis/mapper 文件夹在 IDEA 中会显示为 com.foooor.mybatis.mapper,要确保在硬盘上是一层一层的目录,不是一层目录叫 com.foooor.mybatis.mapper

UserMapper.xml,如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.foooor.mybatis.mapper.UserMapper">

    <!-- 定义查询所有用户的sql -->
    <select id="selectAll" resultType="com.foooor.mybatis.pojo.User">
        SELECT * FROM tb_user
    </select>

</mapper>
1
2
3
4
5
6
7
8
9
10
11
12
13
  • namespace 要和 Mapper 接口的全类名保持一致;
  • 这里是查询,所以使用 <select> 标签, SQL 的 id 要和 Mapper 接口中的方法名保持一致;
  • resultType="com.foooor.mybatis.pojo.User" 表示返回结果类型,类型是 User 或者是 User 的集合。
  • <select></select> 中间定义的是 SQL 语句,SQL是不区分大小写的,建议关键字使用大写

创建完SQL映射文件,需要在 MyBatis 配置文件中引入映射文件。

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!-- 设置 -->
    <settings>
        <!-- 驼峰命名法 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
  
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 数据库的连接信息 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/foooor_db"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 定义 MyBatis 的映射文件所在的位置 -->
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>

</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 7 测试

编写测试类,调用 Mapper 接口,查询数据。

首先需要创建 SqlSessionFactory ,通过 SqlSessionFactory 获取 session 连接,然后进行数据库操作。

src/test/java 下创建 com.foooor.mybatis.test 包(自定义的),在包下创建 MyBatisTest.java

MyBatisTest.java 编写如下:

package com.foooor.mybatis.test;

import com.foooor.mybatis.mapper.UserMapper;
import com.foooor.mybatis.pojo.User;
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.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;


public class MyBatisTest {

    /**
     * 测试查询用户
     */
    @Test
    public void testSelectUser() {
        String resource = "mybatis-config.xml";
        // 加载mybatis-config.xml文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 获取SqlSession连接
        SqlSession sqlSession = sqlSessionFactory.openSession();
      
        // 获取UserMapper接口的代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        // 查询用户列表
        List<User> userList = userMapper.selectAll();

        // 输出用户列表
        userList.forEach(user -> {
            System.out.println(user);
        });

        // 关闭SqlSession
        sqlSession.close();
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  • 上面定义了 getSession() 方法用来获取 SqlSession
  • 然后在 testSelectUser() 方法中获取 session ,通过 session 获取到 Mapper 接口,通过 Mapper 接口调用方法查询用户信息。

Mapper 接口的方法,还可以通过下面的方式来调用。

/**
 * 测试查询用户
 */
@Test
public void testSelectUser() {
    String resource = "mybatis-config.xml";
    // 加载mybatis-config.xml文件
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    // 获取SqlSession连接
    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 查询用户列表
    List<User> userList = sqlSession.selectList("com.foooor.mybatis.mapper.UserMapper.selectAll");

    // 输出用户列表
    userList.forEach(user -> {
        System.out.println(user);
    });

    // 关闭SqlSession
    sqlSession.close();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

最终执行结果:

User(id=1, username=doubi, password=123456, email=doubi@foooor.com, age=30, createTime=Sat Aug 17 08:03:52 CST 2024, updateTime=Sat Aug 17 08:03:52 CST 2024)
User(id=2, username=niubi, password=1234qwer, email=niubi@foooor.com, age=28, createTime=Sat Aug 17 08:03:52 CST 2024, updateTime=Sat Aug 17 08:03:52 CST 2024)
User(id=3, username=erbi, password=88888888, email=erbi@foooor.com, age=35, createTime=Sat Aug 17 08:03:52 CST 2024, updateTime=Sat Aug 17 08:03:52 CST 2024)
1
2
3

# 8 项目结构

# 2.3 HelloWorld优化

# 1 添加日志记录

可以添加日志框架,打印 MyBatis 执行的 SQL 日志,方便我们分析。

这里我就使用 logback 框架了,首先引入 logback 的依赖:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.5.7</version>
</dependency>
1
2
3
4
5

然后在 src/main/resources 下新建 logback.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 控制台输出 -->
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 设置 MyBatis 日志级别为 INFO -->
    <logger name="org.mybatis" level="INFO" additivity="false">
        <appender-ref ref="Console"/>
    </logger>

    <!-- 设置根日志级别 -->
    <root level="DEBUG">
        <appender-ref ref="Console"/>
    </root>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 2 封装 MyBatis 工具类

可以封装一个 MyBatis 工具类,用来获取 SqlSession。

举个栗子:

MyBatisUtils.java

package com.foooor.mybatis;

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 {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 获取SqlSession连接
    public static SqlSession getSession(){
        // 针对插入、更新、删除,自动提交事务
        return sqlSessionFactory.openSession(true);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  • 在上面的代码中,打开 session 的时候,传递的参数是 true,表示使用自动提交事务,在后面进行插入、修改、删除的时候,就不用手动提交事务了。

通过添加日志框架和封装 MyBatis 工具类,就可以在代码中直接通过上面的工具类来获取 SqlSession ,并打印日志。

package com.foooor.mybatis.test;

import com.foooor.mybatis.MyBatisUtils;
import com.foooor.mybatis.mapper.UserMapper;
import com.foooor.mybatis.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

@Slf4j  // 使用lombok提供的的@Slf4j日志注解
public class MyBatisTest {
    /**
     * 测试查询用户
     */
    @Test
    public void testSelectUser() throws IOException {
        // 获取SqlSession连接
        SqlSession sqlSession = MyBatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        // 查询用户列表
        List<User> userList = userMapper.selectAll();

        // 输出用户列表
        userList.forEach(user -> {
            log.info("user: {}", user);
        });

        // 关闭SqlSession
        sqlSession.close();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35