最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis-Plus 復(fù)雜查詢(xún)Lambda+Wrapper 多條件功能實(shí)現(xiàn)

 更新時(shí)間:2026年01月08日 16:54:08   作者:Jinkxs  
通過(guò)本文的介紹,我們深入了解了MyBatis-Plus中Lambda+Wrapper的強(qiáng)大功能,它不僅極大地簡(jiǎn)化了SQL的編寫(xiě),還提高了代碼的安全性和可維護(hù)性,感興趣的朋友跟隨小編一起看看吧

Java 數(shù)據(jù) 01:MyBatis-Plus 復(fù)雜查詢(xún)(Lambda+Wrapper 多條件)

在現(xiàn)代 Java Web 開(kāi)發(fā)中,持久層框架的選擇對(duì)于提升開(kāi)發(fā)效率和系統(tǒng)性能至關(guān)重要。MyBatis-Plus 作為 MyBatis 的增強(qiáng)工具,極大地簡(jiǎn)化了 MyBatis 的使用,提供了豐富的 CRUD 操作和強(qiáng)大的條件構(gòu)造器。特別是其 LambdaWrapper 結(jié)合使用的方式,使得構(gòu)建復(fù)雜查詢(xún)語(yǔ)句變得簡(jiǎn)潔而優(yōu)雅。本文將深入探討如何利用 MyBatis-Plus 的 Lambda + Wrapper 功能進(jìn)行復(fù)雜的多條件查詢(xún)。

一、MyBatis-Plus 簡(jiǎn)介與核心概念

1.1 什么是 MyBatis-Plus?

MyBatis-Plus 是一個(gè) MyBatis 的增強(qiáng)工具,它在 MyBatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開(kāi)發(fā)、提高效率而生。它提供了許多便捷的功能,如:

  • 代碼生成器:一鍵生成 Mapper、Service、Controller 等代碼。
  • 通用 CRUD 操作:無(wú)需編寫(xiě) SQL,即可完成基本的增刪改查。
  • 條件構(gòu)造器 (Wrapper):提供強(qiáng)大且靈活的條件拼接功能。
  • 分頁(yè)插件:輕松實(shí)現(xiàn)分頁(yè)查詢(xún)。
  • 性能分析插件:幫助分析 SQL 性能。
  • 樂(lè)觀鎖支持:簡(jiǎn)化并發(fā)控制。
  • 多租戶(hù)支持:方便實(shí)現(xiàn)數(shù)據(jù)隔離。

1.2 核心組件

  • Mapper 接口:繼承 BaseMapper<T>,獲得通用 CRUD 方法。
  • Entity 實(shí)體類(lèi):映射數(shù)據(jù)庫(kù)表結(jié)構(gòu)。
  • Wrapper 條件構(gòu)造器:用于構(gòu)建查詢(xún)、更新、刪除的條件。
  • LambdaQueryWrapper / LambdaUpdateWrapper:基于 Lambda 表達(dá)式的 Wrapper,避免硬編碼字段名,提高安全性。

二、Lambda + Wrapper 基礎(chǔ)入門(mén)

2.1 準(zhǔn)備工作

首先,確保你的項(xiàng)目已引入 MyBatis-Plus 依賴(lài)。例如,在 Maven 項(xiàng)目中:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.2</version> <!-- 請(qǐng)根據(jù)實(shí)際情況選擇版本 -->
</dependency>

假設(shè)我們有一個(gè)用戶(hù)表 user,對(duì)應(yīng)的實(shí)體類(lèi) User 如下:

package com.example.demo.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("user") // 指定數(shù)據(jù)庫(kù)表名
public class User {
    @TableId(value = "id", type = IdType.AUTO) // 主鍵自增
    private Long id;
    private String name; // 用戶(hù)名
    private Integer age; // 年齡
    private String email; // 郵箱
    private Integer status; // 狀態(tài) (例如: 0 - 無(wú)效, 1 - 有效)
    @TableField(fill = FieldFill.INSERT) // 插入時(shí)自動(dòng)填充
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新時(shí)自動(dòng)填充
    private LocalDateTime updateTime;
    // 構(gòu)造函數(shù)、getter、setter 等省略...
}

對(duì)應(yīng)的 Mapper 接口:

package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
    // 繼承 BaseMapper 后,通常不需要額外定義方法
}

2.2 基本查詢(xún)示例

