MyBatisPlus之Wrapper条件构造器—构建复杂查询

在MyBatisPlus(简称MP)的Wrapper条件构造器无疑是提升查询效率的利器,它摆脱了传统XML中繁琐的SQL拼接,通过面向对象的方式快速构建复杂查询条件,让我们在处理多条件查询时更加得心应手。

一、Wrapper基础知识

Wrapper是MP提供的一套条件构造抽象类,用于动态生成SQL的WHERE条件。它的核心价值在于:

  • 替代XML中的动态SQL:无需在XML中写<if> <where>等标签,通过Java代码直接拼接条件。
  • 支持链式编程:语法简洁直观,可读性强,如eq("name", "张三").gt("age", 18)
  • 适配复杂场景:轻松处理多条件组合、嵌套查询、排序、分页等需求。

MP中常用的Wrapper实现类有:

  • QueryWrapper:最常用,支持所有查询条件构造。
  • UpdateWrapper:用于更新操作的条件构造(如set("name", "李四").eq("id", 1))。
  • LambdaQueryWrapper:通过Lambda表达式构建条件,避免硬编码字段名(推荐,减少字段名写错的风险)。

二、核心API与基础用法

Wrapper的API命名遵循“见名知意”原则,以下是开发中最常用的方法分类及示例(以QueryWrapper为例,基于User表:id、name、age、email字段)。

1. 比较条件

方法说明示例对应SQL
eq(R column, Object val)等于(=)eq("name", "张三")where name = '张三'
ne(R column, Object val)不等于(≠)ne("age", 20)where age <> 20
gt(R column, Object val)大于(>)gt("age", 18)where age > 18
ge(R column, Object val)大于等于(≥)ge("age", 18)where age >= 18
lt(R column, Object val)小于(<)lt("age", 30)where age < 30
le(R column, Object val)小于等于(≤)le("age", 30)where age <= 30

示例:查询年龄大于18且小于30的用户

QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 18)
           .lt("age", 30);
List<User> userList = userMapper.selectList(queryWrapper);

2. 模糊查询

方法说明示例对应SQL
like(R column, Object val)包含(%val%)like("name", "张")where name like '%张%'
likeLeft(R column, Object val)左模糊(%val)likeLeft("name", "三")where name like '%三'
likeRight(R column, Object val)右模糊(val%)likeRight("name", "张")where name like '张%'
notLike(R column, Object val)不包含notLike("email", "qq.com")where email not like '%qq.com%'

示例:查询姓名以“张”开头且邮箱不含“qq.com”的用户

queryWrapper.likeRight("name", "张")
           .notLike("email", "qq.com");

3. 逻辑组合

方法说明示例对应SQL
and(Consumer<Param> consumer)拼接AND条件(嵌套)and(qw -> qw.gt("age",18).lt("age",30))where (age > 18 and age < 30)
or(Consumer<Param> consumer)拼接OR条件(嵌套)or(qw -> qw.eq("name","张三").or().eq("name","李四"))where (name = '张三' or name = '李四')
not()对后续条件取反not().eq("name", "张三")where not (name = '张三')

示例:查询(年龄>18且邮箱含“@163.com”)或(姓名为“李四”且年龄=25)的用户

queryWrapper.and(qw -> qw.gt("age", 18).like("email", "@163.com"))
           .or(qw -> qw.eq("name", "李四").eq("age", 25));

4. 其他常用条件

  • in(R column, Collection<?> coll):包含在集合中,如in("id", Arrays.asList(1,2,3))where id in (1,2,3)
  • isNull(R column):字段为NULL,如isNull("email")where email is null
  • orderByAsc(R... columns):升序排序,如orderByAsc("age", "id")order by age asc, id asc
  • last(String sql):直接拼接SQL在末尾(慎用,可能引发SQL注入),如last("limit 1") → 强制只查1条。

三、LambdaQueryWrapper:避免硬编码的最佳实践

LambdaQueryWrapper通过Lambda表达式引用实体类的字段(如User::getName),彻底避免了字符串字段名写错的问题,是推荐的使用方式。

示例:用LambdaQueryWrapper查询年龄≥20且姓名包含“李”的用户

LambdaQueryWrapper<User> lambdaQuery = new LambdaQueryWrapper<>();
lambdaQuery.ge(User::getAge, 20)  // 引用User类的age字段
           .like(User::getName, "李");  // 引用name字段
List<User> userList = userMapper.selectList(lambdaQuery);

优势:当实体类字段名修改时,IDE会直接报错,避免线上因字段名拼写错误导致的BUG。

四、构建复杂查询:多表关联与子查询

Wrapper不仅支持单表查询,还能通过applyexists等方法处理多表关联和子查询。

1. 多表关联查询(以关联Role表为例)

需求:查询“张三”拥有的所有角色(用户表user与角色表role通过中间表user_role关联)。

QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("u.name", "张三")  // u为user表别名
           .apply("u.id = ur.user_id")  // 关联中间表user_role(ur)
           .apply("ur.role_id = r.id")  // 关联角色表role(r)
           .select("r.id, r.role_name");  // 只查询角色表的字段
List<Map<String, Object>> roleList = userMapper.selectMaps(queryWrapper);

2. 子查询(exists)

需求:查询存在“年龄>30”的用户的部门(假设用户表有dept_id字段)。

LambdaQueryWrapper<Dept> deptQuery = new LambdaQueryWrapper<>();
deptQuery.exists("select 1 from user u where u.dept_id = dept.id and u.age > 30");
List<Dept> deptList = deptMapper.selectList(deptQuery);

