Java Lambda表达式通过LambdaQueryWrapper等工具安全引用字段实现动态查询,需手动判断参数有效性并链式添加条件,避免硬编码与SQL注入风险。

Java Lambda 表达式本身不直接执行数据库查询,但它常配合 JPA Criteria API 或 MyBatis-Plus 的 QueryWrapper/LambdaQueryWrapper 实现多条件动态组合查询。核心思路是:用 Lambda 表达式安全地引用字段名(避免硬编码字符串),再根据业务逻辑判断是否添加条件。
用 MyBatis-Plus 的 LambdaQueryWrapper(推荐,简洁安全)
这是最常用、最直观的方式。LambdaQueryWrapper 利用方法引用来避免字段名拼写错误,支持链式调用 + 条件判断。
- 先创建
LambdaQueryWrapper<User>对象 - 对每个可能的查询参数做非空/有效判断,再用
eq()、like()、between()等方法追加条件 - 所有条件自动 AND 组合;如需 OR,用
or()或apply()
示例:
String name = request.getName();
Integer minAge = request.getMinAge();
Integer maxAge = request.getMaxAge();
String email = request.getEmail();
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(name)) {
wrapper.like(User::getName, name);
}
if (minAge != null && minAge > 0) {
wrapper.ge(User::getAge, minAge);
}
if (maxAge != null && maxAge > 0) {
wrapper.le(User::getAge, maxAge);
}
if (StringUtils.isNotBlank(email)) {
wrapper.eq(User::getEmail, email);
}
List<User> users = userMapper.selectList(wrapper);
用 JPA Criteria API + Lambda 提取字段(类型安全但稍重)
Critera API 原生不支持 Lambda,但可通过 静态元模型 或 反射工具类 辅助实现字段引用。更现代的做法是借助 CriteriaBuilder 和泛型方法封装,结合 Lambda 获取属性名(如使用 BeanUtils.getPropertyName(() -> obj.getField()) 工具)。
立即学习“Java免费学习笔记(深入)”;
关键点:
- 用
CriteriaBuilder构建查询条件树 - 每个条件用
Predicate表示,通过builder.and()或builder.or()组合 - 字段访问建议用
Root.get("fieldName"),若想用 Lambda,可封装一个getFieldPath(root, User::getName)工具方法
自定义工具类:把 Lambda 转成字段名字符串(轻量兼容)
如果你用的是纯 MyBatis 或 JDBC,没有 MyBatis-Plus,也可以自己写一个简单工具,从 Lambda 表达式提取字段名,用于拼 SQL 或设置参数:
public class LambdaUtils {
public static <T, R> String getFieldName(Function<T, R> func) {
try {
Method writeReplace = func.getClass().getDeclaredMethod("writeReplace");
writeReplace.setAccessible(true);
SerializedLambda lambda = (SerializedLambda) writeReplace.invoke(func);
return lambda.getImplMethodName().substring("get".length());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
// 使用:LambdaUtils.getFieldName(User::getName) → "name"
⚠️ 注意:该方式仅适用于 getter 方法,且依赖 JVM 序列化机制,生产环境慎用;建议优先选 MyBatis-Plus 的原生支持。
注意事项与避坑点
- 空值判断必须显式写:Lambda 只解决字段名安全,不解决“要不要加这个条件”,业务逻辑仍需 if 判断
-
Like 查询注意前后缀:用
like时记得补%,或用likeLeft()/likeRight() - 时间范围、枚举、状态码等要校验有效性:避免传入非法值导致 SQL 报错或全表扫描
-
分页务必在条件组装后调用:如
page(wrapper),别在中间打断链式调用


















