MyBatis 框架集成到 SpringBoot 项目的方法

664 阅读5分钟

1. 添加依赖

首先在 SpringBoot 项目的 pom.xml 文件中添加 MyBatis 依赖,我使用的 SpringBoot 版本是 2.5.3,这里我引入最新的 MyBatis 版本:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

然后再在 pom.xml 的build标签中添加资源配置,因为 MyBatis 一般会使用 xml 文件写 SQL,并且我习惯将 xml 文件放在/src/main/java/**/mapper/xml包下,所以这里需要该配置,否则编译或打包的时候 IDEA 不会将该目录下的 xml 文件一起打包的。

<resources>
    <!-- src/main/java下的xml资源编译到classes下 -->
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
    </resource>
    <!-- src/main/resources下的资源编译到classes下 -->
    <resource>
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.*</include>
        </includes>
    </resource>
</resources>

注意:这里未正确配置可能会引起异常org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

2. 配置文件

下面写几条我认为要用到的配置。以下配置均配置在application.properties中。

2.1. 配置 xml 文件地址

当 xml 文件和 mapper 接口不在同一个包下的时候必须配置这个,我的项目一般 mapper 接口在src/main/java/**/mapper包下,而 xml 文件我习惯放在该包下的 xml 包中,也就是src/main/java/**/mapper/xml包下。当 xml 文件和 mapper 接口在同一个包下的时候这个配置可以省略。

mybatis.mapper-locations=classpath:**/mapper/xml/*.xml

注意:这里未正确配置也可能会引起异常org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

2.2. 配置实体包地址

指定 model 包地址,mybatis 的 xml 中的 resultType 等返回类型就可直接写为该类的首字母小写的简写形式,该项配置非必须,我们可以直接写完整类名,便于跳转和识别。比如:

<select id="listOutputTasks" resultType="com.gtcom.web.entity.OutputTask">
    SELECT * FROM output_task
</select>
mybatis.type-aliases-package=com.gtcom.web.entity

2.3. 配置下划线自动映射驼峰

将带有下划线的表字段映射为驼峰格式的实体类属性,因为数据库表字段一般都是以下划线分割的,而 Java 类字段命名都是驼峰命名的。要让 MyBatis 实现自动映射,就要启用该配置项。

mybatis.configuration.map-underscore-to-camel-case=true

2.4. 配置日志级别

mybatis 日志设置,我们可以在开发阶段将 mapper 接口所在的包的日志格式调整为 trace 级别,这样能完整输出 SQL 的执行过程日志,便于调试。其中com.gtcom.web.mapper是我的 mapper 接口和 xml 文件所在的包。

logging.level.com.gtcom.web.mapper=trace

从下面的日志可以看出,SQL 语句和参数以及结果总数的日志级别是 DEBUG,返回结果明细的日志级别是 TRACE,所以我们可以在开发或测试环境指定对应包的日志级别为 TRACE,而生产环境可以指定为 DEBUG 或者 INFO,减少日志输出。

2021-08-21 17:58:44.827 DEBUG 14848 --- [nio-8080-exec-1] c.g.w.m.O.listOutputTasks                : ==>  Preparing: SELECT * FROM output_task 
2021-08-21 17:58:44.857 DEBUG 14848 --- [nio-8080-exec-1] c.g.w.m.O.listOutputTasks                : ==> Parameters: 
2021-08-21 17:58:44.884 TRACE 14848 --- [nio-8080-exec-1] c.g.w.m.O.listOutputTasks                : <==    Columns: id, create_time, update_time
2021-08-21 17:58:44.886 TRACE 14848 --- [nio-8080-exec-1] c.g.w.m.O.listOutputTasks                : <==        Row: 1, 2021-08-15 10:10:07, 2021-08-18 10:11:28
2021-08-21 17:58:44.892 TRACE 14848 --- [nio-8080-exec-1] c.g.w.m.O.listOutputTasks                : <==        Row: 2, 2021-01-01 13:04:04, 2021-08-21 17:08:54
2021-08-21 17:58:44.893 DEBUG 14848 --- [nio-8080-exec-1] c.g.w.m.O.listOutputTasks                : <==      Total: 2

3. 代码编写

OutputTaskMapper.xml

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gtcom.web.mapper.OutputTaskMapper">

    <select id="listOutputTasks" resultType="com.gtcom.web.entity.OutputTask">
        SELECT * FROM data_center.output_task
    </select>

</mapper>

OutputTaskMapper.java

package com.gtcom.web.mapper;

import com.gtcom.web.entity.OutputTask;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author wangbo
 * @date 2021/8/20
 */
@Mapper
public interface OutputTaskMapper {

    /**
     * 查询输出任务列表
     *
     * @return List<OutputTask>
     */
    List<OutputTask> listOutputTasks();

}

4. 注解使用

MyBatis 提供了多种注解来支持 SQL 操作,包括:

  • @Select:用于执行查询操作,将查询结果映射到指定的 Java 对象或基本数据类型。
  • @Insert:用于执行插入操作,将 Java 对象的数据插入到数据库中。
  • @Update:用于执行更新操作,更新数据库中已有的数据。
  • @Delete:用于执行删除操作,从数据库中删除指定的数据行。

此外,还有 @ResultMap@Results@Result 和 @Param 等注解,用于定义查询结果的映射关系和参数命名。

import org.apache.ibatis.annotations.*;

public interface UserMapper {

    // 使用 @Select 注解执行查询操作
    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(Long id);

    // 使用 @Insert 注解执行插入操作
    @Insert("INSERT INTO users (id, username, password) VALUES (#{id}, #{username}, #{password})")
    void insertUser(User user);

    // 使用 @Update 注解执行更新操作
    @Update("UPDATE users SET username = #{username}, password = #{password} WHERE id = #{id}")
    void updateUser(User user);

    // 使用 @Delete 注解执行删除操作
    @Delete("DELETE FROM users WHERE id = #{id}")
    void deleteUserById(Long id);
}

MyBatis 注解 SQL 的最佳实践建议

  1. 合理选择注解与 XML‌:根据项目的实际需求和团队的开发习惯,合理选择使用注解还是 XML 配置。对于简单的 SQL 语句,可以使用注解方式;对于复杂的 SQL 语句,建议使用 XML 配置
  2. 使用参数命名‌:在注解中使用 @Param 注解为参数命名,以便在 SQL 语句中引用。这可以提高代码的可读性和可维护性。
  3. 利用动态 SQL‌:虽然注解方式在支持动态 SQL 方面不如 XML 配置灵活,但可以通过使用 @SelectProvider 等注解提供器方式来动态生成 SQL 语句。
  4. 合理设计 Mapper 接口‌:Mapper 接口的设计应简洁明了,每个方法只负责一个具体的数据库操作。这有助于提高代码的可读性和可维护性。
  5. 充分利用 MyBatis 插件‌:MyBatis 提供了插件机制,可以通过自定义插件来扩展 MyBatis 的功能。开发者可以充分利用这一机制来实现 SQL 拦截、结果集处理等功能,以提高开发效率和代码质量。