【第9章】MyBatis-Plus持久层接口之SimpleQuery

发布于:2024-07-01 ⋅ 阅读:(18) ⋅ 点赞:(0)


前言

SimpleQuery 是 Mybatis-Plus 提供的一个工具类,它对 selectList 查询后的结果进行了封装,使其可以通过 Stream 流的方式进行处理,从而简化了API的调用。

SimpleQuery 的一个特点是它的 peeks 参数,这是一个可变参数,类型为 Consumer…,意味着你可以连续添加多个操作,这些操作会在查询结果被处理时依次执行。

SimpleQuery 的使用方式可以参考官方测试用例

使用 SimpleQuery 前,需要确保项目中已注入对应实体的 BaseMapper。


一、使用步骤

1.引入 SimpleQuery 工具类

import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
import com.baomidou.mybatisplus.extension.toolkit.SimpleQuery;

新版SimpleQuery迁移至toolkit包路径下

2.使用 SimpleQuery 进行查询

// 假设有一个 User 实体类和对应的 BaseMapper
List<Long> ids = SimpleQuery.list(
    Wrappers.lambdaQuery(User.class), // 使用 lambda 查询构建器
    User::getId, // 提取的字段,这里是 User 的 id
    System.out::println, // 第一个 peek 操作,打印每个用户
    user -> userNames.add(user.getName()) // 第二个 peek 操作,将每个用户的名字添加到 userNames 列表中
);

二、使用提示

  • SimpleQuery 工具类提供了一种简洁的方式来处理查询结果,它允许你在查询结果上应用多个操作,这些操作会按照添加的顺序依次执行。
  • 在使用 SimpleQuery 时,你需要提供一个查询构建器(如 Wrappers.lambdaQuery()),一个用于提取结果的字段(如 User::getId),以及一个或多个 Consumer 类型的 peek 操作。
  • peek 操作可以用于执行任何副作用操作,如打印日志、更新缓存、发送通知等,而不会影响查询结果本身。
  • SimpleQuery 返回的结果是一个列表,包含了所有查询到的实体对象,这些对象已经应用了所有的 peek 操作。
  • 通过使用 SimpleQuery,你可以将查询和结果处理逻辑分离,使代码更加清晰和易于维护。

通过使用 SimpleQuery 工具类,开发者可以更加高效地处理查询结果,同时保持代码的简洁性和可读性。这种工具类尤其适合于需要对查询结果进行复杂处理的场景。

三、功能详解

1. keyMap

SimpleQuery 的 keyMap 方法提供了一种便捷的方式来查询数据库,并将查询结果封装成一个Map,其中实体的某个属性作为键(key),实体本身作为值(value)。这个方法还支持在处理查询结果时执行额外的副作用操作,如打印日志或更新缓存。

1.1 方法签名

// 查询表内记录,封装返回为 Map<属性,实体>
Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);

// 查询表内记录,封装返回为 Map<属性,实体>,考虑了并行流的情况
Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);

1.2 参数说明

类型 参数名 描述
E entity 实体对象类型,即查询结果的实体类型。
A attribute 实体属性类型,也是返回的 Map 中键(key)的类型。
LambdaQueryWrapper wrapper 支持 lambda 表达式的条件构造器,用于构建查询条件。
SFunction<E, A> sFunction 实体中属性的 getter 方法引用,用于确定 Map 中键(key)的值。
boolean isParallel 如果设置为 true,则底层使用并行流执行查询,可以提高处理大量数据时的效率。
Consumer… peeks 可变参数,用于指定在处理查询结果时执行的额外操作,如打印日志、更新缓存等。

1.3 使用示例

// 假设有一个 User 实体类和对应的 BaseMapper
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getStatus, "active"); // 查询状态为 "active" 的用户

// 使用 keyMap 方法查询并封装结果
Map<String, User> userMap = SimpleQuery.keyMap(
    queryWrapper, // 查询条件构造器
    User::getUsername, // 使用用户名作为键
    user -> System.out.println("Processing user: " + user.getUsername()) // 打印处理的用户名
);