讓我們從最基礎(chǔ)的查詢(xún)開(kāi)始。假設(shè)我們要查詢(xún)所有狀態(tài)為有效的用戶(hù)(status = 1)。

// UserService.java
package com.example.demo.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public List<User> getUsersByStatus(Integer status) {
        // 使用 LambdaQueryWrapper 構(gòu)建查詢(xún)條件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getStatus, status); // WHERE status = ?
        return userMapper.selectList(queryWrapper);
    }
    // 或者更簡(jiǎn)潔的寫(xiě)法,使用 Wrappers 工具類(lèi)
    public List<User> getUsersByStatusWithWrappers(Integer status) {
        return userMapper.selectList(Wrappers.<User>lambdaQuery().eq(User::getStatus, status));
    }
}

關(guān)鍵點(diǎn)解析:

  • LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>(); 創(chuàng)建了一個(gè) Lambda 查詢(xún)包裝器。
  • queryWrapper.eq(User::getStatus, status); 構(gòu)建了一個(gè)等于條件。User::getStatus 是一個(gè)方法引用,它指向 User 類(lèi)的 getStatus() 方法,MyBatis-Plus 會(huì)通過(guò)反射獲取該方法對(duì)應(yīng)的字段名(status)。
  • userMapper.selectList(queryWrapper); 執(zhí)行查詢(xún),返回符合條件的對(duì)象列表。

這種方式相比傳統(tǒng) MyBatis 直接寫(xiě) SQL,具有以下優(yōu)勢(shì):

  • 類(lèi)型安全:使用方法引用來(lái)指定字段,避免了字符串寫(xiě)錯(cuò)導(dǎo)致的運(yùn)行時(shí)錯(cuò)誤。
  • 可維護(hù)性高:當(dāng)實(shí)體類(lèi)屬性名修改時(shí),IDE 會(huì)提示相關(guān)代碼需要修改,降低維護(hù)成本。
  • 語(yǔ)法簡(jiǎn)潔:代碼更加清晰易讀。

三、復(fù)雜查詢(xún)條件詳解

3.1 基礎(chǔ)比較操作符

MyBatis-Plus 提供了豐富的條件構(gòu)造方法,用于構(gòu)建各種比較操作。

public List<User> getComplexUsers() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 等于 (eq)
    wrapper.eq(User::getStatus, 1);
    // 不等于 (ne)
    wrapper.ne(User::getAge, 18);
    // 大于 (gt)
    wrapper.gt(User::getAge, 18);
    // 大于等于 (ge)
    wrapper.ge(User::getAge, 18);
    // 小于 (lt)
    wrapper.lt(User::getAge, 60);
    // 小于等于 (le)
    wrapper.le(User::getAge, 60);
    // 模糊匹配 (like)
    wrapper.like(User::getName, "張"); // 名字包含 '張'
    // 左模糊匹配 (likeLeft)
    wrapper.likeLeft(User::getName, "張"); // 名字以 '張' 開(kāi)頭
    // 右模糊匹配 (likeRight)
    wrapper.likeRight(User::getName, "三"); // 名字以 '三' 結(jié)尾
    // 不為空 (isNotNull)
    wrapper.isNotNull(User::getEmail);
    // 為空 (isNull)
    wrapper.isNull(User::getPhone); // 假設(shè)存在 phone 字段
    // 在某個(gè)范圍內(nèi) (between)
    wrapper.between(User::getAge, 18, 60); // 年齡在 18 到 60 之間
    // 在某個(gè)集合內(nèi) (in)
    List<Integer> statuses = Arrays.asList(0, 1);
    wrapper.in(User::getStatus, statuses); // 狀態(tài)在 [0, 1] 中
    // 不在某個(gè)集合內(nèi) (notIn)
    List<Long> ids = Arrays.asList(1L, 2L, 3L);
    wrapper.notIn(User::getId, ids); // ID 不在 [1, 2, 3] 中
    // 空值處理 (isNotNull / isNull) 的組合
    // 例如:查詢(xún)有郵箱且狀態(tài)為有效的用戶(hù)
    wrapper.isNotNull(User::getEmail).eq(User::getStatus, 1);
    return userMapper.selectList(wrapper);
}

3.2 邏輯操作符

在實(shí)際應(yīng)用中,往往需要組合多個(gè)條件。MyBatis-Plus 提供了 and()or() 方法來(lái)處理邏輯關(guān)系。

