java中function接口通过方法引用(如user::getname)为mybatis-plus提供字段安全、可重构的动态条件构造,支撑lambdaquerywrapper的类型推导与编译期校验,并用于and()/or()嵌套、apply()字段比较及alleq()智能过滤。

Java 中的 Function 接口本身不直接参与 MyBatis-Plus 的条件构造,真正起作用的是它在 LambdaQueryWrapper 和 Wrappers.lambdaQuery() 中作为方法引用(User::getName)的底层支撑类型。所谓“进阶玩法”,本质是利用 Function 的类型推导能力,实现字段安全、可重构、支持链式嵌套的动态条件组装。
用方法引用替代字符串字段名
这是最基础也最关键的用法。编译器通过 Function<t r></t> 将 User::getAge 解析为 “取 User 实体中 age 字段的 getter 方法”,从而在编译期校验字段是否存在、类型是否匹配。
- ✅ 安全:改字段名时 IDE 可自动提示、编译报错,避免运行时报
Column 'user_nam' not found - ✅ 清晰:一眼看出操作的是哪个属性,无需查实体类或数据库映射
- ❌ 不适用于数据库函数或表达式字段(如
DATE(create_time)),此时仍需字符串或apply()
配合 and() / or() 实现逻辑分组嵌套
and() 和 or() 方法接收 Function<lambdaquerywrapper>, LambdaQueryWrapper<t>></t></lambdaquerywrapper> 类型参数——这正是 Function 的高阶用法体现。它允许你把一组条件封装成独立子块,再嵌入主条件中。
- 例如:查“年龄≥25 且(部门为 A 或部门为 B)”
wrapper.ge(User::getAge, 25).and(q -> q.eq(User::getDept, "A").or().eq(User::getDept, "B"))- 生成 SQL:
WHERE age >= 25 AND (dept = 'A' OR dept = 'B') - 关键点:
q是新创建的子 wrapper,内部条件互不影响,括号层级由 Java 链式调用自然表达
结合 apply() 实现字段间比较或自定义表达式
当需要比较两个字段(如 update_time > create_time)、调用数据库函数(如 YEAR(birth_date) = 1990)时,Function 无法直接描述。这时要借助 apply(),但依然可以靠 Function 提前校验字段存在性来辅助构建安全 SQL 片段。
- 先用
User::getUpdateTime和User::getCreateTime确认字段名无误 - 再写:
wrapper.apply("{0} > {1}", "update_time", "create_time")(注意:占位符填的是数据库列名,不是方法引用) - 更稳妥写法:
wrapper.apply("update_time > create_time")—— 因为字段名固定,无注入风险 - ⚠️ 切记:
apply()不校验字段,纯字符串拼接,务必人工核对列名与数据库一致
用 allEq() + BiPredicate 做智能条件过滤
allEq() 内部使用 BiPredicate<r v></r>(R 是字段名,V 是值)做键值对筛选,本质上也是 Function 思维的延伸:对传入的 Map 做函数式过滤。
- 场景:前端传来一个
Map<string object></string>查询参数,只想对非空、非零、非默认值的字段生效 wrapper.allEq((k, v) -> v != null && !"".equals(v), paramMap, false)- 效果:自动跳过 value 为
null或空字符串的 key,不生成对应 WHERE 条件 - 优势:比一堆
if判断更简洁,且复用性强
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











