MyBatis-Flex 完整使用指南

一、环境准备

1. Maven 依赖

<dependencies>
<!-- MyBatis-Flex 核心依赖 -->
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
<version>1.8.0</version>
</dependency> <!-- 数据库驱动(以 MySQL 为例) -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency> <!-- Lombok(可选) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

二、完整配置流程

1. 数据源配置 (application.yml)

spring:
datasource:
url: jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver # MyBatis-Flex 高级配置
mybatis-flex:
# 是否打印 SQL(开发环境建议开启)
print-sql: true
# 全局配置
global-config:
# 逻辑删除配置
logic-delete:
logic-delete-value: 1 # 已删除值
logic-not-delete-value: 0 # 未删除值
# 多租户配置
tenant-config:
ignore-tables: sys_config, sys_log # 忽略租户过滤的表
# 字段安全类型(脱敏/加密)
column-security:
# 全局加密密钥(可覆盖)
aes-key: "my-secret-key-123"

2. 实体类配置

@Table("tb_account")
@Data
public class Account {
@Id(keyType = KeyType.Auto)
private Long id; @Column("user_name")
private String userName; private Integer age; @Column(onInsertValue = "now()")
private LocalDateTime createTime; @Column(onUpdateValue = "now()")
private LocalDateTime updateTime; // 逻辑删除字段(0:正常,1:删除)
@Column(logicDelete = true)
private Integer isDeleted; // 多租户字段
@Column(tenantId = true)
private Long tenantId; // 加密字段(手机号)
@Column(cryptoType = CryptoType.AES)
private String mobile; // 脱敏字段(银行卡号)
@Column(maskType = MaskType.BANK_CARD)
private String bankCard; // 乐观锁字段
@Column(version = true)
private Integer version;
}

3. Mapper 接口

@Mapper
public interface AccountMapper extends BaseMapper<Account> {
// 自定义SQL方法示例
@Select("SELECT * FROM tb_account WHERE age > #{minAge}")
List<Account> selectByMinAge(@Param("minAge") int minAge);
}

4. Service 层实现

@Service
public class AccountService extends ServiceImpl<AccountMapper, Account> { // 自定义业务方法
public List<Account> findAdults() {
return queryChain()
.select(Account::getId, Account::getUserName)
.where(Account::getAge).ge(18)
.list();
}
}

三、核心 API 完整使用

1. 条件构造器(QueryWrapper)

// 基础查询
QueryWrapper query = QueryWrapper.create()
.select(ACCOUNT.ID, ACCOUNT.USER_NAME, ACCOUNT.AGE)
.from(ACCOUNT)
.where(ACCOUNT.AGE.between(18, 60))
.and(ACCOUNT.USER_NAME.like("张%"))
.orderBy(ACCOUNT.AGE.desc(), ACCOUNT.ID.asc())
.limit(10); // 联表查询(带别名)
QueryWrapper query = QueryWrapper.create()
.select(ACCOUNT.ID, ORDER.ORDER_NO, ORDER.AMOUNT)
.from(ACCOUNT.as("a"))
.leftJoin(ORDER).as("o").on(ACCOUNT.ID.eq(ORDER.ACCOUNT_ID))
.where(ORDER.CREATE_TIME.ge(LocalDate.now().minusMonths(1)))
.groupBy(ACCOUNT.ID)
.having(sum(ORDER.AMOUNT).gt(10000)); // 子查询
QueryWrapper subQuery = QueryWrapper.create()
.select(ORDER.ACCOUNT_ID)
.from(ORDER)
.where(ORDER.STATUS.eq(1)); QueryWrapper mainQuery = QueryWrapper.create()
.select()
.from(ACCOUNT)
.where(ACCOUNT.ID.in(subQuery))
.and(ACCOUNT.TENANT_ID.eq(123)); // Lambda 表达式
LambdaQueryWrapper<Account> lambdaQuery = LambdaQueryWrapper.create()
.select(Account::getId, Account::getUserName)
.eq(Account::getAge, 25)
.likeRight(Account::getUserName, "张")
.orderByDesc(Account::getCreateTime);

2. 更新操作(UpdateWrapper)