3.2.1 AND 連接

默認(rèn)情況下,所有條件都是 AND 關(guān)系。例如,查詢(xún)年齡大于等于 18 且小于等于 60 且狀態(tài)為有效的用戶(hù):

public List<User> getUsersByAgeAndStatus() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 默認(rèn)就是 AND 關(guān)系
    wrapper.ge(User::getAge, 18)
           .le(User::getAge, 60)
           .eq(User::getStatus, 1);
    return userMapper.selectList(wrapper);
}
3.2.2 OR 連接

使用 or() 方法可以將條件轉(zhuǎn)換為 OR 關(guān)系。例如,查詢(xún)用戶(hù)名包含“張”或郵箱包含“@qq.com”的用戶(hù):

public List<User> getUsersByNameOrEmail() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.like(User::getName, "張")
           .or()
           .like(User::getEmail, "@qq.com");
    return userMapper.selectList(wrapper);
}
3.2.3 復(fù)雜嵌套邏輯

可以通過(guò) apply() 方法或者嵌套 LambdaQueryWrapper 來(lái)處理更復(fù)雜的邏輯。

使用 apply() 方法

apply() 方法允許直接傳入 SQL 片段,適用于一些無(wú)法通過(guò)標(biāo)準(zhǔn)方法表達(dá)的復(fù)雜條件。

public List<User> getUsersWithApply() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 示例:查詢(xún)郵箱后綴為 '.com' 且年齡在某個(gè)范圍內(nèi)的用戶(hù)
    wrapper.apply("email LIKE '%.com'")
           .between(User::getAge, 20, 50);
    return userMapper.selectList(wrapper);
}
嵌套 LambdaQueryWrapper

對(duì)于復(fù)雜的 ORAND 組合,可以創(chuàng)建子 LambdaQueryWrapper 并將其作為參數(shù)傳遞給 and()or() 方法。

public List<User> getUsersComplexLogic() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 示例:查詢(xún)滿(mǎn)足以下任一條件的用戶(hù):
    // 1. 年齡大于等于 18 且狀態(tài)為有效 (age >= 18 AND status = 1)
    // 2. 年齡小于 18 且郵箱包含 '@school.edu' (age < 18 AND email LIKE '%@school.edu')
    wrapper.and(subWrapper -> subWrapper.ge(User::getAge, 18).eq(User::getStatus, 1))
           .or()
           .and(subWrapper -> subWrapper.lt(User::getAge, 18).like(User::getEmail, "@school.edu"));
    return userMapper.selectList(wrapper);
}

3.3 聚合函數(shù)與分組查詢(xún)

MyBatis-Plus 也支持聚合函數(shù)和分組查詢(xún),常用于統(tǒng)計(jì)分析。

public void groupByAgeAndCount() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.select(User::getAge, "COUNT(*) as count") // 選擇年齡和計(jì)數(shù)
           .groupBy(User::getAge); // 按年齡分組
    // 注意:selectList 返回的是 List<User>,這里需要特別注意
    // 如果你想得到分組后的結(jié)果,通常會(huì)用到 Map 或自定義 DTO
    // 但 MyBatis-Plus 的 selectList 一般不直接返回聚合結(jié)果
    // 更常見(jiàn)的是使用原生 SQL 或者自定義方法
    // 這里展示一種方式,可能需要調(diào)整
}
// 更推薦的做法是使用自定義 SQL 或者結(jié)合分頁(yè)插件
// 例如,使用自定義 Mapper 方法

對(duì)于更復(fù)雜的聚合查詢(xún),建議使用自定義 SQL 或者結(jié)合 MyBatis 的 <select> 標(biāo)簽。

3.4 排序與分頁(yè)

3.4.1 排序 (orderBy)
public List<User> getUsersSortedByAgeDesc() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.orderByDesc(User::getAge); // 按年齡降序排列
    return userMapper.selectList(wrapper);
}
public List<User> getUsersSortedMultiple() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 先按年齡降序,再按創(chuàng)建時(shí)間升序
    wrapper.orderByDesc(User::getAge).orderByAsc(User::getCreateTime);
    return userMapper.selectList(wrapper);
}
3.4.2 分頁(yè) (Page)

