Lambda表达式优化MyBatis动态SQL,通过方法引用替代字符串字段名,提升编译期安全与可读性;支持判空封装、链式构建、条件化SQL及数据库端计算,但复杂查询仍需XML或注解。

用Lambda表达式优化MyBatis动态SQL参数构建,核心是把“字符串拼字段”换成“方法引用字段”,让条件组装既安全又干净。不用再写一堆if (obj.getName() != null)和wrapper.eq("name", obj.getName())这种容易错配的代码。
用LambdaQueryWrapper替代字符串硬编码
传统QueryWrapper依赖字段名字符串,一改实体类就报错;LambdaQueryWrapper用User::getUsername这类写法,编译期就能校验字段是否存在,IDE还能自动补全。
- 直接引用getter:.eq(User::getStatus, 1) 比 .eq("status", 1) 更可靠
- 模糊匹配更精准:.likeRight(User::getUsername, "张") 表示前缀匹配,语义清晰
- 组合条件可读性强:.ge(User::getCreateTime, start).le(User::getCreateTime, end) 一眼看懂时间区间
多条件动态拼接不靠堆if
当查询参数多达五六个,每个都要判空再加条件,代码会迅速臃肿。Lambda配合工具方法能大幅简化。
- 封装判空逻辑:写一个
MyBatisHelper.equals(obj.getCityCode(), w -> w.eq(User::getCityCode, obj.getCityCode)),一行搞定判空+设条件 - 统一收集谓词:把所有可能条件先存进
List<Consumer<LambdaQueryWrapper<User>>>,再遍历执行,业务规则和SQL构建解耦 - 支持链式追加:wrapper = wrapper.eq(...); wrapper = wrapper.like(...); 不必担心null指针
更新操作也用Lambda链式构建
LambdaUpdateChainWrapper同样适用——尤其是需要选择性更新字段或执行数据库计算时。
- 只更新非空字段:.set(User::getNickname, user.getNickname()).set(User::getAvatar, user.getAvatar()),空值自动跳过
- 数据库端计算:.setSql("points = points + 100").setSql("login_count = login_count + 1"),避免查-改-存三步操作
- 条件化SQL片段:.setSql(isVip, "points = points + 100").setSql(!isVip, "points = points + 10"),逻辑与SQL同步
注意边界:Lambda不是万能胶
Lambda解决的是字段引用安全问题,但不能替代SQL逻辑设计。
- 复杂关联仍需XML或@Select注解:比如多表嵌套聚合、自定义函数调用
- JSON字段更新慎用set:建议用setSql配合JSON_SET等数据库函数
- 敏感参数必须预编译:setSql中若拼接用户输入,务必配合参数占位符,避免SQL注入

















