【MybatisPlus】QueryWapper和LambdaQueryWrapper的区别

时间:2024-07-13 08:09:37

【MybatisPlus】QueryWapper和LambdaQueryWrapper的区别

  • (一)MyBatisPlus的条件查询构造器
    • QueryWrapper
    • LambdaQueryWrapper
    • 优缺点
    • 使用场景
  • (二)Lambda的概念
  • (三)QueryWrapper如何进化成LambdaQueryWrapper的
    • QueryWrapper最基础的使用方式
    • 开始进阶版一:引入 lambda
    • 接着进阶版二:简化 lambda
    • 进阶完成版:简化 `QueryWrapper.lambda()`
  • (四)QueryWapper和LambdaQueryWrapper的常用方法
  • 参考文章

(一)MyBatisPlus的条件查询构造器

MyBatis-Plus 是一个基于 MyBatis 的增强工具库,旨在简化 MyBatis 的使用并提供更多的便利功能。
其中,QueryWrapperLambdaQueryWrapper 都是 MyBatis-Plus 提供的查询条件构造器,用于构建 SQL 查询语句的条件部分。

QueryWrapper

QueryWrapper 是 MyBatis-Plus 最基础的查询条件构造器之一。
它通过链式调用的方式构建查询条件,并使用普通的字符串作为字段名、操作符和值。它的使用方式类似于传统的 SQL 查询。

LambdaQueryWrapper

LambdaQueryWrapper 是在 QueryWrapper 的基础上增加了使用 Lambda 表达式的功能,使得构建查询条件更加类型安全、易读,并且能够在编译时进行语法检查。它通过方法引用的方式来指定实体类的属性,并提供了丰富的方法来构建查询条件。

类图

  • Wrapper:条件构造抽象类,最顶端父类
  • AbstractWrapper:用于查询条件封装,生成 sql 的 where 条件
  • QueryWrapper:Entity 对象封装操作类,不是用lambda语法
  • UpdateWrapper:Update 条件封装,用于Entity对象更新操作
  • AbstractLambdaWrapper :​Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
  • ​LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
  • ​LambdaUpdateWrapper :​Lambda 更新封装Wrapper

优缺点

QueryWrapper

  • 优点:更灵活,支持复杂查询操作和 SQL 片段拼接。
  • 缺点:类型不安全、可读性较差。

LambdaQueryWrapper

  • 优点:类型安全、易读性高,可以直接使用实体类的属性和方法。
  • 缺点:在某些复杂查询操作下可能不支持。

使用场景

  • (1)需要进行复杂的查询操作,特别是涉及到复杂的 SQL 片段拼接等情况,可能需要使用 QueryWrapper
  • (2)查询条件相对简单且你更注重代码的清晰性和类型安全性,可以优先考虑使用 LambdaQueryWrapper

(二)Lambda的概念

Lambda表达式是一种匿名函数,它可以被用作一段可传递的代码。
Lambda表达式通常用于简化代码,特别是在函数式编程中,它允许你在不创建具体方法的情况下定义一个函数。
在Java中,Lambda表达式的语法是->,它可以替代某些接口的匿名内部类。

在MyBatis-Plus中,Lambda表达式的重要性体现在构建查询条件时。
它们提供了一种更加类型安全和直观的方式来构建数据库查询条件,而不需要硬编码SQL语句。
通过使用Lambda表达式,你可以创建查询条件的对象,而不是手动编写字符串,这有助于减少SQL注入的风险,提高了代码的可维护性。

(三)QueryWrapper如何进化成LambdaQueryWrapper的

QueryWrapper最基础的使用方式

// 查询条件构造器
QueryWrapper<BannerItem> wrapper = new QueryWrapper<>();
wrapper.eq("banner_id", id);
// 查询操作
List<BannerItem> bannerItems = bannerItemMapper.selectList(wrapper);

开始进阶版一:引入 lambda

然后我们可以引入lambda,避免我们在代码中写类似的于banner_id的硬编码

QueryWrapper<BannerItem> wrapper = new QueryWrapper<>();
//此处引入了lambda
wrapper.lambda().eq(BannerItem::getBannerId, id);
List<BannerItem> bannerItems = bannerItemMapper.selectList(wrapper);

接着进阶版二:简化 lambda

为了简化lambda的使用,我们可以改写成LambdaQueryWrapper构造器,语法如下:

LambdaQueryWrapper<BannerItem> wrapper = new QueryWrapper<BannerItem>().lambda();
wrapper.eq(BannerItem::getBannerId, id);
List<BannerItem> bannerItems = bannerItemMapper.selectList(wrapper);

进阶完成版:简化 QueryWrapper<BannerItem>.lambda()

可以直接将QueryWrapper<BannerItem>.lambda() 简化掉,变成直接使用LambdaQueryWrapper

LambdaQueryWrapper<BannerItem> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(BannerItem::getBannerId, id);
List<BannerItem> bannerItems = bannerItemMapper.selectList(wrapper);

(四)QueryWapper和LambdaQueryWrapper的常用方法

在这里插入图片描述

我们主要使用以下的方法:

  • eq: 添加等于(=)条件。
  • ne: 添加不等于(<>)条件。
  • like: 添加LIKE条件。
  • gt和lt: 添加大于(>)和小于(<)条件。
  • ge和le: 添加大于等于(>=)和小于等于(<=)条件。
  • between: 添加BETWEEN条件。
  • isNull和isNotNull: 添加IS NULL和IS NOT NULL条件。
  • in和notIn: 添加IN和NOT IN条件。
  • groupBy和orderBy: 添加GROUP BY和ORDER BY条件。
  • having: 添加HAVING条件。

举例一个简单的例子

QueryWrapper写法

QueryWrapper<CustomerBussUser> qw = new QueryWrapper<>();
qw.select("CUST_ID,count(*) as custIdCount");//查询自定义列
qw.eq("user_id",userId);
qw.eq("isvalid","1");
qw.groupBy("cust_Id");
qw.having("count(*) > 1");
//listMaps方法查询
List<Map<String, Object>> maps = customerBussUserService.listMaps(qw);

LambdaQueryWrapper写法

LambdaQueryWrapper<CustomerBussUser> lqw = new LambdaQueryWrapper<>();  
lqw.select("CUST_ID, count(*) as custIdCount")  
    .eq(CustomerBussUser::getUserId, userId)  
    .eq(CustomerBussUser::getIsvalid, "1")
    .groupBy(CustomerBussUser::getCustId)
    .having("count(*) > 1");
List<Map<String, Object>> maps = customerBussUserService.listMaps(lqw);

参考文章

【1】【MybatisPlus】LambdaQueryWrapper和QueryWapper的区别
【2】QueryWrapper中常用方法
【3】MyBatis-Plus QueryWrapper及LambdaQueryWrapper的使用
【4】MyBatis-Plus——超详细讲解条件构造器