MyBatis-Plus 提供了分頁(yè)插件,配合 Page 對(duì)象使用。

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
public IPage<User> getUsersPage(int current, int size) {
    Page<User> page = new Page<>(current, size); // 當(dāng)前頁(yè)碼,每頁(yè)大小
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(User::getStatus, 1) // 狀態(tài)為有效
           .orderByDesc(User::getCreateTime); // 按創(chuàng)建時(shí)間倒序
    // 執(zhí)行分頁(yè)查詢(xún)
    return userMapper.selectPage(page, wrapper);
}

四、高級(jí)特性與最佳實(shí)踐

4.1 動(dòng)態(tài)查詢(xún)構(gòu)建

在實(shí)際業(yè)務(wù)中,查詢(xún)條件往往是動(dòng)態(tài)的。我們可以根據(jù)傳入的參數(shù),動(dòng)態(tài)地構(gòu)建 LambdaQueryWrapper。

public List<User> searchUsers(String name, Integer minAge, Integer maxAge, Integer status, Boolean includeInactive) {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 動(dòng)態(tài)添加條件
    if (name != null && !name.isEmpty()) {
        wrapper.like(User::getName, name);
    }
    if (minAge != null) {
        wrapper.ge(User::getAge, minAge);
    }
    if (maxAge != null) {
        wrapper.le(User::getAge, maxAge);
    }
    if (status != null) {
        wrapper.eq(User::getStatus, status);
    }
    // 特殊處理:如果 includeInactive 為 false,則排除狀態(tài)為 0 的用戶(hù)
    if (includeInactive != null && !includeInactive) {
        wrapper.ne(User::getStatus, 0); // 不等于 0
    } else if (includeInactive == null || includeInactive) {
        // 如果 includeInactive 為 null 或 true,可以不加任何條件,或者加上其他邏輯
        // 這里簡(jiǎn)單示例,不加額外條件
    }
    // 添加排序
    wrapper.orderByDesc(User::getCreateTime);
    return userMapper.selectList(wrapper);
}

4.2 使用select()指定字段

為了提高查詢(xún)效率,通常只查詢(xún)需要的字段,而不是使用 *。

public List<User> getUsersOnlyNameAndEmail() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.select(User::getName, User::getEmail); // 只查詢(xún) name 和 email 字段
    return userMapper.selectList(wrapper);
}

4.3 使用selectObjs()獲取單個(gè)字段值

如果你只需要查詢(xún)某個(gè)字段的所有值,可以使用 selectObjs()。

public List<String> getUserNames() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.select(User::getName); // 查詢(xún)所有用戶(hù)的姓名
    return userMapper.selectObjs(wrapper, row -> (String) row); // 轉(zhuǎn)換為 String 列表
}

4.4 使用exists()和notExists()

用于檢查子查詢(xún)是否存在記錄。

public List<User> getUsersWithOrders() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 查詢(xún)有訂單的用戶(hù)
    wrapper.exists(
        "SELECT 1 FROM order o WHERE o.user_id = user.id"
    );
    return userMapper.selectList(wrapper);
}

4.5 性能優(yōu)化建議

  1. 索引優(yōu)化:確保查詢(xún)條件中涉及的字段有合適的數(shù)據(jù)庫(kù)索引。
  2. **避免 SELECT ***:明確指定需要的字段。
  3. 合理使用分頁(yè):避免一次性查詢(xún)大量數(shù)據(jù)。
  4. 緩存查詢(xún)結(jié)果:對(duì)于不經(jīng)常變動(dòng)的數(shù)據(jù),可以考慮使用緩存。
  5. 避免 N+1 查詢(xún):在關(guān)聯(lián)查詢(xún)時(shí)注意性能問(wèn)題。

五、實(shí)戰(zhàn)案例:用戶(hù)管理后臺(tái)查詢(xún)接口

讓我們結(jié)合一個(gè)完整的場(chǎng)景來(lái)演示如何使用 Lambda + Wrapper 構(gòu)建復(fù)雜的查詢(xún)。假設(shè)我們需要實(shí)現(xiàn)一個(gè)用戶(hù)管理后臺(tái)的查詢(xún)接口,支持以下功能:

  • 按用戶(hù)名模糊搜索
  • 按年齡區(qū)間篩選
  • 按狀態(tài)篩選
  • 按郵箱后綴篩選
  • 支持排序(按創(chuàng)建時(shí)間倒序)
  • 支持分頁(yè)

5.1 控制器層 (Controller)

