فهرست منبع

整合X,mpj

车车 1 سال پیش
والد
کامیت
212c12a8bf

+ 6 - 0
ktg-common/pom.xml

@@ -181,6 +181,12 @@
             <artifactId>mybatis-plus-join-core</artifactId>
             <version>1.4.13</version>
         </dependency>
+        <dependency>
+            <groupId>io.swagger.core.v3</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>2.2.20</version>
+            <scope>compile</scope>
+        </dependency>
 
     </dependencies>
 

+ 191 - 0
ktg-common/src/main/java/com/ktg/common/mapper/BaseMapperX.java

@@ -0,0 +1,191 @@
+package com.ktg.common.mapper;
+
+import cn.hutool.core.collection.CollUtil;
+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.support.SFunction;
+import com.baomidou.mybatisplus.extension.toolkit.Db;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.github.yulichang.interfaces.MPJBaseJoin;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.ktg.common.pojo.PageParam;
+import com.ktg.common.pojo.PageResult;
+import com.ktg.common.pojo.SortablePageParam;
+import com.ktg.common.pojo.SortingField;
+import com.ktg.common.utils.mybatis.MyBatisUtils;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力
+ *
+ * 1. {@link BaseMapper} 为 MyBatis Plus 的基础接口,提供基础的 CRUD 能力
+ * 2. {@link MPJBaseMapper} 为 MyBatis Plus Join 的基础接口,提供连表 Join 能力
+ */
+public interface BaseMapperX<T> extends MPJBaseMapper<T> {
+
+    default PageResult<T> selectPage(SortablePageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
+        return selectPage(pageParam, pageParam.getSortingFields(), queryWrapper);
+    }
+
+    default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
+        return selectPage(pageParam, null, queryWrapper);
+    }
+
+    default PageResult<T> selectPage(PageParam pageParam, Collection<SortingField> sortingFields, @Param("ew") Wrapper<T> queryWrapper) {
+        // 特殊:不分页,直接查询全部
+        if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
+            List<T> list = selectList(queryWrapper);
+            return new PageResult<>(list, (long) list.size());
+        }
+
+        // MyBatis Plus 查询
+        IPage<T> mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
+        selectPage(mpPage, queryWrapper);
+        // 转换返回
+        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
+    }
+
+    default <D> PageResult<D> selectJoinPage(PageParam pageParam, Class<D> clazz, MPJLambdaWrapper<T> lambdaWrapper) {
+        // 特殊:不分页,直接查询全部
+        if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageNo())) {
+            List<D> list = selectJoinList(clazz, lambdaWrapper);
+            return new PageResult<>(list, (long) list.size());
+        }
+
+        // MyBatis Plus Join 查询
+        IPage<D> mpPage = MyBatisUtils.buildPage(pageParam);
+        mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper);
+        // 转换返回
+        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
+    }
+
+    default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass, MPJBaseJoin<T> joinQueryWrapper) {
+        IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam);
+        selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);
+        // 转换返回
+        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
+    }
+
+    default T selectOne(String field, Object value) {
+        return selectOne(new QueryWrapper<T>().eq(field, value));
+    }
+
+    default T selectOne(SFunction<T, ?> field, Object value) {
+        return selectOne(new LambdaQueryWrapper<T>().eq(field, value));
+    }
+
+    default T selectOne(String field1, Object value1, String field2, Object value2) {
+        return selectOne(new QueryWrapper<T>().eq(field1, value1).eq(field2, value2));
+    }
+
+    default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
+        return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
+    }
+
+    default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2,
+                        SFunction<T, ?> field3, Object value3) {
+        return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2)
+                .eq(field3, value3));
+    }
+
+    default Long selectCount() {
+        return selectCount(new QueryWrapper<>());
+    }
+
+    default Long selectCount(String field, Object value) {
+        return selectCount(new QueryWrapper<T>().eq(field, value));
+    }
+
+    default Long selectCount(SFunction<T, ?> field, Object value) {
+        return selectCount(new LambdaQueryWrapper<T>().eq(field, value));
+    }
+
+    default List<T> selectList() {
+        return selectList(new QueryWrapper<>());
+    }
+
+    default List<T> selectList(String field, Object value) {
+        return selectList(new QueryWrapper<T>().eq(field, value));
+    }
+
+    default List<T> selectList(SFunction<T, ?> field, Object value) {
+        return selectList(new LambdaQueryWrapper<T>().eq(field, value));
+    }
+
+    default List<T> selectList(String field, Collection<?> values) {
+        if (CollUtil.isEmpty(values)) {
+            return CollUtil.newArrayList();
+        }
+        return selectList(new QueryWrapper<T>().in(field, values));
+    }
+
+    default List<T> selectList(SFunction<T, ?> field, Collection<?> values) {
+        if (CollUtil.isEmpty(values)) {
+            return CollUtil.newArrayList();
+        }
+        return selectList(new LambdaQueryWrapper<T>().in(field, values));
+    }
+
+    @Deprecated
+    default List<T> selectList(SFunction<T, ?> leField, SFunction<T, ?> geField, Object value) {
+        return selectList(new LambdaQueryWrapper<T>().le(leField, value).ge(geField, value));
+    }
+
+    default List<T> selectList(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
+        return selectList(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
+    }
+
+    /**
+     * 批量插入,适合大量数据插入
+     *
+     * @param entities 实体们
+     */
+    default Boolean insertBatch(Collection<T> entities) {
+        return Db.saveBatch(entities);
+    }
+
+    /**
+     * 批量插入,适合大量数据插入
+     *
+     * @param entities 实体们
+     * @param size     插入数量 Db.saveBatch 默认为 1000
+     */
+    default Boolean insertBatch(Collection<T> entities, int size) {
+        return Db.saveBatch(entities, size);
+    }
+
+    default int updateBatch(T update) {
+        return update(update, new QueryWrapper<>());
+    }
+
+    default Boolean updateBatch(Collection<T> entities) {
+        return Db.updateBatchById(entities);
+    }
+
+    default Boolean updateBatch(Collection<T> entities, int size) {
+        return Db.updateBatchById(entities, size);
+    }
+
+   /* default Boolean insertOrUpdate(T entity) {
+        return  Db.saveOrUpdate(entity);
+    }*/
+
+    default Boolean insertOrUpdateBatch(Collection<T> collection) {
+        return Db.saveOrUpdateBatch(collection);
+    }
+
+    default int delete(String field, String value) {
+        return delete(new QueryWrapper<T>().eq(field, value));
+    }
+
+    default int delete(SFunction<T, ?> field, Object value) {
+        return delete(new LambdaQueryWrapper<T>().eq(field, value));
+    }
+
+}

