Spring Boot 整合 MyBatis


MyBatis 简介

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Ordinary Java Objects,简单 Java 对象)为数据库中的记录。

参考自 MyBatis 的官方简介。

MyBatis 作为一款优秀的持久层框架,具有如下优点:

  1. 小巧并且简单易学。

  2. 相比于 JDBC 减少了大量冗余的代码。

  3. 将 SQL 语句与程序代码进行分离,降低了耦合,便于管理。

  4. 提供 XML 标签,支持编写动态 SQL 语句。

  5. 提供映射标签,支持 Java 对象的属性与数据表字段的映射关系。

MyBatis 实践

下面我们创建一个 Spring Boot 项目,整合 MyBatis,实现简单的 CRUD 功能。

1. 引入依赖

POM 文件如下:

<?xml version="1.0" encoding="UTF-8"?>

    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.5.6
         
    
    com.example
    springboot-mybatis
    0.0.1-SNAPSHOT
    springboot-mybatis
    Demo project for Spring Boot
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            mysql
            mysql-connector-java
            runtime
        

        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.2.0
        

        
            org.springframework.boot
            spring-boot-starter-jdbc
        

        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        

        
            org.projectlombok
            lombok
            true
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    


2. 配置 MySQL 和 MyBatis

配置文件 application.yml 的内容如下:

# 配置 MySQL
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

# 配置 MyBatis
mybatis:
  mapper-locations: classpath:mapper/*
  type-aliases-package: com.example.entity
  configuration:
    map-underscore-to-camel-case: true

MyBatis 的配置项中:

  • mapper-locations:用来指定 mapper.xml 文件的路径,该文件用于编写 SQL 语句。

  • type-aliases-package:用来设置别名,它的作用是告诉 MyBatis 需要设置别名的实体类的所在的包。默认情况下,MyBatis 会使用实体类的非限定类名来作为它的别名,如将 com.example.entity.User 的别名设置为 Useruser(别名不区分大小写)。当然,MyBatis 也支持自定义别名,这个我们在后文中再聊。

  • map-underscore-to-camel-case:用来开启驼峰命名自动映射,如将数据表中的字段 user_name 映射到实体对象的属性 userName。

3. 实体类

编写简单的 User 类:

package com.example.entity;

import lombok.Data;

import java.util.Date;

/**
 * @Author john
 * @Date 2021/11/14
 */
@Data
public class User {

    private long id;

    private String userName;

    private int age;

    private String address;

    private Date createTime;

    private Date updateTime;
}

User 类中封装了用户的 id、姓名、年龄、地址、创建时间以及修改时间等信息。

4. 创建 user 表

user 表的字段设计如下:

5. 编写 Mapper 接口和 mapper 文件

首先编写 UserMapper 接口:

package com.example.mapper;

import com.example.entity.User;

/**
 * @Author john
 * @Date 2021/11/16
 */
public interface UserMapper {
    
    void insertUser(User user);
    
    User findUserById(long id);
}

接口中定义了两个方法,insertUser 用来向数据表中插入一条记录,findUserById 用来通过 id 查询 User。

上述操作完成后,我们在 resources 文件夹中创建 mapper/user-mapper.xml 文件(文件路径在配置文件 application.yml 中设置)。user-mapper.xml 文件的内容如下:

<?xml version="1.0" encoding="UTF-8" ?>




    
        user_name, age, address, gmt_create, gmt_modified
    

    
        id, user_name, age, address, gmt_create, gmt_modified
    

    
        
        
        
        
        
        
    

    

    
        insert into user ()
        values(#{userName}, #{age}, #{address}, UTC_TIMESTAMP(), UTC_TIMESTAMP())
    


可以看到,Mapper 接口中定义的是 CRUD 相关的方法,mapper.xml 文件中定义的是具体的 SQL 语句。MyBatis 允许我们将 Mapper 接口与 mapper.xml 文件关联在一起,这样当调用 Mapper 接口中的方法时,实际的处理逻辑为执行 mapper.xml 文件中对应的 SQL 语句。关联 Mapper 接口和 mapper.xml 文件时需要保证:

  • Mapper 接口的全限定名对应 mapper.xml 文件的 namespace 值。

  • Mapper 接口的方法名对应 statement(每一个 SQL 就是一个 statement)的 id 值。

  • Mapper 接口中方法接收的参数对应 statement 的入参。

  • Mapper 接口中方法的返回值对应 statement 的出参。

下面介绍一下 mapper.xml 文件中几个重要标签的含义:

  • 标签:用于定义复用的 SQL 片段,如果多个 SQL 需要操作相同的字段集,那么就可以使用 标签将这些字段提取出来,然后在 SQL 语句中直接引用即可。引用的语法为 ,其中 refid 的值就是 的 id 值。

  • 标签:用于创建数据表字段与实体属性的映射关系,在查询操作中,MyBatis 会根据查询到的字段名找到 POJO 对应的属性名,然后调用该属性的 setter 方法进行赋值。如果数据表的字段名与实体类的属性名完全相同,或者符合驼峰式命名映射的规则,那么 MyBatis 可以直接完成赋值操作。否则的话,就需要我们使用 标签创建自定义的映射规则,告诉 MyBatis 字段和属性之间应该如何映射。本实验中,user 表的 id 会自动映射为 User 对象的 id,user 表的 user_name 也会自动映射为 User 对象的 userName。但是 gmt_create 和 gmt_modified 不会映射为 createTime 和 updateTime,因为字段名和属性名既不完全一致,也不符合驼峰式命名映射的规则,所以这里我们需要使用 来创建新的映射关系,其中属性 id 用于指明该 resultMap 的标志,属性 type 用于指明映射的实体类。