From fc94326fddf76ae389cea7770f68fc00f17bfc80 Mon Sep 17 00:00:00 2001
From: geshanzsq <497301391@qq.com>
Date: Sun, 9 Jun 2024 21:03:18 +0800
Subject: [PATCH] =?UTF-8?q?feat(=E5=9F=BA=E7=A1=80=E6=A1=86=E6=9E=B6):=20?=
=?UTF-8?q?=E5=B0=81=E8=A3=85=20MyBatis=20Plus=EF=BC=9B=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?=20PageHelper=20=E5=88=86=E9=A1=B5=E6=8F=92=E4=BB=B6=EF=BC=9B?=
=?UTF-8?q?=E6=89=A9=E5=B1=95=20SuperService=E3=80=81SuperMapper?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
mogu_base/pom.xml | 7 +
.../mougblog/base/mapper/SuperMapper.java | 84 +++++-
.../base/mybatis/page/dto/PageDTO.java | 42 +++
.../base/mybatis/page/util/PageUtils.java | 54 ++++
.../mougblog/base/mybatis/page/vo/PageVO.java | 38 +++
.../base/mybatis/plugin/annotation/Query.java | 39 +++
.../plugin/constant/FieldConstant.java | 21 ++
.../base/mybatis/plugin/enums/QueryWay.java | 71 +++++
.../plugin/query/LambdaQueryWrapperPlus.java | 115 ++++++++
.../plugin/query/QueryWrapperPlus.java | 269 ++++++++++++++++++
.../base/mybatis/property/PageProperty.java | 36 +++
.../mybatis/reflect/GenericTypeUtils.java | 24 ++
.../mybatis/reflect/IGenericTypeResolver.java | 13 +
.../reflect/SpringReflectionHelper.java | 20 ++
.../base/mybatis/util/MybatisUtils.java | 48 ++++
.../mougblog/base/service/SuperService.java | 74 ++++-
.../base/serviceImpl/SuperServiceImpl.java | 17 ++
pom.xml | 1 +
18 files changed, 970 insertions(+), 3 deletions(-)
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/dto/PageDTO.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/util/PageUtils.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/vo/PageVO.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/annotation/Query.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/constant/FieldConstant.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/enums/QueryWay.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/query/LambdaQueryWrapperPlus.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/query/QueryWrapperPlus.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/property/PageProperty.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/GenericTypeUtils.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/IGenericTypeResolver.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/SpringReflectionHelper.java
create mode 100644 mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/util/MybatisUtils.java
diff --git a/mogu_base/pom.xml b/mogu_base/pom.xml
index 9ccdbf505..38fa608e7 100644
--- a/mogu_base/pom.xml
+++ b/mogu_base/pom.xml
@@ -29,6 +29,13 @@
${Hutool.version}
+
+
+ com.github.pagehelper
+ pagehelper-spring-boot-starter
+ ${pagehelper.version}
+
+
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mapper/SuperMapper.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mapper/SuperMapper.java
index 05d5f4205..b0f5accb0 100644
--- a/mogu_base/src/main/java/com/moxi/mougblog/base/mapper/SuperMapper.java
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mapper/SuperMapper.java
@@ -1,14 +1,94 @@
package com.moxi.mougblog.base.mapper;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.moxi.mougblog.base.mybatis.page.dto.PageDTO;
+import com.moxi.mougblog.base.mybatis.page.vo.PageVO;
+import com.moxi.mougblog.base.mybatis.plugin.query.QueryWrapperPlus;
+import com.moxi.mougblog.base.mybatis.reflect.GenericTypeUtils;
+import com.moxi.mougblog.base.mybatis.util.MybatisUtils;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
/**
- * mapper 父类,注意这个类不要让 mybatis-plus 扫描到!!
+ * mapper 父类,在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多功能。注意这个类不要让 mybatis-plus 扫描到!!
* @author 陌溪
* @date 2020年12月31日21:32:33
*/
public interface SuperMapper extends BaseMapper {
- // 这里可以放一些公共的方法
+ /**
+ * 查询分页
+ */
+ default PageVO selectPage(PageDTO pageDTO, @Param("ew") Wrapper queryWrapper) {
+ // MyBatis Plus 分页查询
+ IPage myBatisPage = MybatisUtils.buildPage(pageDTO);
+ selectPage(myBatisPage, queryWrapper);
+ // 转换返回值
+ return new PageVO<>(myBatisPage.getRecords(), myBatisPage.getTotal(), myBatisPage.getSize());
+ }
+
+ /**
+ * 查询分页
+ *
+ * @param d 实体类参数对接
+ * @param selectColumns 查询返回的列
+ */
+ default PageVO selectPage(D d, SFunction... selectColumns) {
+ // 构造分页,不能强制转 pageDTO,否则如果没有继承的话,会报错
+ PageDTO pageDTO = d instanceof PageDTO ? (PageDTO) d : null;
+ IPage myBatisPage = MybatisUtils.buildPage(pageDTO);
+ // 查询数据
+ selectPage(myBatisPage, buildQueryWrapper(d, selectColumns));
+ // 转换返回值
+ return new PageVO<>(myBatisPage.getRecords(), myBatisPage.getTotal(), myBatisPage.getSize());
+ }
+
+ /**
+ * 查询列表
+ *
+ * @param d 实体类参数对接
+ * @param selectColumns 查询返回的列
+ */
+ default List selectList(D d, SFunction... selectColumns) {
+ return selectList(buildQueryWrapper(d, selectColumns));
+ }
+
+ /**
+ * 查询单条
+ *
+ * @param d 实体类参数对接
+ */
+ default T selectOne(D d) {
+ return selectOne(buildQueryWrapper(d));
+ }
+
+ /**
+ * 查询总记录数
+ *
+ * @param d 实体类参数对接
+ */
+ default Long selectCount(D d) {
+ return selectCount(buildQueryWrapper(d)).longValue();
+ }
+
+ /**
+ * 构建 Wrapper 查询条件
+ *
+ * @param d DTO 实体参数对象
+ * @param selectColumns 查询返回的列
+ * @return 查询构造器
+ */
+ default QueryWrapperPlus buildQueryWrapper(D d, SFunction... selectColumns) {
+ Class>[] typeArguments = GenericTypeUtils.resolveTypeArguments(ClassUtils.getUserClass(this.getClass()), SuperMapper.class);
+ Class entityClass = null == typeArguments ? null : (Class) typeArguments[0];
+ return new QueryWrapperPlus().buildQueryWrapper(entityClass, d, selectColumns);
+ }
+
+
}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/dto/PageDTO.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/dto/PageDTO.java
new file mode 100644
index 000000000..63927fb53
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/dto/PageDTO.java
@@ -0,0 +1,42 @@
+package com.moxi.mougblog.base.mybatis.page.dto;
+import com.moxi.mougblog.base.mybatis.plugin.annotation.Query;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 分页对象
+ *
+ * @author geshanzsq
+ * @date 2022/3/27
+ */
+@Data
+public class PageDTO implements Serializable {
+
+ private static final Long serialVersionUID = 1L;
+
+ /**
+ * 每页显示记录数
+ */
+ @Query(ignore = true)
+ private Long pageSize;
+
+ /**
+ * 起始页
+ */
+ @Query(ignore = true)
+ private Long currentPage;
+
+ /**
+ * 排序列,多个用逗号分开
+ */
+ @Query(ignore = true)
+ private String orderColumn;
+
+ /**
+ * 排序类型(asc 或 desc),多个用逗号分开
+ */
+ @Query(ignore = true)
+ private String orderType;
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/util/PageUtils.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/util/PageUtils.java
new file mode 100644
index 000000000..322719a78
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/util/PageUtils.java
@@ -0,0 +1,54 @@
+package com.moxi.mougblog.base.mybatis.page.util;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.moxi.mougblog.base.mybatis.page.dto.PageDTO;
+import com.moxi.mougblog.base.mybatis.page.vo.PageVO;
+import com.moxi.mougblog.base.mybatis.property.PageProperty;
+
+import java.util.List;
+
+/**
+ * 分页工具类
+ *
+ * @author geshanzsq
+ * @date 2022/3/27
+ */
+public class PageUtils {
+
+ /**
+ * 开始分页
+ */
+ public static void startPage(PageDTO pageDTO) {
+ startPage(pageDTO.getCurrentPage(), pageDTO.getPageSize());
+ }
+
+ /**
+ * 开始分页
+ * @param pageNum 起始页
+ * @param pageSize 分页记录数
+ */
+ public static void startPage(Long pageNum, Long pageSize) {
+ if (pageNum == null) {
+ pageNum = 1L;
+ }
+ if (pageSize == null) {
+ pageSize = PageProperty.defaultPageSize;
+ }
+ // 如果超过最大分页数,则设置为最大分页数
+ if (pageSize > PageProperty.maxPageSize) {
+ pageSize = PageProperty.maxPageSize;
+ }
+ PageHelper.startPage(pageNum.intValue(), pageSize.intValue());
+ }
+
+
+ /**
+ * 获取分页信息
+ */
+ public static PageVO getPage(List list) {
+ PageInfo pageInfo = new PageInfo(list);
+ return new PageVO(list, pageInfo.getTotal(), pageInfo.getSize());
+ }
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/vo/PageVO.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/vo/PageVO.java
new file mode 100644
index 000000000..1bd98464a
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/page/vo/PageVO.java
@@ -0,0 +1,38 @@
+package com.moxi.mougblog.base.mybatis.page.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 分页对象
+ *
+ * @author geshanzsq
+ * @date 2022/3/27
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PageVO implements Serializable {
+
+ private static final Long serialVersionUID = 1L;
+
+ /**
+ * 数据列表
+ */
+ private List records;
+
+ /**
+ * 总记录数
+ */
+ private long total;
+
+ /**
+ * 每页显示记录数
+ */
+ private long size;
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/annotation/Query.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/annotation/Query.java
new file mode 100644
index 000000000..e5725b22e
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/annotation/Query.java
@@ -0,0 +1,39 @@
+package com.moxi.mougblog.base.mybatis.plugin.annotation;
+
+import com.moxi.mougblog.base.mybatis.plugin.enums.QueryWay;
+
+import java.lang.annotation.*;
+
+/**
+ * 查询注解
+ *
+ * @author geshanzsq
+ * @date 2022/11/4
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Query {
+
+ /**
+ * 查询方式,默认为相等
+ */
+ QueryWay value() default QueryWay.EQ;
+
+ /**
+ * 属性名,如果当前属性名与 PO 不一致,可指定 PO 的属性名
+ */
+ String fieldName() default "";
+
+ /**
+ * 是否忽略查询,如果当前属性不需要查询,则可设置为 true
+ */
+ boolean ignore() default false;
+
+ /**
+ * 是否空查询,当为空时,是否依旧查询,默认不需要查询
+ */
+ boolean empty() default false;
+
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/constant/FieldConstant.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/constant/FieldConstant.java
new file mode 100644
index 000000000..b5325dc83
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/constant/FieldConstant.java
@@ -0,0 +1,21 @@
+package com.moxi.mougblog.base.mybatis.plugin.constant;
+
+/**
+ * 字段常量
+ *
+ * @author geshanzsq
+ * @date 2022/8/7
+ */
+public class FieldConstant {
+
+ /**
+ * 排序列,多个用逗号分开
+ */
+ public static final String ORDER_COLUMN = "orderColumn";
+
+ /**
+ * 排序类型(asc 或 desc),多个用逗号分开
+ */
+ public static final String ORDER_TYPE = "orderType";
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/enums/QueryWay.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/enums/QueryWay.java
new file mode 100644
index 000000000..34c4a90fd
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/enums/QueryWay.java
@@ -0,0 +1,71 @@
+package com.moxi.mougblog.base.mybatis.plugin.enums;
+
+/**
+ * 查询方式枚举
+ *
+ * @author geshanzsq
+ * @date 2022/11/4
+ */
+public enum QueryWay {
+
+ /**
+ * 等于
+ */
+ EQ,
+
+ /**
+ * 不等于
+ */
+ NE,
+
+ /**
+ * 大于
+ */
+ GT,
+
+ /**
+ * 大于等于
+ */
+ GE,
+
+ /**
+ * 小于
+ */
+ LT,
+
+ /**
+ * 小于等于
+ */
+ LE,
+
+ /**
+ * 模糊
+ */
+ LIKE,
+
+ /**
+ * 不模糊
+ */
+ NOT_LIKE,
+
+ /**
+ * 左模糊
+ */
+ LIKE_LEFT,
+
+ /**
+ * 右模糊
+ */
+ LIKE_RIGHT,
+
+ /**
+ * 包含
+ */
+ IN,
+
+ /**
+ * 不包含
+ */
+ NOT_IN
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/query/LambdaQueryWrapperPlus.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/query/LambdaQueryWrapperPlus.java
new file mode 100644
index 000000000..7e0a76827
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/query/LambdaQueryWrapperPlus.java
@@ -0,0 +1,115 @@
+package com.moxi.mougblog.base.mybatis.plugin.query;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.moxi.mogublog.utils.StringUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collection;
+
+/**
+ * 扩展 LambdaQueryWrapper 类
+ * 添加 xxxIf 方法,当值不存在的时候,不要拼接条件
+ *
+ * @author geshanzsq
+ * @date 2022/3/27
+ */
+public class LambdaQueryWrapperPlus extends LambdaQueryWrapper {
+
+ /**
+ * 模糊查询
+ */
+ public LambdaQueryWrapperPlus likeIf(SFunction column, String value) {
+ return StringUtils.isBlank(value) ? this : like(column, value);
+ }
+
+ @Override
+ public LambdaQueryWrapperPlus like(SFunction column, Object value) {
+ return (LambdaQueryWrapperPlus) super.like(column, value);
+ }
+
+ /**
+ * 相等
+ */
+ public LambdaQueryWrapperPlus eqIf(SFunction column, Object value) {
+ return StringUtils.isNullBlank(value) ? this : eq(column, value);
+ }
+
+ @Override
+ public LambdaQueryWrapperPlus eq(SFunction column, Object value) {
+ return (LambdaQueryWrapperPlus) super.eq(column, value);
+ }
+
+ /**
+ * 包含
+ */
+ public LambdaQueryWrapperPlus inIf(SFunction column, Collection> values) {
+ return CollectionUtils.isEmpty(values) ? this : in(column, values);
+ }
+
+ @Override
+ public LambdaQueryWrapperPlus in(SFunction column, Collection> values) {
+ return (LambdaQueryWrapperPlus) super.in(column, values);
+ }
+
+ /**
+ * 不包含
+ */
+ public LambdaQueryWrapperPlus notInIf(SFunction column, Collection> values) {
+ return CollectionUtils.isEmpty(values) ? this : notIn(column, values);
+ }
+
+ @Override
+ public LambdaQueryWrapperPlus notIn(SFunction column, Collection> values) {
+ return (LambdaQueryWrapperPlus) super.notIn(column, values);
+ }
+
+ /**
+ * 小于
+ */
+ public LambdaQueryWrapperPlus ltIf(SFunction column, Object value) {
+ return StringUtils.isNullBlank(value) ? this : lt(column, value);
+ }
+
+ @Override
+ public LambdaQueryWrapperPlus lt(SFunction column, Object value) {
+ return (LambdaQueryWrapperPlus) super.lt(column, value);
+ }
+
+ /**
+ * 小于等于
+ */
+ public LambdaQueryWrapperPlus leIf(SFunction column, Object value) {
+ return StringUtils.isNullBlank(value) ? this : le(column, value);
+ }
+
+ @Override
+ public LambdaQueryWrapperPlus le(SFunction column, Object value) {
+ return (LambdaQueryWrapperPlus) super.le(column, value);
+ }
+
+ /**
+ * 大于
+ */
+ public LambdaQueryWrapperPlus gtIf(SFunction column, Object value) {
+ return StringUtils.isNullBlank(value) ? this : gt(column, value);
+ }
+
+ @Override
+ public LambdaQueryWrapperPlus gt(SFunction column, Object value) {
+ return (LambdaQueryWrapperPlus) super.gt(column, value);
+ }
+
+ /**
+ * 大于等于
+ */
+ public LambdaQueryWrapperPlus geIf(SFunction column, Object value) {
+ return StringUtils.isNullBlank(value) ? this : ge(column, value);
+ }
+
+ @Override
+ public LambdaQueryWrapperPlus ge(SFunction column, Object value) {
+ return (LambdaQueryWrapperPlus) super.ge(column, value);
+ }
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/query/QueryWrapperPlus.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/query/QueryWrapperPlus.java
new file mode 100644
index 000000000..2fab8c930
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/plugin/query/QueryWrapperPlus.java
@@ -0,0 +1,269 @@
+package com.moxi.mougblog.base.mybatis.plugin.query;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.enums.SqlKeyword;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
+import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
+import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.moxi.mogublog.utils.StringUtils;
+import com.moxi.mougblog.base.exception.exceptionType.QueryException;
+import com.moxi.mougblog.base.mybatis.plugin.annotation.Query;
+import com.moxi.mougblog.base.mybatis.plugin.constant.FieldConstant;
+import com.moxi.mougblog.base.mybatis.plugin.enums.QueryWay;
+import com.moxi.mougblog.base.result.ResultCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 扩展 QueryWrapper 类,提供更多功能
+ *
+ * @author geshanzsq
+ * @date 2022/11/4
+ */
+public class QueryWrapperPlus extends QueryWrapper {
+
+ private static final Logger log = LoggerFactory.getLogger(QueryWrapperPlus.class);
+
+ /**
+ * 排序字段分割标识
+ */
+ private static final String ORDER_BY_COLUMN_SPLIT = ",";
+
+ /**
+ * 构建 Wrapper 查询条件
+ *
+ * @param clazz PO 实体类
+ * @param d DTO 实体参数对象
+ * @param selectColumns 查询返回的列
+ * @return 查询构造器
+ */
+ public QueryWrapperPlus buildQueryWrapper(Class clazz, D d, SFunction... selectColumns) {
+ QueryWrapperPlus queryWrapper = new QueryWrapperPlus();
+ // 构建指定返回的列
+ queryWrapper.lambda().select(selectColumns);
+ if (d == null) {
+ return queryWrapper;
+ }
+
+ // 获取 T 属性和列名
+ TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
+ if (tableInfo == null) {
+ log.error("没有找到数据表对应的实体类,当前传入的 Clazz:{}", clazz);
+ throw new QueryException(ResultCode.FAILED.getMsg());
+ }
+
+ // T 属性和列名对应关系
+ Map propertyColumnMap = new HashMap<>(tableInfo.getFieldList().size());
+ tableInfo.getFieldList().forEach(table -> {
+ propertyColumnMap.put(table.getProperty(), table.getColumn());
+ });
+ // 主键不在 fieldList 里,需单独获取
+ if (StringUtils.isNotBlank(tableInfo.getKeyProperty())) {
+ propertyColumnMap.put(tableInfo.getKeyProperty(), tableInfo.getKeyColumn());
+ }
+
+ // 获取 d 属性
+ List fieldList = ReflectionKit.getFieldList(ClassUtils.getUserClass(d.getClass()));
+ for (Field field : fieldList) {
+ field.setAccessible(true);
+ // 获取查询注解
+ Query query = field.getAnnotation(Query.class);
+
+ // 获取查询属性名称
+ String fieldName = getQueryFieldName(query, field);
+ // 是否忽略查询
+ if (query != null && query.ignore()) {
+ continue;
+ }
+
+ // 校验查询属性是否在 T 实体类
+ verifyQueryFieldNameExist(fieldName, propertyColumnMap);
+
+ // 获取查询值
+ Object value = getFieldValue(field, d);
+
+ // 如果为空并且不需要空查询(默认不需要空查询),则跳过此属性查询
+ if (StringUtils.isNullBlank(value) && (query == null || !query.empty())) {
+ continue;
+ }
+
+ // 获取查询属性对应的列
+ String column = propertyColumnMap.get(fieldName);
+ // 构造查询条件
+ buildQueryCondition(queryWrapper, query, column, value);
+ }
+
+ buildOrderByCondition(queryWrapper, propertyColumnMap, fieldList, d);
+
+ return queryWrapper;
+ }
+
+ /**
+ * 获取查询属性名称
+ */
+ private String getQueryFieldName(Query query, Field field) {
+ return query != null && StringUtils.isNotBlank(query.fieldName()) ? query.fieldName() : field.getName();
+ }
+
+ /**
+ * 校验查询属性是否在 T 实体类
+ */
+ private void verifyQueryFieldNameExist(String fieldName, Map propertyColumnMap) {
+ if (!propertyColumnMap.containsKey(fieldName)) {
+ String message = StringUtils.format("查询条件字段:{fieldName} 不存在", fieldName);
+ throw new QueryException(message);
+ }
+ }
+
+ /**
+ * 获取属性值
+ */
+ private Object getFieldValue(Field field, D d) {
+ if (field == null) {
+ return null;
+ }
+ Object value = null;
+ try {
+ value = field.get(d);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ throw new QueryException(ResultCode.FAILED.getMsg());
+ }
+ return value;
+ }
+
+ /**
+ * 构建查询条件
+ *
+ * @param queryWrapper 查询构造器
+ * @param query 查询注解
+ * @param column 列名称
+ * @param value 值
+ */
+ private void buildQueryCondition(QueryWrapperPlus queryWrapper, Query query, String column, Object value) {
+ // 默认为相等
+ if (query == null || query.value() == null) {
+ queryWrapper.eq(column, value);
+ return;
+ }
+ // 查询方式
+ QueryWay queryWay = query.value();
+ switch (queryWay) {
+ case EQ: {
+ queryWrapper.eq(column, value);
+ break;
+ }
+ case NE: {
+ queryWrapper.ne(column, value);
+ break;
+ }
+ case GT: {
+ queryWrapper.gt(column, value);
+ break;
+ }
+ case GE: {
+ queryWrapper.ge(column, value);
+ break;
+ }
+ case LT: {
+ queryWrapper.lt(column, value);
+ break;
+ }
+ case LE: {
+ queryWrapper.le(column, value);
+ break;
+ }
+ case LIKE: {
+ queryWrapper.like(column, value);
+ break;
+ }
+ case NOT_LIKE: {
+ queryWrapper.notLike(column, value);
+ break;
+ }
+ case LIKE_LEFT: {
+ queryWrapper.likeLeft(column, value);
+ break;
+ }
+ case LIKE_RIGHT: {
+ queryWrapper.likeRight(column, value);
+ break;
+ }
+ case IN: {
+ if (value instanceof Collection) {
+ Collection coll = (Collection) value;
+ queryWrapper.in(column, coll);
+ } else {
+ queryWrapper.in(column, value);
+ }
+ break;
+ }
+ case NOT_IN: {
+ if (value instanceof Collection) {
+ Collection coll = (Collection) value;
+ queryWrapper.notIn(column, coll);
+ } else {
+ queryWrapper.notIn(column, value);
+ }
+ break;
+ }
+ default: {
+ queryWrapper.eq(column, value);
+ }
+ }
+ }
+
+ /**
+ * 构造排序
+ *
+ * @param queryWrapper 查询构造器
+ * @param propertyColumnMap T 属性和列名
+ * @param d 参数
+ * @param fieldList d 属性列表
+ */
+ private void buildOrderByCondition(QueryWrapperPlus queryWrapper, Map propertyColumnMap,
+ List fieldList, D d) {
+ // 排序列
+ Field orderColumnField = fieldList.stream().filter(f -> FieldConstant.ORDER_COLUMN.equals(f.getName())).findFirst().orElse(null);
+ // 如果排序字段为空,或者不是 String 类型,不进行排序
+ Object orderColumnObj = getFieldValue(orderColumnField, d);
+ if (!(orderColumnObj instanceof String) || StringUtils.isNullBlank(orderColumnObj)) {
+ return;
+ }
+
+ // 排序类型
+ Field orderTypeField = fieldList.stream().filter(f -> FieldConstant.ORDER_TYPE.equals(f.getName())).findFirst().orElse(null);
+ Object orderTypeObj = getFieldValue(orderTypeField, d);
+
+ String[] orderColumns = orderColumnObj.toString().split(ORDER_BY_COLUMN_SPLIT);
+ String[] orderTypes = orderTypeObj == null ? new String[] {} : orderTypeObj.toString().split(ORDER_BY_COLUMN_SPLIT);
+
+ // 构造排序
+ for (int i = 0; i < orderColumns.length; i++) {
+ String orderColumn = orderColumns[i];
+ if (StringUtils.isBlank(orderColumn)) {
+ continue;
+ }
+ // 校验排序字段是否存在
+ String column = propertyColumnMap.get(orderColumn);
+ if (StringUtils.isBlank(column)) {
+ String message = StringUtils.format("排序字段:{},不存在", orderColumn);
+ throw new QueryException(message);
+ }
+
+ // 是否升序排序
+ boolean isAsc = i < orderTypes.length ? SqlKeyword.ASC.getSqlSegment().equalsIgnoreCase(orderTypes[i]) : true;
+ queryWrapper.orderBy(true, isAsc, column);
+ }
+
+ }
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/property/PageProperty.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/property/PageProperty.java
new file mode 100644
index 000000000..f6b80b454
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/property/PageProperty.java
@@ -0,0 +1,36 @@
+package com.moxi.mougblog.base.mybatis.property;
+
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 分页配置
+ *
+ * @author geshanzsq
+ * @date 2022/3/27
+ */
+@Getter
+@Configuration
+public class PageProperty {
+
+ /**
+ * 默认分页记录数
+ */
+ public static Long defaultPageSize = 10L;
+
+ /**
+ * 最大分页记录数
+ */
+ public static Long maxPageSize = 200L;
+
+ @Value("${page.default-page-size}")
+ public void setDefaultPageSize(Long defaultPageSize) {
+ PageProperty.defaultPageSize = defaultPageSize;
+ }
+
+ @Value("${page.max-page-size}")
+ public void setMaxPageSize(Long maxPageSize) {
+ PageProperty.maxPageSize = maxPageSize;
+ }
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/GenericTypeUtils.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/GenericTypeUtils.java
new file mode 100644
index 000000000..2078a2c4b
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/GenericTypeUtils.java
@@ -0,0 +1,24 @@
+package com.moxi.mougblog.base.mybatis.reflect;
+
+/**
+ * 来源于 MyBatis Plus 更高版本
+ *
+ * @author geshanzsq
+ * @date 2024/6/4
+ */
+public class GenericTypeUtils {
+
+ private static IGenericTypeResolver GENERIC_TYPE_RESOLVER;
+
+ public GenericTypeUtils() {
+ }
+
+ public static Class>[] resolveTypeArguments(final Class> clazz, final Class> genericIfc) {
+ return null == GENERIC_TYPE_RESOLVER ? SpringReflectionHelper.resolveTypeArguments(clazz, genericIfc) : GENERIC_TYPE_RESOLVER.resolveTypeArguments(clazz, genericIfc);
+ }
+
+ public static void setGenericTypeResolver(IGenericTypeResolver genericTypeResolver) {
+ GENERIC_TYPE_RESOLVER = genericTypeResolver;
+ }
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/IGenericTypeResolver.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/IGenericTypeResolver.java
new file mode 100644
index 000000000..ed24d5353
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/IGenericTypeResolver.java
@@ -0,0 +1,13 @@
+package com.moxi.mougblog.base.mybatis.reflect;
+
+/**
+ * 来源于 MyBatis Plus 更高版本
+ *
+ * @author geshanzsq
+ * @date 2024/6/4
+ */
+public interface IGenericTypeResolver {
+
+ Class>[] resolveTypeArguments(final Class> clazz, final Class> genericIfc);
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/SpringReflectionHelper.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/SpringReflectionHelper.java
new file mode 100644
index 000000000..e61e551de
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/reflect/SpringReflectionHelper.java
@@ -0,0 +1,20 @@
+package com.moxi.mougblog.base.mybatis.reflect;
+
+import org.springframework.core.GenericTypeResolver;
+
+/**
+ * 来源于 MyBatis Plus 更高版本
+ *
+ * @author geshanzsq
+ * @date 2024/6/4
+ */
+public class SpringReflectionHelper {
+
+ public SpringReflectionHelper() {
+ }
+
+ public static Class>[] resolveTypeArguments(Class> clazz, Class> genericIfc) {
+ return GenericTypeResolver.resolveTypeArguments(clazz, genericIfc);
+ }
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/util/MybatisUtils.java b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/util/MybatisUtils.java
new file mode 100644
index 000000000..cd03344d6
--- /dev/null
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/mybatis/util/MybatisUtils.java
@@ -0,0 +1,48 @@
+package com.moxi.mougblog.base.mybatis.util;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.moxi.mougblog.base.mybatis.page.dto.PageDTO;
+import com.moxi.mougblog.base.mybatis.property.PageProperty;
+
+/**
+ * MyBatis 工具类
+ *
+ * @author geshanzsq
+ * @date 2022/6/26
+ */
+public class MybatisUtils {
+
+ /**
+ * 构建分页
+ */
+ public static Page buildPage(PageDTO pageDTO) {
+ Long pageNum = null;
+ Long pageSize = null;
+ if (pageDTO != null) {
+ pageNum = pageDTO.getCurrentPage();
+ pageSize = pageDTO.getPageSize();
+ }
+ return buildPage(pageNum, pageSize);
+ }
+
+ /**
+ * 构建分页
+ */
+ public static Page buildPage(Long pageNum, Long pageSize) {
+ // 如果为空,则设置默认值
+ if (pageNum == null) {
+ pageNum = 1L;
+ }
+ if (pageSize == null) {
+ pageSize = PageProperty.defaultPageSize;
+ }
+
+ // 如果超过最大分页数,则设置为最大分页数
+ if (pageSize > PageProperty.maxPageSize) {
+ pageSize = PageProperty.maxPageSize;
+ }
+ Page page = new Page<>(pageNum, pageSize);
+ return page;
+ }
+
+}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/service/SuperService.java b/mogu_base/src/main/java/com/moxi/mougblog/base/service/SuperService.java
index d4363456b..aaaf64b06 100644
--- a/mogu_base/src/main/java/com/moxi/mougblog/base/service/SuperService.java
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/service/SuperService.java
@@ -1,9 +1,15 @@
package com.moxi.mougblog.base.service;
+import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.moxi.mougblog.base.mybatis.page.vo.PageVO;
+import com.moxi.mougblog.base.mybatis.plugin.query.QueryWrapperPlus;
+
+import java.util.List;
/**
- * Service父类
+ * Service父类,在 MyBatis Plus 的 IService 的基础上拓展,提供更多功能
*
* @param
* @author 陌溪
@@ -11,4 +17,70 @@
*/
public interface SuperService extends IService {
+ /**
+ * 查询分页
+ *
+ * @param d 实体类参数对接
+ * @param selectColumns 查询返回的列
+ */
+ PageVO page(D d, SFunction... selectColumns);
+
+ /**
+ * 查询列表
+ *
+ * @param d 实体类参数对接
+ * @param selectColumns 查询返回的列
+ */
+ default List list(D d, SFunction... selectColumns) {
+ return list(buildQueryWrapper(d, selectColumns));
+ }
+
+ /**
+ * 查询单条
+ *
+ * @param d 实体类参数对接
+ */
+ default T getOne(D d) {
+ return getOne(buildQueryWrapper(d));
+ }
+
+ /**
+ * 查询单条
+ *
+ * @param d 实体类参数对接
+ * @param throwEx 有多个结果是否抛出异常
+ */
+ default T getOne(D d, boolean throwEx) {
+ return getOne(buildQueryWrapper( d), throwEx);
+ }
+
+ /**
+ * 查询总记录数
+ *
+ * @param d 实体类参数对接
+ */
+ default Long count(D d) {
+ return (long) count(buildQueryWrapper(d));
+ }
+
+ /**
+ * 构建 Wrapper 查询条件
+ *
+ * @param d DTO 实体参数对象
+ * @param selectColumns 查询返回的列
+ * @return 查询构造器
+ */
+ default QueryWrapperPlus buildQueryWrapper(D d, SFunction... selectColumns) {
+ return new QueryWrapperPlus().buildQueryWrapper(getEntityClass(), d, selectColumns);
+ }
+
+ /**
+ * 获取当前T 类型 Class
+ *
+ * @return
+ */
+ default Class getEntityClass() {
+ return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), 1);
+ }
+
}
diff --git a/mogu_base/src/main/java/com/moxi/mougblog/base/serviceImpl/SuperServiceImpl.java b/mogu_base/src/main/java/com/moxi/mougblog/base/serviceImpl/SuperServiceImpl.java
index d366ab2e1..988301bb9 100644
--- a/mogu_base/src/main/java/com/moxi/mougblog/base/serviceImpl/SuperServiceImpl.java
+++ b/mogu_base/src/main/java/com/moxi/mougblog/base/serviceImpl/SuperServiceImpl.java
@@ -1,8 +1,11 @@
package com.moxi.mougblog.base.serviceImpl;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moxi.mougblog.base.mapper.SuperMapper;
+import com.moxi.mougblog.base.mybatis.page.vo.PageVO;
import com.moxi.mougblog.base.service.SuperService;
+import org.springframework.beans.factory.annotation.Autowired;
/**
@@ -15,4 +18,18 @@
public class SuperServiceImpl, T> extends ServiceImpl implements SuperService {
+ @Autowired
+ private M baseMapper;
+
+ /**
+ * 查询分页
+ *
+ * @param d 实体类参数对接
+ * @param selectColumns 查询返回的列
+ */
+ @Override
+ public PageVO page(D d, SFunction... selectColumns) {
+ return baseMapper.selectPage(d, selectColumns);
+ }
+
}
diff --git a/pom.xml b/pom.xml
index 548abac0c..edd3f9ac6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,6 +47,7 @@
3.0.2
2.2.4.RELEASE
2.2.5.RELEASE
+ 1.4.1