+ 35 - 0
ktg-common/src/main/java/com/ktg/common/pojo/PageParam.java

@@ -0,0 +1,35 @@
+package com.ktg.common.pojo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class PageParam implements Serializable {
+
+    private static final Integer PAGE_NO = 1;
+    private static final Integer PAGE_SIZE = 10;
+
+    /**
+     * 每页条数 - 不分页
+     *
+     * 例如说,导出接口,可以设置 {@link #pageSize} 为 -1 不分页,查询所有数据。
+     */
+    public static final Integer PAGE_SIZE_NONE = -1;
+
+    @Schema(description = "页码,从 1 开始", requiredMode = Schema.RequiredMode.REQUIRED,example = "1")
+    @NotNull(message = "页码不能为空")
+    @Min(value = 1, message = "页码最小值为 1")
+    private Integer pageNo = PAGE_NO;
+
+    @Schema(description = "每页条数,最大值为 100", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+    @NotNull(message = "每页条数不能为空")
+    @Min(value = 1, message = "每页条数最小值为 1")
+    @Max(value = 100, message = "每页条数最大值为 100")
+    private Integer pageSize = PAGE_SIZE;
+
+}

+ 41 - 0
ktg-common/src/main/java/com/ktg/common/pojo/PageResult.java

@@ -0,0 +1,41 @@
+package com.ktg.common.pojo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Schema(description = "分页结果")
+@Data
+public final class PageResult<T> implements Serializable {
+
+    @Schema(description = "数据", requiredMode = Schema.RequiredMode.REQUIRED)
+    private List<T> list;
+
+    @Schema(description = "总量", requiredMode = Schema.RequiredMode.REQUIRED)
+    private Long total;
+
+    public PageResult() {
+    }
+
+    public PageResult(List<T> list, Long total) {
+        this.list = list;
+        this.total = total;
+    }
+
+    public PageResult(Long total) {
+        this.list = new ArrayList<>();
+        this.total = total;
+    }
+
+    public static <T> PageResult<T> empty() {
+        return new PageResult<>(0L);
+    }
+
+    public static <T> PageResult<T> empty(Long total) {
+        return new PageResult<>(total);
+    }
+
+}

+ 16 - 0
ktg-common/src/main/java/com/ktg/common/pojo/SortablePageParam.java

@@ -0,0 +1,16 @@
+package com.ktg.common.pojo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.List;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SortablePageParam extends PageParam {
+
+    private List<SortingField> sortingFields;
+
+}

+ 37 - 0
ktg-common/src/main/java/com/ktg/common/pojo/SortingField.java

@@ -0,0 +1,37 @@
+package com.ktg.common.pojo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 排序字段 DTO
+ *
+ * 类名加了 ing 的原因是,避免和 ES SortField 重名。
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SortingField implements Serializable {
+
+    /**
+     * 顺序 - 升序
+     */
+    public static final String ORDER_ASC = "asc";
+    /**
+     * 顺序 - 降序
+     */
+    public static final String ORDER_DESC = "desc";
+
+    /**
+     * 字段
+     */
+    private String field;
+    /**
+     * 顺序
+     */
+    private String order;
+
+}

+ 88 - 0
ktg-common/src/main/java/com/ktg/common/utils/mybatis/MyBatisUtils.java

@@ -0,0 +1,88 @@
+package com.ktg.common.utils.mybatis;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ktg.common.pojo.PageParam;
+import com.ktg.common.pojo.SortingField;
+import net.sf.jsqlparser.expression.Alias;
+import net.sf.jsqlparser.schema.Column;
+import net.sf.jsqlparser.schema.Table;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * MyBatis 工具类
+ */
+public class MyBatisUtils {
+
+    private static final String MYSQL_ESCAPE_CHARACTER = "`";
+
+    public static <T> Page<T> buildPage(PageParam pageParam) {
+        return buildPage(pageParam, null);
+    }
+
+    public static <T> Page<T> buildPage(PageParam pageParam, Collection<SortingField> sortingFields) {
+        // 页码 + 数量
+        Page<T> page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());
+        // 排序字段
+        if (!CollectionUtil.isEmpty(sortingFields)) {
+            page.addOrder(sortingFields.stream().map(sortingField -> SortingField.ORDER_ASC.equals(sortingField.getOrder()) ?
+                    OrderItem.asc(sortingField.getField()) : OrderItem.desc(sortingField.getField()))
+                    .collect(Collectors.toList()));
+        }
+        return page;
+    }
+
+    /**
+     * 将拦截器添加到链中
+     * 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置
+     *
+     * @param interceptor 链
+     * @param inner       拦截器
+     * @param index       位置
+     */
+    public static void addInterceptor(MybatisPlusInterceptor interceptor, InnerInterceptor inner, int index) {
+        List<InnerInterceptor> inners = new ArrayList<>(interceptor.getInterceptors());
+        inners.add(index, inner);
+        interceptor.setInterceptors(inners);
+    }
+
+    /**
+     * 获得 Table 对应的表名
+     *
+     * 兼容 MySQL 转义表名 `t_xxx`
+     *
+     * @param table 表
+     * @return 去除转移字符后的表名
+     */
+    public static String getTableName(Table table) {
+        String tableName = table.getName();
+        if (tableName.startsWith(MYSQL_ESCAPE_CHARACTER) && tableName.endsWith(MYSQL_ESCAPE_CHARACTER)) {
+            tableName = tableName.substring(1, tableName.length() - 1);
+        }
+        return tableName;
+    }
+
+    /**
+     * 构建 Column 对象
+     *
+     * @param tableName  表名
+     * @param tableAlias 别名
+     * @param column     字段名
+     * @return Column 对象
+     */
+    public static Column buildColumn(String tableName, Alias tableAlias, String column) {
+        if (tableAlias != null) {
+            tableName = tableAlias.getName();
+        }
+        return new Column(tableName + StringPool.DOT + column);
+    }
+
+}

+ 22 - 0
ktg-framework/src/main/java/com/ktg/framework/config/MyMetaObjectHandler.java

@@ -0,0 +1,22 @@
+package com.ktg.framework.config;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.ktg.common.utils.SecurityUtils;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.stereotype.Component;
+
+/**
+ * mybatis-plus自动填充
+ */
+@Component
+public class MyMetaObjectHandler implements MetaObjectHandler {
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        this.strictInsertFill(metaObject,"createBy",String.class, SecurityUtils.getLoginUser().getUsername());
+    }
+
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        this.strictUpdateFill(metaObject,"updateBy",String.class,SecurityUtils.getLoginUser().getUsername());
+    }
+}