ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# MyBatis-Plus Wrapper 条件方法参数详解 ## 📌 参数个数与类型概览 MyBatis-Plus 的 Wrapper 条件方法主要有 **2参数**、**3参数** 和 **4参数** 三种形式,下表展示了常见方法的参数配置: | 方法 | 2参数形式 | 3参数形式 | 4参数形式 | 特殊形式 | |------|-----------|-----------|-----------|----------| | **eq/ne** | ✓ | ✓ | ✓ | | | **gt/ge/lt/le** | ✓ | ✓ | ✓ | | | **between** | 3参数 | 4参数 | 5参数 | | | **like** | ✓ | ✓ | ✓ | | | **in/notIn** | 2参数 | 3参数 | - | 可变参数 | --- ## 🔍 详细参数解析 ### 1. **2参数形式**(最常用) ```java // 基本语法:method(column, value) wrapper.eq("column_name", value); // 示例 wrapper.eq("status", 1); // status = 1 wrapper.like("name", "张"); // name LIKE '%张%' wrapper.gt("age", 18); // age > 18 wrapper.in("role_id", idsList); // role_id IN (1, 2, 3) ``` **参数说明:** - 参数1: `String column` - 数据库字段名(字符串) - 参数2: `Object value` - 条件值 --- ### 2. **3参数形式**(条件控制) ```java // 基本语法:method(condition, column, value) wrapper.eq(condition, "column_name", value); // 示例 String searchName = "张三"; Integer minAge = 18; wrapper.eq(searchName != null, "name", searchName); wrapper.gt(minAge != null && minAge > 0, "age", minAge); ``` **参数说明:** - 参数1: `boolean condition` - 控制条件,为 `true` 时生效,为 `false` 时忽略 - 参数2: `String column` - 数据库字段名 - 参数3: `Object value` - 条件值 **实际应用:动态查询构建** ```java public List<User> search(UserQuery query) { QueryWrapper<User> wrapper = new QueryWrapper<>(); // 动态条件控制 wrapper.eq(query.getStatus() != null, "status", query.getStatus()) .like(query.getName() != null, "name", query.getName()) .between(query.getStartTime() != null && query.getEndTime() != null, "create_time", query.getStartTime(), query.getEndTime()); return userMapper.selectList(wrapper); } ``` --- ### 3. **4参数形式**(复杂条件) 某些方法有4参数形式,主要用于处理更复杂的场景: ```java // between 方法的4参数形式 wrapper.between(condition, column, value1, value2); // 示例 Date startDate = getStartDate(); Date endDate = getEndDate(); wrapper.between(startDate != null && endDate != null, "create_time", startDate, endDate); ``` **参数说明:** - 参数1: `boolean condition` - 控制条件 - 参数2: `String column` - 数据库字段名 - 参数3: `Object value1` - 第一个值 - 参数4: `Object value2` - 第二个值 --- ## 🎯 LambdaWrapper 参数形式 LambdaWrapper 使用函数式引用,参数形式与 QueryWrapper 类似: ### 1. **2参数形式**(Lambda版) ```java // 基本语法:method(SFunction<T,?> column, value) lambdaWrapper.eq(User::getName, "张三"); // 等价于 QueryWrapper 的: wrapper.eq("name", "张三"); ``` **优点:** 类型安全,编译时检查,重构友好 ### 2. **3参数形式**(带条件控制) ```java // 基本语法:method(condition, SFunction<T,?> column, value) lambdaWrapper.eq(name != null, User::getName, name); ``` ### 3. **完整示例对比** ```java // QueryWrapper 示例 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("deleted", 0) .eq(status != null, "status", status) .like(name != null, "name", name); // LambdaQueryWrapper 等效写法 LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>(); lambdaWrapper.eq(User::getDeleted, 0) .eq(status != null, User::getStatus, status) .like(name != null, User::getName, name); ``` --- ## 📊 参数类型汇总表 ### 常见方法的完整参数形式 | 方法 | 参数个数 | 参数类型 | 示例 | SQL 等价 | |------|---------|----------|------|----------| | **eq/ne** | 2 | (String column, Object val) | `eq("status", 1)` | `status = 1` | | | 3 | (boolean condition, String column, Object val) | `eq(active, "status", 1)` | 条件满足时生效 | | **gt/ge/lt/le** | 2 | (String column, Object val) | `gt("age", 18)` | `age > 18` | | | 3 | (boolean condition, String column, Object val) | `gt(hasMinAge, "age", minAge)` | | | **between** | 3 | (String column, Object val1, Object val2) | `between("age", 18, 60)` | `age BETWEEN 18 AND 60` | | | 4 | (boolean condition, String column, Object val1, Object val2) | `between(hasRange, "age", min, max)` | | | **like** | 2 | (String column, Object val) | `like("name", "张")` | `name LIKE '%张%'` | | | 3 | (boolean condition, String column, Object val) | `like(hasKeyword, "name", keyword)` | | | **in** | 2 | (String column, Collection<?> value) | `in("role", roles)` | `role IN (1,2,3)` | | | 2 | (String column, Object... values) | `in("id", 1, 2, 3)` | `id IN (1,2,3)` | | | 3 | (boolean condition, String column, Collection<?> value) | `in(hasRoles, "role", roles)` | | --- ## 🔄 Lambda表达式参数的特殊性 ### 1. **SFunction 类型参数** LambdaWrapper 使用 `SFunction<T, R>` 作为列名参数: ```java // LambdaQueryWrapper 中的 eq 方法签名 eq(SFunction<T, ?> column, Object val) eq(boolean condition, SFunction<T, ?> column, Object val) // 使用示例 lambdaWrapper.eq(User::getName, "张三") .eq(age != null, User::getAge, age) .in(User::getRoleId, Arrays.asList(1, 2, 3)); ``` ### 2. **方法引用的好处** ```java // ✅ 类型安全:编译时检查字段是否存在 lambdaWrapper.eq(User::getName, "张三"); // ❌ 如果字段名写错,编译时就会报错 // lambdaWrapper.eq(User::getNmae, "张三"); // 编译错误:找不到getNmae方法 // ✅ 重构友好:重命名字段时,IDE可以自动更新所有引用 // 右键 Refactor → Rename "getName" → 所有使用处都会自动更新 ``` --- ## 🎪 特殊方法的参数说明 ### 1. **apply 方法**(自定义SQL片段) ```java // 2参数形式:apply(String applySql, Object... params) wrapper.apply("date_format(create_time,'%Y-%m-%d') = {0}", "2023-10-01"); // 3参数形式:apply(boolean condition, String applySql, Object... params) wrapper.apply(date != null, "date_format(create_time,'%Y-%m-%d') = {0}", dateStr); ``` ### 2. **inSql / notInSql 方法** ```java // 2参数形式:inSql(String column, String inValue) wrapper.inSql("dept_id", "SELECT id FROM dept WHERE status=1"); // 3参数形式:inSql(boolean condition, String column, String inValue) wrapper.inSql(hasSubQuery, "user_id", "SELECT user_id FROM audit WHERE result='PASS'"); ``` ### 3. **exists / notExists 方法** ```java // 1参数形式:exists(String existsSql) wrapper.exists("SELECT 1 FROM user_role ur WHERE ur.user_id = id"); // 2参数形式:exists(boolean condition, String existsSql) wrapper.exists(needCheckRole, "SELECT 1 FROM role r WHERE r.id = role_id AND r.enabled=1"); ``` --- ## ⚡ 参数使用的最佳实践 ### 1. **条件控制推荐写法** ```java // ✅ 推荐:使用3参数形式处理null值 wrapper.eq(query.getName() != null, "name", query.getName()) .gt(query.getMinAge() != null, "age", query.getMinAge()); // ❌ 避免:使用if语句嵌套 if (query.getName() != null) { wrapper.eq("name", query.getName()); } if (query.getMinAge() != null) { wrapper.gt("age", query.getMinAge()); } ``` ### 2. **LambdaWrapper 参数使用技巧** ```java // 链式调用配合条件参数 lambdaWrapper.eq(User::getDeleted, 0) .eq(query.getStatus() != null, User::getStatus, query.getStatus()) .like(StringUtils.isNotBlank(query.getKeyword()), User::getName, query.getKeyword()) .between(query.getStartDate() != null && query.getEndDate() != null, User::getCreateTime, query.getStartDate(), query.getEndDate()); ``` ### 3. **参数类型转换** ```java // MyBatis-Plus 会自动处理类型转换 wrapper.eq("age", "18"); // 字符串"18" → 数字18(如果数据库字段是数字类型) wrapper.eq("id", 100L); // Long → 数据库对应类型 wrapper.eq("is_active", true); // boolean → 数据库对应类型(通常为0/1或true/false) // 日期类型 wrapper.eq("create_time", new Date()); // java.util.Date wrapper.eq("update_time", LocalDateTime.now()); // java.time.LocalDateTime ``` ### 4. **集合参数的特殊处理** ```java // List/Collection 参数 List<Integer> roleIds = Arrays.asList(1, 2, 3); wrapper.in("role_id", roleIds); // role_id IN (1, 2, 3) // 数组参数 Integer[] ids = {1, 2, 3}; wrapper.in("id", ids); // id IN (1, 2, 3) // 可变参数 wrapper.in("status", 1, 2, 3); // status IN (1, 2, 3) // 空集合处理 List<Integer> emptyList = Collections.emptyList(); wrapper.in("role_id", emptyList); // 会生成错误的SQL: role_id IN () // 推荐使用条件控制避免空集合 wrapper.in(!CollectionUtils.isEmpty(roleIds), "role_id", roleIds); ``` --- ## 🔧 自定义参数处理 ### 1. **使用 SqlCondition 常量** ```java import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.sql.SqlCondition; // 使用预定义的SQL条件常量 wrapper.eq(SqlCondition.EQUAL, "name", "张三"); // 等价于 wrapper.eq("name", "张三"); // 其他可用的SqlCondition常量: // SqlCondition.LIKE, SqlCondition.GT, SqlCondition.LT等 ``` ### 2. **自定义比较操作符** ```java // 使用apply方法实现自定义比较 wrapper.apply("column_name != {0}", value); // 自定义不等于 wrapper.apply("column_name LIKE CONCAT({0}, '%')", prefix); // 自定义LIKE wrapper.apply("LENGTH(column_name) > {0}", length); // 自定义函数 ``` --- ## 📝 总结要点 1. **参数个数灵活**:大部分方法都有2参数和3参数两种形式 2. **条件控制**:3参数形式第一个参数控制条件是否生效 3. **类型安全**:LambdaWrapper使用函数式引用,编译时检查字段有效性 4. **动态查询**:配合条件参数实现优雅的动态SQL构建 5. **自动类型转换**:MyBatis-Plus会自动处理Java类型到数据库类型的转换 通过合理选择参数形式,可以编写出既简洁又强大的条件查询代码,提高开发效率和代码可维护性。