【MybatisPlus】QueryWapper和LambdaQueryWrapper的区别
- (一)MyBatisPlus的条件查询构造器
- QueryWrapper
- LambdaQueryWrapper
- 优缺点
- 使用场景
- (二)Lambda的概念
- (三)QueryWrapper如何进化成LambdaQueryWrapper的
- QueryWrapper最基础的使用方式
- 开始进阶版一:引入 lambda
- 接着进阶版二:简化 lambda
- 进阶完成版:简化 `QueryWrapper<BannerItem>.lambda()`
- (四)QueryWapper和LambdaQueryWrapper的常用方法
- 参考文章
(一)MyBatisPlus的条件查询构造器
MyBatis-Plus 是一个基于 MyBatis 的增强工具库,旨在简化 MyBatis 的使用并提供更多的便利功能。
其中,QueryWrapper 和 LambdaQueryWrapper 都是 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——超详细讲解条件构造器