From 3ff34db2abf5e84fb748a03cae0333a8be75417d Mon Sep 17 00:00:00 2001 From: yulichang <570810310@qq.com> Date: Wed, 17 Nov 2021 12:14:48 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=88=AB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/metadata/MPJMappingWrapper.java | 104 ++++ .../core/metadata/MPJTableFieldInfo.java | 368 ++++++++++++ .../core/metadata/MPJTableInfo.java | 51 ++ .../core/metadata/MPJTableMapperHelper.java | 24 + .../yulichang/annotation/EntityMapping.java | 102 ++++ .../yulichang/annotation/FieldMapping.java | 101 ++++ .../yulichang/annotation/MPJMappingApply.java | 21 + .../annotation/MPJMappingCondition.java | 34 ++ .../yulichang/base/mapper/MPJDeepMapper.java | 534 +++++++++++++++++ .../yulichang/base/mapper/MPJJoinMapper.java | 76 +++ .../base/service/MPJDeepService.java | 556 ++++++++++++++++++ .../base/service/MPJJoinService.java | 66 +++ .../yulichang/config/MappingConfig.java | 22 + .../yulichang/toolkit/SpringContentUtils.java | 25 + 14 files changed, 2084 insertions(+) create mode 100644 src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java create mode 100644 src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java create mode 100644 src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java create mode 100644 src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableMapperHelper.java create mode 100644 src/main/java/com/github/yulichang/annotation/EntityMapping.java create mode 100644 src/main/java/com/github/yulichang/annotation/FieldMapping.java create mode 100644 src/main/java/com/github/yulichang/annotation/MPJMappingApply.java create mode 100644 src/main/java/com/github/yulichang/annotation/MPJMappingCondition.java create mode 100644 src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java create mode 100644 src/main/java/com/github/yulichang/base/mapper/MPJJoinMapper.java create mode 100644 src/main/java/com/github/yulichang/base/service/MPJDeepService.java create mode 100644 src/main/java/com/github/yulichang/base/service/MPJJoinService.java create mode 100644 src/main/java/com/github/yulichang/config/MappingConfig.java create mode 100644 src/main/java/com/github/yulichang/toolkit/SpringContentUtils.java diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java new file mode 100644 index 0000000..cb029ac --- /dev/null +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java @@ -0,0 +1,104 @@ +package com.baomidou.mybatisplus.core.metadata; + + +import com.baomidou.mybatisplus.core.enums.SqlKeyword; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.github.yulichang.annotation.MPJMappingApply; +import com.github.yulichang.annotation.MPJMappingCondition; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * 关联查询条件 + * + * @author yulichang + * @since 1.2.0 + */ +@Getter +public class MPJMappingWrapper { + + private final boolean hasFirst; + private String first; + + private final boolean hasSelect; + private String select; + + private final boolean hasApply; + private List applyList; + + private final boolean hasCondition; + private List conditionList; + + private final boolean hasLast; + private String last; + + private final boolean hasOrderByAsc; + private List orderByAsc; + + private final boolean hasOrderByDesc; + private List orderByDesc; + + public MPJMappingWrapper(String first, String select, MPJMappingApply[] applys, + MPJMappingCondition[] conditions, String last, String orderByAsc, String orderByDesc) { + this.hasFirst = StringUtils.isNotBlank(first); + if (this.hasFirst) { + this.first = first; + } + + this.hasSelect = StringUtils.isNotBlank(select); + if (this.hasSelect) { + this.select = select; + } + + this.hasApply = applys.length > 0; + if (this.hasApply) { + this.applyList = new ArrayList<>(); + for (MPJMappingApply apply : applys) { + this.applyList.add(new Apply(apply.value(), apply.args())); + } + } + + this.hasCondition = conditions.length > 0; + if (this.hasCondition) { + this.conditionList = new ArrayList<>(); + for (MPJMappingCondition condition : conditions) { + conditionList.add(new Condition(condition.keyWord(), condition.column(), condition.value())); + } + } + + this.hasLast = StringUtils.isNotBlank(last); + if (this.hasLast) { + this.last = last; + } + + this.hasOrderByAsc = StringUtils.isNotBlank(orderByAsc); + if (this.hasOrderByAsc) { + this.orderByAsc = Arrays.asList(orderByAsc.split(StringPool.COMMA)); + } + + this.hasOrderByDesc = StringUtils.isNotBlank(orderByDesc); + if (this.hasOrderByDesc) { + this.orderByDesc = Arrays.asList(orderByDesc.split(StringPool.COMMA)); + } + } + + @Getter + @AllArgsConstructor + public static class Apply { + private final String sql; + private final String[] val; + } + + @Getter + @AllArgsConstructor + public static class Condition { + private final SqlKeyword keyword; + private final String column; + private final String[] val; + } +} diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java new file mode 100644 index 0000000..92dc1eb --- /dev/null +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java @@ -0,0 +1,368 @@ +package com.baomidou.mybatisplus.core.metadata; + +import com.baomidou.mybatisplus.core.toolkit.*; +import com.github.yulichang.annotation.EntityMapping; +import com.github.yulichang.annotation.FieldMapping; +import com.github.yulichang.base.MPJBaseMapper; +import com.github.yulichang.exception.MPJException; +import com.github.yulichang.toolkit.SpringContentUtils; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 字段属性 + * + * @author yulichang + * @see TableFieldInfo + * @since 1.2.0 + */ +@Getter +@ToString +@EqualsAndHashCode +public class MPJTableFieldInfo { + + /** + * 是否是实体映射 + */ + private final boolean isMappingEntity; + /** + * 是否是属性映射 + */ + private final boolean isMappingField; + /** + * 字段映射是绑定的字段 + */ + private Field bindField; + /** + * 是否移除绑定字段 + */ + private final boolean isRemoveBindField; + /** + * 实体类 + */ + private final Class entityType; + /** + * 属性 + */ + private Field field; + /** + * 属性名 + */ + private String property; + /** + * 数据结构是否是Map或者List + */ + private boolean fieldIsMap; + /** + * 属性是否是集合 + */ + private boolean isCollection; + /** + * 当前映射属性 + */ + private Field thisField; + /** + * 当前类实体属性 + */ + private String thisProperty; + /** + * 当前字段信息 + */ + private String thisColumn; + /** + * 当前字段信息 + */ + private String thisMapKey; + /** + * 映射实体类 + */ + private Class joinClass; + /** + * 映射属性名 + */ + private String joinProperty; + /** + * 映射属性数据库列名 + */ + private String joinColumn; + /** + * 映射属性字段 + */ + private Field joinField; + /** + * fieldIsMap 为true时使用 + * 映射查询Map 的key + * 默认为 关联字段的数据库列名 + */ + private String joinMapKey; + /** + * 关联的mapper引用 + */ + private MPJBaseMapper joinMapper; + /** + * 关联查询条件配置 + */ + private final MPJMappingWrapper wrapper; + /** + * 一对一查询结果数量不匹配是是否抛出异常 + */ + private final boolean isThrowExp; + + /** + * 初始化关联字段信息 + */ + public MPJTableFieldInfo(Class entityType, EntityMapping mapping, Field field) { + this.isMappingEntity = true; + this.isMappingField = false; + initField(field); + if (mapping.tag() != Object.class) { + this.joinClass = mapping.tag(); + } + this.entityType = entityType; + this.isThrowExp = mapping.isThrowExp(); + initThisField(mapping.thisMapKey(), mapping.thisField()); + initJoinField(mapping.joinMapKey(), mapping.joinField()); + this.isRemoveBindField = StringUtils.isNotBlank(mapping.select()) && (!Arrays.asList(mapping.select().split( + StringPool.COMMA)).contains(this.joinColumn.trim())); + this.wrapper = new MPJMappingWrapper(mapping.first(), StringUtils.isBlank(mapping.select()) ? null : + (this.isRemoveBindField ? this.joinColumn + StringPool.COMMA + mapping.select() : mapping.select()), + mapping.apply(), mapping.condition(), mapping.last(), mapping.orderByAsc(), mapping.orderByDesc()); + } + + public MPJTableFieldInfo(Class entityType, FieldMapping mappingField, Field field) { + this.isMappingEntity = false; + this.isMappingField = true; + field.setAccessible(true); + this.field = field; + this.property = field.getName(); + this.isCollection = Collection.class.isAssignableFrom(field.getType()); + if (this.isCollection && !List.class.isAssignableFrom(this.field.getType())) { + throw new MPJException("对多关系的数据结构目前只支持 暂不支持其他Collection实现 " + this.field.getType().getTypeName()); + } + this.joinClass = mappingField.tag(); + this.entityType = entityType; + this.isThrowExp = mappingField.isThrowExp(); + initThisField(mappingField.thisMapKey(), mappingField.thisField()); + initJoinField(mappingField.joinMapKey(), mappingField.joinField()); + this.isRemoveBindField = !mappingField.select().equals(this.joinColumn.trim()); + this.wrapper = new MPJMappingWrapper(mappingField.first(), this.isRemoveBindField ? this.joinColumn + + StringPool.COMMA + mappingField.select() : mappingField.select(), mappingField.apply(), + mappingField.condition(), mappingField.last(), mappingField.orderByAsc(), mappingField.orderByDesc()); + initBindField(mappingField.select()); + } + + private void initBindField(String bindName) { + List fields = ReflectionKit.getFieldList(ClassUtils.getUserClass(this.joinClass)); + Field field = fields.stream().filter(f -> f.getName().equals(bindName)).findFirst().orElse(null); + if (field == null) { + throw new MPJException("字段不存在 " + this.joinClass.getName() + " ," + bindName); + } + this.bindField = field; + } + + private void initJoinField(String joinMapKey, String joinField) { + if (StringUtils.isNotBlank(joinField)) { + this.joinProperty = joinField; + } else { + TableInfo info = getTableInfo(this.joinClass); + Assert.isTrue(info.havePK(), "实体未定义主键 %s ", this.joinClass.getName()); + this.joinProperty = info.getKeyProperty(); + } + + TableInfo joinTableInfo = getTableInfo(this.joinClass); + TableFieldInfo joinFieldInfo = joinTableInfo.getFieldList().stream().filter(f -> + f.getField().getName().equals(this.joinProperty)).findFirst().orElse(null); + if (joinFieldInfo == null) { + if (joinTableInfo.havePK() && this.joinProperty.equals(joinTableInfo.getKeyProperty())) { + this.joinColumn = joinTableInfo.getKeyColumn(); + this.joinField = ReflectionKit.getFieldList(this.joinClass).stream().filter(i -> + i.getName().equals(joinTableInfo.getKeyProperty())).findFirst().orElse(null); + } + } else { + this.joinColumn = joinFieldInfo.getColumn(); + this.joinField = joinFieldInfo.getField(); + } + Assert.notNull(this.joinField, "注解属性thisField不存在 %s , %s", this.joinClass.getName(), + StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); + Assert.notNull(this.joinColumn, "注解属性thisField不存在 %s , %s", this.joinClass.getName(), + StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); + this.joinField.setAccessible(true); + this.joinMapKey = StringUtils.isBlank(joinMapKey) ? this.joinColumn : joinMapKey; + } + + private void initThisField(String thisMapKey, String thisField) { + if (StringUtils.isNotBlank(thisField)) { + this.thisProperty = thisField; + } else { + TableInfo info = getTableInfo(this.entityType); + Assert.isTrue(info.havePK(), "实体未定义主键 %s ", this.entityType.getName()); + this.thisProperty = info.getKeyProperty(); + } + + TableInfo tableInfo = getTableInfo(this.entityType); + if (tableInfo.havePK() && this.thisProperty.equals(tableInfo.getKeyProperty())) { + this.thisField = ReflectionKit.getFieldList(ClassUtils.getUserClass(entityType)).stream().filter(f -> + f.getName().equals(tableInfo.getKeyProperty())).findFirst().orElse(null); + Assert.notNull(this.thisField, "注解属性thisField不存在 %s , %s", entityType.getName(), + StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty); + this.thisColumn = tableInfo.getKeyColumn(); + } else { + TableFieldInfo fieldInfo = tableInfo.getFieldList().stream().filter(f -> + f.getField().getName().equals(this.thisProperty)).findFirst().orElse(null); + Assert.notNull(fieldInfo, "注解属性thisField不存在 %s , %s", entityType.getName(), + StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty); + this.thisField = fieldInfo.getField(); + this.thisColumn = fieldInfo.getColumn(); + } + this.thisField.setAccessible(true); + this.thisMapKey = StringUtils.isBlank(thisMapKey) ? this.thisColumn : thisMapKey; + } + + private void initField(Field field) { + field.setAccessible(true); + this.field = field; + this.property = field.getName(); + this.isCollection = Collection.class.isAssignableFrom(field.getType()); + if (this.isCollection && !List.class.isAssignableFrom(this.field.getType())) { + throw new MPJException("对多关系的数据结构目前只支持 暂不支持其他Collection实现 " + this.field.getType().getTypeName()); + } + if (Map.class.isAssignableFrom(field.getType())) { + this.fieldIsMap = true; + } else { + if (field.getGenericType() instanceof ParameterizedType) { + ParameterizedType t = (ParameterizedType) field.getGenericType(); + Type type = t.getActualTypeArguments()[0]; + if (type instanceof ParameterizedType) { + this.fieldIsMap = ((ParameterizedType) type).getRawType() == Map.class; + } else { + this.fieldIsMap = false; + } + } else { + this.fieldIsMap = false; + } + } + + if (!this.fieldIsMap) { + if (List.class.isAssignableFrom(field.getType())) { + if (field.getGenericType() instanceof ParameterizedType) { + ParameterizedType t = (ParameterizedType) field.getGenericType(); + this.joinClass = (Class) t.getActualTypeArguments()[0]; + } + } else { + this.joinClass = field.getType(); + } + } + } + + public MPJBaseMapper getJoinMapper() { + if (this.joinMapper == null) { + MPJTableInfo joinTableInfo = MPJTableInfoHelper.getTableInfos().stream().filter(table -> + table.getTableInfo().getEntityType() == this.joinClass).findFirst().orElse(null); + if (joinTableInfo == null) { + throw new MPJException("未注册 mapper " + this.joinClass.getName()); + } + this.joinMapper = (MPJBaseMapper) SpringContentUtils.getApplicationContext().getBean(joinTableInfo.getMapperClass()); + } + return this.joinMapper; + } + + private TableInfo getTableInfo(Class clazz) { + TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz); + if (tableInfo == null) { + throw new MPJException("未注册 mapper " + clazz.getName()); + } + return tableInfo; + } + + + public void fieldSet(Object o, Object val) { + try { + this.field.set(o, val); + } catch (Exception e) { + throw new MPJException("无法设置关联字段,请检查关联字段数据类型是否匹配 " + this.entityType.getName() + + " , " + this.field.getName() + " , " + o.getClass().getName()); + } + } + + public Object thisFieldGet(Object o) { + try { + return getThisField().get(o); + } catch (Exception e) { + throw new MPJException("无法获取当前关联字段,请检查关联字段是否匹配 " + this.entityType.getName() + " , " + + this.thisField.getName() + " , " + o.getClass().getName()); + } + } + + public Object joinFieldGet(Object o) { + try { + return getJoinField().get(o); + } catch (Exception e) { + throw new MPJException("无法设置关联字段,请检查关联字段数据类型是否匹配 " + this.joinClass.getName() + " , " + + this.joinField.getName() + " , " + o.getClass().getName()); + } + } + + public Object bindFieldGet(Object o) { + try { + return getBindField().get(o); + } catch (Exception e) { + throw new MPJException("无法设置关联字段,请检查关联字段数据类型是否匹配 " + this.joinClass.getName() + " , " + + this.bindField.getName() + " , " + o.getClass().getName()); + } + } + + public void joinFieldSetNull(Object o) { + try { + this.joinField.set(o, null); + } catch (Exception e) { + throw new MPJException("无法设置关联字段,请检查关联字段数据类型是否匹配 " + this.entityType.getName() + + " , " + this.joinField.getName() + " , " + o.getClass().getName()); + } + } + + @SuppressWarnings({"unchecked", "RedundantCast"}) + public void removeJoinField(List joinList) { + if (this.isMappingEntity() && this.isRemoveBindField()) { + if (this.isFieldIsMap()) { + ((List>) joinList).forEach(m -> m.remove(this.getJoinMapKey())); + } else { + joinList.forEach(this::joinFieldSetNull); + } + } + } + + public static void bind(MPJTableFieldInfo fieldInfo, T i, List data) { + if (fieldInfo.isCollection()) { + fieldInfo.fieldSet(i, data); + } else { + if (data.size() > 1 && fieldInfo.isThrowExp()) { + throw new MPJException("Expected one result (or null) to be returned by select, but found: " + + data.size() + " , " + fieldInfo.getField().getName()); + } else { + fieldInfo.fieldSet(i, data.stream().findFirst().orElse(null)); + } + } + } + + public static void bindMap(MPJTableFieldInfo fieldInfo, Map i, List data) { + if (fieldInfo.isCollection()) { + i.put(fieldInfo.getField().getName(), data); + } else { + if (data.size() > 1 && fieldInfo.isThrowExp()) { + throw new MPJException("Expected one result (or null) to be returned by select, but found: " + + data.size() + " , " + fieldInfo.getField().getName()); + } else { + i.put(fieldInfo.getField().getName(), data.stream().findFirst().orElse(null)); + } + } + } +} diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java new file mode 100644 index 0000000..5cfff19 --- /dev/null +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java @@ -0,0 +1,51 @@ +package com.baomidou.mybatisplus.core.metadata; + +import lombok.AccessLevel; +import lombok.Data; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 数据库表反射信息 + * + * @author yulichang + * @see TableInfo + * @since 1.2.0 + */ +@Data +@Setter(AccessLevel.PACKAGE) +@Accessors(chain = true) +public class MPJTableInfo { + + /** + * mybatis-plus 表信息 + */ + private TableInfo tableInfo; + + /** + * 是否包含 EntityMapping 或者 FieldMapping + */ + private boolean hasMappingOrField; + + /** + * 是否包含映射注解 + */ + private boolean hasMapping; + + /** + * 是否包含映射注解 + */ + private boolean hasMappingField; + + /** + * mapperClass + */ + private Class mapperClass; + + /** + * 包含映射实体注解的字段列表 + */ + private List fieldList; +} diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableMapperHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableMapperHelper.java new file mode 100644 index 0000000..7df1a73 --- /dev/null +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableMapperHelper.java @@ -0,0 +1,24 @@ +package com.baomidou.mybatisplus.core.metadata; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 实体类对应的mapper管理 + * + * @author yulichang + * @since 1.2.0 + */ +public class MPJTableMapperHelper { + + private static final Map, Class> CACHE = new ConcurrentHashMap<>(); + + public static void init(Class clazz, Class mapper) { + CACHE.put(clazz, mapper); + } + + public static Class get(Class clazz) { + return CACHE.get(clazz); + } +} diff --git a/src/main/java/com/github/yulichang/annotation/EntityMapping.java b/src/main/java/com/github/yulichang/annotation/EntityMapping.java new file mode 100644 index 0000000..5d6ffdd --- /dev/null +++ b/src/main/java/com/github/yulichang/annotation/EntityMapping.java @@ -0,0 +1,102 @@ +package com.github.yulichang.annotation; + + +import java.lang.annotation.*; + +/** + * 实体类关系映射注解 + * + * @author yulichang + * @since 1.2.0 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) +public @interface EntityMapping { + + /** + * 关联的数据库实体类
+ * 默认获取此注解所对应的类 + */ + Class tag() default Object.class; + + /** + * 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称)
+ * 默认获取当前类上定义的主键 @TableId + */ + String thisField() default ""; + + /** + * 关联类的字段名称 (是实体类字段名称而不是数据库字段名称)
+ * 默认获取关联类上定义的主键 @TableId + */ + String joinField() default ""; + + /** + * 一对一查询时 如果查询到多条记录是否抛出异常
+ * true 抛出异常
+ * false 不抛异常,获取列表第一条数据
+ */ + boolean isThrowExp() default true; + + /** + * 针对查询结果map的时候使用
+ * 默认为thisField对应的数据库列名
+ *

+ * 如果此类是以map方式查询的
+ * 并且查询出来的map的key不是thisField对应的数据库列名就需要设置
+ */ + String thisMapKey() default ""; + + /** + * isMap为true时生效
+ * 针对查询结果map的时候使用
+ * 默认为joinField对应的数据库列名
+ *

+ * 如果此类是以map方式查询的
+ * 并且查询出来的map的key不是thisField对应的数据库列名就需要设置
+ */ + String joinMapKey() default ""; + + /** + * 映射表查询条件之 select
+ * 等效于 Wrappers.query().select(xxx); + */ + String select() default ""; + + /** + * 映射表查询条件之 first
+ * 等效于 Wrappers.query().first(xxx); + */ + String first() default ""; + + /** + * 映射表查询条件之 apply
+ * 等效于 Wrappers.query().apply(xxx); + */ + MPJMappingApply[] apply() default {}; + + /** + * 映射表查询条件 + */ + MPJMappingCondition[] condition() default {}; + + /** + * 映射表查询条件之 orderBy
+ * 等效于 Wrappers.query().orderByAsc(xxx); + */ + String orderByAsc() default ""; + + /** + * 映射表查询条件之 orderByDesc
+ * 等效于 Wrappers.query().orderByDesc(xxx); + */ + String orderByDesc() default ""; + + /** + * 映射表查询条件之 last
+ * 建议不要在这使用分页语句,会导致关联查的时候查询不全
+ * 等效于 Wrappers.query().last(xxx); + */ + String last() default ""; +} diff --git a/src/main/java/com/github/yulichang/annotation/FieldMapping.java b/src/main/java/com/github/yulichang/annotation/FieldMapping.java new file mode 100644 index 0000000..a61c7db --- /dev/null +++ b/src/main/java/com/github/yulichang/annotation/FieldMapping.java @@ -0,0 +1,101 @@ +package com.github.yulichang.annotation; + + +import java.lang.annotation.*; + +/** + * 字段关系映射注解 + * + * @author yulichang + * @since 1.2.0 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) +public @interface FieldMapping { + + /** + * 关联的数据库实体类
+ * 默认获取此注解所对应的类 + */ + Class tag(); + + /** + * 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称)
+ * 默认获取当前类上定义的主键 @TableId + */ + String thisField() default ""; + + /** + * 关联类的字段名称 (是实体类字段名称而不是数据库字段名称)
+ * 默认获取关联类上定义的主键 @TableId + */ + String joinField() default ""; + + /** + * 一对一查询时 如果查询到多条记录是否抛出异常
+ * true 抛出异常
+ * false 不抛异常,获取列表第一条数据
+ */ + boolean isThrowExp() default true; + + /** + * 字段映射对应的属性名 + */ + String select(); + + /** + * 针对查询结果map的时候使用
+ * 默认为thisField对应的数据库列名
+ *

+ * 如果此类是以map方式查询的
+ * 并且查询出来的map的key不是thisField对应的数据库列名就需要设置
+ */ + String thisMapKey() default ""; + + /** + * isMap为true时生效
+ * 针对查询结果map的时候使用
+ * 默认为joinField对应的数据库列名
+ *

+ * 如果此类是以map方式查询的
+ * 并且查询出来的map的key不是thisField对应的数据库列名就需要设置
+ */ + String joinMapKey() default ""; + + /** + * 映射表查询条件之 first
+ * 等效于 Wrappers.query().first(xxx); + */ + String first() default ""; + + /** + * 映射表查询条件之 apply
+ * 等效于 Wrappers.query().apply(xxx); + */ + MPJMappingApply[] apply() default {}; + + /** + * 映射表查询条件 + */ + MPJMappingCondition[] condition() default {}; + + /** + * 映射表查询条件之 orderBy
+ * 等效于 Wrappers.query().orderByAsc(xxx); + */ + String orderByAsc() default ""; + + /** + * 映射表查询条件之 orderByDesc
+ * 等效于 Wrappers.query().orderByDesc(xxx); + */ + String orderByDesc() default ""; + + /** + * 映射表查询条件之 last
+ * 建议不要在这使用分页语句,会导致关联查的时候查询不全
+ * 等效于 Wrappers.query().last(xxx); + */ + String last() default ""; +} diff --git a/src/main/java/com/github/yulichang/annotation/MPJMappingApply.java b/src/main/java/com/github/yulichang/annotation/MPJMappingApply.java new file mode 100644 index 0000000..8784957 --- /dev/null +++ b/src/main/java/com/github/yulichang/annotation/MPJMappingApply.java @@ -0,0 +1,21 @@ +package com.github.yulichang.annotation; + +/** + * 映射表条件 + * 用法参考 mybatis plus wrapper 的 .apply()方法 + * + * @author yulichang + * @since 1.2.0 + */ +public @interface MPJMappingApply { + + /** + * sql片段 + */ + String value(); + + /** + * .apply() 对应的可变参数 + */ + String[] args() default {}; +} diff --git a/src/main/java/com/github/yulichang/annotation/MPJMappingCondition.java b/src/main/java/com/github/yulichang/annotation/MPJMappingCondition.java new file mode 100644 index 0000000..da024a5 --- /dev/null +++ b/src/main/java/com/github/yulichang/annotation/MPJMappingCondition.java @@ -0,0 +1,34 @@ +package com.github.yulichang.annotation; + +import com.baomidou.mybatisplus.core.enums.SqlKeyword; + +/** + * 映射表条件 + * + * @author yulichang + * @since 1.2.0 + */ +public @interface MPJMappingCondition { + + /** + * 条件枚举 + * 目前只实现了 = != > >= < <= + * 其他的暂未实现 TODO + * + * @see SqlKeyword + */ + SqlKeyword keyWord() default SqlKeyword.EQ; + + /** + * 数据库列名 + */ + String column(); + + /** + * 对应的值 + * 一般是一个值 + * 如果条件是 between 会取前两个 + * 如果条件是 in 就会取全部 + */ + String[] value(); +} diff --git a/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java b/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java new file mode 100644 index 0000000..c1e5479 --- /dev/null +++ b/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java @@ -0,0 +1,534 @@ +package com.github.yulichang.base.mapper; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.enums.SqlKeyword; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.*; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; +import com.github.yulichang.toolkit.LambdaUtils; + +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author yulichang + * @see BaseMapper + */ +@SuppressWarnings({"unused", "unchecked"}) +public interface MPJDeepMapper extends BaseMapper { + + /** + * 根据 ID 查询 并关联全部映射 + * + * @param id 主键ID + */ + default T selectByIdDeep(Serializable id) { + return queryMapping(selectById(id), null); + } + + /** + * 根据 ID 查询 并关联指定映射 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param id 主键ID + * @param property 需要关联的字段 + */ + default T selectByIdDeep(Serializable id, SFunction... property) { + return queryMapping(selectById(id), Arrays.asList(property)); + } + + /** + * 针对可变参数堆污染提供的重载 + * list为null或空,会查询全部映射关系 + *

+ * 例: selectByIdDeep(1, Arrays.asList(User::getId, ... )) + * + * @param id 主键ID + * @param property 需要关联的字段 + */ + default T selectByIdDeep(Serializable id, List> property) { + return queryMapping(selectById(id), property); + } + + /** + * 查询(根据ID 批量查询) + * + * @param idList 主键ID列表(不能为 null 以及 empty) + */ + default List selectBatchIdsDeep(Collection idList) { + return queryMapping(selectBatchIds(idList), null); + } + + /** + * 查询(根据ID 批量查询) + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param idList 主键ID列表(不能为 null 以及 empty) + * @param property 需要关联的字段 + */ + default List selectBatchIdsDeep(Collection idList, SFunction... property) { + return queryMapping(selectBatchIds(idList), Arrays.asList(property)); + } + + /** + * 针对可变参数堆污染提供的重载 + * list为null或空,会查询全部映射关系 + *

+ * 例: selectBatchIdsDeep(idList, Arrays.asList(User::getId, ... )) + * + * @param idList 主键ID列表(不能为 null 以及 empty) + * @param property 需要关联的字段 + */ + default List selectBatchIdsDeep(Collection idList, List> property) { + return queryMapping(selectBatchIds(idList), property); + } + + /** + * 查询(根据 columnMap 条件) + * + * @param columnMap 表字段 map 对象 + */ + default List selectByMapDeep(Map columnMap) { + return queryMapping(selectByMap(columnMap), null); + } + + /** + * 查询(根据 columnMap 条件) + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param columnMap 表字段 map 对象 + * @param property 需要关联的字段 + */ + default List selectByMapDeep(Map columnMap, SFunction... property) { + return queryMapping(selectByMap(columnMap), Arrays.asList(property)); + } + + /** + * 针对可变参数堆污染提供的重载 + * list为null或空,会查询全部映射关系 + *

+ * 例: selectByMapDeep(columnMap, Arrays.asList(User::getId, ... )) + * + * @param columnMap 表字段 map 对象 + * @param property 需要关联的字段 + */ + default List selectByMapDeep(Map columnMap, List> property) { + return queryMapping(selectByMap(columnMap), property); + } + + /** + * 根据 entity 条件,查询一条记录 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default T selectOneDeep(Wrapper queryWrapper) { + return queryMapping(selectOne(queryWrapper), null); + } + + /** + * 根据 entity 条件,查询一条记录 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default T selectOneDeep(Wrapper queryWrapper, SFunction... property) { + return queryMapping(selectOne(queryWrapper), Arrays.asList(property)); + } + + /** + * 针对可变参数堆污染提供的重载 + * list为null或空,会查询全部映射关系 + *

+ * 例: selectOneDeep(queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default T selectOneDeep(Wrapper queryWrapper, List> property) { + return queryMapping(selectOne(queryWrapper), property); + } + + /** + * 根据 entity 条件,查询全部记录 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default List selectListDeep(Wrapper queryWrapper) { + return queryMapping(selectList(queryWrapper), null); + } + + /** + * 根据 entity 条件,查询全部记录 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default List selectListDeep(Wrapper queryWrapper, SFunction... property) { + return queryMapping(selectList(queryWrapper), Arrays.asList(property)); + } + + /** + * 针对可变参数堆污染提供的重载 + * list为null或空,会查询全部映射关系 + *

+ * 例: selectListDeep(queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default List selectListDeep(Wrapper queryWrapper, List> property) { + return queryMapping(selectList(queryWrapper), property); + } + + /** + * 根据 Wrapper 条件,查询全部记录 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default List> selectMapsDeep(Class clazz, Wrapper queryWrapper) { + return queryMapMapping(selectMaps(queryWrapper), clazz, null); + } + + /** + * 根据 entity 条件,查询全部记录(并翻页) + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param clazz 实体类class + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default List> selectMapsDeep(Class clazz, Wrapper queryWrapper, SFunction... property) { + return queryMapMapping(selectMaps(queryWrapper), clazz, Arrays.asList(property)); + } + + /** + * 针对可变参数堆污染提供的重载 + * list为null或空,会查询全部映射关系 + *

+ * 例: selectMapsDeep(UserDO.class, queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default List> selectMapsDeep(Class clazz, Wrapper queryWrapper, List> property) { + return queryMapMapping(selectMaps(queryWrapper), clazz, property); + } + + /** + * 根据 entity 条件,查询全部记录(并翻页) + * + * @param page 分页查询条件(可以为 RowBounds.DEFAULT) + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default > E selectPageDeep(E page, Wrapper queryWrapper) { + E e = selectPage(page, queryWrapper); + queryMapping(e.getRecords(), null); + return e; + } + + /** + * 根据 entity 条件,查询全部记录(并翻页) + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param page 分页查询条件(可以为 RowBounds.DEFAULT) + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default > E selectPageDeep(E page, Wrapper queryWrapper, SFunction... property) { + E e = selectPage(page, queryWrapper); + queryMapping(e.getRecords(), Arrays.asList(property)); + return e; + } + + /** + * 针对可变参数堆污染提供的重载 + * list为null或空,会查询全部映射关系 + *

+ * 例: selectPageDeep(page, queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param page 分页查询条件(可以为 RowBounds.DEFAULT) + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default > E selectPageDeep(E page, Wrapper queryWrapper, List> property) { + E e = selectPage(page, queryWrapper); + queryMapping(e.getRecords(), property); + return e; + } + + + /** + * 根据 entity 条件,查询全部记录(并翻页) + * + * @param page 分页查询条件(可以为 RowBounds.DEFAULT) + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default >> E selectMapsPageDeep(E page, Class clazz, Wrapper queryWrapper) { + E e = selectMapsPage(page, queryWrapper); + queryMapMapping(e.getRecords(), clazz, null); + return e; + } + + + /** + * 根据 entity 条件,查询全部记录(并翻页) + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param page 分页查询条件(可以为 RowBounds.DEFAULT) + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default >> E selectMapsPageDeep(E page, Class clazz, Wrapper queryWrapper, + SFunction... property) { + E e = selectMapsPage(page, queryWrapper); + queryMapMapping(e.getRecords(), clazz, Arrays.asList(property)); + return e; + } + + + /** + * 针对可变参数堆污染提供的重载 + * list为null或空,会查询全部映射关系 + *

+ * 例: selectMapsPage(page, UserDO.class, queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param page 分页查询条件(可以为 RowBounds.DEFAULT) + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @param property 需要关联的字段 + */ + default >> E selectMapsPageDeep(E page, Class clazz, Wrapper queryWrapper, + List> property) { + E e = selectMapsPage(page, queryWrapper); + queryMapMapping(e.getRecords(), clazz, property); + return e; + } + + /** + * 查询映射关系
+ * 对结果进行二次查询
+ * 可以自行查询然后在通过此方法进行二次查询
+ * list为null或空,会查询全部映射关系
+ * + * @param t 第一次查询结果 + */ + default T queryMapping(T t, List> property) { + if (t == null) { + return null; + } + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass()); + if (tableInfo.isHasMappingOrField()) { + boolean hasProperty = CollectionUtils.isNotEmpty(property); + List list = hasProperty ? property.stream().map(LambdaUtils::getName).collect( + Collectors.toList()) : null; + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + if (!hasProperty || list.contains(fieldInfo.getProperty())) { + Object obj = fieldInfo.thisFieldGet(t); + if (obj != null) { + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( + fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), obj, fieldInfo); + bindData(t, fieldInfo, joinList); + fieldInfo.removeJoinField(joinList); + } + } + } + } + return t; + } + + /** + * 查询映射关系
+ * 对结果进行二次查询
+ * 可以自行查询然后在通过此方法进行二次查询
+ * list为null或空,会查询全部映射关系
+ * + * @param map 第一次查询结果 + */ + default Map queryMapMapping(Map map, Class clazz, List> property) { + if (CollectionUtils.isEmpty(map)) { + return map; + } + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(clazz); + if (tableInfo.isHasMappingOrField()) { + boolean hasProperty = CollectionUtils.isNotEmpty(property); + List list = hasProperty ? property.stream().map(LambdaUtils::getName).collect( + Collectors.toList()) : null; + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + if (!hasProperty || list.contains(fieldInfo.getProperty())) { + Object obj = map.get(fieldInfo.getThisMapKey()); + if (obj != null) { + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( + fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), obj, fieldInfo); + bindMap(map, fieldInfo, joinList); + fieldInfo.removeJoinField(joinList); + } + } + } + } + return map; + } + + /** + * 查询映射关系
+ * 对结果进行二次查询
+ * 可以自行查询然后在通过此方法进行二次查询
+ * list为null或空,会查询全部映射关系
+ * + * @param list 第一次查询结果 + */ + default List queryMapping(List list, List> property) { + if (CollectionUtils.isEmpty(list)) { + return list; + } + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(list.get(0).getClass()); + if (tableInfo.isHasMappingOrField()) { + boolean hasProperty = CollectionUtils.isNotEmpty(property); + List listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect( + Collectors.toList()) : null; + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) { + List itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(itemList)) { + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( + fieldInfo.isMappingEntity() && fieldInfo.isFieldIsMap(), SqlKeyword.IN, + fieldInfo.getJoinColumn(), itemList, fieldInfo); + list.forEach(i -> bindData(i, fieldInfo, joinList)); + fieldInfo.removeJoinField(joinList); + } else { + list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>())); + } + } + } + } + return list; + } + + /** + * 查询映射关系
+ * 对结果进行二次查询
+ * 可以自行查询然后在通过此方法进行二次查询
+ * list为null或空,会查询全部映射关系
+ * + * @param list 第一次查询结果 + */ + default List> queryMapMapping(List> list, Class clazz, List> property) { + if (CollectionUtils.isEmpty(list)) { + return list; + } + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(clazz); + if (tableInfo.isHasMappingOrField()) { + boolean hasProperty = CollectionUtils.isNotEmpty(property); + List listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect( + Collectors.toList()) : null; + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) { + List itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey())) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(itemList)) { + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( + fieldInfo.isMappingEntity() && fieldInfo.isFieldIsMap(), SqlKeyword.IN, + fieldInfo.getJoinColumn(), itemList, fieldInfo); + list.forEach(i -> bindMap(i, fieldInfo, joinList)); + fieldInfo.removeJoinField(joinList); + } else { + list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>())); + } + } + } + } + return list; + } + + /** + * 绑定数据 + */ + default void bindData(T t, MPJTableFieldInfo fieldInfo, List joinList) { + if (fieldInfo.isMappingEntity()) { + List list = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals(fieldInfo.thisFieldGet(t))) + .collect(Collectors.toList()); + MPJTableFieldInfo.bind(fieldInfo, t, list); + } + if (fieldInfo.isMappingField()) { + MPJTableFieldInfo.bind(fieldInfo, t, joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals( + fieldInfo.thisFieldGet(t))).map(fieldInfo::bindFieldGet).collect(Collectors.toList())); + } + } + + /** + * 绑定数据 + */ + default void bindMap(Map t, MPJTableFieldInfo fieldInfo, List joinList) { + List list = null; + if (fieldInfo.isMappingEntity()) { + if (fieldInfo.isFieldIsMap()) { + list = ((List>) joinList).stream().filter(j -> + j.get(fieldInfo.getJoinMapKey()).equals(t.get(fieldInfo.getThisMapKey()))) + .collect(Collectors.toList()); + } else { + list = joinList.stream().filter(j -> + fieldInfo.joinFieldGet(j).equals(t.get(fieldInfo.getThisMapKey()))) + .collect(Collectors.toList()); + } + } + if (fieldInfo.isMappingField()) { + list = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals( + t.get(fieldInfo.getThisMapKey()))).map(fieldInfo::bindFieldGet).collect(Collectors.toList()); + } + MPJTableFieldInfo.bindMap(fieldInfo, t, list); + } + + /** + * 映射 wrapper 构造器 + * 仅对使用映射注解时使用 + */ + default Object mappingWrapperConstructor(boolean selectMap, SqlKeyword keyword, + String column, Object val, MPJTableFieldInfo fieldInfo) { + MPJMappingWrapper infoWrapper = fieldInfo.getWrapper(); + MappingQuery wrapper = new MappingQuery<>(); + if (infoWrapper.isHasCondition()) { + infoWrapper.getConditionList().forEach(c -> wrapper.addCondition(true, c.getColumn(), + c.getKeyword(), c.getVal())); + } + wrapper.eq(SqlKeyword.EQ == keyword, column, val) + .first(infoWrapper.isHasFirst(), infoWrapper.getFirst()) + .orderByAsc(infoWrapper.isHasOrderByAsc(), infoWrapper.getOrderByAsc()) + .orderByDesc(infoWrapper.isHasOrderByDesc(), infoWrapper.getOrderByDesc()) + .last(infoWrapper.isHasLast(), infoWrapper.getLast()); + if (SqlKeyword.IN == keyword) { + //由于Java发放调用机制 无法使用链式 + wrapper.in(column, (List) val); + } + if (infoWrapper.isHasSelect()) { + wrapper.select(infoWrapper.getSelect()); + } + if (infoWrapper.isHasApply()) { + infoWrapper.getApplyList().forEach(a -> wrapper.apply(a.getSql(), (Object[]) a.getVal())); + } + if (selectMap) { + return selectMaps(wrapper); + } + return selectList(wrapper); + } + + /** + * 公开 addCondition 方法 + */ + class MappingQuery extends QueryWrapper { + @Override + public QueryWrapper addCondition(boolean condition, String column, SqlKeyword sqlKeyword, Object val) { + return super.addCondition(condition, column, sqlKeyword, val); + } + } +} diff --git a/src/main/java/com/github/yulichang/base/mapper/MPJJoinMapper.java b/src/main/java/com/github/yulichang/base/mapper/MPJJoinMapper.java new file mode 100644 index 0000000..f186ad4 --- /dev/null +++ b/src/main/java/com/github/yulichang/base/mapper/MPJJoinMapper.java @@ -0,0 +1,76 @@ +package com.github.yulichang.base.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.github.yulichang.interfaces.MPJBaseJoin; +import com.github.yulichang.toolkit.Constant; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @author yulichang + * @see BaseMapper + */ +public interface MPJJoinMapper extends BaseMapper { + + /** + * 根据 Wrapper 条件,查询总记录数 + * + * @param wrapper joinWrapper + */ + Integer selectJoinCount(@Param(Constants.WRAPPER) MPJBaseJoin wrapper); + + /** + * 连表查询返回一条记录 + * + * @param wrapper joinWrapper + * @param clazz resultType + */ + DTO selectJoinOne(@Param(Constant.CLAZZ) Class clazz, + @Param(Constants.WRAPPER) MPJBaseJoin wrapper); + + /** + * 连表查询返回Map + * + * @param wrapper joinWrapper + */ + Map selectJoinMap(@Param(Constants.WRAPPER) MPJBaseJoin wrapper); + + /** + * 连表查询返回记录集合 + * + * @param wrapper joinWrapper + * @param clazz resultType + */ + List selectJoinList(@Param(Constant.CLAZZ) Class clazz, + @Param(Constants.WRAPPER) MPJBaseJoin wrapper); + + /** + * 连表查询返回Map集合 + * + * @param wrapper joinWrapper + */ + List> selectJoinMaps(@Param(Constants.WRAPPER) MPJBaseJoin wrapper); + + /** + * 连表查询返回记录集合并分页 + * + * @param wrapper joinWrapper + * @param clazz resultType + * @param 分页返回对象 + */ + > IPage selectJoinPage(P page, + @Param(Constant.CLAZZ) Class clazz, + @Param(Constants.WRAPPER) MPJBaseJoin wrapper); + + /** + * 连表查询返回Map集合并分页 + * + * @param wrapper joinWrapper + */ +

> IPage> selectJoinMapsPage(P page, + @Param(Constants.WRAPPER) MPJBaseJoin wrapper); +} diff --git a/src/main/java/com/github/yulichang/base/service/MPJDeepService.java b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java new file mode 100644 index 0000000..e2c2fd1 --- /dev/null +++ b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java @@ -0,0 +1,556 @@ +package com.github.yulichang.base.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.yulichang.annotation.EntityMapping; +import com.github.yulichang.annotation.FieldMapping; +import com.github.yulichang.base.MPJBaseMapper; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 深度查询 + *

+ * 对配置了映射注解的字段进行查询 + * 目前查询深度只支持2级(只解析当前实体类的映射注解,不会对查询结果再次解析注解) + * 多级查询可能存在循环引用的问题,也可能会导致全量查询 + * + * @author yulichang + * @see EntityMapping + * @see FieldMapping + * @since 1.2.0 + */ +@SuppressWarnings({"unused", "unchecked"}) +public interface MPJDeepService extends IService { + + Class currentModelClass(); + + /** + * 根据 ID 深度查询 + * + * @param id 主键ID列表 + */ + default T getByIdDeep(Serializable id) { + return ((MPJBaseMapper) getBaseMapper()).selectByIdDeep(id); + } + + /** + * 根据 ID 深度查询 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param id 主键ID列表 + * @param property 需要关联的字段 + */ + default T getByIdDeep(Serializable id, SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).selectByIdDeep(id, property); + } + + /** + * 针对可变参数堆污染提供的重载 + * list为null或空,会查询全部映射关系 + *

+ * 例: getByIdDeep(id, Arrays.asList(User::getId, ... )) + * + * @param id 主键ID列表 + * @param property 需要关联的字段 + */ + default T getByIdDeep(Serializable id, List> property) { + return ((MPJBaseMapper) getBaseMapper()).selectByIdDeep(id, property); + } + + /** + * 查询(根据ID 批量查询) + * + * @param idList 主键ID列表 + */ + default List listByIdsDeep(Collection idList) { + return ((MPJBaseMapper) getBaseMapper()).selectBatchIdsDeep(idList); + } + + /** + * 查询(根据ID 批量查询) + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param idList 主键ID列表 + * @param property 需要关联的字段 + */ + default List listByIdsDeep(Collection idList, SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).selectBatchIdsDeep(idList, Arrays.asList(property)); + } + + /** + * 查询(根据ID 批量查询) + * list为null或空,会查询全部映射关系 + *

+ * 例: listByIdsDeep(idList, Arrays.asList(User::getId, ... )) + * + * @param idList 主键ID列表 + * @param property 需要关联的字段 + */ + default List listByIdsDeep(Collection idList, List> property) { + return ((MPJBaseMapper) getBaseMapper()).selectBatchIdsDeep(idList, property); + } + + /** + * 查询(根据 columnMap 条件) + * + * @param columnMap 表字段 map 对象 + */ + default List listByMapDeep(Map columnMap) { + return ((MPJBaseMapper) getBaseMapper()).selectByMapDeep(columnMap); + } + + /** + * 查询(根据 columnMap 条件) + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param columnMap 表字段 map 对象 + * @param property 需要关联的字段 + */ + default List listByMapDeep(Map columnMap, SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).selectByMapDeep(columnMap, Arrays.asList(property)); + } + + /** + * 查询(根据 columnMap 条件) + * list为null或空,会查询全部映射关系 + *

+ * 例: listByMapDeep(columnMap, Arrays.asList(User::getId, ... )) + * + * @param columnMap 表字段 map 对象 + * @param property 需要关联的字段 + */ + default List listByMapDeep(Map columnMap, List> property) { + return ((MPJBaseMapper) getBaseMapper()).selectByMapDeep(columnMap, property); + } + + + /** + * 根据 Wrapper,查询一条记录
+ *

结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")

+ * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default T getOneDeep(Wrapper queryWrapper) { + return ((MPJBaseMapper) getBaseMapper()).selectOneDeep(queryWrapper); + } + + /** + * 根据 Wrapper,查询一条记录
+ *

结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")

+ *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default T getOneDeep(Wrapper queryWrapper, SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).selectOneDeep(queryWrapper, Arrays.asList(property)); + } + + /** + * 根据 Wrapper,查询一条记录
+ * list为null或空,会查询全部映射关系
+ *

结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")

+ *

+ * 例: getOneDeep(queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default T getOneDeep(Wrapper queryWrapper, List> property) { + return ((MPJBaseMapper) getBaseMapper()).selectOneDeep(queryWrapper, property); + } + + /** + * 根据 Wrapper,查询一条记录 + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param throwEx 有多个 result 是否抛出异常 + */ + default T getOneDeep(Wrapper queryWrapper, boolean throwEx) { + return ((MPJBaseMapper) getBaseMapper()).queryMapping(getOne(queryWrapper, throwEx), null); + } + + /** + * 根据 Wrapper,查询一条记录 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param throwEx 有多个 result 是否抛出异常 + * @param property 需要关联的字段 + */ + default T getOneDeep(Wrapper queryWrapper, boolean throwEx, SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).queryMapping(getOne(queryWrapper, throwEx), Arrays.asList(property)); + } + + /** + * 根据 Wrapper,查询一条记录 + * list为null或空,会查询全部映射关系 + *

+ * 例: getOneDeep(queryWrapper, throwEx, Arrays.asList(User::getId, ... )) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param throwEx 有多个 result 是否抛出异常 + * @param property 需要关联的字段 + */ + default T getOneDeep(Wrapper queryWrapper, boolean throwEx, List> property) { + return ((MPJBaseMapper) getBaseMapper()).queryMapping(getOne(queryWrapper, throwEx), property); + } + + /** + * 根据 Wrapper,查询一条记录 + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default Map getMapDeep(Wrapper queryWrapper) { + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(), + null); + } + + /** + * 根据 Wrapper,查询一条记录 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default Map getMapDeep(Wrapper queryWrapper, SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(), + Arrays.asList(property)); + } + + /** + * 根据 Wrapper,查询一条记录 + * list为null或空,会查询全部映射关系 + *

+ * 例:getMapDeep(queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default Map getMapDeep(Wrapper queryWrapper, List> property) { + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(), property); + } + + /** + * 查询列表 + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default List listDeep(Wrapper queryWrapper) { + return ((MPJBaseMapper) getBaseMapper()).selectListDeep(queryWrapper); + } + + /** + * 查询列表 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default List listDeep(Wrapper queryWrapper, SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).selectListDeep(queryWrapper, Arrays.asList(property)); + } + + /** + * 查询列表 + * list为null或空,会查询全部映射关系 + *

+ * 例:listDeep(queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default List listDeep(Wrapper queryWrapper, List> property) { + return ((MPJBaseMapper) getBaseMapper()).selectListDeep(queryWrapper, property); + } + + /** + * 查询所有 + * + * @see Wrappers#emptyWrapper() + */ + default List listDeep() { + return ((MPJBaseMapper) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper()); + } + + /** + * 查询所有 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param property 需要关联的字段 + * @see Wrappers#emptyWrapper() + */ + default List listDeep(SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), Arrays.asList(property)); + } + + /** + * 查询所有 + * list为null或空,会查询全部映射关系 + *

+ * 例:listDeep(Arrays.asList(User::getId, ... )) + * + * @param property 需要关联的字段 + * @see Wrappers#emptyWrapper() + */ + default List listDeep(List> property) { + return ((MPJBaseMapper) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), property); + } + + /** + * 翻页查询 + * + * @param page 翻页对象 + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default > E pageDeep(E page, Wrapper queryWrapper) { + E e = page(page, queryWrapper); + ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords(), null); + return e; + } + + /** + * 翻页查询 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param page 翻页对象 + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default > E pageDeep(E page, Wrapper queryWrapper, SFunction... property) { + E e = page(page, queryWrapper); + ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords(), Arrays.asList(property)); + return e; + } + + /** + * 翻页查询 + * list为null或空,会查询全部映射关系 + *

+ * 例:pageDeep(page, queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param page 翻页对象 + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default > E pageDeep(E page, Wrapper queryWrapper, List> property) { + E e = page(page, queryWrapper); + ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords(), property); + return e; + } + + /** + * 无条件翻页查询 + * + * @param page 翻页对象 + * @see Wrappers#emptyWrapper() + */ + default > E pageDeep(E page) { + E e = page(page); + ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords(), null); + return e; + } + + /** + * 无条件翻页查询 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param page 翻页对象 + * @param property 需要关联的字段 + * @see Wrappers#emptyWrapper() + */ + default > E pageDeep(E page, SFunction... property) { + E e = page(page); + ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords(), Arrays.asList(property)); + return e; + } + + /** + * 无条件翻页查询 + * list为null或空,会查询全部映射关系 + *

+ * 例:pageDeep(page, Arrays.asList(User::getId, ... )) + * + * @param page 翻页对象 + * @param property 需要关联的字段 + * @see Wrappers#emptyWrapper() + */ + default > E pageDeep(E page, List> property) { + E e = page(page); + ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords(), property); + return e; + } + + /** + * 查询列表 + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default List> listMapsDeep(Wrapper queryWrapper) { + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), null); + } + + /** + * 查询列表 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default List> listMapsDeep(Wrapper queryWrapper, SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), + Arrays.asList(property)); + } + + /** + * 查询列表 + * list为null或空,会查询全部映射关系 + *

+ * 例:listMapsDeep(queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default List> listMapsDeep(Wrapper queryWrapper, List> property) { + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), property); + } + + /** + * 查询所有列表 + * + * @see Wrappers#emptyWrapper() + */ + default List> listMapsDeep() { + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), null); + } + + /** + * 查询所有列表 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param property 需要关联的字段 + * @see Wrappers#emptyWrapper() + */ + default List> listMapsDeep(SFunction... property) { + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), Arrays.asList(property)); + } + + /** + * 查询所有列表 + * list为null或空,会查询全部映射关系 + *

+ * 例:listMapsDeep(Arrays.asList(User::getId, ... )) + * + * @param property 需要关联的字段 + * @see Wrappers#emptyWrapper() + */ + default List> listMapsDeep(List> property) { + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), property); + } + + /** + * 翻页查询 + * + * @param page 翻页对象 + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default >> E pageMapsDeep(E page, Wrapper queryWrapper) { + E e = pageMaps(page, queryWrapper); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), null); + return e; + } + + /** + * 翻页查询 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param page 翻页对象 + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default >> E pageMapsDeep(E page, Wrapper queryWrapper, SFunction... property) { + E e = pageMaps(page, queryWrapper); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property)); + return e; + } + + /** + * 翻页查询 + * list为null或空,会查询全部映射关系 + *

+ * 例:pageMapsDeep(page, queryWrapper, Arrays.asList(User::getId, ... )) + * + * @param page 翻页对象 + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param property 需要关联的字段 + */ + default >> E pageMapsDeep(E page, Wrapper queryWrapper, List> property) { + E e = pageMaps(page, queryWrapper); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), property); + return e; + } + + /** + * 无条件翻页查询 + * + * @param page 翻页对象 + * @see Wrappers#emptyWrapper() + */ + default >> E pageMapsDeep(E page) { + E e = pageMaps(page); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), null); + return e; + } + + /** + * 无条件翻页查询 + *

+ * JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) + * + * @param page 翻页对象 + * @param property 需要关联的字段 + * @see Wrappers#emptyWrapper() + */ + default >> E pageMapsDeep(E page, SFunction... property) { + E e = pageMaps(page); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property)); + return e; + } + + /** + * 无条件翻页查询 + * list为null或空,会查询全部映射关系 + *

+ * 例:pageMapsDeep(page, Arrays.asList(User::getId, ... )) + * + * @param page 翻页对象 + * @param property 需要关联的字段 + * @see Wrappers#emptyWrapper() + */ + default >> E pageMapsDeep(E page, List> property) { + E e = pageMaps(page); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), property); + return e; + } +} diff --git a/src/main/java/com/github/yulichang/base/service/MPJJoinService.java b/src/main/java/com/github/yulichang/base/service/MPJJoinService.java new file mode 100644 index 0000000..b68b87b --- /dev/null +++ b/src/main/java/com/github/yulichang/base/service/MPJJoinService.java @@ -0,0 +1,66 @@ +package com.github.yulichang.base.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.yulichang.base.MPJBaseMapper; +import com.github.yulichang.interfaces.MPJBaseJoin; + +import java.util.List; +import java.util.Map; + +/** + * @author yulichang + * @see IService + */ +@SuppressWarnings("unused") +public interface MPJJoinService extends IService { + + /** + * 根据 Wrapper 条件,查询总记录数 + */ + default Integer selectJoinCount(MPJBaseJoin wrapper) { + return ((MPJBaseMapper) getBaseMapper()).selectJoinCount(wrapper); + } + + /** + * 连接查询返回一条记录 + */ + default DTO selectJoinOne(Class clazz, MPJBaseJoin wrapper) { + return ((MPJBaseMapper) getBaseMapper()).selectJoinOne(clazz, wrapper); + } + + /** + * 连接查询返回集合 + */ + default List selectJoinList(Class clazz, MPJBaseJoin wrapper) { + return ((MPJBaseMapper) getBaseMapper()).selectJoinList(clazz, wrapper); + } + + /** + * 连接查询返回集合并分页 + */ + default > IPage selectJoinListPage(P page, Class clazz, MPJBaseJoin wrapper) { + return ((MPJBaseMapper) getBaseMapper()).selectJoinPage(page, clazz, wrapper); + } + + /** + * 连接查询返回Map + */ + default Map selectJoinMap(MPJBaseJoin wrapper) { + return ((MPJBaseMapper) getBaseMapper()).selectJoinMap(wrapper); + } + + /** + * 连接查询返回Map集合 + */ + default List> selectJoinMaps(MPJBaseJoin wrapper) { + return ((MPJBaseMapper) getBaseMapper()).selectJoinMaps(wrapper); + } + + /** + * 连接查询返回Map集合并分页 + */ + default

>> IPage> selectJoinMapsPage(P page, MPJBaseJoin wrapper) { + return ((MPJBaseMapper) getBaseMapper()).selectJoinMapsPage(page, wrapper); + } +} diff --git a/src/main/java/com/github/yulichang/config/MappingConfig.java b/src/main/java/com/github/yulichang/config/MappingConfig.java new file mode 100644 index 0000000..e3d4a3b --- /dev/null +++ b/src/main/java/com/github/yulichang/config/MappingConfig.java @@ -0,0 +1,22 @@ +package com.github.yulichang.config; + +import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; +import com.baomidou.mybatisplus.core.metadata.MPJTableMapperHelper; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.ApplicationListener; + +/** + * 关系映射配置 + * + * @author yulichang + * @since 1.2.0 + */ +public class MappingConfig implements ApplicationListener { + + @Override + public void onApplicationEvent(ApplicationReadyEvent event) { + TableInfoHelper.getTableInfos().forEach(i -> + MPJTableInfoHelper.initTableInfo(i.getEntityType(), MPJTableMapperHelper.get(i.getEntityType()))); + } +} diff --git a/src/main/java/com/github/yulichang/toolkit/SpringContentUtils.java b/src/main/java/com/github/yulichang/toolkit/SpringContentUtils.java new file mode 100644 index 0000000..7beb082 --- /dev/null +++ b/src/main/java/com/github/yulichang/toolkit/SpringContentUtils.java @@ -0,0 +1,25 @@ +package com.github.yulichang.toolkit; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * spring容器工具类 + * + * @author yulichang + * @since 1.2.0 + */ +public class SpringContentUtils implements ApplicationContextAware { + + private static ApplicationContext context; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + context = applicationContext; + } + + public static ApplicationContext getApplicationContext() { + return context; + } +}