MyBatis-Flex 完全学习指南 - 从入门到精通

作者:Administrator 发布时间: 2026-03-09 阅读量:25 评论数:0

MyBatis-Flex 完全学习指南 - 从入门到精通

一个优雅的 MyBatis 增强框架,让数据库操作变得简单高效


一、什么是 MyBatis-Flex?

1.1 简介

MyBatis-Flex 是一个优雅的 MyBatis 增强框架,它非常轻量、同时拥有极高的性能与灵活性。我们可以轻松的使用 MyBatis-Flex 连接任何数据库,其内置的 QueryWrapper 帮助我们极大的减少了 SQL 编写的工作,同时减少出错的可能性。

1.2 核心特性

┌─────────────────────────────────────────────────────────────┐
│                    MyBatis-Flex 核心特性                      │
├─────────────────────────────────────────────────────────────┤
│  🪶 轻量                                                      │
│     • 除 MyBatis 外无任何第三方依赖                              │
│     • 无拦截器,通过 SqlProvider 实现                            │
│     • 执行过程无 SQL 解析,性能极高                              │
├─────────────────────────────────────────────────────────────┤
│  🔧 灵活                                                      │
│     • 支持 Entity 增删改查 + 分页                               │
│     • 提供 Db + Row 工具,无需实体类操作                          │
│     • QueryWrapper 支持多表查询、关联查询、子查询                    │
├─────────────────────────────────────────────────────────────┤
│  💪 强大                                                      │
│     • 支持任意关系型数据库,可扩展方言                              │
│     • 多主键、逻辑删除、乐观锁、数据脱敏                            │
│     • 数据审计、数据填充等高级功能                                 │
└─────────────────────────────────────────────────────────────┘

二、快速开始

2.1 环境准备

  • JDK: 1.8 或更高版本

  • Maven: 3.6+ 或 Gradle 7+

  • 数据库: MySQL、PostgreSQL、Oracle 等任意关系型数据库

2.2 创建 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>
    
    <groupId>com.example</groupId>
    <artifactId>mybatis-flex-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <mybatis-flex.version>1.8.0</mybatis-flex.version>
    </properties>
    
    <dependencies>
        <!-- MyBatis-Flex 核心依赖 -->
        <dependency>
            <groupId>com.mybatis-flex</groupId>
            <artifactId>mybatis-flex-core</artifactId>
            <version>${mybatis-flex.version}</version>
        </dependency>
        
        <!-- 数据库驱动 - 以 MySQL 为例 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        
        <!-- 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.20</version>
        </dependency>
        
        <!-- 日志 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>2.0.9</version>
        </dependency>
    </dependencies>
</project>

2.3 配置文件

mybatis-flex.properties:

# 数据源配置
dataSource.type=com.alibaba.druid.pool.DruidDataSource
dataSource.driver-class-name=com.mysql.cj.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
dataSource.username=root
dataSource.password=your_password
​
# MyBatis-Flex 配置
mybatis-flex.mapper-locations=classpath*:mapper/**/*.xml
mybatis-flex.type-aliases-package=com.example.entity

或者使用 Java 配置类:

import com.alibaba.druid.pool.DruidDataSource;
import com.mybatisflex.core.MybatisFlexBootstrap;
import javax.sql.DataSource;
​
public class MyBatisConfig {
    
    public static DataSource createDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8");
        dataSource.setUsername("root");
        dataSource.setPassword("your_password");
        dataSource.setInitialSize(5);
        dataSource.setMaxActive(20);
        return dataSource;
    }
    
    public static void init() {
        MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance();
        bootstrap.setDataSource(createDataSource());
        bootstrap.addMapper(UserMapper.class);
        bootstrap.start();
    }
}

三、实体类与 Mapper

3.1 创建实体类

User.java:

import com.mybatisflex.annotation.*;
import java.util.Date;
​
@Table("tb_user")  // 映射数据库表名
public class User {
    
    @Id(keyType = KeyType.Auto)  // 主键,自增
    private Long id;
    
    @Column("user_name")  // 指定列名
    private String userName;
    
    private String email;
    
    private Integer age;
    
    @Column(isLogicDelete = true)  // 逻辑删除字段
    private Boolean isDeleted;
    
