AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
在 MyBatis-Plus 中,选择 `LambdaQueryWrapper` 还是 `QueryWrapper` 主要取决于你对**代码健壮性**和**维护成本**的权衡。 简单来说:**绝大多数场景下,推荐首选 `LambdaQueryWrapper`。** * * * ### 1\. 核心区别对比 | **特性** | **QueryWrapper** | **LambdaQueryWrapper** | | --- | --- | --- | | **字段引用方式** | **硬编码字符串** (如 `"bill_id"`) | **方法引用** (如 `Bill::getBillId`) | | **重构友好度** | 差。修改数据库字段名,代码不会报错 | **优**。修改实体类属性名,代码立即编译报错 | | **报错时机** | 运行时 (Runtime) | **编译时 (Compile-time)** | | **可读性** | 一般 | 极高(接近自然语言) | * * * ### 2\. 什么时候用 LambdaQueryWrapper? (强烈推荐) 只要你的查询条件是基于实体类属性的,就应该使用它。 #### 场景示例:常规业务查询 当你需要根据业务主键 `billId` 查询时: Java ~~~ // 优点:不怕写错字段名。如果实体类删除了 billId,这行代码会直接飘红报错。 LambdaQueryWrapper<Bill> lqw = Wrappers.lambdaQuery(); lqw.eq(Bill::getBillId, "B001") .gt(Bill::getAmount, 100); List<Bill> list = billMapper.selectList(lqw); ~~~ * * * ### 3\. 什么时候用 QueryWrapper? 虽然 `LambdaQueryWrapper` 很香,但在以下特殊情况下,`QueryWrapper` 更灵活或不可替代: #### A. 涉及复杂的 SQL 函数或子查询 当你需要手动拼凑一些复杂的 SQL 片段,而这些片段没有对应的 Lambda 方法支持时。 Java ~~~ QueryWrapper<Bill> qw = new QueryWrapper<>(); // 这种自定义的 SQL 片段,Lambda 表达起来比较麻烦 qw.select("id", "DATE_FORMAT(create_time, '%Y-%m-%d') as create_date") .apply("amount > (select avg(amount) from t_bill)"); ~~~ #### B. 动态拼接字段名 如果你的查询字段名是从前端传过来的字符串,或者需要根据某些逻辑动态拼接列名,硬编码的 `QueryWrapper` 更方便。 Java ~~~ String columnName = "total_price"; // 假设这是动态获取的 QueryWrapper<Bill> qw = new QueryWrapper<>(); qw.orderByDesc(columnName); ~~~ #### C. 极简的单条件删除/查询 如果你追求极致的代码简短,且字段非常固定: Java ~~~ // 稍微快一点点,但失去了重构安全性 billMapper.delete(new QueryWrapper<Bill>().eq("status", 0)); ~~~ * * * ### 4\. 最佳实践总结 1. **优先使用 `LambdaQuery`:** 为了防止以后修改数据库字段导致代码线上报错,请形成使用 Lambda 的习惯。 2. **善用链式编程:** `service.lambdaQuery().eq(...).one()` 这种写法比手动 new Wrapper 更优雅。 3. **配合 IDEA 插件:** 安装 **MyBatisPlus 插件**,它可以帮助你在使用字符串字段名时提供智能提示。 * * * ### 补充:链式调用小技巧 如果你在 Service 层,可以连 `Wrapper` 都不用创建: Java ~~~ // 这种写法最简洁,也属于 Lambda 风格 Bill detail = this.lambdaQuery() .eq(Bill::getBillId, billId) .last("LIMIT 1") .one(); ~~~