// 条件更新
UpdateWrapper update = UpdateWrapper.create()
.set(ACCOUNT.AGE, ACCOUNT.AGE.add(1))
.set(ACCOUNT.UPDATE_TIME, LocalDateTime.now())
.where(ACCOUNT.LAST_LOGIN_TIME.lt(LocalDate.now().minusYears(1))); // 实体更新
Account account = new Account();
account.setStatus(2);
UpdateWrapper update = UpdateWrapper.of(account)
.where(ACCOUNT.STATUS.eq(1).and(ACCOUNT.AGE.lt(18))); // Lambda 更新
LambdaUpdateWrapper<Account> lambdaUpdate = LambdaUpdateWrapper.create()
.set(Account::getAge, 30)
.set(Account::getUpdateTime, LocalDateTime.now())
.eq(Account::getId, 1001);

3. 分页与聚合

// 分页查询
Page<Account> page = Page.of(1, 20); // 第1页,每页20条
QueryWrapper query = QueryWrapper.create()
.where(ACCOUNT.AGE.ge(18))
.orderBy(ACCOUNT.CREATE_TIME.desc()); Page<Account> result = mapper.paginate(page, query); // 分页结果处理
List<Account> records = result.getRecords();
long total = result.getTotalRow();
long totalPages = result.getTotalPage(); // 聚合查询
QueryWrapper aggQuery = QueryWrapper.create()
.select(
ACCOUNT.DEPT_ID,
count().as("emp_count"),
avg(ACCOUNT.SALARY).as("avg_salary"),
max(ACCOUNT.SALARY).as("max_salary")
)
.groupBy(ACCOUNT.DEPT_ID)
.having(avg(ACCOUNT.SALARY).gt(10000));

4. 事务管理

// 声明式事务
@Transactional(rollbackFor = Exception.class)
public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
// 扣减转出账户
UpdateWrapper deduct = UpdateWrapper.create()
.setRaw(ACCOUNT.BALANCE, "balance - ?", amount)
.where(ACCOUNT.ID.eq(fromId));
accountMapper.updateByQuery(deduct); // 增加转入账户
UpdateWrapper add = UpdateWrapper.create()
.setRaw(ACCOUNT.BALANCE, "balance + ?", amount)
.where(ACCOUNT.ID.eq(toId));
accountMapper.updateByQuery(add); // 记录交易流水
transactionService.logTransfer(fromId, toId, amount);
} // 编程式事务
public void batchImport(List<Account> accounts) {
Transaction.tx(() -> {
for (Account account : accounts) {
if (account.getAge() < 18) {
throw new RuntimeException("未成年账户禁止导入");
}
accountMapper.insert(account);
}
return true;
});
}

5. 高级特性

// 1. 逻辑删除(自动添加条件)
accountMapper.deleteById(1L); // → UPDATE SET is_deleted=1 WHERE id=1 // 2. 多租户过滤(自动添加租户ID条件)
List<Account> list = accountMapper.selectAll();
// → SELECT * FROM tb_account WHERE tenant_id=当前租户ID // 3. 字段加密/解密(自动处理)
Account account = accountMapper.selectOneById(1L);
System.out.println(account.getMobile()); // 自动解密 → 13800138000 // 4. 数据脱敏
Account account = accountMapper.selectOneById(1L);
System.out.println(account.getBankCard()); // → 622202******1234 // 5. 乐观锁更新
Account account = accountMapper.selectOneById(1L);
account.setBalance(account.getBalance() + 100);
accountMapper.update(account);
// → UPDATE ... WHERE id=1 AND version=旧版本

6. 工具类使用

// Db 工具类快速操作
Db.insert("account", "id,user_name,age", 1001, "张三", 30);
Db.updateById("account", "age", 31, 1001);
List<Account> list = Db.selectAllByCondition(Account.class, "age > ?", 18); // 批量操作
List<Account> accounts = ...;
Db.executeBatch(accounts, 1000, (mapper, account) -> {
mapper.insert(account);
}); // SQL 工具
String inSql = SqlUtil.buildInCondition("id", Arrays.asList(1,2,3));
// → id IN (1,2,3) String safeSql = SqlUtil.escapeSql("SELECT * FROM user WHERE name='admin' OR 1=1");
// → 防止 SQL 注入的安全处理

四、MyBatis-Flex vs MyBatis-Plus 终极对比

