首页 > 其他分享 >在 MyBatis-Plus 中使用 IN 语法

在 MyBatis-Plus 中使用 IN 语法

时间:2024-12-31 11:30:51浏览次数:1  
标签:queryWrapper LambdaQueryWrapper List ids 语法 Plus SQL MyBatis public

在 MyBatis-Plus 中使用 IN 语法

在 MyBatis-Plus 中使用 IN​ 语法可以通过以下几种方式实现:

1. 使用 QueryWrapper​ 的 in​ 方法

QueryWrapper​ 是 MyBatis-Plus 提供的查询条件构造器,可以使用 in​ 方法来构建 IN​ 查询。

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    public List<User> findUsersByIds(List<Long> ids) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        return baseMapper.selectList(queryWrapper);
    }
}

SQL 输出:

SELECT * FROM user WHERE id IN (1, 2, 3);

2. 使用 LambdaQueryWrapper​ 的 in​ 方法

LambdaQueryWrapper​ 提供了类型安全的查询条件构造,可以使用 in​ 方法来构建 IN​ 查询。

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    public List<User> findUsersByIds(List<Long> ids) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(User::getId, ids);
        return baseMapper.selectList(lambdaQueryWrapper);
    }
}

SQL 输出:

SELECT * FROM user WHERE id IN (1, 2, 3);

3. 使用 XML 映射文件

在 MyBatis 的 XML 映射文件中,可以直接编写 SQL 语句,使用 IN​ 语法。

<select id="findUsersByIds" resultType="User">
    SELECT * FROM user WHERE id IN
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

运行 HTML

Java 代码:

public interface UserMapper extends BaseMapper<User> {
    List<User> findUsersByIds(@Param("ids") List<Long> ids);
}

SQL 输出:

SELECT * FROM user WHERE id IN (1, 2, 3);

4. 使用注解方式

在 MyBatis 的注解方式中,可以使用 @Select​ 注解编写 SQL 语句,使用 IN​ 语法。

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface UserMapper extends BaseMapper<User> {

    @Select("SELECT * FROM user WHERE id IN (#{ids})")
    List<User> findUsersByIds(@Param("ids") List<Long> ids);
}

注意: 这种方式需要手动将 List​ 转换为逗号分隔的字符串。

5. 处理空列表的情况

在使用 IN​ 语法时,如果传入的列表为空,可能会导致 SQL 语法错误。可以通过以下方式处理:

public List<User> findUsersByIds(List<Long> ids) {
    if (ids == null || ids.isEmpty()) {
        return new ArrayList<>();
    }
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.in("id", ids);
    return baseMapper.selectList(queryWrapper);
}

总结

  • QueryWrapper LambdaQueryWrapper​ 是 MyBatis-Plus 提供的便捷查询条件构造器,适合在 Java 代码中动态构建查询条件。
  • XML 映射文件注解方式 适合在需要编写复杂 SQL 或需要复用 SQL 的场景下使用。
  • 处理空列表 是使用 IN​ 语法时需要注意的一个细节,避免 SQL 语法错误。

根据具体需求选择合适的方式来实现 IN​ 查询。

除此之外,在使用 LambdaQueryWrapper​ 的 in​ 方法时,如果传入的数组或列表为空,可能会导致生成的 SQL 语句不合法(例如 IN ()​),从而引发 SQL 语法错误。为了避免这种情况,可以在调用 in​ 方法之前对数组或列表进行判空处理。

以下是处理空数组的几种常见方式:


1. 直接返回空结果

如果传入的数组为空,直接返回一个空列表,避免执行 SQL 查询。

public List<User> findUsersByIds(List<Long> ids) {
    if (ids == null || ids.isEmpty()) {
        return new ArrayList<>();
    }
    LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.in(User::getId, ids);
    return baseMapper.selectList(queryWrapper);
}

优点:

  • 简单直接,避免执行无意义的查询。

缺点:

  • 需要在业务逻辑中显式处理空列表。

2. 添加空值检查条件

如果希望即使传入空列表也能执行查询,可以通过添加一个永假条件(例如 1 = 0​)来避免生成 IN ()​。

public List<User> findUsersByIds(List<Long> ids) {
    LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
    if (ids == null || ids.isEmpty()) {
        queryWrapper.apply("1 = 0"); // 永假条件,避免生成 IN ()
    } else {
        queryWrapper.in(User::getId, ids);
    }
    return baseMapper.selectList(queryWrapper);
}

生成的 SQL:

SELECT * FROM user WHERE 1 = 0;

优点:

  • 统一处理空列表,避免在业务逻辑中显式返回空列表。

缺点:

  • 生成的 SQL 可能不够直观。

3. 使用 Optional处理空值

使用 Optional​ 对传入的列表进行包装,避免空指针异常。

public List<User> findUsersByIds(List<Long> ids) {
    List<Long> nonNullIds = Optional.ofNullable(ids).orElse(Collections.emptyList());
    if (nonNullIds.isEmpty()) {
        return new ArrayList<>();
    }
    LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.in(User::getId, nonNullIds);
    return baseMapper.selectList(queryWrapper);
}

优点:

  • 代码更健壮,避免空指针异常。

缺点:

  • 需要额外引入 Optional​。

4. 自定义工具方法

封装一个工具方法,统一处理 in​ 方法的空列表问题。

public class QueryWrapperUtils {
    public static <T, R> void inIfNotEmpty(LambdaQueryWrapper<T> queryWrapper, SFunction<T, R> column, Collection<R> values) {
        if (values != null && !values.isEmpty()) {
            queryWrapper.in(column, values);
        } else {
            queryWrapper.apply("1 = 0"); // 永假条件
        }
    }
}

