com.baomidou.mybatisplus.extension.toolkit.SimpleQuery Maven / Gradle / Ivy
package com.baomidou.mybatisplus.extension.toolkit;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionUtils;
import java.util.*;
import java.util.function.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* simple-query 让简单的查询更简单
*
* @author VampireAchao
* @since 2021/11/9 18:27
*/
public class SimpleQuery {
private SimpleQuery() {
/* Do not new me! */
}
/**
* 通过lambda获取Class
*
* @param sFunction 可序列化的lambda
* @param Class类型
* @return 对应的Class
*/
@SuppressWarnings("unchecked")
public static Class getType(SFunction sFunction) {
return (Class) LambdaUtils.extract(sFunction).getInstantiatedClass();
}
/**
* ignore
*/
@SafeVarargs
public static Map keyMap(LambdaQueryWrapper wrapper, SFunction sFunction, Consumer... peeks) {
return list2Map(selectList(getType(sFunction), wrapper), sFunction, Function.identity(), peeks);
}
/**
* 传入Wrappers和key,从数据库中根据条件查询出对应的列表,封装成Map
*
* @param wrapper 条件构造器
* @param sFunction key
* @param isParallel 是否并行流
* @param peeks 封装成map时可能需要的后续操作,不需要可以不传
* @param 实体类型
* @param 实体中的属性类型
* @return Map<实体中的属性, 实体>
*/
@SafeVarargs
public static Map keyMap(LambdaQueryWrapper wrapper, SFunction sFunction, boolean isParallel, Consumer... peeks) {
return list2Map(selectList(getType(sFunction), wrapper), sFunction, Function.identity(), isParallel, peeks);
}
/**
* ignore
*/
@SafeVarargs
public static Map map(LambdaQueryWrapper wrapper, SFunction keyFunc, SFunction valueFunc, Consumer... peeks) {
return list2Map(selectList(getType(keyFunc), wrapper), keyFunc, valueFunc, peeks);
}
/**
* 传入Wrappers和key,从数据库中根据条件查询出对应的列表,封装成Map
*
* @param wrapper 条件构造器
* @param keyFunc key
* @param valueFunc value
* @param isParallel 是否并行流
* @param peeks 封装成map时可能需要的后续操作,不需要可以不传
* @param 实体类型
* @param 实体中的属性类型
* @param 实体中的属性类型
* @return Map<实体中的属性, 实体>
*/
@SafeVarargs
public static Map map(LambdaQueryWrapper wrapper, SFunction keyFunc, SFunction valueFunc, boolean isParallel, Consumer... peeks) {
return list2Map(selectList(getType(keyFunc), wrapper), keyFunc, valueFunc, isParallel, peeks);
}
/**
* ignore
*/
@SafeVarargs
public static Map> group(LambdaQueryWrapper wrapper, SFunction sFunction, Consumer... peeks) {
return listGroupBy(selectList(getType(sFunction), wrapper), sFunction, peeks);
}
/**
* ignore
*/
@SafeVarargs
public static Map> group(LambdaQueryWrapper wrapper, SFunction sFunction, boolean isParallel, Consumer... peeks) {
return listGroupBy(selectList(getType(sFunction), wrapper), sFunction, isParallel, peeks);
}
/**
* ignore
*/
@SafeVarargs
public static > M group(LambdaQueryWrapper wrapper, SFunction sFunction, Collector super T, A, D> downstream, Consumer... peeks) {
return listGroupBy(selectList(getType(sFunction), wrapper), sFunction, downstream, false, peeks);
}
/**
* 传入Wrappers和key,从数据库中根据条件查询出对应的列表,封装成Map
*
* @param wrapper 条件构造器
* @param sFunction 分组依据
* @param downstream 下游操作
* @param isParallel 是否并行流
* @param peeks 后续操作
* @param 实体类型
* @param 实体中的分组依据对应类型,也是Map中key的类型
* @param 下游操作对应返回类型,也是Map中value的类型
* @param 下游操作在进行中间操作时对应类型
* @param 最后返回结果Map类型
* @return Map<实体中的属性, List < 实体>>
*/
@SafeVarargs
public static > M group(LambdaQueryWrapper wrapper, SFunction sFunction, Collector super T, A, D> downstream, boolean isParallel, Consumer... peeks) {
return listGroupBy(selectList(getType(sFunction), wrapper), sFunction, downstream, isParallel, peeks);
}
/**
* ignore
*/
@SafeVarargs
public static List list(LambdaQueryWrapper wrapper, SFunction sFunction, Consumer... peeks) {
return list2List(selectList(getType(sFunction), wrapper), sFunction, peeks);
}
/**
* 传入wrappers和需要的某一列,从数据中根据条件查询出对应的列,转换成list
*
* @param wrapper 条件构造器
* @param sFunction 需要的列
* @param isParallel 是否并行流
* @param peeks 后续操作
* @return java.util.List
* @since 2021/11/9 17:59
*/
@SafeVarargs
public static List list(LambdaQueryWrapper wrapper, SFunction sFunction, boolean isParallel, Consumer... peeks) {
return list2List(selectList(getType(sFunction), wrapper), sFunction, isParallel, peeks);
}
/**
* ignore
*/
@SafeVarargs
public static List list2List(List list, SFunction sFunction, Consumer... peeks) {
return list2List(list, sFunction, false, peeks);
}
/**
* 对list进行map、peek操作
*
* @param list 数据
* @param sFunction 需要的列
* @param isParallel 是否并行流
* @param peeks 后续操作
* @return java.util.List
* @since 2021/11/9 18:01
*/
@SafeVarargs
public static List list2List(List list, SFunction sFunction, boolean isParallel, Consumer... peeks) {
return peekStream(list, isParallel, peeks).map(sFunction).collect(Collectors.toList());
}
/**
* ignore
*/
@SafeVarargs
public static Map> listGroupBy(List list, SFunction sFunction, Consumer... peeks) {
return listGroupBy(list, sFunction, false, peeks);
}
/**
* ignore
*/
@SafeVarargs
public static Map> listGroupBy(List list, SFunction sFunction, boolean isParallel, Consumer... peeks) {
return listGroupBy(list, sFunction, Collectors.toList(), isParallel, peeks);
}
/**
* ignore
*/
@SafeVarargs
public static > M listGroupBy(List list, SFunction sFunction, Collector super T, A, D> downstream, Consumer... peeks) {
return listGroupBy(list, sFunction, downstream, false, peeks);
}
/**
* 对list进行groupBy操作
*
* @param list 数据
* @param sFunction 分组的key,依据
* @param downstream 下游操作
* @param isParallel 是否并行流
* @param peeks 封装成map时可能需要的后续操作,不需要可以不传
* @param 实体类型
* @param 实体中的分组依据对应类型,也是Map中key的类型
* @param 下游操作对应返回类型,也是Map中value的类型
* @param 下游操作在进行中间操作时对应类型
* @param 最后返回结果Map类型
* @return Map<实体中的属性, List < 实体>>
*/
@SafeVarargs
@SuppressWarnings("unchecked")
public static > M listGroupBy(List list, SFunction sFunction, Collector super T, A, D> downstream, boolean isParallel, Consumer... peeks) {
boolean hasFinished = downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH);
return peekStream(list, isParallel, peeks).collect(new Collector, M>() {
@Override
public Supplier> supplier() {
return HashMap::new;
}
@Override
public BiConsumer, T> accumulator() {
return (m, t) -> {
// 只此一处,和原版groupingBy修改只此一处,成功在支持下游操作的情况下支持null值
K key = Optional.ofNullable(t).map(sFunction).orElse(null);
A container = m.computeIfAbsent(key, k -> downstream.supplier().get());
downstream.accumulator().accept(container, t);
};
}
@Override
public BinaryOperator> combiner() {
return (m1, m2) -> {
for (Map.Entry e : m2.entrySet()) {
m1.merge(e.getKey(), e.getValue(), downstream.combiner());
}
return m1;
};
}
@Override
public Function, M> finisher() {
return hasFinished ? i -> (M) i : intermediate -> {
intermediate.replaceAll((k, v) -> (A) downstream.finisher().apply(v));
@SuppressWarnings("unchecked")
M castResult = (M) intermediate;
return castResult;
};
}
@Override
public Set characteristics() {
return hasFinished ? Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH)) : Collections.emptySet();
}
});
}
/**
* ignore
*/
@SafeVarargs
public static Map list2Map(List list, SFunction keyFunc, Function valueFunc, Consumer... peeks) {
return list2Map(list, keyFunc, valueFunc, false, peeks);
}
/**
* list转换为map
*
* @param 实体类型
* @param 实体中的属性类型
* @param 实体中的属性类型
* @param list 数据
* @param keyFunc key
* @param isParallel 是否并行流
* @param peeks 封装成map时可能需要的后续操作,不需要可以不传
* @return Map<实体中的属性, 实体>
*/
@SafeVarargs
public static Map list2Map(List list, SFunction keyFunc, Function valueFunc, boolean isParallel, Consumer... peeks) {
return peekStream(list, isParallel, peeks).collect(HashMap::new, (m, v) -> m.put(keyFunc.apply(v), valueFunc.apply(v)), HashMap::putAll);
}
/**
* 将list转为Stream流,然后再叠加peek操作
*
* @param list 数据
* @param isParallel 是否并行流
* @param peeks 叠加的peek操作
* @param 数据元素类型
* @return 转换后的流
*/
@SafeVarargs
public static Stream peekStream(List list, boolean isParallel, Consumer... peeks) {
if (CollectionUtils.isEmpty(list)) {
return Stream.empty();
}
return Stream.of(peeks).reduce(StreamSupport.stream(list.spliterator(), isParallel), Stream::peek, Stream::concat);
}
/**
* 通过entityClass查询列表,并关闭sqlSession
*
* @param entityClass 表对应实体
* @param wrapper 条件构造器
* @param 实体类型
* @return 查询列表结果
*/
public static List selectList(Class entityClass, LambdaQueryWrapper wrapper) {
SqlSession sqlSession = SqlHelper.sqlSession(entityClass);
List result;
try {
BaseMapper userMapper = SqlHelper.getMapper(entityClass, sqlSession);
result = userMapper.selectList(wrapper);
} finally {
SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(entityClass));
}
return result;
}
}