// 遍历结果
for (Map.Entry<String, User> entry : userMap.entrySet()) {
    System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

1.4 使用提示

  • keyMap 方法适用于需要根据实体的某个属性快速查找实体的场景。
  • 通过 sFunction 参数,你可以指定任何实体属性作为 Map 的键,这使得查询结果的访问更加直观和高效。
  • peeks 参数允许你在处理查询结果时执行额外的副作用操作,这些操作不会影响最终的 Map 结果。
  • 当处理大量数据时,可以考虑将 isParallel 参数设置为 true 以启用并行流,从而提高查询效率。

通过使用 SimpleQuery 的 keyMap 方法,开发者可以更加高效地处理查询结果,并将其封装成易于使用的数据结构,同时还可以执行额外的副作用操作,使代码更加简洁和灵活。

2. map

SimpleQuery 的 map 方法提供了一种便捷的方式来查询数据库,并将查询结果封装成一个 Map,其中实体的某个属性作为键(key),另一个属性作为值(value)。这个方法还支持在处理查询结果时执行额外的副作用操作,如打印日志或更新缓存。

2.1 方法签名

// 查询表内记录,封装返回为 Map<属性,属性>
Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, Consumer<E>... peeks);

// 查询表内记录,封装返回为 Map<属性,属性>,考虑了并行流的情况
Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, boolean isParallel, Consumer<E>... peeks);

2.2 参数说明

类型 参数名 描述
E entity 实体对象类型,即查询结果的实体类型。
A attribute 实体属性类型,作为返回的 Map 中键(key)的类型。
P attribute 实体属性类型,作为返回的 Map 中值(value)的类型。
LambdaQueryWrapper wrapper 支持 lambda 表达式的条件构造器,用于构建查询条件。
SFunction<E, A> keyFunc 实体中属性的 getter 方法引用,用于确定 Map 中键(key)的值。
SFunction<E, P> valueFunc 实体中属性的 getter 方法引用,用于确定 Map 中值(value)的值。
boolean isParallel 如果设置为 true,则底层使用并行流执行查询,可以提高处理大量数据时的效率。
Consumer… peeks 可变参数,用于指定在处理查询结果时执行的额外操作,如打印日志、更新缓存等。

2.3 使用示例

// 假设有一个 User 实体类和对应的 BaseMapper
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getStatus, "active"); // 查询状态为 "active" 的用户

// 使用 map 方法查询并封装结果
Map<String, Integer> userMap = SimpleQuery.map(
    queryWrapper, // 查询条件构造器
    User::getUsername, // 使用用户名作为键
    User::getAge, // 使用年龄作为值
    user -> System.out.println("Processing user: " + user.getUsername()) // 打印处理的用户名
);

// 遍历结果
for (Map.Entry<String, Integer> entry : userMap.entrySet()) {
    System.out.println("Username: " + entry.getKey() + ", Age: " + entry.getValue());
}

2.4 使用提示

  • map 方法适用于需要根据实体的某个属性快速查找另一个属性的场景。
  • 通过 keyFuncvalueFunc 参数,你可以指定任何实体属性作为 Map 的键和值,这使得查询结果的访问更加直观和高效。
  • peeks 参数允许你在处理查询结果时执行额外的副作用操作,这些操作不会影响最终的 Map 结果。
  • 当处理大量数据时,可以考虑将 isParallel 参数设置为 true 以启用并行流,从而提高查询效率。

通过使用 SimpleQuery 的 map 方法,开发者可以更加高效地处理查询结果,并将其封装成易于使用的数据结构,同时还可以执行额外的副作用操作,使代码更加简洁和灵活。

3. group

SimpleQuery 的 group 方法提供了一种便捷的方式来查询数据库,并将查询结果按照实体的某个属性进行分组,封装成一个 Map。这个方法还支持在处理查询结果时执行额外的副作用操作,如打印日志或更新缓存。此外,它还允许你使用 Collector 对分组后的集合进行进一步的处理。

3.1 方法签名

// 查询表内记录,封装返回为 Map<属性,List<实体>>
Map<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Consumer<T>... peeks);

// 查询表内记录,封装返回为 Map<属性,List<实体>>,考虑了并行流的情况
Map<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, boolean isParallel, Consumer<T>... peeks);

// 查询表内记录,封装返回为 Map<属性,分组后对集合进行的下游收集器>
M group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, Consumer<T>... peeks);

// 查询表内记录,封装返回为 Map<属性,分组后对集合进行的下游收集器>,考虑了并行流的情况
M group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, boolean isParallel, Consumer<T>... peeks);

3.2 参数说明

