content: package com.admin4j.framework.mp.service.impl;
  
  import com.admin4j.framework.mp.service.IQueryService;
  import com.baomidou.mybatisplus.core.conditions.Wrapper;
  import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  import com.baomidou.mybatisplus.core.metadata.IPage;
  import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
  
  import java.io.Serializable;
  import java.util.Collection;
  import java.util.List;
  import java.util.Map;
  import java.util.Objects;
  import java.util.function.Function;
  import java.util.stream.Collectors;
  
  /**
   * 复杂的业务查询
   *
   * @author andanyang
   * @since 2023/8/17 11:04
   */
  public class QueryServiceImpl<M extends BaseMapper<T>, T> extends BaseServiceImpl<M, T> implements IQueryService<T> {
  
      /**
       * 普通查询
       *
       * @return QueryWrapper 的包装类
       */
      protected QueryWrapper<T> query() {
          return Wrappers.query();
      }
  
      /**
       * 普通查询
       *
       * @return QueryWrapper 的包装类
       */
      protected QueryWrapper<T> query(T entity) {
          return Wrappers.query(entity);
      }
  
      /**
       * 链式查询 lambda 式
       * <p>注意：不支持 Kotlin </p>
       *
       * @return LambdaQueryWrapper 的包装类
       */
      protected LambdaQueryWrapper<T> lambdaQuery() {
          return Wrappers.lambdaQuery();
      }
  
      /**
       * 链式查询 lambda 式
       * <p>注意：不支持 Kotlin </p>
       *
       * @param entity 实体对象
       * @return LambdaQueryWrapper 的包装类
       */
      protected LambdaQueryWrapper<T> lambdaQuery(T entity) {
          return Wrappers.lambdaQuery(entity);
      }
  
  
      /**
       * 根据 Wrapper，查询一条记录 <br/>
       * <p>结果集，如果是多个会抛出异常，随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
       *
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       */
      public T getOne(Wrapper<T> queryWrapper) {
          return getOne(queryWrapper, true);
      }
  
  
      /**
       * 根据 ID 查询
       *
       * @param id 主键ID
       */
      public T getById(Serializable id) {
          return getBaseMapper().selectById(id);
      }
  
      /**
       * 根据 Wrapper，查询一条记录
       *
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       * @param throwEx      有多个 result 是否抛出异常
       */
      public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
          if (throwEx) {
              return getBaseMapper().selectOne(queryWrapper);
          }
          return SqlHelper.getObject(log, getBaseMapper().selectList(queryWrapper));
      }
  
      /**
       * 根据 Wrapper，查询一条记录
       *
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       */
      public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
          return SqlHelper.getObject(log, getBaseMapper().selectMaps(queryWrapper));
      }
  
      /**
       * 根据 Wrapper，查询一条记录
       *
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       * @param mapper       转换函数
       */
      public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
          return SqlHelper.getObject(log, listObjs(queryWrapper, mapper));
      }
  
      /**
       * 查询总记录数
       *
       * @see Wrappers#emptyWrapper()
       */
      public long count() {
          return count(Wrappers.emptyWrapper());
      }
  
      /**
       * 根据 Wrapper 条件，查询总记录数
       *
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       */
      public long count(Wrapper<T> queryWrapper) {
          return SqlHelper.retCount(getBaseMapper().selectCount(queryWrapper));
      }
  
  
      //---------------------------------------------------------------- list --------------------------------
  
      /**
       * 查询（根据ID 批量查询）
       *
       * @param idList 主键ID列表
       */
      public List<T> listByIds(Collection<? extends Serializable> idList) {
          return getBaseMapper().selectBatchIds(idList);
      }
  
      /**
       * 查询（根据 columnMap 条件）
       *
       * @param columnMap 表字段 map 对象
       */
      public List<T> listByMap(Map<String, Object> columnMap) {
          return getBaseMapper().selectByMap(columnMap);
      }
  
      /**
       * 查询列表
       *
       * @param entity 实体
       */
      @Override
      public List<T> list(T entity) {
          return getBaseMapper().selectList(Wrappers.query(entity));
      }
  
  
      /**
       * 查询列表
       *
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       */
      public List<T> list(Wrapper<T> queryWrapper) {
          return getBaseMapper().selectList(queryWrapper);
      }
  
      /**
       * 查询所有
       *
       * @see Wrappers#emptyWrapper()
       */
      public List<T> list() {
          return list(Wrappers.emptyWrapper());
      }
  
  
      /**
       * 查询列表
       *
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       */
      public List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper) {
          return getBaseMapper().selectMaps(queryWrapper);
      }
  
      /**
       * 查询所有列表
       *
       * @see Wrappers#emptyWrapper()
       */
      public List<Map<String, Object>> listMaps() {
          return listMaps(Wrappers.emptyWrapper());
      }
  
      /**
       * 查询全部记录
       */
      public List<Object> listObjs() {
          return listObjs(Function.identity());
      }
  
      /**
       * 查询全部记录
       *
       * @param mapper 转换函数
       */
      public <V> List<V> listObjs(Function<? super Object, V> mapper) {
          return listObjs(Wrappers.emptyWrapper(), mapper);
      }
  
      /**
       * 根据 Wrapper 条件，查询全部记录
       *
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       */
      public List<Object> listObjs(Wrapper<T> queryWrapper) {
          return listObjs(queryWrapper, Function.identity());
      }
  
      /**
       * 根据 Wrapper 条件，查询全部记录
       *
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       * @param mapper       转换函数
       */
      public <V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
          return getBaseMapper().selectObjs(queryWrapper).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());
      }
  
      //---------------------------------------------------------------- page ------------------------
  
      /**
       * 无条件翻页查询
       *
       * @param page 翻页对象
       * @see Wrappers#emptyWrapper()
       */
  
      public <E extends IPage<T>> E page(E page) {
          return page(page, Wrappers.emptyWrapper());
      }
  
      /**
       * 翻页查询
       *
       * @param page   翻页对象
       * @param entity 实体
       */
  
      public <E extends IPage<T>> E page(E page, T entity) {
          return page(page, Wrappers.query(entity));
      }
  
      /**
       * 翻页查询
       *
       * @param page         翻页对象
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       */
      public <E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper) {
          return getBaseMapper().selectPage(page, queryWrapper);
      }
  
  
      /**
       * 翻页查询
       *
       * @param page         翻页对象
       * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
       */
      public <E extends IPage<Map<String, Object>>> E pageMaps(E page, Wrapper<T> queryWrapper) {
          return getBaseMapper().selectMapsPage(page, queryWrapper);
      }
  
      /**
       * 无条件翻页查询
       *
       * @param page 翻页对象
       * @see Wrappers#emptyWrapper()
       */
      public <E extends IPage<Map<String, Object>>> E pageMaps(E page) {
          return pageMaps(page, Wrappers.emptyWrapper());
      }
  }
  