注意事项

  1. 字段名与数据库一致性:Wrapper的字段名需与数据库表字段一致(而非实体类的@TableField别名,除非用Lambda方式)。
  2. SQL注入风险last()apply()方法会直接拼接SQL,避免传入用户输入的参数,必要时用{0}占位符(如apply("date_format(create_time, '%Y-%m') = {0}", "2023-10"))。
  3. 条件优先级:复杂条件建议用and()/or()的嵌套Consumer,明确优先级(类似SQL中的括号)。
  4. 分页查询:结合MP的IPage接口,Wrapper可直接作为分页条件,如userMapper.selectPage(page, queryWrapper)

总结

Wrapper条件构造器是MyBatisPlus简化查询的核心工具,通过链式API和Lambda表达式,让复杂查询条件的构建变得简洁高效,建议在实际开发中优先使用LambdaQueryWrapper,并合理利用and()/or()的嵌套处理复杂逻辑,同时注意规避SQL注入风险。

若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ

资源下载链接为: https://pan.quark.cn/s/9e7ef05254f8 在网页设计中,为图片添加文字是一种常见的需求,用于增强视觉效果或传达更多信息。本文将介绍两种常用的方法:一种是将图片设置为背景并添加文字;另一种是利用<span>标签结合CSS定位来实现。 这种方法通过CSS实现,将图片设置为一个容器(通常是<div>)的背景,然后在容器中添加文字。具体步骤如下: 创建一个包含文字的<div>元素: 使用CSS设置<div>的背景图片,并调整其尺寸以匹配图片大小: 如有需要,可使用background-position属性调整图片位置,确保文字显示在合适位置。这样,文字就会显示在图片之上。 另一种方法是将文字放在<span>标签内,并通过CSS绝对定位将其放置在图片上。步骤如下: 创建一个包含图片和<span>标签的<div>: 设置<div>为相对定位,以便内部元素可以相对于它进行绝对定位: 设置<span>为绝对定位,并通过调整top和left属性来确定文字在图片上的位置: 这种方法的优点是可以精确控制文字的位置,并且可以灵活调整文字的样式,如颜色和字体大小。 两种方法各有优势,可根据实际需求选择。在实际开发中,还可以结合JavaScript或jQuery动态添加文字,实现更复杂的交互效果。通过合理运用HTML和CSS,我们可以在图片上添加文字,创造出更具吸引力的视觉效果。
<think>我们被要求回答关于MyBatis-Plus Wrapper条件构造器的使用示例。根据引用内容,WrapperMyBatis-Plus中用于构造查询条件的强大工具,包括QueryWrapper、UpdateWrapper等。我们将按照以下步骤进行: 1. 介绍Wrapper的基本概念和常用子类。 2. 展示基本查询条件构造的示例(如eq, ne, gt, lt, like等)。 3. 展示复杂条件构造(如and, or, nested conditions)的示例。 4. 展示Lambda表达式的使用(LambdaQueryWrapper, LambdaUpdateWrapper)以避免字段名硬编码。 5. 结合自定义SQL片段的使用。 注意:所有示例代码使用Java,并假设已经配置好MyBatis-Plus环境。 以下为回答内容:</think>### MyBatis-Plus Wrapper 查询条件构造方法详解 MyBatis-Plus 的 Wrapper 条件构造器是用于动态构建 SQL 条件的核心工具,通过链式调用替代手写 SQL。以下是常用方法及示例: #### 1. **基础查询条件** ```java // 等于、不等于、大于 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("name", "张三") // WHERE name = '张三' .ne("age", 25) // AND age <> 25 .gt("salary", 5000); // AND salary > 5000 List<User> users = userMapper.selectList(wrapper); // 模糊查询 wrapper.like("email", "@gmail.com"); // WHERE email LIKE '%@gmail.com%' ``` #### 2. **逻辑组合** ```java // AND/OR 嵌套 wrapper.and(w -> w.gt("age", 18).lt("age", 30)) // WHERE (age > 18 AND age < 30) .or().eq("status", 1); // OR status = 1 // IN 查询 wrapper.in("id", Arrays.asList(1, 3, 5)); // WHERE id IN (1,3,5) ``` #### 3. **Lambda 表达式(推荐)** 避免硬编码字段名,编译期检查: ```java LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>(); lambdaWrapper.eq(User::getName, "李四") // 字段名通过方法引用获取 .ge(User::getCreateTime, LocalDate.now().minusMonths(1)); List<User> userList = userMapper.selectList(lambdaWrapper); ``` #### 4. **更新操作** ```java UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(); updateWrapper.set("salary", 8000) // SET salary = 8000 .eq("department", "技术部"); // WHERE department = '技术部' userMapper.update(null, updateWrapper); ``` #### 5. **复杂 SQL 片段** ```java wrapper.apply("date_format(create_time,'%Y-%m') = '2023-08'") // 自定义SQL片段 .orderByDesc("id") // ORDER BY id DESC .last("LIMIT 10"); // 拼接尾部SQL ``` #### 6. **子查询** ```java wrapper.inSql("department_id", "SELECT id FROM department WHERE name LIKE '研发%'"); // 子查询 ``` > **最佳实践**: > 1. 优先使用 `LambdaQueryWrapper` 避免字段名拼写错误[^1] > 2. 复杂条件用 `nested()` 或 `apply()` 封装 > 3. 更新操作用 `UpdateWrapper` 避免实体类属性覆盖问题[^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值