948 字
3 分钟
MyBatis-Flex 入门教程
2026-03-25

一.简介#

做 Java 开发的同学基本都离不开 MyBatis
MyBatis 的灵活性确实很强,但写 XML 配置文件有时候确实比较繁琐;后来出现的 MyBatis-Plus 在单表 CRUD 方面体验很好,不过一旦涉及复杂的多表查询,还是需要手写 SQL。

最近做项目使用了一下 MyBatis-Flex,感觉确实比较惊喜:
既保留了 MyBatis 的灵活性和高性能,又在单表操作和多表 Join 上提供了非常优雅的写法,而且代码提示非常友好。

这篇文章简单介绍一下 MyBatis-Flex 的基础使用


二.APT 与强类型 SQL介绍#

MyBatis-Flex 的一个核心特点是 APT(编译期注解处理器)

我们经常使用的Lombok就是基于APT实现的 Lombok的@Data注解就是利用APT 在编译阶段生成getter,setter代码。

传统 MyBatis 在写查询条件时,经常需要写字符串形式的字段名,例如:

@Select("SELECT * FROM user WHERE user_name = #{userName}")

这种方式的问题是:

  • 字段名是字符串,没有代码提示

  • 容易拼写错误

  • 数据库字段修改时,代码不会在编译期报错

MyBatis-Flex 的 APT 会在编译时自动生成 表定义类(TableDef)

例如: 你有一个User的实体类,在编译时就会生成UserTableDef

这样写查询条件时就可以变成:

QueryWrapper query = QueryWrapper.create()
.where(USER.USER_NAME.eq(userName));

优势很明显:

  • idea 自动提示字段

  • 类型安全

  • 字段变更时编译期就能发现问题


三.搭建开发环境#

我这里的演示环境是:

  • Java 21

  • Spring Boot 4

  • MyBatis-Flex 1.11.6

1.依赖导入#

核心 pom.xml 配置如下:

