在 MyBatis-Plus 中使用 IN 语法


在 MyBatis-Plus 中使用 IN 语法

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

1. 使用 QueryWrapper​ 的 in​ 方法

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

1
2
3
4
5
6
7
8
9
10
11
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 输出:

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

2. 使用 LambdaQueryWrapper​ 的 in​ 方法

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

1
2
3
4
5
6
7
8
9
10
11
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 输出:

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

3. 使用 XML 映射文件

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

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

运行 HTML

Java 代码:

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

SQL 输出:

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

4. 使用注解方式

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

1
2
3
4
5
6
7
8
9
10
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 语法错误。可以通过以下方式处理:

1
2
3
4
5
6
7
8
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 查询。

1
2
3
4
5
6
7
8
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 ()​。

1
2
3
4
5
6
7
8
9
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:

1
SELECT * FROM user WHERE 1 = 0;

优点:

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

缺点:

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

3. 使用 Optional处理空值

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

1
2
3
4
5
6
7
8
9
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​ 方法的空列表问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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​ 子句,避免空列表问题。

1
2
3
4
5
6
7
8
9
10
11
12
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:

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

优点:

  • 灵活控制 SQL 生成。

缺点:

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

总结

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

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


文章作者: Damonny
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Damonny !
 上一篇
SpringBoot引入本地Jar包 SpringBoot引入本地Jar包
本文介绍了在SpringBoot项目中引入本地Jar包的两种方法。方法一是直接在项目中引用:创建*src/main/resources/lib*目录并放入Jar包,然后在*pom.xml*中添加依赖配置,使用`system`并指定``路径,
下一篇 
Java List 分片工具类 Java List 分片工具类
本文介绍了如何使用Java将一个大List分片为多个小List,每个小List的大小为50。通过`subList`方法实现分片,具体步骤包括:确定原List大小、使用循环分组、获取子列表并复制到新ArrayList、处理边界情况等。代码示例
  目录