package com.example.demo.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.dto.UserQueryDTO;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    /**
     * 查詢(xún)用戶(hù)列表
     * @param queryDTO 查詢(xún)條件
     * @return 分頁(yè)結(jié)果
     */
    @GetMapping("/list")
    public Page<User> listUsers(UserQueryDTO queryDTO) {
        return userService.getUsersPage(queryDTO);
    }
    /**
     * 獲取所有用戶(hù)(不分頁(yè))
     * @param queryDTO 查詢(xún)條件
     * @return 用戶(hù)列表
     */
    @GetMapping("/all")
    public List<User> getAllUsers(UserQueryDTO queryDTO) {
        return userService.getAllUsers(queryDTO);
    }
}

5.2 DTO 層 (Data Transfer Object)

package com.example.demo.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class UserQueryDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name; // 用戶(hù)名
    private Integer minAge; // 最小年齡
    private Integer maxAge; // 最大年齡
    private Integer status; // 狀態(tài)
    private String emailSuffix; // 郵箱后綴 (例如: @gmail.com)
    private Integer current = 1; // 當(dāng)前頁(yè)碼
    private Integer size = 10; // 每頁(yè)大小
}

5.3 Service 層 (Service)

package com.example.demo.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.dto.UserQueryDTO;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    /**
     * 分頁(yè)查詢(xún)用戶(hù)
     * @param queryDTO 查詢(xún)條件
     * @return 分頁(yè)結(jié)果
     */
    public Page<User> getUsersPage(UserQueryDTO queryDTO) {
        Page<User> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        // 構(gòu)建查詢(xún)條件
        buildQueryCondition(queryDTO, page);
        return userMapper.selectPage(page, page.getOptimizeJoinFlag());
    }
    /**
     * 獲取所有符合條件的用戶(hù)(不分頁(yè))
     * @param queryDTO 查詢(xún)條件
     * @return 用戶(hù)列表
     */
    public List<User> getAllUsers(UserQueryDTO queryDTO) {
        // 構(gòu)建查詢(xún)條件
        buildQueryCondition(queryDTO, null); // 注意:這里傳入 null 或者構(gòu)建一個(gè)沒(méi)有分頁(yè)的 wrapper
        // 由于 selectPage 需要 wrapper 參數(shù),我們直接調(diào)用 selectList
        // 但是為了復(fù)用邏輯,我們先構(gòu)建一個(gè) wrapper
        return userMapper.selectList(buildQueryCondition(queryDTO, null));
    }
    /**
     * 構(gòu)建查詢(xún)條件并返回 LambdaQueryWrapper
     * @param queryDTO 查詢(xún)條件
     * @param page 分頁(yè)對(duì)象(可選,如果不需要分頁(yè)則傳 null)
     * @return LambdaQueryWrapper
     */
    private com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<User> buildQueryCondition(UserQueryDTO queryDTO, Page<User> page) {
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<User> wrapper = new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
        // 動(dòng)態(tài)添加查詢(xún)條件
        if (queryDTO.getName() != null && !queryDTO.getName().isEmpty()) {
            wrapper.like(User::getName, queryDTO.getName());
        }
        if (queryDTO.getMinAge() != null) {
            wrapper.ge(User::getAge, queryDTO.getMinAge());
        }
        if (queryDTO.getMaxAge() != null) {
            wrapper.le(User::getAge, queryDTO.getMaxAge());
        }
        if (queryDTO.getStatus() != null) {
            wrapper.eq(User::getStatus, queryDTO.getStatus());
        }
        if (queryDTO.getEmailSuffix() != null && !queryDTO.getEmailSuffix().isEmpty()) {
            // 使用 likeRight 或者 apply 都可以
            // 這里使用 likeRight 示例
            wrapper.likeRight(User::getEmail, queryDTO.getEmailSuffix());
            // 或者使用 apply: wrapper.apply("email LIKE '%" + queryDTO.getEmailSuffix() + "'");
        }
        // 添加排序
        wrapper.orderByDesc(User::getCreateTime);
        // 如果傳入了分頁(yè)對(duì)象,則設(shè)置分頁(yè)信息
        if (page != null) {
            // 這里可以設(shè)置分頁(yè)信息,但實(shí)際上 selectPage 會(huì)自動(dòng)處理
            // 但為了清晰,我們可以將 wrapper 傳回給 selectPage
            // 注意:selectPage 方法本身會(huì)接收 wrapper 和 page 對(duì)象
        }
        return wrapper;
    }
    // 修正后的 getAllUsers 方法,使用單獨(dú)的方法構(gòu)建 wrapper
    public List<User> getAllUsersCorrect(UserQueryDTO queryDTO) {
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<User> wrapper = buildQueryCondition(queryDTO, null);
        return userMapper.selectList(wrapper);
    }
}