    @Column(onInsertValue = "now()")  // 插入时自动填充
    private Date createTime;
    
    @Column(onInsertValue = "now()", onUpdateValue = "now()")  // 插入和更新时自动填充
    private Date updateTime;
    
    // Getters and Setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    
    public String getUserName() { return userName; }
    public void setUserName(String userName) { this.userName = userName; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    
    public Boolean getIsDeleted() { return isDeleted; }
    public void setIsDeleted(Boolean isDeleted) { this.isDeleted = isDeleted; }
    
    public Date getCreateTime() { return createTime; }
    public void setCreateTime(Date createTime) { this.createTime = createTime; }
    
    public Date getUpdateTime() { return updateTime; }
    public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }
    
    @Override
    public String toString() {
        return "User{id=" + id + ", userName='" + userName + "', email='" + email + "', age=" + age + "}";
    }
}

3.2 创建 Mapper 接口

UserMapper.java:

import com.mybatisflex.core.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
​
public interface UserMapper extends BaseMapper<User> {
    
    // 自定义 SQL 方法
    List<User> selectByAgeGreaterThan(@Param("age") Integer age);
}

对应的 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.example.mapper.UserMapper">
    
    <select id="selectByAgeGreaterThan" resultType="com.example.entity.User">
        SELECT * FROM tb_user WHERE age > #{age} AND is_deleted = 0
    </select>
    
</mapper>

四、CRUD 操作实战

4.1 插入数据

import com.mybatisflex.core.query.QueryWrapper;
​
public class UserService {
    
    private UserMapper userMapper;
    
    // 插入单条记录
    public void insertUser() {
        User user = new User();
        user.setUserName("张三");
        user.setEmail("zhangsan@example.com");
        user.setAge(25);
        
        int rows = userMapper.insert(user);
        System.out.println("插入成功,影响行数:" + rows);
        System.out.println("生成的主键 ID:" + user.getId());
    }
    
    // 批量插入
    public void batchInsert() {
        List<User> users = Arrays.asList(
            createUser("张三", "zs@example.com", 25),
            createUser("李四", "ls@example.com", 30),
            createUser("王五", "ww@example.com", 28)
        );
        
        int rows = userMapper.insertBatch(users);
        System.out.println("批量插入成功,影响行数:" + rows);
    }
    
    private User createUser(String name, String email, Integer age) {
        User user = new User();
        user.setUserName(name);
        user.setEmail(email);
        user.setAge(age);
        return user;
    }
}

4.2 查询数据

public class UserQueryService {
    
    private UserMapper userMapper;
    
    // 根据 ID 查询
    public User getById(Long id) {
        return userMapper.selectOneById(id);
    }
    
    // 条件查询 - 使用 QueryWrapper
    public List<User> queryByCondition() {
        QueryWrapper wrapper = QueryWrapper.create()
            .from(User.class)
            .where(User::getAge).ge(20)  // age >= 20
            .and(User::getUserName).like("张")  // user_name like '%张%'
            .orderBy(User::getCreateTime).desc();
        
        return userMapper.selectListByQuery(wrapper);
    }
    
    // 多条件组合查询
    public List<User> complexQuery(String keyword, Integer minAge, Integer maxAge) {
        QueryWrapper wrapper = QueryWrapper.create()
            .from(User.class)
            .where(User::getIsDeleted).eq(false)
            .and(wrapper -> {
                wrapper.where(User::getUserName).like(keyword)
                       .or(User::getEmail).like(keyword);
            })
            .and(User::getAge).between(minAge, maxAge)
            .orderBy(User::getAge).asc()
            .orderBy(User::getCreateTime).desc();
        
        return userMapper.selectListByQuery(wrapper);
    }
    
    // 分页查询
    public Page<User> queryByPage(int pageNum, int pageSize) {
        QueryWrapper wrapper = QueryWrapper.create()
            .from(User.class)
            .where(User::getIsDeleted).eq(false)
            .orderBy(User::getCreateTime).desc();
        
        Page<User> page = Page.of(pageNum, pageSize);
        return userMapper.paginate(page, wrapper);
    }
    