特性维度 MyBatis-Flex MyBatis-Plus 优势分析
架构设计 纯 Java 实现,无第三方依赖 (500KB+) 依赖 Javassist 等工具 Flex 更轻量,启动更快
多表查询 原生支持 JOIN/UNION/子查询 需自定义 XML 或使用插件 Flex 复杂查询开发效率高 5 倍+
性能表现 基准测试快 5-10 倍 中等水平 Flex 高并发场景优势明显
条件构造器 链式调用,SQL 风格 方法名拼接 Flex 更直观,学习成本低
Lambda 支持 全 Lambda 类型推断 部分场景需手动指定类型 Flex 类型安全更好
注解功能 30+ 种注解覆盖企业级需求 基础注解 Flex 功能更全面
字段加密 原生支持 AES/RSA 等算法 需自定义实现 Flex 开箱即用
多租户 注解配置,支持忽略表 需插件配置 Flex 配置更简洁
SQL 生成 智能识别数据库方言 基础分页支持 Flex 适配性更好
代码生成器 高度可定制,支持多种模板 基础生成功能 Flex 扩展性更强
社区生态 快速增长,文档完善 成熟稳定,社区庞大 Plus 更成熟,Flex 更活跃
学习曲线 陡峭(功能强大) 平缓(简单易用) 新项目选 Flex,老项目选 Plus

五、总结与最佳实践

MyBatis-Flex 核心价值:

  1. 极致性能:比传统 ORM 框架快 5-10 倍,适合高并发场景
  2. 轻量灵活:无冗余依赖,功能模块可插拔
  3. 开发效率:复杂 SQL 开发效率提升 3 倍以上
  4. ️ 企业级特性:多租户/字段加密/数据脱敏开箱即用
  5. 智能优化:自动识别数据库方言,智能 SQL 优化

最佳实践场景:

  1. 新项目选型:特别是微服务架构下的新系统
  2. 金融级应用:对数据安全和性能有高要求的系统
  3. 复杂业务系统:需要大量复杂 SQL 的业务(如 ERP、CRM)
  4. 高并发场景:电商、社交等需要处理高并发的系统
  5. 多租户 SaaS:需要灵活租户管理的云应用

迁移建议:

  1. MyBatis → MyBatis-Flex:直接引入,兼容性好
  2. MyBatis-Plus → MyBatis-Flex
    • 保留实体类和 Mapper 接口
    • 逐步替换条件构造器代码
    • 利用 Flex 的兼容模式平滑过渡
  3. 其他 ORM 框架
    • 保留数据库设计
    • 重新生成实体类和 Mapper
    • 业务层逐步重写

终极建议

  • 追求 性能灵活性 → 选择 MyBatis-Flex
  • 需要 稳定简单 CRUD → 选择 MyBatis-Plus
  • 金融/电商 等高性能场景 → 强烈推荐 MyBatis-Flex

MyBatis-Flex 代表了 MyBatis 增强框架的新方向,在保持轻量级的同时提供了企业级功能,是现代化 Java 应用开发的理想选择。

【还在使用MyBatis-Plus?更强大的来了】MyBatis-Flex 完整使用指南的更多相关文章

  1. 比 Navicat 还要好用、功能更强大的工具!

    DBeaver 是一个基于 Java 开发,免费开源的通用数据库管理和开发工具,使用非常友好的 ASL 协议.可以通过官方网站或者 Github 进行下载. 由于 DBeaver 基于 Java 开发 ...

  2. Python的regex模块——更强大的正则表达式引擎

    Python自带了正则表达式引擎(内置的re模块),但是不支持一些高级特性,比如下面这几个: 固化分组    Atomic grouping 占有优先量词    Possessive quantifi ...

  3. 让Docker功能更强大的10个开源工具

    让Docker功能更强大的10个开源工具 更好的管理.Web前端程序.更深入地了解容器应用程序,Docker生态系统正在迅速发展,这还得归功于其充满活力的开源社区. 软件项目的成功常常根据其催生的生态 ...

  4. summerDao-比mybatis更强大无需映射配置的dao工具

    summerDao是summer框架中的一个数据库操作工具,项目地址:http://git.oschina.net/xiwa/summer. 怎么比mybatis更强大,怎么比beetlsql更简单, ...

  5. 【译】AI 让科技公司变得更强大吗

    机器学习可能是当今技术中最重要的基本趋势.由于机器学习的基础是数据 - 大量的数据 - 很常见的是,人们越来越担心已经拥有大量数据的公司会变得更强大.这有一定的道理,但是以相当狭窄的方式,同时ML也看 ...

  6. MyBatis 的真正强大在于它的映射语句 如果有一个独立且完美的数据库映射模式,所有应用程序都可以使用它

    mybatis – MyBatis 3 | Mapper XML 文件 http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html mybatis – My ...

  7. Android内存优化9 内存检测工具3 MAT比Menmery Monitor更强大

    在Android性能优化第(一)篇---基本概念中讲了JAVA的四大引用,讲了一下GCRoot,第二篇Memory Monitor检测内存泄露仅仅说了Menmery Monitor的使用,这篇博客谈一 ...

  8. Android性能优化第(三)篇---MAT比Menmery Monitor更强大

    作者 LooperJing 2016.11.17 16:42* 字数 1687 阅读 1603评论 3喜欢 21 在Android性能优化第(一)篇---基本概念中讲了JAVA的四大引用,讲了一下GC ...

  9. Excel催化剂开源第24波-较VBA更强大的.Net环境的正则表达式

    在VBA上可以调用正则表达式库,从而编写正则表达式自定义函数,这个相信不少VBA开发者已经熟知,但VBA的VBScript正则表达式库毕竟是一个过时的产品,不像.Net那样是与时俱进的,所以两者实现出 ...

  10. 苹果IOS 12将使您的iPhone更安全,并有更强大的黑客保护

    一年一度的IOS刷新正在进行中,苹果已经预览了它,beta测试者已经安装了它,当iPhone在9月份到货时我们其他人应该获得iOS12.虽然软件3-D表情符号和屏幕时间限制等功能在软件到货时可能会受到 ...

