MyBatis-Plus中‌QueryWrapper使用方法及示例代码详解

原创 2025-05-14 10:13:39编程技术
797

在MyBatis-Plus中,QueryWrapper 是构建动态SQL查询条件的核心工具类,它通过链式调用和Lambda表达式支持,极大简化了条件构造过程。本文将结合代码示例,详细讲解其核心用法及最佳实践。

一、QueryWrapper核心概念

QueryWrapper 继承自 AbstractWrapper,主要用于构建 SELECT 语句的 WHERE 条件,同时支持以下特性:

  • 类型安全:通过Lambda表达式避免硬编码字段名

  • 链式调用:支持连续的条件拼接

  • 自动防注入:对用户输入参数自动转义

  • 灵活组合:支持嵌套条件、逻辑运算符(AND/OR)

MyBatis-Plus.webp

二、基础条件构造方法

1. 等于(eq) / 不等于(ne)

// 查询name等于"张三"且age不等于25的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三")
       .ne("age", 25);
List<User> users = userMapper.selectList(wrapper);

Lambda版本(推荐):

wrapper.lambda().eq(User::getName, "张三")
              .ne(User::getAge, 25);

2. 模糊查询(like)

// 模糊查询name包含"三"的用户
wrapper.like("name", "三");

// 左模糊查询(LIKE '%三')
wrapper.likeLeft("name", "三");

// 右模糊查询(LIKE '三%')
wrapper.likeRight("name", "三");

3. 范围查询

// BETWEEN查询(age在20到30之间)
wrapper.between("age", 20, 30);

// IN查询(id在指定列表中)
wrapper.in("id", Arrays.asList(1, 3, 5));

// NOT IN查询
wrapper.notIn("id", Arrays.asList(2, 4, 6));

4. 空值判断

// 查询email为空的记录
wrapper.isNull("email");

// 查询email非空的记录
wrapper.isNotNull("email");

三、高级条件组合

1. 嵌套条件(AND/OR)

// 查询 (age > 20 AND age < 30) OR (name LIKE '%张%')
wrapper.and(wq -> wq.gt("age", 20).lt("age", 30))
       .or(wq -> wq.like("name", "张"));

Lambda版本

wrapper.and(wq -> wq.lambda().gt(User::getAge, 20)
                           .lt(User::getAge, 30))
       .or(wq -> wq.lambda().like(User::getName, "张"));

2. 排序控制

// 按age降序,create_time升序
wrapper.orderByDesc("age")
       .orderByAsc("create_time");

3. 选择字段

// 仅查询id和name字段
wrapper.select("id", "name");

Lambda版本

wrapper.select(User::getId, User::getName);

四、实用示例场景

示例1:分页查询带条件

// 创建分页对象(当前页1,每页10条)
Page<User> page = new Page<>(1, 10);

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.lambda()
       .like(User::getName, "张")
       .orderByDesc(User::getCreateTime);

// 执行分页查询
IPage<User> userPage = userMapper.selectPage(page, wrapper);

// 获取分页数据
List<User> records = userPage.getRecords();
long total = userPage.getTotal();

示例2:动态条件构建

public List<User> searchUsers(String keyword, Integer minAge, Integer maxAge) {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    
    wrapper.lambda()
           .like(StringUtils.isNotBlank(keyword), User::getName, keyword)
           .gt(minAge != null, User::getAge, minAge)
           .lt(maxAge != null, User::getAge, maxAge);

    return userMapper.selectList(wrapper);
}

示例3:子查询

// 查询年龄大于平均年龄的用户
QueryWrapper<User> subQuery = new QueryWrapper<>();
subQuery.select("avg(age)").lambda().from(User.class);

wrapper.gt("age", subQuery);

五、最佳实践建议

  1. 优先使用Lambda版本
    避免硬编码字段名,提升代码可维护性:

    // 错误方式(字段名变更时需修改多处)
    wrapper.eq("user_name", "张三");
    
    // 正确方式(字段变更自动同步)
    wrapper.lambda().eq(User::getUserName, "张三");
  2. 合理使用条件判断
    动态条件推荐使用 Predicate 参数:

    wrapper.lambda()
           .eq(condition1, User::getField1, value1)
           .like(condition2, User::getField2, value2);
  3. 注意SQL注入防护
    避免直接拼接用户输入:

    // 危险!存在SQL注入风险
    wrapper.apply("name = {0}", userInput);
    
    // 安全方式
    wrapper.eq("name", userInput);
  4. 性能优化技巧

    • 为常用查询字段添加数据库索引

    • 避免在循环中频繁创建QueryWrapper

    • 大数据量分页时使用 last("LIMIT 1000") 限制返回量

六、总结

QueryWrapper 通过其流畅的API设计,使复杂SQL条件的构建变得直观高效。掌握其链式调用、Lambda表达式、嵌套条件等特性,可以显著提升MyBatis-Plus的开发效率。实际使用时建议结合Service层封装常用查询方法,保持代码的整洁性和可复用性。

MyBatis-Plus QueryWrapper
THE END
战地网
频繁记录吧,生活的本意是开心

相关推荐

QueryWrapper入门教程:从零开始构建MyBatis-Plus查询条件
MyBatis-Plus QueryWrapper 是构建动态查询条件的核心类之一,能够帮助开发者高效、安全地拼接SQL查询语句。本文ZHANID工具网将从零开始,详细介绍 QueryWrapper 的基本用法,...
2025-08-29 编程技术
430

深入解读MyBatis-Plus @TableField注解的用法
在MyBatis-Plus中,@TableField注解是一个非常重要的组件,用于映射实体类字段与数据库表字段之间的关系。正确使用@TableField注解,不仅可以实现自动化的字段映射,还能在一...
2024-12-31 编程技术
896