类型 参数名 描述
T entity 实体对象类型,即查询结果的实体类型。
K attribute 实体属性类型,作为返回的 Map 中键(key)的类型。
D - 下游收集器返回类型,作为 Map 中值(value)的类型。
A - 下游操作中间类型,用于 Collector 的中间结果。
M - 最终结束返回的 Map<K, D> 类型。
LambdaQueryWrapper wrapper 支持 lambda 表达式的条件构造器,用于构建查询条件。
SFunction<T, K> sFunction 分组依据,实体中属性的 getter 方法引用,用于确定 Map 中键(key)的值。
Collector<T, A, D> downstream 下游收集器,用于对分组后的集合进行进一步的处理。
boolean isParallel 如果设置为 true,则底层使用并行流执行查询,可以提高处理大量数据时的效率。
Consumer… peeks 可变参数,用于指定在处理查询结果时执行的额外操作,如打印日志、更新缓存等。

3.3 使用示例

// 假设有一个 User 实体类和对应的 BaseMapper
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getStatus, "active"); // 查询状态为 "active" 的用户

// 使用 group 方法查询并封装结果,按照用户名分组
Map<String, List<User>> userGroup = SimpleQuery.group(
    queryWrapper, // 查询条件构造器
    User::getUsername, // 使用用户名作为分组键
    user -> System.out.println("Processing user: " + user.getUsername()) // 打印处理的用户名
);

// 遍历结果
for (Map.Entry<String, List<User>> entry : userGroup.entrySet()) {
    System.out.println("Username: " + entry.getKey());
    for (User user : entry.getValue()) {
        System.out.println(" - User: " + user);
    }
}

3.4 使用提示

  • group 方法适用于需要根据实体的某个属性对查询结果进行分组的场景。
  • 通过 sFunction 参数,你可以指定任何实体属性作为分组的依据,这使得查询结果的组织更加灵活。
  • downstream 参数允许你使用 Collector 对分组后的集合进行进一步的处理,如计数、求和、平均值等。
  • peeks 参数允许你在处理查询结果时执行额外的副作用操作,这些操作不会影响最终的 Map 结果。
  • 当处理大量数据时,可以考虑将 isParallel 参数设置为 true 以启用并行流,从而提高查询效率。

通过使用 SimpleQuery 的 group 方法,开发者可以更加高效地处理查询结果,并将其按照特定属性进行分组,同时还可以执行额外的副作用操作,使代码更加简洁和灵活。

4. list

SimpleQuery 的 list 方法提供了一种便捷的方式来查询数据库,并将查询结果封装成一个 List,其中列表的元素是实体的某个属性。这个方法还支持在处理查询结果时执行额外的副作用操作,如打印日志或更新缓存。

4.1 方法签名

// 查询表内记录,封装返回为 List<属性>
List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);

// 查询表内记录,封装返回为 List<属性>,考虑了并行流的情况
List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);

4.2 参数说明

类型 参数名 描述
E entity 实体对象类型,即查询结果的实体类型。
A attribute 实体属性类型,作为返回的 List 中元素的类型。
LambdaQueryWrapper wrapper 支持 lambda 表达式的条件构造器,用于构建查询条件。
SFunction<E, A> sFunction 实体中属性的 getter 方法引用,用于确定 List 中元素的值。
boolean isParallel 如果设置为 true,则底层使用并行流执行查询,可以提高处理大量数据时的效率。
Consumer… peeks 可变参数,用于指定在处理查询结果时执行的额外操作,如打印日志、更新缓存等。

4.3 使用示例

// 假设有一个 User 实体类和对应的 BaseMapper
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getStatus, "active"); // 查询状态为 "active" 的用户

// 使用 list 方法查询并封装结果,提取所有用户的用户名
List<String> userNames = SimpleQuery.list(
    queryWrapper, // 查询条件构造器
    User::getUsername, // 提取用户名作为列表元素
    user -> System.out.println("Processing user: " + user.getUsername()) // 打印处理的用户名
);

// 遍历结果
for (String username : userNames) {
    System.out.println("Username: " + username);
}

4.4 使用提示

  • list 方法适用于需要根据实体的某个属性快速获取一个列表的场景。
  • 通过 sFunction 参数,你可以指定任何实体属性作为 List的元素,这使得查询结果的访问更加直观和高效。
  • peeks 参数允许你在处理查询结果时执行额外的副作用操作,这些操作不会影响最终的 List 结果。
  • 当处理大量数据时,可以考虑将 isParallel 参数设置为 true 以启用并行流,从而提高查询效率。

通过使用 SimpleQuery 的 list 方法,开发者可以更加高效地处理查询结果,并将其封装成易于使用的数据结构,同时还可以执行额外的副作用操作,使代码更加简洁和灵活。


总结

回到顶部