<properties>
<java.version>21</java.version>
<mybatis-flex.version>1.11.6</mybatis-flex.version>
</properties>
<dependencies>
<dependency>
<!--flex的配置-->
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot4-starter</artifactId>
<version>${mybatis-flex.version}</version>
</dependency>
<!--jdbc配置,springboot4因 stater 提供的 spring-boot-autoconfigure ,
不再默认包含 jdbc(datasource) 的 autoconfigure,
需要添加依赖 spring-boot-starter-jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<!--flex的apt配置-->
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-processor</artifactId>
<version>${mybatis-flex.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>

如果使用 IDEA,需要开启 注解处理器


2.配置文件和数据库配置#

我这里使用的是mysql 8.0 配置文件:

spring:
datasource:
url: jdbc:mysql://localhost:3306/flex-demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: 你的用户名
password: 你的密码
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-flex:
configuration:
# 开启控制台 SQL 打印
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

这里创建两个简单的表:

# 创建数据库
CREATE DATABASE IF NOT EXISTS flex_db;
# 用户表
CREATE TABLE user(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
age INT
);
# 用户详情表
CREATE TABLE user_detail(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT,
address VARCHAR(100),
phone VARCHAR(20)
);
  • user 表:存储用户的基础信息
  • user_detail 表:存储用户的详细信息
  • 两张表通过 user_detail.user_iduser.id 建立关联关系

3.实体类和VO#

实体类只需要使用 @Table@Id 注解即可:

  • @Table用于标注实体类对应的数据库表名
  • @Id指定主键字段
@Data
@Table("user")
public class User {
@Id
private Long id;
private String username;
private Integer age;
}
@Data
@Table("user_detail")
public class UserDetail {
@Id
private Long id;
private Long userId;
private String address;
private String phone;
}

VO用于连表查询返回

import lombok.Data;
@Data
public class UserVO {
// 来自 user 表的字段
private Long id;
private String username;
private Integer age;
// 来自 user_detail 表的字段
private String address;
private String phone;
}

4.Mapper 接口#

MyBatis-Flex 提供了 BaseMapper,继承后即可获得大量基础 CRUD 方法。

import com.mybatisflex.core.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
@Mapper
public interface UserDetailMapper extends BaseMapper<UserDetail> {
}

常见的方法

方法功能
insert插入数据
deleteById根据主键删除
update根据主键更新
selectById根据主键查询
selectList查询列表

5.添加源代码根目录#

没有添加之前,代码会因为找不到 Flex 生成的 TableDef 类无法导包而爆红。这是因为 IDEA 默认不会去扫描 target 目录下的代码。

解决办法:

在左侧目录树中,找到 target/generated-sources/annotations 文件夹(如图二)。

右键点击 annotations 文件夹。

选择 将目录标记为 -> 源代码更根目录。 设置完成后,文件夹图标会变色,IDEA 建立索引后代码就可以正常导包了。#

四.查询示例#

1.单表查询示例#

查询 年龄大于 18 岁的用户

public void testSingleTableQuery() {
// 1. 创建查询条件包装器 (QueryWrapper)
QueryWrapper queryWrapper = QueryWrapper.create()
// USER: 是 MyBatis-Flex 自动生成的类,代表 `user` 表
// AGE: 代表 `user` 表里的 `age` 字段
// gt(18):gt 是 "greater than" 的缩写,意思是“大于 (>) 18”
// 组合起来相当于 SQL 里的:WHERE age > 18
.where(USER.AGE.gt(18));
// 2. 调用 userMapper 执行查询,返回值是一个 List,里面装的是 User 实体类
List<User> adultUsers = userMapper.selectListByQuery(queryWrapper);

MyBatis-Flex 实际生成的 SQL 类似:

SELECT *
FROM user
WHERE age > 18;

2.多表 Join 查询#

查询 用户及其详情信息

public void testJoinTableQuery() {
// 1. 创建查询条件包装器,构建 Join 查询的 SQL
QueryWrapper queryWrapper = QueryWrapper.create()
.select() // 代表查询这两张表的所有字段 (相当于 SELECT *)
.from(USER) // 主表是 user 表 (相当于 FROM user)
// leftJoin: 代表左连接 user_detail 表 (相当于 LEFT JOIN user_detail)
.leftJoin(USER_DETAIL)
// on: 定义连表的关联条件
// USER.ID.eq(...) : eq 是 "equals" 的缩写,意思是“等于 (=)”
// 组合起来相当于 SQL 里的:ON user.id = user_detail.user_id
.on(USER.ID.eq(USER_DETAIL.USER_ID))
// where: 筛选条件
// ge(20) : ge 是 "greater than or equal to" 的缩写,意思是“大于等于 (>=) 20”
// 组合起来相当于 SQL 里的:WHERE user.age >= 20
.where(USER.AGE.ge(20));
// 2. 执行查询并转换结果类型
// selectListByQueryAs 的第二个参数 UserVO.class 非常关键
// 框架会自动把查出来的字段(如 username, address, phone)映射到 UserVO 对应的属性里
List<UserVO> userVOList = userMapper.selectListByQueryAs(queryWrapper, UserVO.class);

对应生成的 SQL 类似:

SELECT *
FROM user
LEFT JOIN user_detail
ON user.id = user_detail.user_id
WHERE user.age >= 20;

eq = Equal (等于 =)

ne = Not Equal (不等于 !=)

gt = Greater Than (大于 >)

ge = Greater than or Equal (大于等于 >=)

lt = Less Than (小于 <)

le = Less than or Equal (小于等于 <=)


五.总结#

本文只介绍了 MyBatis-Flex 的基本使用流程以及可能遇到的问题,更多高级功能和详细用法可参考官方文档进一步学习。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

MyBatis-Flex 入门教程
https://csa.fur1na.top/posts/mybatis-flex-入门教程/
作者
fur1na
发布于
2026-03-25
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00