    // 只查询部分字段
    public List<Map<String, Object>> querySimple() {
        QueryWrapper wrapper = QueryWrapper.create()
            .select(User::getId, User::getUserName, User::getEmail)
            .from(User.class)
            .where(User::getAge).ge(18);
        
        return userMapper.selectMapsByQuery(wrapper);
    }
}

4.3 更新数据

public class UserUpdateService {
    
    private UserMapper userMapper;
    
    // 根据 ID 更新
    public void updateById(Long id) {
        User user = new User();
        user.setId(id);
        user.setUserName("张三(已修改)");
        user.setAge(26);
        
        int rows = userMapper.update(user);
        System.out.println("更新成功,影响行数:" + rows);
    }
    
    // 条件更新
    public void updateByCondition() {
        User user = new User();
        user.setAge(30);
        
        QueryWrapper wrapper = QueryWrapper.create()
            .where(User::getUserName).like("测试");
        
        int rows = userMapper.updateByQuery(user, wrapper);
        System.out.println("条件更新成功,影响行数:" + rows);
    }
    
    // 使用 UpdateWrapper 进行更灵活的更新
    public void updateWithWrapper() {
        int rows = userMapper.updateByQuery(
            UpdateWrapper.create()
                .set(User::getAge, User::getAge + 1)  // age = age + 1
                .setRaw("update_time", "now()")
                .where(User::getId).eq(1L)
        );
        System.out.println("更新成功,影响行数:" + rows);
    }
}

4.4 删除数据

public class UserDeleteService {
    
    private UserMapper userMapper;
    
    // 根据 ID 删除(逻辑删除)
    public void deleteById(Long id) {
        int rows = userMapper.deleteById(id);
        System.out.println("删除成功,影响行数:" + rows);
    }
    
    // 批量删除
    public void batchDelete(List<Long> ids) {
        int rows = userMapper.deleteBatchByIds(ids);
        System.out.println("批量删除成功,影响行数:" + rows);
    }
    
    // 条件删除
    public void deleteByCondition() {
        QueryWrapper wrapper = QueryWrapper.create()
            .where(User::getAge).lt(18)
            .and(User::getIsDeleted).eq(false);
        
        int rows = userMapper.deleteByQuery(wrapper);
        System.out.println("条件删除成功,影响行数:" + rows);
    }
}

五、高级特性

5.1 多表关联查询

// 定义关联查询结果实体
public class UserDetailVO {
    private Long userId;
    private String userName;
    private String email;
    private String departmentName;  // 部门名称
    private List<String> roleNames; // 角色列表
}
​
// 多表查询
public List<UserDetailVO> selectUserWithDepartment() {
    QueryWrapper wrapper = QueryWrapper.create()
        .select(
            User::getId.as("userId"),
            User::getUserName,
            User::getEmail,
            Department::getDeptName.as("departmentName")
        )
        .from(User.class)
        .leftJoin(Department.class).on(User::getDeptId, Department::getId)
        .where(User::getIsDeleted).eq(false);
    
    return userMapper.selectListByQueryAs(wrapper, UserDetailVO.class);
}

5.2 使用 Db + Row 工具

import com.mybatisflex.core.Db;
import com.mybatisflex.core.row.Row;
​
public class RowService {
    
    // 使用 Row 进行增删改查(无需实体类)
    public void rowExample() {
        // 插入
        Row row = new Row();
        row.set("user_name", "赵六");
        row.set("email", "zl@example.com");
        row.set("age", 35);
        
        Db.insert("tb_user", row);
        
        // 查询
        List<Row> rows = Db.selectListByQuery(
            "tb_user",
            QueryWrapper.create()
                .where("age").ge(25)
                .orderBy("create_time").desc()
        );
        
        for (Row r : rows) {
            System.out.println("用户名:" + r.getString("user_name"));
            System.out.println("邮箱:" + r.getString("email"));
        }
        
        // 更新
        Row updateRow = new Row();
        updateRow.set("age", 36);
        
        Db.updateByQuery("tb_user", updateRow,
            QueryWrapper.create().where("user_name").eq("赵六")
        );
    }
}

5.3 乐观锁

// 实体类添加版本号字段
@Table("tb_account")
public class Account {
    @Id
    private Long id;
    
    private String accountName;
    
    private Double balance;
    