5.4 Mapper 層 (Mapper)

package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
    // 繼承 BaseMapper 后,通常不需要額外定義方法
    // 如果需要自定義 SQL,可以在 XML 文件中定義
}

5.5 請(qǐng)求示例

啟動(dòng)應(yīng)用后,可以通過(guò)如下請(qǐng)求來(lái)測(cè)試接口:

  • 獲取所有有效用戶(hù)(分頁(yè))
    GET /users/list?status=1&current=1&size=10
  • 獲取用戶(hù)名包含“李”且年齡在 20 到 40 之間的有效用戶(hù)
    GET /users/list?name=李&minAge=20&maxAge=40&status=1&current=1&size=10
  • 獲取郵箱以 “@gmail.com” 結(jié)尾的所有用戶(hù)
    GET /users/list?emailSuffix=@gmail.com&current=1&size=10

六、常見(jiàn)問(wèn)題與解決方案

6.1 字段名拼寫(xiě)錯(cuò)誤

使用 Lambda 表達(dá)式可以有效避免字段名拼寫(xiě)錯(cuò)誤的問(wèn)題,因?yàn)榫幾g期就會(huì)檢查方法引用是否正確。

6.2 性能問(wèn)題

  • 原因:未建立合適的索引、查詢(xún)字段過(guò)多、未使用分頁(yè)等。
  • 解決:確保查詢(xún)字段上有索引;只查詢(xún)需要的字段;使用分頁(yè)。

6.3 空指針異常

  • 原因:在構(gòu)建條件時(shí),沒(méi)有對(duì)傳入的參數(shù)進(jìn)行非空判斷。
  • 解決:在構(gòu)建條件前,對(duì)參數(shù)進(jìn)行判空處理。

6.4 SQL 注入風(fēng)險(xiǎn)

  • 原因:使用 apply() 方法時(shí),如果直接拼接用戶(hù)輸入,可能導(dǎo)致 SQL 注入。
  • 解決:使用參數(shù)化查詢(xún),避免直接拼接用戶(hù)輸入。對(duì)于 apply(),應(yīng)謹(jǐn)慎使用,并確保輸入經(jīng)過(guò)驗(yàn)證。

七、總結(jié)與展望

通過(guò)本文的介紹,我們深入了解了 MyBatis-Plus 中 Lambda + Wrapper 的強(qiáng)大功能。它不僅極大地簡(jiǎn)化了 SQL 的編寫(xiě),還提高了代碼的安全性和可維護(hù)性。從簡(jiǎn)單的條件查詢(xún)到復(fù)雜的嵌套邏輯,從動(dòng)態(tài)構(gòu)建到性能優(yōu)化,Lambda + Wrapper 都能勝任。

掌握這些技巧,可以讓我們的 Java Web 開(kāi)發(fā)更加高效和優(yōu)雅。隨著 MyBatis-Plus 的持續(xù)發(fā)展,相信未來(lái)會(huì)有更多便捷的功能加入,進(jìn)一步提升開(kāi)發(fā)體驗(yàn)。

?? 參考資料

希望這篇文章能幫助你更好地理解和使用 MyBatis-Plus 的 Lambda + Wrapper 功能!??

到此這篇關(guān)于MyBatis-Plus 復(fù)雜查詢(xún)Lambda+Wrapper 多條件功能實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)mybits-plus復(fù)雜查詢(xún)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

荃湾区| 平乐县| 正宁县| 库车县| 五河县| 白沙| 定陶县| 朝阳区| 政和县| 常山县| 青田县| 肇源县| 邢台市| 孝义市| 辛集市| 彭阳县| 大同县| 道孚县| 浦县| 体育| 定日县| 怀集县| 福鼎市| 什邡市| 喀喇沁旗| 桃园市| 淮阳县| 扎囊县| 义乌市| 藁城市| 红桥区| 株洲市| 凤山市| 永昌县| 磐石市| 来凤县| 通州区| 叶城县| 江永县| 辽阳市| 浠水县|