// 使用工具方法
public List<User> findUsersByIds(List<Long> ids) {
    LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
    QueryWrapperUtils.inIfNotEmpty(queryWrapper, User::getId, ids);
    return baseMapper.selectList(queryWrapper);
}

优点:

  • 代码复用,逻辑清晰。

缺点:

  • 需要额外定义工具类。

5. 使用 MyBatis-Plus 的 apply方法动态生成 SQL

通过 apply​ 方法动态生成 IN​ 子句,避免空列表问题。

public List<User> findUsersByIds(List<Long> ids) {
    LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
    if (ids != null && !ids.isEmpty()) {
        String inClause = ids.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(",", "(", ")"));
        queryWrapper.apply("id IN " + inClause);
    } else {
        queryWrapper.apply("1 = 0");
    }
    return baseMapper.selectList(queryWrapper);
}

生成的 SQL:

SELECT * FROM user WHERE id IN (1, 2, 3);

优点:

  • 灵活控制 SQL 生成。

缺点:

  • 需要手动拼接 SQL,可能引入 SQL 注入风险(需确保输入安全)。

总结

方法 优点 缺点
直接返回空结果 简单直接 需在业务逻辑中显式处理
添加永假条件 统一处理空列表 生成的 SQL 不够直观
使用 Optional 避免空指针异常,代码健壮 需要额外引入 Optional
自定义工具方法 代码复用,逻辑清晰 需要额外定义工具类
动态生成 SQL 灵活控制 SQL 生成 需手动拼接 SQL,可能引入 SQL 注入风险

根据具体场景选择合适的方式处理空数组问题。推荐使用 直接返回空结果自定义工具方法,既简单又安全。

标签:queryWrapper,LambdaQueryWrapper,List,ids,语法,Plus,SQL,MyBatis,public
From: https://www.cnblogs.com/createBUG/p/18643628/use-in-grammar-in-mybatisplus-1bihse

相关文章

  • 由 Mybatis 源码畅谈软件设计(七):从根上理解 Mybatis 一级缓存
    作者:京东保险王奕龙本篇我们来讲一级缓存,重点关注它的实现原理:何时生效、生效范围和何时失效,在未来设计缓存使用时,提供一些借鉴和参考。1.准备工作定义实体publicclassDepartment{publicDepartment(Stringid){this.id=id;}privateStri......
  • Makefile 语法速查
    本文是我在看南京大学NEMU项目makefile总结的看到的语法,非面相零基础人员学习。make​是一个用于构建大型项目的命令工具,其通过预先定义的Makefile来构建可执行文件。Makefile中定义了各文件之间的依赖关系,以及需要执行哪些相应的命令来完成项目构建。make的基础参数:-......
  • XshellPlus V7中文版绿色免安装版下载及使用教程
    XshellPlus是一款将Xshell和Xftp打包在一起的强大远程管理工具,结合了Xshell和Xftp的所有功能,提供更高效的远程控制和文件传输体验。目前xshell个人用户已经可以免费使用,官方已经推出个人版!什么是XshellPlus?XshellPlus是一款集成了Xshell和Xftp的工具,专为个人用......
  • java之mybatis框架第一天-mybatis入门
    1.前言什么是mybatisMyBatis是一款优秀的持久层框架,用于简化JDBC的开发。MyBatis本是Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了googlecode,并且改名为MyBatis。2013年11月迁移到Github。2.mybatis快速入门目标:使用Mybatis查询所有用户数据(1)准备工......
  • 由 Mybatis 源码畅谈软件设计(四):动态 SQL 执行流程
    作者:京东保险王奕龙本节我们探究动态SQL的执行流程,由于在前一节我们已经对各个组件进行了详细介绍,所以本节不再赘述相关内容,在本节中主要强调静态SQL和动态SQL执行的不同之处。在这个过程中,SqlNode相关实现值得关注,它为动态SQL标签都定义了专用实现类,遵循单一职责的原......
  • C# EPPlus 导出excel
    C#Winform 中DataGridView数据集通过EPPlus导出excel到本地 ///<summary>///查询数据导出///</summary>///<paramname="sender"></param>///<paramname="e"></param>privatevoidbtnGridExport_Click(objectsender,Event......
  • Android 兼容 Java 8 语法特性的原理分析4
       本文主要阐述了Lambda表达式及其底层实现(invokedynamic指令)的原理、Android第三方插件RetroLambda对其的支持过程、Android官方最新的dex编译器D8对其的编译支持。通过对这三个方面的跟踪分析,以Java8的代表性特性——Lambda表达式为着眼点,将Android如何兼容Java8的过程......
  • 【MyBatis 核心工作机制】注解式开发与动态代理原理
    有很多朋友可能已经在开发中熟练使用MyBatis 或者刚开始学习MyBatis,对于它的一些工作机制不太了解。“咦,怎么写几个注解,写几个配置文件,就能实现这些效果呢,好神奇呀!”当你看完这篇博客之后,你会不经赞叹MyBatis框架设计者的巧妙,并且会帮助你理解这个工作机制。还是先大......
  • 使用数组语法访问对象
    //定义一个名为FakeArray的类,它实现了ArrayAccess接口classFakeArrayimplementsArrayAccess{//定义一个私有属性elements,用于存储数组元素private$elements;//构造函数,初始化elements属性为一个空数组publicfunction__construct(){$this->elements=array();......
  • 【Mybatis歌剧院】开发人员常用的操作数据库效率贼快的框架——Mybatis, 工作常用,面试
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......