随机推荐

  1. 【UEFI】DXE阶段从概念到代码

    总述 DXE(Driver Execution Environment)阶段,是执行大部分系统初始化的阶段,也就是说是BIOS发挥作用,初始化整个主板的主战场.在这个阶段我们可以进行大量的驱动工作. ...

  2. java数组--对象数组的随机赋值及其他

    包含考点: 对象数组的随机赋值 浮点数的指定位数 换用思路进行对象数组的某一属性进行排序 现有Book类,定义如下: private String author; private String ISB ...

  3. 汇编语言笔记——8086&&寻址方式与指令系统

    汇编语言中 语句不区分大小写,编译软件会自动识别语句 用户自定义的变量和符号必须区分大小写. 8086 1.寄存器 cpu在访问存储器时,必须指明: 段寄存器:所访问的存储单元属于哪个段 偏移量:相应 ...

  4. 揭秘!测试开发速看,Mockaroo 如何轻松解决 90% 测试数据难题!

    在软件测试领域,模拟生成测试数据一直是至关重要的环节.无论是验证系统功能的准确性,还是测试边界条件下的系统稳定性,都离不开丰富且真实的测试数据. 今天,向大家推荐一款强大的模拟生成测试数据工具 --M ...

  5. 异步日志监控:FastAPI与MongoDB的高效整合之道

    title: 异步日志监控:FastAPI与MongoDB的高效整合之道 date: 2025/05/27 17:49:39 updated: 2025/05/27 17:49:39 author: ...

  6. Java catch多重异常捕获

    摘要:Java中多重异常捕获机制可以更加简洁.有效地处理多个异常,提高了程序的鲁棒性,是编写高质量代码的重要技巧之一.   小编在<浅谈Java异常处理机制>中梳理了异常处理机制,在< ...

  7. Java四种引用类型回收时机介绍

       每种编程语言都有操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过"引用"(reference).在 Java 中一切都被视作对象,但是我 ...

  8. mysql中compact行的存储结构

    mysql中行的格式类型包括:Compact.redundant.dynamic.compressed这四种,行和行之间是通过一个单向链表的形式来连接的,而我在实际工作中最常用到的是compact类型 ...

  9. Seo工具使用与流量数据观察实践(中)

    第12章.Seo工具使用与数据观察实践(中) 继上一节的SimilarWeb流量粗分析,我们已经选定了竞品,并且有了一个大致的用户画像和群体,接下来我们就进入细节的关键词和内容的分析. 那么这本节中, ...

  10. 数栈产品分享:基于StreamWorks构建实时大数据处理平台

    数栈是云原生-站式数据中台PaaS,我们在github和gitee上有一个有趣的开源项目:FlinkX,FlinkX是一个基于Flink的批流统一的数据同步工具,既可以采集静态的数据,也可以采集实时变 ...