    @Column(isVersion = true)  // 乐观锁版本号
    private Integer version;
}
​
// 使用乐观锁更新
public void transfer(Long fromId, Long toId, Double amount) {
    Account fromAccount = accountMapper.selectOneById(fromId);
    Account toAccount = accountMapper.selectOneById(toId);
    
    fromAccount.setBalance(fromAccount.getBalance() - amount);
    toAccount.setBalance(toAccount.getBalance() + amount);
    
    // 乐观锁会自动处理版本号
    int rows1 = accountMapper.update(fromAccount);
    int rows2 = accountMapper.update(toAccount);
    
    if (rows1 == 0 || rows2 == 0) {
        throw new RuntimeException("转账失败,账户信息已被修改");
    }
}

5.4 数据填充

// 自动填充创建人和更新人
public class BaseEntity {
    
    @Column(onInsertValue = "current_user()")
    private String createBy;
    
    @Column(onInsertValue = "now()", onUpdateValue = "now()")
    private Date updateTime;
    
    @Column(onUpdateValue = "current_user()")
    private String updateBy;
}

六、性能优化

6.1 缓存配置

// 开启二级缓存
@Table(value = "tb_user", cache = true)
public class User {
    // ...
}
​
// 或者在配置文件中全局开启
mybatis-flex.configuration.cache-enabled=true

6.2 SQL 打印

# 开发环境开启 SQL 打印
mybatis-flex.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

6.3 批量操作优化

// 大批量插入使用分批处理
public void largeBatchInsert(List<User> users) {
    int batchSize = 500;
    List<User> batch = new ArrayList<>();
    
    for (int i = 0; i < users.size(); i++) {
        batch.add(users.get(i));
        
        if (batch.size() >= batchSize || i == users.size() - 1) {
            userMapper.insertBatch(batch);
            batch.clear();
        }
    }
}

七、完整示例项目结构

mybatis-flex-demo/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           ├── MyBatisFlexApplication.java    # 启动类
│   │   │           ├── config/
│   │   │           │   └── MyBatisConfig.java          # 配置类
│   │   │           ├── entity/
│   │   │           │   ├── User.java                   # 用户实体
│   │   │           │   └── Department.java             # 部门实体
│   │   │           ├── mapper/
│   │   │           │   ├── UserMapper.java             # 用户 Mapper
│   │   │           │   └── DepartmentMapper.java       # 部门 Mapper
│   │   │           ├── service/
│   │   │           │   ├── UserService.java            # 用户服务
│   │   │           │   └── impl/
│   │   │           │       └── UserServiceImpl.java    # 服务实现
│   │   │           └── vo/
│   │   │               └── UserDetailVO.java           # 视图对象
│   │   └── resources/
│   │       ├── mybatis-flex.properties                 # 配置文件
│   │       └── mapper/
│   │           └── UserMapper.xml                      # XML 映射文件
│   └── test/
│       └── java/
│           └── com/
│               └── example/
│                   └── UserMapperTest.java             # 测试类
└── pom.xml                                             # Maven 配置

八、总结

8.1 MyBatis-Flex vs MyBatis-Plus

特性

MyBatis-Flex

MyBatis-Plus

依赖

仅 MyBatis

MyBatis + 其他

SQL 解析

性能

更高

QueryWrapper

更灵活

灵活

学习曲线

平缓

平缓

8.2 最佳实践

  1. 实体类设计:合理使用注解,避免过度设计

  2. 查询优化:复杂查询使用 QueryWrapper,简单查询使用 BaseMapper 方法

  3. 事务管理:Service 层使用 @Transactional 注解

  4. 分页查询:大数据量必须使用分页,避免内存溢出

  5. 日志配置:生产环境关闭 SQL 打印,开发环境开启

8.3 学习资源


结语

MyBatis-Flex 是一个值得尝试的 MyBatis 增强框架,它以轻量、灵活、高性能的特点,为 Java 开发者提供了更加优雅的数据库操作方式。无论是小型项目还是大型企业应用,MyBatis-Flex 都能很好地满足需求。

希望这篇学习笔记能帮助你快速上手 MyBatis-Flex,在实际项目中发挥其强大的功能!


文章作者:李立亮 发布时间:2026-03-09 分类:mybatis-flex 标签:MyBatis-Flex, Java, ORM, 数据库, 教程

评论