SimpleQuery.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. package com.baomidou.mybatisplus.extension.toolkit;
  2. import java.util.Collections;
  3. import java.util.EnumSet;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Optional;
  8. import java.util.Set;
  9. import java.util.function.BiConsumer;
  10. import java.util.function.BinaryOperator;
  11. import java.util.function.Consumer;
  12. import java.util.function.Function;
  13. import java.util.function.Supplier;
  14. import java.util.stream.Collector;
  15. import java.util.stream.Collectors;
  16. import java.util.stream.Stream;
  17. import java.util.stream.StreamSupport;
  18. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  19. import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
  20. import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
  21. import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
  22. /**
  23. * simple-query 让简单的查询更简单
  24. *
  25. * @author VampireAchao
  26. * @since 2021/11/9 18:27
  27. */
  28. public class SimpleQuery {
  29. private SimpleQuery() {
  30. /* Do not new me! */
  31. }
  32. /**
  33. * 通过lambda获取Class
  34. *
  35. * @param sFunction 可序列化的lambda
  36. * @param <E> Class类型
  37. * @return 对应的Class
  38. */
  39. @SuppressWarnings("unchecked")
  40. public static <E> Class<E> getType(SFunction<E, ?> sFunction) {
  41. return (Class<E>) LambdaUtils.extract(sFunction).getInstantiatedClass();
  42. }
  43. /**
  44. * ignore
  45. */
  46. @SafeVarargs
  47. public static <E, A> Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks) {
  48. return list2Map(selectList(getType(sFunction), wrapper), sFunction, Function.identity(), peeks);
  49. }
  50. /**
  51. * 传入Wrappers和key,从数据库中根据条件查询出对应的列表,封装成Map
  52. *
  53. * @param wrapper 条件构造器
  54. * @param sFunction key
  55. * @param isParallel 是否并行流
  56. * @param peeks 封装成map时可能需要的后续操作,不需要可以不传
  57. * @param <E> 实体类型
  58. * @param <A> 实体中的属性类型
  59. * @return Map<实体中的属性, 实体>
  60. */
  61. @SafeVarargs
  62. public static <E, A> Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks) {
  63. return list2Map(selectList(getType(sFunction), wrapper), sFunction, Function.identity(), isParallel, peeks);
  64. }
  65. /**
  66. * ignore
  67. */
  68. @SafeVarargs
  69. public static <E, A, P> Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, Consumer<E>... peeks) {
  70. return list2Map(selectList(getType(keyFunc), wrapper), keyFunc, valueFunc, peeks);
  71. }
  72. /**
  73. * 传入Wrappers和key,从数据库中根据条件查询出对应的列表,封装成Map
  74. *
  75. * @param wrapper 条件构造器
  76. * @param keyFunc key
  77. * @param valueFunc value
  78. * @param isParallel 是否并行流
  79. * @param peeks 封装成map时可能需要的后续操作,不需要可以不传
  80. * @param <E> 实体类型
  81. * @param <A> 实体中的属性类型
  82. * @param <P> 实体中的属性类型
  83. * @return Map<实体中的属性, 实体>
  84. */
  85. @SafeVarargs
  86. public static <E, A, P> Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, boolean isParallel, Consumer<E>... peeks) {
  87. return list2Map(selectList(getType(keyFunc), wrapper), keyFunc, valueFunc, isParallel, peeks);
  88. }
  89. /**
  90. * ignore
  91. */
  92. @SafeVarargs
  93. public static <E, A> Map<A, List<E>> group(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks) {
  94. return listGroupBy(selectList(getType(sFunction), wrapper), sFunction, peeks);
  95. }
  96. /**
  97. * ignore
  98. */
  99. @SafeVarargs
  100. public static <T, K> Map<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, boolean isParallel, Consumer<T>... peeks) {
  101. return listGroupBy(selectList(getType(sFunction), wrapper), sFunction, isParallel, peeks);
  102. }
  103. /**
  104. * ignore
  105. */
  106. @SafeVarargs
  107. public static <T, K, D, A> Map<K, D> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<T, A, D> downstream, Consumer<T>... peeks) {
  108. return listGroupBy(selectList(getType(sFunction), wrapper), sFunction, downstream, false, peeks);
  109. }
  110. /**
  111. * 传入Wrappers和key,从数据库中根据条件查询出对应的列表,封装成Map
  112. *
  113. * @param wrapper 条件构造器
  114. * @param sFunction 分组依据
  115. * @param downstream 下游操作
  116. * @param isParallel 是否并行流
  117. * @param peeks 后续操作
  118. * @param <T> 实体类型
  119. * @param <K> 实体中的分组依据对应类型,也是Map中key的类型
  120. * @param <D> 下游操作对应返回类型,也是Map中value的类型
  121. * @param <A> 下游操作在进行中间操作时对应类型
  122. * @return Map<实体中的属性, List < 实体>>
  123. */
  124. @SafeVarargs
  125. public static <T, K, D, A> Map<K, D> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<T, A, D> downstream, boolean isParallel, Consumer<T>... peeks) {
  126. return listGroupBy(selectList(getType(sFunction), wrapper), sFunction, downstream, isParallel, peeks);
  127. }
  128. /**
  129. * ignore
  130. */
  131. @SafeVarargs
  132. public static <E, A> List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks) {
  133. return list2List(selectList(getType(sFunction), wrapper), sFunction, peeks);
  134. }
  135. /**
  136. * 传入wrappers和需要的某一列,从数据中根据条件查询出对应的列,转换成list
  137. *
  138. * @param wrapper 条件构造器
  139. * @param sFunction 需要的列
  140. * @param isParallel 是否并行流
  141. * @param peeks 后续操作
  142. * @return java.util.List<A>
  143. * @since 2021/11/9 17:59
  144. */
  145. @SafeVarargs
  146. public static <E, A> List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks) {
  147. return list2List(selectList(getType(sFunction), wrapper), sFunction, isParallel, peeks);
  148. }
  149. /**
  150. * ignore
  151. */
  152. @SafeVarargs
  153. public static <A, E> List<A> list2List(List<E> list, SFunction<E, A> sFunction, Consumer<E>... peeks) {
  154. return list2List(list, sFunction, false, peeks);
  155. }
  156. /**
  157. * 对list进行map、peek操作
  158. *
  159. * @param list 数据
  160. * @param sFunction 需要的列
  161. * @param isParallel 是否并行流
  162. * @param peeks 后续操作
  163. * @return java.util.List<A>
  164. * @since 2021/11/9 18:01
  165. */
  166. @SafeVarargs
  167. public static <A, E> List<A> list2List(List<E> list, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks) {
  168. return peekStream(list, isParallel, peeks).map(sFunction).collect(Collectors.toList());
  169. }
  170. /**
  171. * ignore
  172. */
  173. @SafeVarargs
  174. public static <K, T> Map<K, List<T>> listGroupBy(List<T> list, SFunction<T, K> sFunction, Consumer<T>... peeks) {
  175. return listGroupBy(list, sFunction, false, peeks);
  176. }
  177. /**
  178. * ignore
  179. */
  180. @SafeVarargs
  181. public static <K, T> Map<K, List<T>> listGroupBy(List<T> list, SFunction<T, K> sFunction, boolean isParallel, Consumer<T>... peeks) {
  182. return listGroupBy(list, sFunction, Collectors.toList(), isParallel, peeks);
  183. }
  184. /**
  185. * ignore
  186. */
  187. @SafeVarargs
  188. public static <T, K, D, A> Map<K, D> listGroupBy(List<T> list, SFunction<T, K> sFunction, Collector<T, A, D> downstream, Consumer<T>... peeks) {
  189. return listGroupBy(list, sFunction, downstream, false, peeks);
  190. }
  191. /**
  192. * 对list进行groupBy操作
  193. *
  194. * @param list 数据
  195. * @param sFunction 分组的key,依据
  196. * @param downstream 下游操作
  197. * @param isParallel 是否并行流
  198. * @param peeks 封装成map时可能需要的后续操作,不需要可以不传
  199. * @param <T> 实体类型
  200. * @param <K> 实体中的分组依据对应类型,也是Map中key的类型
  201. * @param <D> 下游操作对应返回类型,也是Map中value的类型
  202. * @param <A> 下游操作在进行中间操作时对应类型
  203. * @return Map<实体中的属性, List < 实体>>
  204. */
  205. @SafeVarargs
  206. @SuppressWarnings("unchecked")
  207. public static <T, K, D, A> Map<K, D> listGroupBy(List<T> list, SFunction<T, K> sFunction, Collector<T, A, D> downstream, boolean isParallel, Consumer<T>... peeks) {
  208. boolean hasFinished = downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH);
  209. return peekStream(list, isParallel, peeks).collect(new Collector<T, HashMap<K, A>, Map<K, D>>() {
  210. @Override
  211. public Supplier<HashMap<K, A>> supplier() {
  212. return HashMap::new;
  213. }
  214. @Override
  215. public BiConsumer<HashMap<K, A>, T> accumulator() {
  216. return (m, t) -> {
  217. // 只此一处,和原版groupingBy修改只此一处,成功在支持下游操作的情况下支持null值
  218. K key = Optional.ofNullable(t).map(sFunction).orElse(null);
  219. A container = m.computeIfAbsent(key, k -> downstream.supplier().get());
  220. downstream.accumulator().accept(container, t);
  221. };
  222. }
  223. @Override
  224. public BinaryOperator<HashMap<K, A>> combiner() {
  225. return (m1, m2) -> {
  226. for (Map.Entry<K, A> e : m2.entrySet()) {
  227. m1.merge(e.getKey(), e.getValue(), downstream.combiner());
  228. }
  229. return m1;
  230. };
  231. }
  232. @Override
  233. public Function<HashMap<K, A>, Map<K, D>> finisher() {
  234. return hasFinished ? i -> (Map<K, D>) i : intermediate -> {
  235. intermediate.replaceAll((k, v) -> (A) downstream.finisher().apply(v));
  236. @SuppressWarnings("unchecked")
  237. Map<K, D> castResult = (Map<K, D>) intermediate;
  238. return castResult;
  239. };
  240. }
  241. @Override
  242. public Set<Characteristics> characteristics() {
  243. return hasFinished ? Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH)) : Collections.emptySet();
  244. }
  245. });
  246. }
  247. /**
  248. * ignore
  249. */
  250. @SafeVarargs
  251. public static <E, A, P> Map<A, P> list2Map(List<E> list, SFunction<E, A> keyFunc, Function<E, P> valueFunc, Consumer<E>... peeks) {
  252. return list2Map(list, keyFunc, valueFunc, false, peeks);
  253. }
  254. /**
  255. * list转换为map
  256. *
  257. * @param <E> 实体类型
  258. * @param <A> 实体中的属性类型
  259. * @param <P> 实体中的属性类型
  260. * @param list 数据
  261. * @param keyFunc key
  262. * @param isParallel 是否并行流
  263. * @param peeks 封装成map时可能需要的后续操作,不需要可以不传
  264. * @return Map<实体中的属性, 实体>
  265. */
  266. @SafeVarargs
  267. public static <E, A, P> Map<A, P> list2Map(List<E> list, SFunction<E, A> keyFunc, Function<E, P> valueFunc, boolean isParallel, Consumer<E>... peeks) {
  268. return peekStream(list, isParallel, peeks).collect(HashMap::new, (m, v) -> m.put(keyFunc.apply(v), valueFunc.apply(v)), HashMap::putAll);
  269. }
  270. /**
  271. * 将list转为Stream流,然后再叠加peek操作
  272. *
  273. * @param list 数据
  274. * @param isParallel 是否并行流
  275. * @param peeks 叠加的peek操作
  276. * @param <E> 数据元素类型
  277. * @return 转换后的流
  278. */
  279. @SafeVarargs
  280. public static <E> Stream<E> peekStream(List<E> list, boolean isParallel, Consumer<E>... peeks) {
  281. if (CollectionUtils.isEmpty(list)) {
  282. return Stream.empty();
  283. }
  284. return Stream.of(peeks).reduce(StreamSupport.stream(list.spliterator(), isParallel), Stream::peek, Stream::concat);
  285. }
  286. /**
  287. * 通过entityClass查询列表,并关闭sqlSession
  288. *
  289. * @param entityClass 表对应实体
  290. * @param wrapper 条件构造器
  291. * @param <E> 实体类型
  292. * @return 查询列表结果
  293. */
  294. public static <E> List<E> selectList(Class<E> entityClass, LambdaQueryWrapper<E> wrapper) {
  295. return SqlHelper.execute(entityClass, m -> m.selectList(wrapper));
  296. }
  297. }