From 866bccff286cd6967b2102a9972892cfcf1b0164 Mon Sep 17 00:00:00 2001 From: bjdys Date: Thu, 12 Aug 2021 09:28:32 +0800 Subject: [PATCH 01/33] =?UTF-8?q?=E4=B8=80=E5=AF=B9=E4=B8=80=20=E4=B8=80?= =?UTF-8?q?=E5=AF=B9=E5=A4=9A=20=E5=85=B3=E7=B3=BB=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 +- .../core/metadata/MPJMappingWrapper.java | 86 +++++ .../core/metadata/MPJTableFieldInfo.java | 243 ++++++++++++++ .../core/metadata/MPJTableInfo.java | 38 +++ .../core/metadata/MPJTableInfoHelper.java | 117 +++++-- .../yulichang/annotation/MPJMapping.java | 88 +++++ .../yulichang/annotation/MPJMappingApply.java | 21 ++ .../annotation/MPJMappingCondition.java | 34 ++ .../yulichang/base/MPJBaseDeepService.java | 307 ++++++++++++++++++ .../yulichang/base/MPJBaseJoinService.java | 65 ++++ .../github/yulichang/base/MPJBaseMapper.java | 47 +++ .../github/yulichang/base/MPJBaseService.java | 50 +-- .../yulichang/base/MPJBaseServiceImpl.java | 66 +--- .../yulichang/injector/MPJSqlInjector.java | 36 +- .../yulichang/interceptor/MPJInterceptor.java | 9 +- .../yulichang/toolkit/SpringContentUtils.java | 25 ++ src/main/resources/META-INF/spring.factories | 3 +- 17 files changed, 1074 insertions(+), 166 deletions(-) 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/github/yulichang/annotation/MPJMapping.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/MPJBaseDeepService.java create mode 100644 src/main/java/com/github/yulichang/base/MPJBaseJoinService.java create mode 100644 src/main/java/com/github/yulichang/toolkit/SpringContentUtils.java diff --git a/pom.xml b/pom.xml index 0cdb9ad..86c0ff6 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.yulichang mybatis-plus-join - 1.1.8 + 1.1.9-SNAPSHOT mybatis-plus-join An enhanced toolkit of Mybatis-Plus to simplify development. https://github.com/yulichang/mybatis-plus-join @@ -32,6 +32,9 @@ UTF-8 1.8 1.8 + + 1.8 + 1.8 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..7a1bb20 --- /dev/null +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java @@ -0,0 +1,86 @@ +package com.baomidou.mybatisplus.core.metadata; + + +import com.baomidou.mybatisplus.core.enums.SqlKeyword; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.github.yulichang.annotation.MPJMapping; +import com.github.yulichang.annotation.MPJMappingApply; +import com.github.yulichang.annotation.MPJMappingCondition; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 关联查询条件 + * + * @author yulichang + * @since 1.2.0 + */ +@Data +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; + + public MPJMappingWrapper(MPJMapping mapping) { + this.hasFirst = StringUtils.isNotBlank(mapping.first()); + if (this.hasFirst) { + this.first = mapping.first(); + } + + this.hasSelect = StringUtils.isNotBlank(mapping.select()); + if (this.hasSelect) { + this.select = mapping.select(); + } + + this.hasApply = mapping.apply().length > 0; + if (this.hasApply) { + this.applyList = new ArrayList<>(); + for (MPJMappingApply apply : mapping.apply()) { + this.applyList.add(new Apply(apply.value(), apply.args())); + } + } + + this.hasCondition = mapping.condition().length > 0; + if (this.hasCondition) { + this.conditionList = new ArrayList<>(); + for (MPJMappingCondition condition : mapping.condition()) { + conditionList.add(new Condition(condition.keyWord(), condition.column(), condition.value())); + } + } + + this.hasLast = StringUtils.isNotBlank(mapping.last()); + if (this.hasLast) { + this.last = mapping.last(); + } + } + + @Data + @AllArgsConstructor + public static class Apply { + private String sql; + private String[] val; + } + + @Data + @AllArgsConstructor + public static class Condition { + private SqlKeyword keyword; + private String column; + private 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..42e3db6 --- /dev/null +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java @@ -0,0 +1,243 @@ +package com.baomidou.mybatisplus.core.metadata; + +import com.baomidou.mybatisplus.core.toolkit.Assert; +import com.baomidou.mybatisplus.core.toolkit.ClassUtils; +import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.github.yulichang.annotation.MPJMapping; +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.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * 字段属性 + * + * @author yulichang + * @see TableFieldInfo + * @since 1.2.0 + */ +@Getter +@ToString +@EqualsAndHashCode +public class MPJTableFieldInfo { + + /** + * 实体类 + */ + private final Class entityType; + /** + * 属性 + */ + private final Field field; + /** + * 属性 + */ + private final boolean fieldIsMap; + /** + * 属性是否是集合 + */ + private final boolean isCollection; + /** + * 当前映射属性 + */ + private Field thisField; + /** + * 当前类实体属性 + */ + private final String thisProperty; + /** + * 当前字段信息 + */ + private String thisColumn; + /** + * 当前字段信息 + */ + private String thisMapKey; + /** + * 映射实体类 + */ + private final Class joinClass; + /** + * 映射属性名 + */ + private final String joinProperty; + /** + * 映射属性数据库列名 + */ + private String joinColumn; + /** + * 映射属性字段 + */ + private Field joinField; + /** + * fieldIsMap 为true时使用 + * 映射查询Map 的key + * 默认为 关联字段的数据库列名 + */ + private String joinMapKey; + /** + * 关联的mapper引用 + */ + private MPJBaseMapper joinMapper; + /** + * 关联查询条件配置 + */ + private final MPJMappingWrapper wrapper; + + /** + * 初始化关联字段信息 + */ + public MPJTableFieldInfo(Class entityType, MPJMapping mapping, Field field) { + field.setAccessible(true); + this.entityType = entityType; + this.field = field; + this.joinClass = mapping.tag(); + this.isCollection = Collection.class.isAssignableFrom(field.getType()); + this.thisMapKey = StringUtils.isBlank(mapping.thisMapKey()) ? null : mapping.thisMapKey(); + this.joinMapKey = StringUtils.isBlank(mapping.joinMapKsy()) ? null : mapping.joinMapKsy(); + this.fieldIsMap = mapping.isMap();//TODO 应该可以自动检测 + this.wrapper = new MPJMappingWrapper(mapping); + if (this.isCollection && field.getType() != List.class && field.getType() != ArrayList.class) { + throw new MPJException("对多关系的数据结构目前只支持 暂不支持其他Collection实现 " + field.getType().getTypeName()); + } + if (StringUtils.isNotBlank(mapping.joinField())) { + this.joinProperty = mapping.joinField(); + } else { + TableInfo info = getTableInfo(this.joinClass); + Assert.isTrue(info.havePK(), "实体未定义主键 %s ", this.joinClass.getName()); + this.joinProperty = info.getKeyProperty(); + } + if (StringUtils.isNotBlank(mapping.thisField())) { + this.thisProperty = mapping.thisField(); + } else { + TableInfo info = getTableInfo(this.entityType); + Assert.isTrue(info.havePK(), "实体未定义主键 %s ", this.entityType.getName()); + this.thisProperty = info.getKeyProperty(); + } + } + + @SuppressWarnings("ConstantConditions") + public Field getThisField() { + if (this.thisField == null) { + 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, "MPJMapping注解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, "MPJMapping注解thisField不存在 %s , %s", entityType.getName(), + StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty); + this.thisField = fieldInfo.getField(); + this.thisColumn = fieldInfo.getColumn(); + } + this.thisField.setAccessible(true); + } + return this.thisField; + } + + public String getJoinColumn() { + if (StringUtils.isBlank(this.joinColumn)) { + 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, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(), + StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); + Assert.notNull(this.joinColumn, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(), + StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); + this.joinField.setAccessible(true); + } + return this.joinColumn; + } + + public String getThisMapKey() { + if (this.thisMapKey == null) { + this.thisMapKey = getJoinColumn(); + } + return this.thisMapKey; + } + + public Field getJoinField() { + if (this.joinField == null) { + this.getJoinColumn(); + } + return this.joinField; + } + + + public String getJoinMapKey() { + if (this.joinMapKey == null) { + this.joinMapKey = getJoinColumn(); + } + return joinMapKey; + } + + 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()); + } + } +} 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..a54a309 --- /dev/null +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java @@ -0,0 +1,38 @@ +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 { + + private TableInfo tableInfo; + + /** + * 是否包含映射注解 + */ + private boolean hasMapping; + + /** + * mapperClass + */ + private Class mapperClass; + + /** + * 包含映射注解的字段列表 + */ + private List fieldList; +} diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java index e555896..e8f9f52 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java @@ -3,6 +3,8 @@ package com.baomidou.mybatisplus.core.metadata; import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.core.config.GlobalConfig; import com.baomidou.mybatisplus.core.toolkit.*; +import com.github.yulichang.annotation.MPJMapping; +import org.apache.ibatis.builder.MapperBuilderAssistant; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; import org.apache.ibatis.mapping.ResultFlag; @@ -38,7 +40,7 @@ public class MPJTableInfoHelper { /** * 储存反射类表信息 */ - private static final Map, TableInfo> TABLE_INFO_CACHE = new ConcurrentHashMap<>(); + private static final Map, MPJTableInfo> TABLE_INFO_CACHE = new ConcurrentHashMap<>(); /** * 默认表主键名称 @@ -54,13 +56,47 @@ public class MPJTableInfoHelper { * @param clazz 反射实体类 * @return 数据库表反射信息 */ - public static TableInfo getTableInfo(Class clazz) { + public static MPJTableInfo getTableInfo(Class clazz) { if (clazz == null || ReflectionKit.isPrimitiveOrWrapper(clazz) || clazz == String.class || clazz.isInterface()) { return null; } return TABLE_INFO_CACHE.get(clazz); } + /** + *

+ * 实体类反射获取表信息【初始化】 + *

+ * + * @param clazz 反射实体类 + * @param mapperClass mapperClass + */ + public synchronized static void initTableInfo(MapperBuilderAssistant builderAssistant, Class clazz, Class mapperClass) { + MPJTableInfo targetTableInfo = TABLE_INFO_CACHE.get(clazz); + final Configuration configuration = builderAssistant.getConfiguration(); + if (targetTableInfo != null) { + Configuration oldConfiguration = targetTableInfo.getTableInfo().getConfiguration(); + if (!oldConfiguration.equals(configuration)) { + // 不是同一个 Configuration,进行重新初始化 + initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz, mapperClass); + } + return; + } + initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz, mapperClass); + } + + + /** + *

+ * 获取所有实体映射表信息 + *

+ * + * @return 数据库表反射信息集合 + */ + public static List getTableInfos() { + return Collections.unmodifiableList(new ArrayList<>(TABLE_INFO_CACHE.values())); + } + /** *

* 实体类反射获取表信息【初始化】 @@ -69,13 +105,26 @@ public class MPJTableInfoHelper { * @param clazz 反射实体类 * @return 数据库表反射信息 */ - public synchronized static TableInfo initTableInfo(Configuration configuration, String currentNamespace, Class clazz) { - TableInfo info = TABLE_INFO_CACHE.get(clazz); + public synchronized static MPJTableInfo initTableInfo(Configuration configuration, String currentNamespace, Class clazz, Class mapperClass) { + MPJTableInfo info = TABLE_INFO_CACHE.get(clazz); if (info != null) { return info; } /* 没有获取到缓存信息,则初始化 */ - TableInfo tableInfo = new TableInfo(clazz); + MPJTableInfo mpjTableInfo = new MPJTableInfo(); + mpjTableInfo.setMapperClass(mapperClass); + TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz); + if (tableInfo != null) { + mpjTableInfo.setTableInfo(tableInfo); + initMapping(mpjTableInfo); + /* 添加缓存 */ + TABLE_INFO_CACHE.put(clazz, mpjTableInfo); + return mpjTableInfo; + } + + + tableInfo = new TableInfo(clazz); + mpjTableInfo.setTableInfo(tableInfo); tableInfo.setCurrentNamespace(currentNamespace); tableInfo.setConfiguration(configuration); GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration); @@ -86,17 +135,20 @@ public class MPJTableInfoHelper { List excludePropertyList = excludeProperty != null && excludeProperty.length > 0 ? Arrays.asList(excludeProperty) : Collections.emptyList(); /* 初始化字段相关 */ - initTableFields(clazz, globalConfig, tableInfo, excludePropertyList); + initTableFields(clazz, globalConfig, mpjTableInfo, excludePropertyList); /* 自动构建 resultMap */ initResultMapIfNeed(tableInfo); /* 添加缓存 */ - TABLE_INFO_CACHE.put(clazz, tableInfo); + TABLE_INFO_CACHE.put(clazz, mpjTableInfo); /* 缓存 lambda */ LambdaUtils.installCache(tableInfo); - return tableInfo; + + /* 初始化映射关系 */ + initMapping(mpjTableInfo); + return mpjTableInfo; } @@ -179,10 +231,6 @@ public class MPJTableInfoHelper { tableInfo.setTableName(targetTableName); - /* 开启了自定义 KEY 生成器 */ -// if (CollectionUtils.isNotEmpty(dbConfig.getKeyGenerators())) { -// tableInfo.setKeySequence(clazz.getAnnotation(KeySequence.class)); -// } return excludeProperty; } @@ -216,12 +264,12 @@ public class MPJTableInfoHelper { * * @param clazz 实体类 * @param globalConfig 全局配置 - * @param tableInfo 数据库表反射信息 + * @param mpjTableInfo 数据库表反射信息 */ - private static void initTableFields(Class clazz, GlobalConfig globalConfig, TableInfo tableInfo, List excludeProperty) { + private static void initTableFields(Class clazz, GlobalConfig globalConfig, MPJTableInfo mpjTableInfo, List excludeProperty) { /* 数据库全局配置 */ GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig(); - ReflectorFactory reflectorFactory = tableInfo.getConfiguration().getReflectorFactory(); + ReflectorFactory reflectorFactory = mpjTableInfo.getTableInfo().getConfiguration().getReflectorFactory(); Reflector reflector = reflectorFactory.findForClass(clazz); List list = getAllFields(clazz); // 标记是否读取到主键 @@ -244,31 +292,33 @@ public class MPJTableInfoHelper { if (isReadPK) { throw ExceptionUtils.mpe("@TableId can't more than one in Class: \"%s\".", clazz.getName()); } else { - initTableIdWithAnnotation(dbConfig, tableInfo, field, tableId, reflector); + initTableIdWithAnnotation(dbConfig, mpjTableInfo.getTableInfo(), field, tableId, reflector); isReadPK = true; continue; } } } else if (!isReadPK) { - isReadPK = initTableIdWithoutAnnotation(dbConfig, tableInfo, field, reflector); + isReadPK = initTableIdWithoutAnnotation(dbConfig, mpjTableInfo.getTableInfo(), field, reflector); if (isReadPK) { continue; } } + final TableField tableField = field.getAnnotation(TableField.class); /* 有 @TableField 注解的字段初始化 */ if (tableField != null) { - fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, tableField, reflector, existTableLogic)); + fieldList.add(new TableFieldInfo(dbConfig, mpjTableInfo.getTableInfo(), field, tableField, reflector, existTableLogic)); continue; } /* 无 @TableField 注解的字段初始化 */ - fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, reflector, existTableLogic)); + fieldList.add(new TableFieldInfo(dbConfig, mpjTableInfo.getTableInfo(), field, reflector, existTableLogic)); } /* 字段列表 */ - tableInfo.setFieldList(fieldList); + mpjTableInfo.getTableInfo().setFieldList(fieldList); + /* 未发现主键注解,提示警告信息 */ if (!isReadPK) { @@ -300,6 +350,10 @@ public class MPJTableInfoHelper { return list.stream().anyMatch(field -> field.isAnnotationPresent(TableLogic.class)); } + private static boolean isExistMapping(Class clazz) { + return ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz)).stream().anyMatch(field -> field.isAnnotationPresent(MPJMapping.class)); + } + /** *

* 主键属性初始化 @@ -430,4 +484,27 @@ public class MPJTableInfoHelper { return (tableField == null || tableField.exist()); }).collect(toList()); } + + /** + * 初始化映射相关 + */ + public static void initMapping(MPJTableInfo mpjTableInfo) { + // 是否存在 @MPJMapping 注解 + boolean existMapping = isExistMapping(mpjTableInfo.getTableInfo().getEntityType()); + mpjTableInfo.setHasMapping(existMapping); + /* 关系映射初始化 */ + List mpjFieldList = new ArrayList<>(); + List fields = ReflectionKit.getFieldList(ClassUtils.getUserClass(mpjTableInfo.getTableInfo().getEntityType())); + for (Field field : fields) { + if (existMapping) { + MPJMapping mapping = field.getAnnotation(MPJMapping.class); + if (mapping != null) { + mpjFieldList.add(new MPJTableFieldInfo(mpjTableInfo.getTableInfo().getEntityType(), mapping, field)); + } + } + } + /* 映射字段列表 */ + mpjTableInfo.setFieldList(mpjFieldList); + } + } diff --git a/src/main/java/com/github/yulichang/annotation/MPJMapping.java b/src/main/java/com/github/yulichang/annotation/MPJMapping.java new file mode 100644 index 0000000..f1f60fd --- /dev/null +++ b/src/main/java/com/github/yulichang/annotation/MPJMapping.java @@ -0,0 +1,88 @@ +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 MPJMapping { + + /** + * 关联的数据库实体类 + */ + Class tag(); + + /** + * 当前类的属性数据结构 是否是Map 或 List + * 如果是 true 关联查询会调用 getMap() / listMaps() 等Map相关方法进行匹配 + * 如果是 false 关联查询会调用 getOne() / getById() / list() 等实体类相关方法进行匹配 + */ + boolean isMap() default false; + + /** + * 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称) + * 默认获取当前类上定义的主键 @TableId + */ + String thisField() default ""; + + /** + * 关联类的字段名称 (是实体类字段名称而不是数据库字段名称) + * 默认获取关联类上定义的主键 @TableId + */ + String joinField() default ""; + + /** + * 针对查询结果map的时候使用 + * 默认为thisField对应的数据库列名 + *

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

+ * 如果此类是以map方式查询的 + * 并且查询出来的map的key不是thisField对应的数据库列名就需要设置 + */ + String joinMapKsy() 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 {}; + + /** + * 映射表查询条件之 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..a060ad2 --- /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(); +} 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/MPJBaseDeepService.java b/src/main/java/com/github/yulichang/base/MPJBaseDeepService.java new file mode 100644 index 0000000..7ed7143 --- /dev/null +++ b/src/main/java/com/github/yulichang/base/MPJBaseDeepService.java @@ -0,0 +1,307 @@ +package com.github.yulichang.base; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.enums.SqlKeyword; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.MPJTableFieldInfo; +import com.baomidou.mybatisplus.core.metadata.MPJTableInfo; +import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.yulichang.annotation.MPJMapping; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 深度查询 + *

+ * 对配置了@MPJMapping注解的字段进行查询 + * 目前查询深度只支持2级(只解析当前实体类的MPJMapping注解,不会对查询结果再次解析注解) + * 多级查询可能存在循环引用的问题,也可能会导致全量查询 + * + * @author yulichang + * @see MPJMapping + * @since 1.2.0 + */ +@SuppressWarnings("unused") +public interface MPJBaseDeepService extends IService { + + Class currentModelClass(); + + /** + * 根据 ID 深度查询 + * + * @param id 主键ID列表 + */ + default T getByIdDeep(Serializable id) { + return queryMapping(getById(id)); + } + + + /** + * 查询(根据ID 批量查询) + * + * @param idList 主键ID列表 + */ + default List listByIdsDeep(Collection idList) { + return queryMapping(listByIds(idList)); + } + + /** + * 查询(根据 columnMap 条件) + * + * @param columnMap 表字段 map 对象 + */ + default List listByMapDeep(Map columnMap) { + return queryMapping(listByMap(columnMap)); + } + + + /** + * 根据 Wrapper,查询一条记录
+ *

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

+ * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default T getOneDeep(Wrapper queryWrapper) { + return queryMapping(getOne(queryWrapper)); + } + + + /** + * 根据 Wrapper,查询一条记录 + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + * @param throwEx 有多个 result 是否抛出异常 + */ + default T getOneDeep(Wrapper queryWrapper, boolean throwEx) { + return queryMapping(getOne(queryWrapper, throwEx)); + } + + /** + * 根据 Wrapper,查询一条记录 + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default Map getMapDeep(Wrapper queryWrapper) { + Map map = getMap(queryWrapper); + if (CollectionUtils.isNotEmpty(map)) { + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); + if (tableInfo.isHasMapping()) { + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + Object o = map.get(fieldInfo.getThisMapKey()); + if (o != null) { + map.put(fieldInfo.getField().getName(), fieldInfo.getJoinMapper() + .mappingWrapperConstructor(fieldInfo.isCollection(), fieldInfo.isFieldIsMap(), SqlKeyword.EQ, + fieldInfo.getJoinColumn(), o, fieldInfo)); + } + } + } + } + return map; + } + + + /** + * 查询列表 + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default List listDeep(Wrapper queryWrapper) { + return queryMapping(list(queryWrapper)); + } + + /** + * 查询所有 + * + * @see Wrappers#emptyWrapper() + */ + default List listDeep() { + return queryMapping(list()); + } + + /** + * 翻页查询 + * + * @param page 翻页对象 + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default > E pageDeep(E page, Wrapper queryWrapper) { + E e = page(page, queryWrapper); + if (CollectionUtils.isNotEmpty(e.getRecords())) { + queryMapping(e.getRecords()); + } + return e; + } + + /** + * 无条件翻页查询 + * + * @param page 翻页对象 + * @see Wrappers#emptyWrapper() + */ + default > E pageDeep(E page) { + E e = page(page); + if (CollectionUtils.isNotEmpty(e.getRecords())) { + queryMapping(e.getRecords()); + } + return e; + } + + /** + * 查询列表 + * + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default List> listMapsDeep(Wrapper queryWrapper) { + return queryMapMapping(listMaps(queryWrapper)); + } + + /** + * 查询所有列表 + * + * @see Wrappers#emptyWrapper() + */ + default List> listMapsDeep() { + return queryMapMapping(listMaps()); + } + + + /** + * 翻页查询 + * + * @param page 翻页对象 + * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ + default >> E pageMapsDeep(E page, Wrapper queryWrapper) { + E e = pageMaps(page, queryWrapper); + if (CollectionUtils.isNotEmpty(e.getRecords())) { + queryMapMapping(e.getRecords()); + } + return e; + } + + /** + * 无条件翻页查询 + * + * @param page 翻页对象 + * @see Wrappers#emptyWrapper() + */ + default >> E pageMapsDeep(E page) { + E e = pageMaps(page); + if (CollectionUtils.isNotEmpty(e.getRecords())) { + queryMapMapping(e.getRecords()); + } + return e; + } + + /** + * 查询映射关系 + * 对结果进行二次查询 + * 可以自行查询然后在通过此方法进行二次查询 + * + * @param t 第一次查询结果 + */ + default T queryMapping(T t) { + if (t == null) { + return null; + } + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); + if (tableInfo.isHasMapping()) { + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + Object get = fieldInfo.thisFieldGet(t); + if (get != null) { + fieldInfo.fieldSet(t, fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isCollection(), + fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), + get, fieldInfo)); + } + } + } + return t; + } + + /** + * 查询映射关系 + * 对结果进行二次查询 + * 可以自行查询然后在通过此方法进行二次查询 + * + * @param list 第一次查询结果 + */ + default List queryMapping(List list) { + if (CollectionUtils.isEmpty(list)) { + return list; + } + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); + if (tableInfo.isHasMapping()) { + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + List itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(itemList)) { + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(true, + fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); + list.forEach(i -> { + Stream stream = joinList.stream().filter(j -> + fieldInfo.joinFieldGet(j).equals(fieldInfo.thisFieldGet(i))); + fieldInfo.fieldSet(i, fieldInfo.isCollection() ? stream.collect(Collectors.toList()) : + stream.findFirst().orElse(null)); + }); + } else { + list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>())); + } + } + } + return list; + } + + /** + * 查询映射关系 + * 对结果进行二次查询 + * 可以自行查询然后在通过此方法进行二次查询 + * + * @param list 第一次查询结果 + */ + @SuppressWarnings("unchecked") + default List> queryMapMapping(List> list) { + if (CollectionUtils.isEmpty(list)) { + return list; + } + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); + if (tableInfo.isHasMapping()) { + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + List itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey())).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(itemList)) { + if (fieldInfo.isFieldIsMap()) { + List> joinList = (List>) fieldInfo.getJoinMapper().mappingWrapperConstructor(true, + fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); + list.forEach(i -> { + Stream> stream = joinList.stream().filter(j -> j.containsKey(fieldInfo.getJoinMapKey()) + && j.get(fieldInfo.getJoinMapKey()).equals(i.get(fieldInfo.getThisMapKey()))); + i.put(fieldInfo.getField().getName(), fieldInfo.isCollection() ? stream.collect(Collectors.toList()) : + stream.findFirst().orElse(null)); + }); + } else { + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(true, + fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); + list.forEach(i -> { + Stream stream = joinList.stream().filter(j -> { + Object o = fieldInfo.joinFieldGet(j); + return o != null && o.equals(i.get(fieldInfo.getThisMapKey())); + }); + i.put(fieldInfo.getField().getName(), fieldInfo.isCollection() ? stream.collect(Collectors.toList()) : + stream.findFirst().orElse(null)); + }); + } + } else { + list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>())); + } + } + } + return list; + } +} diff --git a/src/main/java/com/github/yulichang/base/MPJBaseJoinService.java b/src/main/java/com/github/yulichang/base/MPJBaseJoinService.java new file mode 100644 index 0000000..c475364 --- /dev/null +++ b/src/main/java/com/github/yulichang/base/MPJBaseJoinService.java @@ -0,0 +1,65 @@ +package com.github.yulichang.base; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.github.yulichang.interfaces.MPJBaseJoin; + +import java.util.List; +import java.util.Map; + +/** + * @author yulichang + * @see IService + */ +@SuppressWarnings("unused") +public interface MPJBaseJoinService 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/base/MPJBaseMapper.java b/src/main/java/com/github/yulichang/base/MPJBaseMapper.java index d6e5c90..0e435eb 100644 --- a/src/main/java/com/github/yulichang/base/MPJBaseMapper.java +++ b/src/main/java/com/github/yulichang/base/MPJBaseMapper.java @@ -1,7 +1,11 @@ package com.github.yulichang.base; +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.IPage; +import com.baomidou.mybatisplus.core.metadata.MPJMappingWrapper; +import com.baomidou.mybatisplus.core.metadata.MPJTableFieldInfo; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.github.yulichang.interfaces.MPJBaseJoin; import com.github.yulichang.toolkit.Constant; @@ -73,4 +77,47 @@ public interface MPJBaseMapper extends BaseMapper { */

> IPage> selectJoinMapsPage(P page, @Param(Constants.WRAPPER) MPJBaseJoin wrapper); + + + /** + * 映射 wrapper 构造器 + * 仅对使用 @MPJMapping 时使用 + */ + default Object mappingWrapperConstructor(boolean isCollection, 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()) + .last(infoWrapper.isHasLast(), infoWrapper.getLast()); + if (SqlKeyword.IN == keyword) { + 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 isCollection ? selectMaps(wrapper) : selectMaps(wrapper).stream().findFirst().orElse(null); + } + return isCollection ? selectList(wrapper) : selectOne(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/MPJBaseService.java b/src/main/java/com/github/yulichang/base/MPJBaseService.java index 1d42595..e9092a6 100644 --- a/src/main/java/com/github/yulichang/base/MPJBaseService.java +++ b/src/main/java/com/github/yulichang/base/MPJBaseService.java @@ -1,50 +1,12 @@ package com.github.yulichang.base; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.service.IService; -import com.github.yulichang.interfaces.MPJBaseJoin; - -import java.util.List; -import java.util.Map; - /** + * 基础service + * 目前包含两个模块 连表查询 和 关系映射 + * * @author yulichang - * @see IService + * @see MPJBaseJoinService + * @see MPJBaseDeepService */ -public interface MPJBaseService extends IService { - - /** - * 根据 Wrapper 条件,查询总记录数 - */ - Integer selectJoinCount(MPJBaseJoin wrapper); - - /** - * 连接查询返回一条记录 - */ - DTO selectJoinOne(Class clazz, MPJBaseJoin wrapper); - - /** - * 连接查询返回集合 - */ - List selectJoinList(Class clazz, MPJBaseJoin wrapper); - - /** - * 连接查询返回集合并分页 - */ - > IPage selectJoinListPage(P page, Class clazz, MPJBaseJoin wrapper); - - /** - * 连接查询返回Map - */ - Map selectJoinMap(MPJBaseJoin wrapper); - - /** - * 连接查询返回Map集合 - */ - List> selectJoinMaps(MPJBaseJoin wrapper); - - /** - * 连接查询返回Map集合并分页 - */ -

>> IPage> selectJoinMapsPage(P page, MPJBaseJoin wrapper); +public interface MPJBaseService extends MPJBaseJoinService, MPJBaseDeepService { } diff --git a/src/main/java/com/github/yulichang/base/MPJBaseServiceImpl.java b/src/main/java/com/github/yulichang/base/MPJBaseServiceImpl.java index b0c0e00..f6b01f1 100644 --- a/src/main/java/com/github/yulichang/base/MPJBaseServiceImpl.java +++ b/src/main/java/com/github/yulichang/base/MPJBaseServiceImpl.java @@ -1,76 +1,16 @@ package com.github.yulichang.base; -import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.github.yulichang.interfaces.MPJBaseJoin; -import com.github.yulichang.toolkit.ReflectionKit; - -import java.util.List; -import java.util.Map; /** * @author yulichang * @see ServiceImpl */ -@SuppressWarnings("unchecked") +@SuppressWarnings("unused") public class MPJBaseServiceImpl, T> extends ServiceImpl implements MPJBaseService { - /** - * mybatis plus 3.4.3 bug - *

- * https://gitee.com/baomidou/mybatis-plus/issues/I3SE8R - *

- * https://gitee.com/baomidou/mybatis-plus/commit/7210b461b23211e6b95ca6de2d846aa392bdc28c - */ @Override - protected Class currentMapperClass() { - return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), ServiceImpl.class, 0); - } - - /** - * mybatis plus 3.4.3 bug - *

- * https://gitee.com/baomidou/mybatis-plus/issues/I3SE8R - *

- * https://gitee.com/baomidou/mybatis-plus/commit/7210b461b23211e6b95ca6de2d846aa392bdc28c - */ - @Override - protected Class currentModelClass() { - return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), ServiceImpl.class, 1); - } - - @Override - public Integer selectJoinCount(MPJBaseJoin wrapper) { - return baseMapper.selectJoinCount(wrapper); - } - - @Override - public DTO selectJoinOne(Class clazz, MPJBaseJoin wrapper) { - return baseMapper.selectJoinOne(clazz, wrapper); - } - - @Override - public List selectJoinList(Class clazz, MPJBaseJoin wrapper) { - return baseMapper.selectJoinList(clazz, wrapper); - } - - @Override - public > IPage selectJoinListPage(P page, Class clazz, MPJBaseJoin wrapper) { - return baseMapper.selectJoinPage(page, clazz, wrapper); - } - - @Override - public Map selectJoinMap(MPJBaseJoin wrapper) { - return baseMapper.selectJoinMap(wrapper); - } - - @Override - public List> selectJoinMaps(MPJBaseJoin wrapper) { - return baseMapper.selectJoinMaps(wrapper); - } - - @Override - public

>> IPage> selectJoinMapsPage(P page, MPJBaseJoin wrapper) { - return baseMapper.selectJoinMapsPage(page, wrapper); + public Class currentModelClass() { + return super.currentModelClass(); } } diff --git a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java index b3b6522..e7f4e65 100644 --- a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java +++ b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java @@ -2,20 +2,12 @@ package com.github.yulichang.injector; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; -import com.baomidou.mybatisplus.core.mapper.Mapper; -import com.baomidou.mybatisplus.core.metadata.TableInfo; -import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; -import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; -import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils; +import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; import com.github.yulichang.method.*; -import com.github.yulichang.toolkit.ReflectionKit; import org.apache.ibatis.builder.MapperBuilderAssistant; -import org.apache.ibatis.logging.Log; -import org.apache.ibatis.logging.LogFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import java.util.List; -import java.util.Set; /** * SQL 注入器 @@ -25,7 +17,6 @@ import java.util.Set; */ @ConditionalOnMissingBean(DefaultSqlInjector.class) public class MPJSqlInjector extends DefaultSqlInjector { - private static final Log logger = LogFactory.getLog(MPJSqlInjector.class); @Override public List getMethodList(Class mapperClass) { @@ -40,30 +31,9 @@ public class MPJSqlInjector extends DefaultSqlInjector { return list; } - /** - * mybatis plus 3.4.3 bug - *

- * https://gitee.com/baomidou/mybatis-plus/issues/I3SE8R - *

- * https://gitee.com/baomidou/mybatis-plus/commit/7210b461b23211e6b95ca6de2d846aa392bdc28c - */ @Override public void inspectInject(MapperBuilderAssistant builderAssistant, Class mapperClass) { - Class modelClass = ReflectionKit.getSuperClassGenericType(mapperClass, Mapper.class, 0); - if (modelClass != null) { - String className = mapperClass.toString(); - Set mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration()); - if (!mapperRegistryCache.contains(className)) { - List methodList = this.getMethodList(mapperClass); - if (CollectionUtils.isNotEmpty(methodList)) { - TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass); - // 循环注入自定义方法 - methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo)); - } else { - logger.debug(mapperClass + ", No effective injection method was found."); - } - mapperRegistryCache.add(className); - } - } + super.inspectInject(builderAssistant, mapperClass); + MPJTableInfoHelper.initTableInfo(builderAssistant, extractModelClass(mapperClass), mapperClass); } } diff --git a/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java b/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java index 3f961a3..1be1daf 100644 --- a/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java +++ b/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java @@ -1,5 +1,6 @@ package com.github.yulichang.interceptor; +import com.baomidou.mybatisplus.core.metadata.MPJTableInfo; import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; @@ -116,13 +117,13 @@ public class MPJInterceptor implements Interceptor { if (tableInfo != null && tableInfo.isAutoInitResultMap() && tableInfo.getEntityType() == resultType) { return ms.getConfiguration().getResultMap(tableInfo.getResultMap()); } - TableInfo infoDTO = MPJTableInfoHelper.getTableInfo(resultType); + MPJTableInfo infoDTO = MPJTableInfoHelper.getTableInfo(resultType); if (infoDTO == null) { infoDTO = MPJTableInfoHelper.initTableInfo(ms.getConfiguration(), - ms.getId().substring(0, ms.getId().lastIndexOf(".")), resultType); + ms.getId().substring(0, ms.getId().lastIndexOf(".")), resultType, null); } - if (infoDTO.isAutoInitResultMap()) { - return ms.getConfiguration().getResultMap(infoDTO.getResultMap()); + if (infoDTO.getTableInfo().isAutoInitResultMap()) { + return ms.getConfiguration().getResultMap(infoDTO.getTableInfo().getResultMap()); } return new ResultMap.Builder(ms.getConfiguration(), ms.getId(), resultType, EMPTY_RESULT_MAPPING).build(); } 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; + } +} diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories index 37270fe..2ba1665 100644 --- a/src/main/resources/META-INF/spring.factories +++ b/src/main/resources/META-INF/spring.factories @@ -1,4 +1,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.github.yulichang.interceptor.MPJInterceptor,\ com.github.yulichang.injector.MPJSqlInjector,\ - com.github.yulichang.config.InterceptorConfig + com.github.yulichang.config.InterceptorConfig,\ + com.github.yulichang.toolkit.SpringContentUtils From a6c577ee889ef1180dc19b9f8db49eb24553fce6 Mon Sep 17 00:00:00 2001 From: bjdys Date: Thu, 12 Aug 2021 11:56:02 +0800 Subject: [PATCH 02/33] =?UTF-8?q?=E4=B8=80=E5=AF=B9=E4=B8=80=20=E4=B8=80?= =?UTF-8?q?=E5=AF=B9=E5=A4=9A=20=E5=85=B3=E7=B3=BB=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/metadata/MPJMappingWrapper.java | 18 ++--- .../core/metadata/MPJTableFieldInfo.java | 77 ++++++++++++++++--- .../yulichang/annotation/MPJMapping.java | 22 ++++-- .../yulichang/annotation/MPJMappingApply.java | 2 +- .../yulichang/base/MPJBaseDeepService.java | 46 +++++------ .../github/yulichang/base/MPJBaseMapper.java | 8 +- 6 files changed, 117 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java index 7a1bb20..24141b0 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java @@ -7,7 +7,7 @@ import com.github.yulichang.annotation.MPJMapping; import com.github.yulichang.annotation.MPJMappingApply; import com.github.yulichang.annotation.MPJMappingCondition; import lombok.AllArgsConstructor; -import lombok.Data; +import lombok.Getter; import java.util.ArrayList; import java.util.List; @@ -18,7 +18,7 @@ import java.util.List; * @author yulichang * @since 1.2.0 */ -@Data +@Getter public class MPJMappingWrapper { private final boolean hasFirst; @@ -69,18 +69,18 @@ public class MPJMappingWrapper { } } - @Data + @Getter @AllArgsConstructor public static class Apply { - private String sql; - private String[] val; + private final String sql; + private final String[] val; } - @Data + @Getter @AllArgsConstructor public static class Condition { - private SqlKeyword keyword; - private String column; - private String[] val; + 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 index 42e3db6..5b23ed1 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java @@ -13,9 +13,12 @@ import lombok.Getter; import lombok.ToString; import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; /** * 字段属性 @@ -36,15 +39,15 @@ public class MPJTableFieldInfo { /** * 属性 */ - private final Field field; + private Field field; /** - * 属性 + * 数据结构是否是Map或者List */ - private final boolean fieldIsMap; + private boolean fieldIsMap; /** * 属性是否是集合 */ - private final boolean isCollection; + private boolean isCollection; /** * 当前映射属性 */ @@ -91,22 +94,24 @@ public class MPJTableFieldInfo { * 关联查询条件配置 */ private final MPJMappingWrapper wrapper; + /** + * 一对一查询结果数量不匹配是是否抛出异常 + */ + private final boolean isThrowExp; /** * 初始化关联字段信息 */ - public MPJTableFieldInfo(Class entityType, MPJMapping mapping, Field field) { - field.setAccessible(true); + public MPJTableFieldInfo(Class entityType, MPJMapping mapping, Field field1) { + initField(field1); this.entityType = entityType; - this.field = field; this.joinClass = mapping.tag(); - this.isCollection = Collection.class.isAssignableFrom(field.getType()); + this.isThrowExp = mapping.isThrowExp(); this.thisMapKey = StringUtils.isBlank(mapping.thisMapKey()) ? null : mapping.thisMapKey(); this.joinMapKey = StringUtils.isBlank(mapping.joinMapKsy()) ? null : mapping.joinMapKsy(); - this.fieldIsMap = mapping.isMap();//TODO 应该可以自动检测 this.wrapper = new MPJMappingWrapper(mapping); - if (this.isCollection && field.getType() != List.class && field.getType() != ArrayList.class) { - throw new MPJException("对多关系的数据结构目前只支持 暂不支持其他Collection实现 " + field.getType().getTypeName()); + if (this.isCollection && this.field.getType() != List.class && this.field.getType() != ArrayList.class) { + throw new MPJException("对多关系的数据结构目前只支持 暂不支持其他Collection实现 " + this.field.getType().getTypeName()); } if (StringUtils.isNotBlank(mapping.joinField())) { this.joinProperty = mapping.joinField(); @@ -124,6 +129,28 @@ public class MPJTableFieldInfo { } } + private void initField(Field field) { + field.setAccessible(true); + this.field = field; + this.isCollection = Collection.class.isAssignableFrom(field.getType()); + + 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; + } + } + } + @SuppressWarnings("ConstantConditions") public Field getThisField() { if (this.thisField == null) { @@ -240,4 +267,32 @@ public class MPJTableFieldInfo { this.joinField.getName() + " , " + o.getClass().getName()); } } + + public static void bind(MPJTableFieldInfo fieldInfo, T i, List data) { + if (!fieldInfo.isCollection()) { + 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)); + } + } else { + fieldInfo.fieldSet(i, data); + } + } + + public static void bindMap(MPJTableFieldInfo fieldInfo, Map i, List data) { + if (!fieldInfo.isCollection()) { + 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)); + } + } else { + i.put(fieldInfo.getField().getName(), data); + } + } + + } diff --git a/src/main/java/com/github/yulichang/annotation/MPJMapping.java b/src/main/java/com/github/yulichang/annotation/MPJMapping.java index f1f60fd..264ff15 100644 --- a/src/main/java/com/github/yulichang/annotation/MPJMapping.java +++ b/src/main/java/com/github/yulichang/annotation/MPJMapping.java @@ -19,13 +19,6 @@ public @interface MPJMapping { */ Class tag(); - /** - * 当前类的属性数据结构 是否是Map 或 List - * 如果是 true 关联查询会调用 getMap() / listMaps() 等Map相关方法进行匹配 - * 如果是 false 关联查询会调用 getOne() / getById() / list() 等实体类相关方法进行匹配 - */ - boolean isMap() default false; - /** * 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称) * 默认获取当前类上定义的主键 @TableId @@ -38,6 +31,20 @@ public @interface MPJMapping { */ String joinField() default ""; + /** + * 当前类的属性数据结构 是否是Map 或 List + * 如果是 true 关联查询会调用 getMap() / listMaps() 等Map相关方法进行匹配 + * 如果是 false 关联查询会调用 getOne() / getById() / list() 等实体类相关方法进行匹配 + */ + boolean isMap() default false; + + /** + * 一对一查询时 如果查询到多条记录是否抛出异常 + * true 抛出异常 + * false 不抛异常,获取列表第一条数据 + */ + boolean isThrowExp() default true; + /** * 针对查询结果map的时候使用 * 默认为thisField对应的数据库列名 @@ -82,6 +89,7 @@ public @interface MPJMapping { /** * 映射表查询条件之 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 index a060ad2..8784957 100644 --- a/src/main/java/com/github/yulichang/annotation/MPJMappingApply.java +++ b/src/main/java/com/github/yulichang/annotation/MPJMappingApply.java @@ -17,5 +17,5 @@ public @interface MPJMappingApply { /** * .apply() 对应的可变参数 */ - String[] args(); + String[] args() default {}; } diff --git a/src/main/java/com/github/yulichang/base/MPJBaseDeepService.java b/src/main/java/com/github/yulichang/base/MPJBaseDeepService.java index 7ed7143..a984e3f 100644 --- a/src/main/java/com/github/yulichang/base/MPJBaseDeepService.java +++ b/src/main/java/com/github/yulichang/base/MPJBaseDeepService.java @@ -17,7 +17,6 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import java.util.stream.Stream; /** * 深度查询 @@ -98,9 +97,9 @@ public interface MPJBaseDeepService extends IService { for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { Object o = map.get(fieldInfo.getThisMapKey()); if (o != null) { - map.put(fieldInfo.getField().getName(), fieldInfo.getJoinMapper() - .mappingWrapperConstructor(fieldInfo.isCollection(), fieldInfo.isFieldIsMap(), SqlKeyword.EQ, - fieldInfo.getJoinColumn(), o, fieldInfo)); + List data = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(), + SqlKeyword.EQ, fieldInfo.getJoinColumn(), o, fieldInfo); + MPJTableFieldInfo.bindMap(fieldInfo, map, data); } } } @@ -218,9 +217,9 @@ public interface MPJBaseDeepService extends IService { for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { Object get = fieldInfo.thisFieldGet(t); if (get != null) { - fieldInfo.fieldSet(t, fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isCollection(), - fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), - get, fieldInfo)); + List o = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(), + SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo); + MPJTableFieldInfo.bind(fieldInfo, t, o); } } } @@ -243,13 +242,12 @@ public interface MPJBaseDeepService extends IService { for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { List itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(itemList)) { - List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(true, + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); list.forEach(i -> { - Stream stream = joinList.stream().filter(j -> - fieldInfo.joinFieldGet(j).equals(fieldInfo.thisFieldGet(i))); - fieldInfo.fieldSet(i, fieldInfo.isCollection() ? stream.collect(Collectors.toList()) : - stream.findFirst().orElse(null)); + List data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j) + .equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList()); + MPJTableFieldInfo.bind(fieldInfo, i, data); }); } else { list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>())); @@ -259,6 +257,7 @@ public interface MPJBaseDeepService extends IService { return list; } + /** * 查询映射关系 * 对结果进行二次查询 @@ -277,24 +276,23 @@ public interface MPJBaseDeepService extends IService { List itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey())).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(itemList)) { if (fieldInfo.isFieldIsMap()) { - List> joinList = (List>) fieldInfo.getJoinMapper().mappingWrapperConstructor(true, - fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); + List> joinList = (List>) fieldInfo.getJoinMapper() + .mappingWrapperConstructor(fieldInfo.isFieldIsMap(), SqlKeyword.IN, + fieldInfo.getJoinColumn(), itemList, fieldInfo); list.forEach(i -> { - Stream> stream = joinList.stream().filter(j -> j.containsKey(fieldInfo.getJoinMapKey()) - && j.get(fieldInfo.getJoinMapKey()).equals(i.get(fieldInfo.getThisMapKey()))); - i.put(fieldInfo.getField().getName(), fieldInfo.isCollection() ? stream.collect(Collectors.toList()) : - stream.findFirst().orElse(null)); + List> data = joinList.stream().filter(j -> j.containsKey(fieldInfo.getJoinMapKey()) + && j.get(fieldInfo.getJoinMapKey()).equals(i.get(fieldInfo.getThisMapKey()))).collect(Collectors.toList()); + MPJTableFieldInfo.bindMap(fieldInfo, i, data); }); } else { - List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(true, + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); list.forEach(i -> { - Stream stream = joinList.stream().filter(j -> { + List data = joinList.stream().filter(j -> { Object o = fieldInfo.joinFieldGet(j); return o != null && o.equals(i.get(fieldInfo.getThisMapKey())); - }); - i.put(fieldInfo.getField().getName(), fieldInfo.isCollection() ? stream.collect(Collectors.toList()) : - stream.findFirst().orElse(null)); + }).collect(Collectors.toList()); + MPJTableFieldInfo.bindMap(fieldInfo, i, data); }); } } else { @@ -304,4 +302,6 @@ public interface MPJBaseDeepService extends IService { } return list; } + + } diff --git a/src/main/java/com/github/yulichang/base/MPJBaseMapper.java b/src/main/java/com/github/yulichang/base/MPJBaseMapper.java index 0e435eb..7ee7bcc 100644 --- a/src/main/java/com/github/yulichang/base/MPJBaseMapper.java +++ b/src/main/java/com/github/yulichang/base/MPJBaseMapper.java @@ -83,7 +83,7 @@ public interface MPJBaseMapper extends BaseMapper { * 映射 wrapper 构造器 * 仅对使用 @MPJMapping 时使用 */ - default Object mappingWrapperConstructor(boolean isCollection, boolean selectMap, SqlKeyword keyword, + default Object mappingWrapperConstructor(boolean selectMap, SqlKeyword keyword, String column, Object val, MPJTableFieldInfo fieldInfo) { MPJMappingWrapper infoWrapper = fieldInfo.getWrapper(); MappingQuery wrapper = new MappingQuery<>(); @@ -103,12 +103,10 @@ public interface MPJBaseMapper extends BaseMapper { if (infoWrapper.isHasApply()) { infoWrapper.getApplyList().forEach(a -> wrapper.apply(a.getSql(), (Object[]) a.getVal())); } - - if (selectMap) { - return isCollection ? selectMaps(wrapper) : selectMaps(wrapper).stream().findFirst().orElse(null); + return selectMaps(wrapper); } - return isCollection ? selectList(wrapper) : selectOne(wrapper); + return selectList(wrapper); } /** From 4121413a7fad23fb88476aedad00af00802e81bf Mon Sep 17 00:00:00 2001 From: bjdys Date: Thu, 12 Aug 2021 14:04:14 +0800 Subject: [PATCH 03/33] =?UTF-8?q?=E4=B8=80=E5=AF=B9=E4=B8=80=20=E4=B8=80?= =?UTF-8?q?=E5=AF=B9=E5=A4=9A=20=E5=85=B3=E7=B3=BB=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 MAPPING.md diff --git a/MAPPING.md b/MAPPING.md new file mode 100644 index 0000000..d2dad1a --- /dev/null +++ b/MAPPING.md @@ -0,0 +1,137 @@ +# mybatis-plus-join + +* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta1 + +* 点个Star支持一下吧 :) + +QQ群:1022221898 + +## 使用方法 + +### 安装 + +- Maven + ```xml + + com.github.yulichang + mybatis-plus-join + 1.2.0.Beta1 + + ``` +- Gradle + ``` + implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta1' + ``` + 或者clone代码到本地执行 mvn install, 再引入以上依赖 +
+ 注意: mybatis plus version >= 3.4.0 +
+ +### 使用 + +* mapper继承MPJBaseMapper (必选) +* service继承MPJBaseService (可选) +* serviceImpl继承MPJBaseServiceImpl (可选) + +#### @MPJMapping注解 + +UserDO.java + +```java + +@Data +@TableName("user") +public class UserDO { + + @TableId + private Integer id; + private Integer pid;//父id + /* 其他属性略 */ + + /** + * 一对一 + */ + @TableField(exist = false) + @MPJMapping(tag = UserDO.class, thisField = "pid") + private UserDO pUser; + + /** + * 一对多 + */ + @TableField(exist = false) + @MPJMapping(tag = UserAddressDO.class, joinField = "userId") + private List addressDOList; +} +``` + +UserAddressDO.java + +```java + +@Data +@TableName("user_address") +public class UserAddressDO { + + @TableId + private Integer id; + private Integer userId; + /* 其他属性略 */ +} +``` + +使用 + +```java + +@SpringBootTest +public class MPJDeepTest { + @Resource + private UserService userService; + + @Test + void test1() { + UserDO deep = userService.getByIdDeep(1); + System.out.println(deep); + } + + @Test + void test2() { + List list = userService.listByIdsDeep(Arrays.asList(1, 4)); + list.forEach(System.out::println); + } + + @Test + void test3() { + List list = userService.listByMapDeep(new HashMap() {{ + put("id", 1); + }}); + list.forEach(System.out::println); + } + + @Test + void test4() { + UserDO one = userService.getOneDeep(Wrappers.lambdaQuery() + .eq(UserDO::getId, 1)); + System.out.println(one); + } + + @Test + void test5() { + Map deep = userService.getMapDeep(Wrappers.lambdaQuery() + .eq(UserDO::getId, 1)); + System.out.println(deep); + } +} +``` + +MPJMapping 说明: + +* MPJMapping tag 关联实体类 +* MPJMapping thisField 当前类关联对应的字段的属性名,可以不填,默认为当前类的主键 +* MPJMapping joinField 关联类对应的字段的属性名,可以不填,默认为关联类的主键 +* MPJMapping isThrowExp 一对一查询时,如果查询到多条记录是否抛出异常,true:抛出异常,false:获取列表第一条数据 +* 更多功能请看代码注释 [MPJMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/MPJMapping.java) + + + + From 92505f6390e3469760ddc0245a5d575770a44db7 Mon Sep 17 00:00:00 2001 From: bjdys Date: Thu, 12 Aug 2021 14:20:54 +0800 Subject: [PATCH 04/33] =?UTF-8?q?=E4=B8=80=E5=AF=B9=E4=B8=80=20=E4=B8=80?= =?UTF-8?q?=E5=AF=B9=E5=A4=9A=20=E5=85=B3=E7=B3=BB=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +-- pom.xml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6793d5e..9c38295 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # mybatis-plus-join * 支持连表查询的 [mybatis-plus](https://gitee.com/baomidou/mybatis-plus) - * [演示工程](https://gitee.com/best_handsome/mybatis-plus-join-demo) - * 点个Star支持一下吧 :) +* [一对一 一对多 (测试)](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/MAPPING.md) QQ群:1022221898 diff --git a/pom.xml b/pom.xml index 86c0ff6..6aa51a1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.yulichang mybatis-plus-join - 1.1.9-SNAPSHOT + 1.1.8 mybatis-plus-join An enhanced toolkit of Mybatis-Plus to simplify development. https://github.com/yulichang/mybatis-plus-join From e1789a26972e4fb2125b87d728a8d2ff76b6b4df Mon Sep 17 00:00:00 2001 From: bjdys Date: Thu, 12 Aug 2021 15:01:47 +0800 Subject: [PATCH 05/33] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c38295..a35b92e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ * 支持连表查询的 [mybatis-plus](https://gitee.com/baomidou/mybatis-plus) * [演示工程](https://gitee.com/best_handsome/mybatis-plus-join-demo) * 点个Star支持一下吧 :) -* [一对一 一对多 (测试)](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/MAPPING.md) +* [一对一,一对多](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/MAPPING.md) QQ群:1022221898 From fa5db152024853ebd0b5ac8e68854efb2ac2b4b7 Mon Sep 17 00:00:00 2001 From: bjdys Date: Fri, 13 Aug 2021 10:30:15 +0800 Subject: [PATCH 06/33] =?UTF-8?q?=E7=A7=BB=E9=99=A4=20isMap=20=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E8=87=AA=E5=8A=A8=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 4 ++-- .../java/com/github/yulichang/annotation/MPJMapping.java | 7 ------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index d2dad1a..d6c0a1f 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -52,14 +52,14 @@ public class UserDO { * 一对一 */ @TableField(exist = false) - @MPJMapping(tag = UserDO.class, thisField = "pid") + @MPJMapping(tag = UserDO.class, thisField = "pid" /*joinField = "id" 可以不填默认获取主键*/) private UserDO pUser; /** * 一对多 */ @TableField(exist = false) - @MPJMapping(tag = UserAddressDO.class, joinField = "userId") + @MPJMapping(tag = UserAddressDO.class, /*thisField = "id" 可以不填默认获取主键*/ joinField = "userId") private List addressDOList; } ``` diff --git a/src/main/java/com/github/yulichang/annotation/MPJMapping.java b/src/main/java/com/github/yulichang/annotation/MPJMapping.java index 264ff15..8b381e9 100644 --- a/src/main/java/com/github/yulichang/annotation/MPJMapping.java +++ b/src/main/java/com/github/yulichang/annotation/MPJMapping.java @@ -31,13 +31,6 @@ public @interface MPJMapping { */ String joinField() default ""; - /** - * 当前类的属性数据结构 是否是Map 或 List - * 如果是 true 关联查询会调用 getMap() / listMaps() 等Map相关方法进行匹配 - * 如果是 false 关联查询会调用 getOne() / getById() / list() 等实体类相关方法进行匹配 - */ - boolean isMap() default false; - /** * 一对一查询时 如果查询到多条记录是否抛出异常 * true 抛出异常 From ac6c6760e6211cbd93f7c93da7fdc030a5f22526 Mon Sep 17 00:00:00 2001 From: bjdys Date: Fri, 13 Aug 2021 10:46:17 +0800 Subject: [PATCH 07/33] OneToOne OneToMany --- MAPPING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index d6c0a1f..9e5b206 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -29,9 +29,9 @@ QQ群:1022221898 ### 使用 -* mapper继承MPJBaseMapper (必选) -* service继承MPJBaseService (可选) -* serviceImpl继承MPJBaseServiceImpl (可选) +* mapper继承MPJBaseMapper +* service继承MPJBaseService +* serviceImpl继承MPJBaseServiceImpl #### @MPJMapping注解 From e52f0ed5a47110a6f1173e9fdf146c4bc697dc65 Mon Sep 17 00:00:00 2001 From: bjdys Date: Fri, 13 Aug 2021 15:26:00 +0800 Subject: [PATCH 08/33] OneToOne OneToMany --- MAPPING.md | 81 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index 9e5b206..50e406d 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -52,30 +52,15 @@ public class UserDO { * 一对一 */ @TableField(exist = false) - @MPJMapping(tag = UserDO.class, thisField = "pid" /*joinField = "id" 可以不填默认获取主键*/) + @MPJMapping(tag = UserDO.class, thisField = "pid", joinField = "pid") private UserDO pUser; /** * 一对多 */ @TableField(exist = false) - @MPJMapping(tag = UserAddressDO.class, /*thisField = "id" 可以不填默认获取主键*/ joinField = "userId") - private List addressDOList; -} -``` - -UserAddressDO.java - -```java - -@Data -@TableName("user_address") -public class UserAddressDO { - - @TableId - private Integer id; - private Integer userId; - /* 其他属性略 */ + @MPJMapping(tag = UserAddressDO.class, thisField = "id", joinField = "userId") + private List childUserList; } ``` @@ -83,45 +68,61 @@ public class UserAddressDO { ```java +/** + * 一对一,一对多关系映射查询 + * 映射只对MPJBaseDeepService中的方法有效果 ,一般以Deep结尾,比如 getByIdDeep listByIdsDeep 等 + * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 getById listByIds 等 + * + * @see com.github.yulichang.base.MPJBaseDeepService + */ @SpringBootTest -public class MPJDeepTest { +class MappingTest { @Resource private UserService userService; + /** + * 根据id查询 + *

+ * 查询过程: + * 一共查询了3次 + * 第一次查询目标UserDO + * 第二次根据pid查询上级用户 + * 第三次根据自身id查询下级用户 + */ @Test void test1() { - UserDO deep = userService.getByIdDeep(1); + UserDO deep = userService.getByIdDeep(2); System.out.println(deep); } + /** + * 查询全部 + *

+ * 查询过程: + * 一共查询了3次 + * 第一次查询目标UserDO集合 + * 第二次根据pid查询上级用户(不会一条记录一条记录的去查询,对pid进行汇总,用in语句一次性查出来,然后进行匹配) + * 第三次根据自身id查询下级用户(不会一条记录一条记录的去查询,对id进行汇总,用in语句一次性查出来,然后进行匹配) + */ @Test void test2() { - List list = userService.listByIdsDeep(Arrays.asList(1, 4)); + List list = userService.listDeep(); list.forEach(System.out::println); } + /** + * 分页查询 + *

+ * 查询过程与上面一致 + */ @Test void test3() { - List list = userService.listByMapDeep(new HashMap() {{ - put("id", 1); - }}); - list.forEach(System.out::println); + Page page = userService.pageDeep(new Page<>(2, 2)); + page.getRecords().forEach(System.out::println); } - @Test - void test4() { - UserDO one = userService.getOneDeep(Wrappers.lambdaQuery() - .eq(UserDO::getId, 1)); - System.out.println(one); - } - - @Test - void test5() { - Map deep = userService.getMapDeep(Wrappers.lambdaQuery() - .eq(UserDO::getId, 1)); - System.out.println(deep); - } } + ``` MPJMapping 说明: @@ -130,7 +131,9 @@ MPJMapping 说明: * MPJMapping thisField 当前类关联对应的字段的属性名,可以不填,默认为当前类的主键 * MPJMapping joinField 关联类对应的字段的属性名,可以不填,默认为关联类的主键 * MPJMapping isThrowExp 一对一查询时,如果查询到多条记录是否抛出异常,true:抛出异常,false:获取列表第一条数据 -* 更多功能请看代码注释 [MPJMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/MPJMapping.java) +* + +更多功能请看代码注释 [MPJMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/MPJMapping.java) From 5ad214a3a35131c9da02310435c0fc0e36c9c88b Mon Sep 17 00:00:00 2001 From: bjdys Date: Fri, 13 Aug 2021 15:39:16 +0800 Subject: [PATCH 09/33] OneToOne OneToMany --- MAPPING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAPPING.md b/MAPPING.md index 50e406d..0cc3bc8 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -59,7 +59,7 @@ public class UserDO { * 一对多 */ @TableField(exist = false) - @MPJMapping(tag = UserAddressDO.class, thisField = "id", joinField = "userId") + @MPJMapping(tag = UserAddressDO.class, thisField = "id", joinField = "pid") private List childUserList; } ``` From 2080d67d4d2666285aacfffbc1d1e862c9a596cf Mon Sep 17 00:00:00 2001 From: bjdys Date: Fri, 13 Aug 2021 15:39:51 +0800 Subject: [PATCH 10/33] OneToOne OneToMany --- MAPPING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAPPING.md b/MAPPING.md index 0cc3bc8..f2a7add 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -52,7 +52,7 @@ public class UserDO { * 一对一 */ @TableField(exist = false) - @MPJMapping(tag = UserDO.class, thisField = "pid", joinField = "pid") + @MPJMapping(tag = UserDO.class, thisField = "pid", joinField = "id") private UserDO pUser; /** From 46e6e645793f8c76a56e49d1f2adf8fd9e136c3b Mon Sep 17 00:00:00 2001 From: bjdys Date: Fri, 13 Aug 2021 15:44:35 +0800 Subject: [PATCH 11/33] OneToOne OneToMany --- MAPPING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAPPING.md b/MAPPING.md index f2a7add..9e770b1 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -59,7 +59,7 @@ public class UserDO { * 一对多 */ @TableField(exist = false) - @MPJMapping(tag = UserAddressDO.class, thisField = "id", joinField = "pid") + @MPJMapping(tag = UserDO.class, thisField = "id", joinField = "pid") private List childUserList; } ``` From 6d2cda978b793fda7c601a29d24db62275bcb71d Mon Sep 17 00:00:00 2001 From: bjdys Date: Fri, 13 Aug 2021 16:04:20 +0800 Subject: [PATCH 12/33] =?UTF-8?q?fix=20bug:=20select=3Dfalse=E4=B8=8D?= =?UTF-8?q?=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/github/yulichang/query/MPJLambdaQueryWrapper.java | 2 +- src/main/java/com/github/yulichang/query/MPJQueryWrapper.java | 2 +- .../java/com/github/yulichang/wrapper/MPJLambdaWrapper.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java b/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java index 6b7e8bc..8a76fa4 100644 --- a/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java +++ b/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java @@ -192,7 +192,7 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper + selectColumns.addAll(info.getFieldList().stream().filter(TableFieldInfo::isSelect).map(i -> as + StringPool.DOT + i.getColumn()).collect(Collectors.toList())); return typedThis; } diff --git a/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java b/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java index 23228e3..dbd8242 100644 --- a/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java +++ b/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java @@ -149,7 +149,7 @@ public class MPJQueryWrapper extends AbstractWrapper + selectColumns.addAll(info.getFieldList().stream().filter(TableFieldInfo::isSelect).map(i -> as + StringPool.DOT + i.getColumn()).collect(Collectors.toList())); return typedThis; } diff --git a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java index d63c9dc..0b31d25 100644 --- a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java +++ b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java @@ -160,7 +160,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper + info.getFieldList().stream().filter(TableFieldInfo::isSelect).forEach(c -> selectColumns.add(SelectColumn.of(clazz, c.getColumn()))); return typedThis; } From 55d4a9eb59e89814e7677c7ee5bcfe928ef18523 Mon Sep 17 00:00:00 2001 From: bjdys Date: Sat, 14 Aug 2021 09:05:59 +0800 Subject: [PATCH 13/33] =?UTF-8?q?=E5=AE=B9=E5=99=A8=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E6=97=B6=E7=94=9F=E6=88=90=E5=88=AB=E5=90=8D=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E5=8A=A8=E6=80=81=E7=94=9F=E6=88=90=E5=88=AB?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/metadata/MPJTableInfo.java | 8 +++++ .../core/metadata/MPJTableInfoHelper.java | 20 ++++++++++++- .../yulichang/annotation/MPJTableAlias.java | 22 ++++++++++++++ .../yulichang/injector/MPJSqlInjector.java | 28 ++++++++++++++++-- .../yulichang/method/MPJAbstractMethod.java | 9 +++--- .../yulichang/method/SelectJoinCount.java | 2 +- .../yulichang/method/SelectJoinList.java | 2 +- .../yulichang/method/SelectJoinMap.java | 2 +- .../yulichang/method/SelectJoinMaps.java | 2 +- .../yulichang/method/SelectJoinMapsPage.java | 2 +- .../yulichang/method/SelectJoinOne.java | 2 +- .../yulichang/method/SelectJoinPage.java | 2 +- .../query/MPJLambdaQueryWrapper.java | 23 +++++++++++---- .../yulichang/query/MPJQueryWrapper.java | 20 ++++++++++--- .../github/yulichang/toolkit/Constant.java | 5 ---- .../wrapper/MPJAbstractLambdaWrapper.java | 10 ++----- .../yulichang/wrapper/MPJLambdaWrapper.java | 29 +++++-------------- 17 files changed, 130 insertions(+), 58 deletions(-) create mode 100644 src/main/java/com/github/yulichang/annotation/MPJTableAlias.java diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java index a54a309..ff3e7f3 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java @@ -19,8 +19,16 @@ import java.util.List; @Accessors(chain = true) public class MPJTableInfo { + /** + * mybatis-plus 表信息 + */ private TableInfo tableInfo; + /** + * 表别名 + */ + private String alias; + /** * 是否包含映射注解 */ diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java index e8f9f52..8cf02dd 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.core.config.GlobalConfig; import com.baomidou.mybatisplus.core.toolkit.*; import com.github.yulichang.annotation.MPJMapping; +import com.github.yulichang.annotation.MPJTableAlias; import org.apache.ibatis.builder.MapperBuilderAssistant; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; @@ -17,6 +18,7 @@ import org.apache.ibatis.session.Configuration; import java.lang.reflect.Field; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; import static java.util.stream.Collectors.toList; @@ -34,6 +36,11 @@ import static java.util.stream.Collectors.toList; */ public class MPJTableInfoHelper { + /** + * 用于生成别名的序号 + */ + private static final AtomicInteger index = new AtomicInteger(1); + private static final Log logger = LogFactory.getLog(TableInfoHelper.class); @@ -116,13 +123,13 @@ public class MPJTableInfoHelper { TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz); if (tableInfo != null) { mpjTableInfo.setTableInfo(tableInfo); + initTableAlias(mpjTableInfo); initMapping(mpjTableInfo); /* 添加缓存 */ TABLE_INFO_CACHE.put(clazz, mpjTableInfo); return mpjTableInfo; } - tableInfo = new TableInfo(clazz); mpjTableInfo.setTableInfo(tableInfo); tableInfo.setCurrentNamespace(currentNamespace); @@ -146,11 +153,22 @@ public class MPJTableInfoHelper { /* 缓存 lambda */ LambdaUtils.installCache(tableInfo); + /* 初始化表别名 */ + initTableAlias(mpjTableInfo); + /* 初始化映射关系 */ initMapping(mpjTableInfo); return mpjTableInfo; } + private static void initTableAlias(MPJTableInfo tableInfo) { + MPJTableAlias tableAlias = tableInfo.getTableInfo().getEntityType().getAnnotation(MPJTableAlias.class); + if (tableAlias != null && StringUtils.isNotBlank(tableAlias.value())) { + tableInfo.setAlias(tableAlias.value()); + return; + } + tableInfo.setAlias("t" + index.getAndIncrement()); + } /** * 自动构建 resultMap 并注入(如果条件符合的话) diff --git a/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java b/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java new file mode 100644 index 0000000..4b491cc --- /dev/null +++ b/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java @@ -0,0 +1,22 @@ +package com.github.yulichang.annotation; + +import java.lang.annotation.*; + +/** + * 关联查询时的表别名 + * 框架默认会随机生成 一般是 t1 t2 t3 ... + * 这个注解定义的表别名或者随机生成的别名只对MPJLambdaWrapper生效 + * 对MPJQueryWrapper不生效, + * + * @author yulichang + * @see com.github.yulichang.wrapper.MPJLambdaWrapper + * @see com.github.yulichang.query.MPJQueryWrapper + * @since 1.2.0 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +public @interface MPJTableAlias { + + String value() default ""; +} diff --git a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java index e7f4e65..6baeb1e 100644 --- a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java +++ b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java @@ -3,11 +3,18 @@ package com.github.yulichang.injector; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils; import com.github.yulichang.method.*; import org.apache.ibatis.builder.MapperBuilderAssistant; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import java.util.List; +import java.util.Set; /** * SQL 注入器 @@ -18,6 +25,8 @@ import java.util.List; @ConditionalOnMissingBean(DefaultSqlInjector.class) public class MPJSqlInjector extends DefaultSqlInjector { + private static final Log logger = LogFactory.getLog(MPJSqlInjector.class); + @Override public List getMethodList(Class mapperClass) { List list = super.getMethodList(mapperClass); @@ -33,7 +42,22 @@ public class MPJSqlInjector extends DefaultSqlInjector { @Override public void inspectInject(MapperBuilderAssistant builderAssistant, Class mapperClass) { - super.inspectInject(builderAssistant, mapperClass); - MPJTableInfoHelper.initTableInfo(builderAssistant, extractModelClass(mapperClass), mapperClass); + Class modelClass = extractModelClass(mapperClass); + if (modelClass != null) { + String className = mapperClass.toString(); + Set mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration()); + if (!mapperRegistryCache.contains(className)) { + List methodList = this.getMethodList(mapperClass); + if (CollectionUtils.isNotEmpty(methodList)) { + TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass); + MPJTableInfoHelper.initTableInfo(builderAssistant, extractModelClass(mapperClass), mapperClass); + // 循环注入自定义方法 + methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo)); + } else { + logger.debug(mapperClass + ", No effective injection method was found."); + } + mapperRegistryCache.add(className); + } + } } } diff --git a/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java b/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java index f5a16d9..2a1ed19 100644 --- a/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java +++ b/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java @@ -1,10 +1,10 @@ package com.github.yulichang.method; import com.baomidou.mybatisplus.core.injector.AbstractMethod; +import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils; -import com.github.yulichang.toolkit.Constant; import java.util.ArrayList; import java.util.List; @@ -40,7 +40,7 @@ public abstract class MPJAbstractMethod extends AbstractMethod { String[] columns = selectColumns.split(StringPool.COMMA); List selectColumnList = new ArrayList<>(); for (String c : columns) { - selectColumnList.add(Constant.TABLE_ALIAS + StringPool.DOT + c); + selectColumnList.add(MPJTableInfoHelper.getTableInfo(table.getEntityType()).getAlias() + StringPool.DOT + c); } selectColumns = String.join(StringPool.COMMA, selectColumnList); } @@ -58,8 +58,9 @@ public abstract class MPJAbstractMethod extends AbstractMethod { SqlScriptUtils.unSafeParam(Q_WRAPPER_SQL_SELECT), ASTERISK); } - protected String sqlAlias() { - return SqlScriptUtils.convertIf("${ew.alias}", String.format("%s != null and %s != ''", "ew.alias", "ew.alias"), false); + protected String sqlAlias(Class modelClass) { + return SqlScriptUtils.convertChoose(String.format("%s != null and %s != ''", "ew.autoAlias", "ew.autoAlias"), + MPJTableInfoHelper.getTableInfo(modelClass).getAlias(), "${ew.alias}"); } protected String sqlFrom() { diff --git a/src/main/java/com/github/yulichang/method/SelectJoinCount.java b/src/main/java/com/github/yulichang/method/SelectJoinCount.java index 628d277..c45a010 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinCount.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinCount.java @@ -17,7 +17,7 @@ public class SelectJoinCount extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_COUNT; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlCount(), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Integer.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinList.java b/src/main/java/com/github/yulichang/method/SelectJoinList.java index 6918275..dc1452d 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinList.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinList.java @@ -15,7 +15,7 @@ public class SelectJoinList extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_LIST; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinMap.java b/src/main/java/com/github/yulichang/method/SelectJoinMap.java index efffa5f..c457b20 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinMap.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinMap.java @@ -17,7 +17,7 @@ public class SelectJoinMap extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAP; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinMaps.java b/src/main/java/com/github/yulichang/method/SelectJoinMaps.java index 9aa3ca7..5445852 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinMaps.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinMaps.java @@ -17,7 +17,7 @@ public class SelectJoinMaps extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAPS; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java b/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java index 2ca6219..5bb24b8 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java @@ -17,7 +17,7 @@ public class SelectJoinMapsPage extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAPS_PAGE; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinOne.java b/src/main/java/com/github/yulichang/method/SelectJoinOne.java index 3d37df4..93c2728 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinOne.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinOne.java @@ -15,7 +15,7 @@ public class SelectJoinOne extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_ONE; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinPage.java b/src/main/java/com/github/yulichang/method/SelectJoinPage.java index 0f9a03b..44d8d11 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinPage.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinPage.java @@ -15,7 +15,7 @@ public class SelectJoinPage extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_PAGE; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class); } diff --git a/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java b/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java index 8a76fa4..835d066 100644 --- a/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java +++ b/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java @@ -50,7 +50,7 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper extends AbstractLambdaWrapper alias(String tableAlias) { + this.alias = tableAlias; + return typedThis; + } + /** * SELECT 部分 SQL 设置 * @@ -130,7 +138,7 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper selectIgnore(SFunction... columns) { if (ArrayUtils.isNotEmpty(columns)) { for (SFunction s : columns) { - ignoreColumns.add(Constant.TABLE_ALIAS + StringPool.DOT + getColumnCache(s).getColumn()); + ignoreColumns.add(this.alias + StringPool.DOT + getColumnCache(s).getColumn()); } } return typedThis; @@ -138,7 +146,7 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper column, boolean onlyColumn) { - return Constant.TABLE_ALIAS + StringPool.DOT + super.columnToString(column, onlyColumn); + return this.alias + StringPool.DOT + super.columnToString(column, onlyColumn); } public MPJLambdaQueryWrapper select(String... columns) { @@ -166,7 +174,7 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper - Constant.TABLE_ALIAS + StringPool.DOT + c.getColumn()).collect(Collectors.toList())); + this.alias + StringPool.DOT + c.getColumn()).collect(Collectors.toList())); return typedThis; } @@ -177,7 +185,7 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper selectAll(Class clazz) { - return selectAll(clazz, Constant.TABLE_ALIAS); + return selectAll(clazz, this.alias); } /** @@ -220,9 +228,12 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper extends AbstractWrapper extends AbstractWrapper alias(String tableAlias) { + this.alias = tableAlias; + return typedThis; + } + @Override public MPJQueryWrapper select(String... columns) { if (ArrayUtils.isNotEmpty(columns)) { @@ -122,7 +130,7 @@ public class MPJQueryWrapper extends AbstractWrapper - Constant.TABLE_ALIAS + StringPool.DOT + c.getColumn()).collect(Collectors.toList())); + this.alias + StringPool.DOT + c.getColumn()).collect(Collectors.toList())); return typedThis; } @@ -133,7 +141,7 @@ public class MPJQueryWrapper extends AbstractWrapper selectAll(Class clazz) { - selectAll(clazz, Constant.TABLE_ALIAS); + selectAll(clazz, this.alias); return typedThis; } @@ -170,8 +178,12 @@ public class MPJQueryWrapper extends AbstractWrapper> extends MPJAbstractWrapper { - - /** - * 关联的表 - */ - protected Map, Integer> subTable = new HashMap<>(); - /** * 缓存字段 */ @@ -43,7 +37,7 @@ public abstract class MPJAbstractLambdaWrapper column) { - return Constant.TABLE_ALIAS + getDefault(subTable.get(LambdaUtils.getEntityClass(column))) + StringPool.DOT + + return MPJTableInfoHelper.getTableInfo(LambdaUtils.getEntityClass(column)).getAlias() + StringPool.DOT + getCache(column).getColumn(); } diff --git a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java index 0b31d25..6ba5f8e 100644 --- a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java +++ b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java @@ -2,6 +2,7 @@ package com.github.yulichang.wrapper; import com.baomidou.mybatisplus.core.conditions.SharedString; import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; +import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; @@ -47,11 +48,6 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper extends MPJAbstractLambdaWrapper ignoreColumns = new ArrayList<>(); - /** - * 表序号 - */ - private int tableIndex = 1; - /** * ON sql wrapper集合 */ @@ -98,7 +89,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, - Map, Integer> subTable, String keyWord, Class joinClass) { + String keyWord, Class joinClass) { super.setEntity(entity); super.setEntityClass(entityClass); this.paramNameSeq = paramNameSeq; @@ -108,7 +99,6 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper extends MPJAbstractLambdaWrapper { - String str = Constant.TABLE_ALIAS + getDefault(subTable.get(i.getClazz())) + StringPool.DOT + i.getColumnName(); + String str = MPJTableInfoHelper.getTableInfo(i.getClazz()).getAlias() + StringPool.DOT + i.getColumnName(); return (i.getFuncEnum() == null ? str : String.format(i.getFuncEnum().getSql(), str)) + (StringUtils.isBlank(i.getAlias()) ? StringPool.EMPTY : (Constant.AS + i.getAlias())); }).collect(Collectors.joining(StringPool.COMMA)); @@ -206,8 +196,8 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper extends MPJAbstractLambdaWrapper extends MPJAbstractLambdaWrapper instance(String keyWord, Class joinClass) { return new MPJLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs, new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), - this.subTable, keyWord, joinClass); + keyWord, joinClass); } @Override @@ -242,7 +232,6 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper extends MPJAbstractLambdaWrapper apply = function.apply(instance(keyWord, clazz)); onWrappers.add(apply); - subTable.put(clazz, tableIndex); - tableIndex++; } return typedThis; } From 626a98601d0b4bf81b22873415cdf2f23131d632 Mon Sep 17 00:00:00 2001 From: bjdys Date: Sat, 14 Aug 2021 14:35:33 +0800 Subject: [PATCH 14/33] =?UTF-8?q?MPJLambdaWrapper=E6=94=AF=E6=8C=81select?= =?UTF-8?q?=E5=AD=90=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/metadata/MPJTableInfo.java | 5 + .../core/metadata/MPJTableInfoHelper.java | 4 +- .../yulichang/annotation/MPJTableAlias.java | 3 + .../wrapper/MPJAbstractLambdaWrapper.java | 23 +-- .../yulichang/wrapper/MPJAbstractWrapper.java | 83 +++----- .../yulichang/wrapper/MPJLambdaWrapper.java | 180 ++++++------------ .../yulichang/wrapper/interfaces/Query.java | 17 ++ .../wrapper/interfaces/on/OnCompare.java | 37 +--- 8 files changed, 118 insertions(+), 234 deletions(-) diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java index ff3e7f3..3c0f543 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java @@ -29,6 +29,11 @@ public class MPJTableInfo { */ private String alias; + /** + * 前缀 + */ + private String aliasDOT; + /** * 是否包含映射注解 */ diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java index 8cf02dd..c9b5ec3 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.config.GlobalConfig; import com.baomidou.mybatisplus.core.toolkit.*; import com.github.yulichang.annotation.MPJMapping; import com.github.yulichang.annotation.MPJTableAlias; +import com.github.yulichang.toolkit.Constant; import org.apache.ibatis.builder.MapperBuilderAssistant; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; @@ -167,7 +168,8 @@ public class MPJTableInfoHelper { tableInfo.setAlias(tableAlias.value()); return; } - tableInfo.setAlias("t" + index.getAndIncrement()); + tableInfo.setAlias(Constant.TABLE_ALIAS + index.getAndIncrement()); + tableInfo.setAliasDOT(tableInfo.getAlias() + StringPool.DOT); } /** diff --git a/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java b/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java index 4b491cc..b4a89f3 100644 --- a/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java +++ b/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java @@ -5,6 +5,9 @@ import java.lang.annotation.*; /** * 关联查询时的表别名 * 框架默认会随机生成 一般是 t1 t2 t3 ... + * 不要在程序中使用随机别名,运行期间是不变的,但是重启就不一定了 + * 如需使用请配合此注解一起使用 + *

* 这个注解定义的表别名或者随机生成的别名只对MPJLambdaWrapper生效 * 对MPJQueryWrapper不生效, * diff --git a/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java b/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java index f79789c..9b68c19 100644 --- a/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java +++ b/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java @@ -9,7 +9,6 @@ import com.github.yulichang.toolkit.LambdaUtils; import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import static java.util.stream.Collectors.joining; @@ -27,7 +26,13 @@ public abstract class MPJAbstractLambdaWrapper String columnToString(X column) { - return columnToString((SFunction) column); + return columnToString((SFunction) column, hasAlias || entityClass != + LambdaUtils.getEntityClass((SFunction) column)); + } + + @Override + protected String columnToString(X column, boolean hasAlias) { + return columnToString((SFunction) column, hasAlias); } @Override @@ -36,9 +41,9 @@ public abstract class MPJAbstractLambdaWrapper columnToString((SFunction) i)).collect(joining(StringPool.COMMA)); } - protected String columnToString(SFunction column) { - return MPJTableInfoHelper.getTableInfo(LambdaUtils.getEntityClass(column)).getAlias() + StringPool.DOT + - getCache(column).getColumn(); + protected String columnToString(SFunction column, boolean hasAlias) { + return (hasAlias ? MPJTableInfoHelper.getTableInfo(LambdaUtils.getEntityClass(column)).getAliasDOT() : + StringPool.EMPTY) + getCache(column).getColumn(); } protected ColumnCache getCache(SFunction fn) { @@ -50,12 +55,4 @@ public abstract class MPJAbstractLambdaWrapper> extends Wrapper implements Compare, Nested, Join, Func, OnCompare { + + /** + * 是否使用别名 + */ + protected boolean hasAlias; + /** * 占位符 */ @@ -51,7 +59,7 @@ public abstract class MPJAbstractWrapper entityClass; + protected Class entityClass; @Override public T getEntity() { return entity; } - public Children setEntity(T entity) { - this.entity = entity; - return typedThis; - } - - public Class getEntityClass() { - if (entityClass == null && entity != null) { - entityClass = (Class) entity.getClass(); - } - return entityClass; - } - - public Children setEntityClass(Class entityClass) { - if (entityClass != null) { - this.entityClass = entityClass; - } - return typedThis; - } - @Override public Children allEq(boolean condition, Map, V> params, boolean null2IsNull) { if (condition && CollectionUtils.isNotEmpty(params)) { @@ -329,7 +318,6 @@ public abstract class MPJAbstractWrapper SFunction columnSqlInjectFilter(SFunction column) { return column; @@ -384,9 +372,11 @@ public abstract class MPJAbstractWrapper formatParam(null, val))); } - protected Children addCondition(boolean condition, SFunction column, SqlKeyword sqlKeyword, SFunction val) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword, - columnToSqlSegment(val))); + protected Children addCondition(boolean condition, SFunction column, SqlKeyword sqlKeyword, + SFunction val) { + return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, hasAlias || entityClass != + LambdaUtils.getEntityClass(column)), sqlKeyword, columnToSqlSegment(val, hasAlias || + entityClass != LambdaUtils.getEntityClass(val)))); } /** @@ -417,6 +407,7 @@ public abstract class MPJAbstractWrapper columnToString(column); } + protected final ISqlSegment columnToSqlSegment(SFunction column, boolean hasAlias) { + return () -> columnToString(column, hasAlias); + } + /** * 获取 columnName */ @@ -579,6 +574,10 @@ public abstract class MPJAbstractWrapper String columnToString(X column, boolean hasAlias) { + return (String) column; + } + /** * 多字段转换为逗号 "," 分割字符串 * @@ -634,36 +633,4 @@ public abstract class MPJAbstractWrapper Children le(boolean condition, SFunction column, SFunction val) { return addCondition(condition, column, LE, val); } - - @Override - public Children between(boolean condition, SFunction column, SFunction val1, SFunction val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN, - columnToSqlSegment(val1), AND, columnToSqlSegment(val2))); - } - - public Children between(boolean condition, SFunction column, Object val1, SFunction val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN, - () -> formatParam(null, val1), AND, columnToSqlSegment(val2))); - } - - public Children between(boolean condition, SFunction column, SFunction val1, Object val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN, - columnToSqlSegment(val1), AND, () -> formatParam(null, val2))); - } - - @Override - public Children notBetween(boolean condition, SFunction column, SFunction val1, SFunction val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN, - columnToSqlSegment(val1), AND, columnToSqlSegment(val2))); - } - - public Children notBetween(boolean condition, SFunction column, Object val1, SFunction val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN, - () -> formatParam(null, val1), AND, columnToSqlSegment(val2))); - } - - public Children notBetween(boolean condition, SFunction column, SFunction val1, Object val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN, - columnToSqlSegment(val1), AND, () -> formatParam(null, val2))); - } } diff --git a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java index 6ba5f8e..c278d9a 100644 --- a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java +++ b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java @@ -2,10 +2,7 @@ package com.github.yulichang.wrapper; import com.baomidou.mybatisplus.core.conditions.SharedString; import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; -import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; -import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; -import com.baomidou.mybatisplus.core.metadata.TableInfo; -import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.core.metadata.*; import com.baomidou.mybatisplus.core.toolkit.*; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.github.yulichang.toolkit.Constant; @@ -14,13 +11,10 @@ import com.github.yulichang.wrapper.enums.BaseFuncEnum; import com.github.yulichang.wrapper.interfaces.LambdaJoin; import com.github.yulichang.wrapper.interfaces.Query; import com.github.yulichang.wrapper.interfaces.on.OnFunction; -import lombok.Data; -import lombok.Getter; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -34,14 +28,14 @@ import java.util.stream.Collectors; * @author yulichang * @see com.github.yulichang.toolkit.Wrappers */ -@SuppressWarnings("all") +@SuppressWarnings("unused") public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper> implements Query>, LambdaJoin> { /** * 查询字段 sql */ - private SharedString sqlSelect = new SharedString(); + private final SharedString sqlSelect = new SharedString(); /** * 查询表 @@ -51,34 +45,23 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper selectColumns = new ArrayList<>(); + private final List selectColumns = new ArrayList<>(); /** * 忽略查询的字段 */ - private final List ignoreColumns = new ArrayList<>(); + private final List ignoreColumns = new ArrayList<>(); /** * ON sql wrapper集合 */ - private final List> onWrappers = new ArrayList<>(); - - /** - * 连表关键字 on 条件 func 使用 - */ - @Getter - private String keyWord; - - /** - * 连表实体类 on 条件 func 使用 - */ - @Getter - private Class joinClass; + private final List joinSql = new ArrayList<>(); /** * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery() */ public MPJLambdaWrapper() { + this.hasAlias = true; super.initNeed(); } @@ -86,21 +69,27 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq, + MPJLambdaWrapper(Class entityClass, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, - SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, - String keyWord, Class joinClass) { - super.setEntity(entity); - super.setEntityClass(entityClass); + SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, boolean hasAlias) { + this.entityClass =entityClass; this.paramNameSeq = paramNameSeq; this.paramNameValuePairs = paramNameValuePairs; this.expression = mergeSegments; - this.sqlSelect = sqlSelect; this.lastSql = lastSql; this.sqlComment = sqlComment; this.sqlFirst = sqlFirst; - this.keyWord = keyWord; - this.joinClass = joinClass; + this.hasAlias = hasAlias; + } + + @Override + protected MPJLambdaWrapper instance() { + return instance(true, null); + } + + protected MPJLambdaWrapper instance(boolean hasAlias, Class entityClass) { + return new MPJLambdaWrapper<>(entityClass, paramNameSeq, paramNameValuePairs, new MergeSegments(), + SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), hasAlias); } @Override @@ -108,7 +97,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper select(SFunction... columns) { if (ArrayUtils.isNotEmpty(columns)) { for (SFunction s : columns) { - selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(s), getCache(s).getColumn())); + selectColumns.add(getThisAlias(s) + getCache(s).getColumn()); } } return typedThis; @@ -118,20 +107,23 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper select(Class entityClass, Predicate predicate) { TableInfo info = TableInfoHelper.getTableInfo(entityClass); Assert.notNull(info, "table can not be find"); - info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach( - i -> selectColumns.add(SelectColumn.of(entityClass, i.getColumn()))); + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(entityClass); + info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(i -> + selectColumns.add((hasAlias ? tableInfo.getAliasDOT() : StringPool.EMPTY) + i.getColumn())); return typedThis; } @Override public MPJLambdaWrapper selectAs(SFunction column, String alias) { - selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(column), getCache(column).getColumn(), alias)); + selectColumns.add(getThisAlias(column) + getCache(column).getColumn() + Constants.AS + alias); return typedThis; } - public MPJLambdaWrapper selectFunc(boolean condition, BaseFuncEnum funcEnum, SFunction column, String alias) { + public MPJLambdaWrapper selectFunc(boolean condition, BaseFuncEnum funcEnum, SFunction column, + String alias) { if (condition) { - selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(column), getCache(column).getColumn(), alias, funcEnum)); + selectColumns.add(String.format(funcEnum.getSql(), getThisAlias(column) + getCache(column).getColumn()) + + Constants.AS + alias); } return typedThis; } @@ -139,7 +131,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper selectFunc(boolean condition, BaseFuncEnum funcEnum, Object column, String alias) { if (condition) { - selectColumns.add(SelectColumn.of(null, column.toString(), alias, funcEnum)); + selectColumns.add(String.format(funcEnum.getSql(), column.toString()) + Constants.AS + alias); } return typedThis; } @@ -147,11 +139,12 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper selectAll(Class clazz) { TableInfo info = TableInfoHelper.getTableInfo(clazz); Assert.notNull(info, "table can not be find -> %s", clazz); + String dot = hasAlias ? MPJTableInfoHelper.getTableInfo(clazz).getAliasDOT() : StringPool.EMPTY; if (info.havePK()) { - selectColumns.add(SelectColumn.of(clazz, info.getKeyColumn())); + selectColumns.add(dot + info.getKeyColumn()); } info.getFieldList().stream().filter(TableFieldInfo::isSelect).forEach(c -> - selectColumns.add(SelectColumn.of(clazz, c.getColumn()))); + selectColumns.add(dot + c.getColumn())); return typedThis; } @@ -160,12 +153,21 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper selectIgnore(SFunction... columns) { if (ArrayUtils.isNotEmpty(columns)) { for (SFunction s : columns) { - ignoreColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(s), getCache(s).getColumn())); + ignoreColumns.add(getThisAlias(s) + getCache(s).getColumn()); } } return typedThis; } + + @Override + public MPJLambdaWrapper selectQuery(Class clazz, OnFunction function, String alias) { + MPJLambdaWrapper apply = function.apply(instance(false, clazz)); + selectColumns.add(String.format("(SELECT %s FROM %s %s)", apply.getSqlSelect(), + TableInfoHelper.getTableInfo(clazz).getTableName(), apply.getCustomSqlSegment()) + Constants.AS + alias); + return this; + } + /** * 查询条件 SQL 片段 */ @@ -173,15 +175,9 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper c.getFuncEnum() == null && ignoreColumns.stream().anyMatch(i -> - i.getClazz() == c.getClazz() && Objects.equals(c.getColumnName(), i.getColumnName()))); + selectColumns.removeIf(ignoreColumns::contains); } - String s = selectColumns.stream().map(i -> { - String str = MPJTableInfoHelper.getTableInfo(i.getClazz()).getAlias() + StringPool.DOT + i.getColumnName(); - return (i.getFuncEnum() == null ? str : String.format(i.getFuncEnum().getSql(), str)) + - (StringUtils.isBlank(i.getAlias()) ? StringPool.EMPTY : (Constant.AS + i.getAlias())); - }).collect(Collectors.joining(StringPool.COMMA)); - sqlSelect.setStringValue(s); + sqlSelect.setStringValue(String.join(StringPool.COMMA, selectColumns)); } return sqlSelect.getStringValue(); } @@ -191,17 +187,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper wrapper : onWrappers) { - String tableName = TableInfoHelper.getTableInfo(wrapper.getJoinClass()).getTableName(); - value.append(wrapper.getKeyWord()) - .append(tableName) - .append(Constants.SPACE) - .append(MPJTableInfoHelper.getTableInfo(wrapper.getJoinClass()).getAlias()) - .append(Constant.ON) - .append(wrapper.getExpression().getNormal().getSqlSegment()); - } - from.setStringValue(value.toString()); + from.setStringValue(String.join(StringPool.SPACE, joinSql)); } return from.getStringValue(); } @@ -210,20 +196,6 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper故 sqlSelect 不向下传递

- */ - @Override - protected MPJLambdaWrapper instance() { - return instance(null, null); - } - - protected MPJLambdaWrapper instance(String keyWord, Class joinClass) { - return new MPJLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs, - new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), - keyWord, joinClass); - } @Override public void clear() { @@ -232,65 +204,21 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper join(String keyWord, boolean condition, Class clazz, OnFunction function) { if (condition) { - MPJLambdaWrapper apply = function.apply(instance(keyWord, clazz)); - onWrappers.add(apply); + joinSql.add(keyWord + TableInfoHelper.getTableInfo(clazz).getTableName() + + Constants.SPACE + MPJTableInfoHelper.getTableInfo(clazz).getAlias() + + Constant.ON + function.apply(instance()).getExpression().getNormal().getSqlSegment()); } return typedThis; } - /** - * select字段 - */ - @Data - public static class SelectColumn { - - /** - * 字段实体类 - */ - private Class clazz; - - /** - * 数据库字段名 - */ - private String columnName; - - /** - * 字段别名 - */ - private String alias; - - /** - * 字段函数 - */ - private BaseFuncEnum funcEnum; - - /** - * 自定义函数填充参数 - */ - private List> funcArgs; - - private SelectColumn(Class clazz, String columnName, String alias, BaseFuncEnum funcEnum) { - this.clazz = clazz; - this.columnName = columnName; - this.alias = alias; - this.funcEnum = funcEnum; - } - - public static SelectColumn of(Class clazz, String columnName) { - return new SelectColumn(clazz, columnName, null, null); - } - - public static SelectColumn of(Class clazz, String columnName, String alias) { - return new SelectColumn(clazz, columnName, alias, null); - } - - public static SelectColumn of(Class clazz, String columnName, String alias, BaseFuncEnum funcEnum) { - return new SelectColumn(clazz, columnName, alias, funcEnum); - } + private String getThisAlias(SFunction function) { + return hasAlias ? MPJTableInfoHelper.getTableInfo(LambdaUtils.getEntityClass(function)).getAliasDOT() : + StringPool.EMPTY; } } diff --git a/src/main/java/com/github/yulichang/wrapper/interfaces/Query.java b/src/main/java/com/github/yulichang/wrapper/interfaces/Query.java index 6557c10..66adf65 100644 --- a/src/main/java/com/github/yulichang/wrapper/interfaces/Query.java +++ b/src/main/java/com/github/yulichang/wrapper/interfaces/Query.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.github.yulichang.toolkit.LambdaUtils; import com.github.yulichang.wrapper.enums.BaseFuncEnum; import com.github.yulichang.wrapper.enums.DefaultFuncEnum; +import com.github.yulichang.wrapper.interfaces.on.OnFunction; import java.io.Serializable; import java.util.function.Predicate; @@ -51,6 +52,22 @@ public interface Query extends Serializable { */ Children selectAs(SFunction column, String alias); + /** + * 子查询 + * + * @param clazz 查询的类 + * @param function 查询lambda + * @param alias 别名 + */ + Children selectQuery(Class clazz, OnFunction function, String alias); + + /** + * ignore + */ + default Children selectQuery(Class clazz, OnFunction function, SFunction alias) { + return selectQuery(clazz, function, LambdaUtils.getName(alias)); + } + /** * 聚合函数查询 * diff --git a/src/main/java/com/github/yulichang/wrapper/interfaces/on/OnCompare.java b/src/main/java/com/github/yulichang/wrapper/interfaces/on/OnCompare.java index 8048a79..0113cb7 100644 --- a/src/main/java/com/github/yulichang/wrapper/interfaces/on/OnCompare.java +++ b/src/main/java/com/github/yulichang/wrapper/interfaces/on/OnCompare.java @@ -12,6 +12,7 @@ import java.io.Serializable; * * @since 1.1.8 */ +@SuppressWarnings("unused") public interface OnCompare extends Serializable { /** * ignore @@ -114,40 +115,4 @@ public interface OnCompare extends Serializable { * @return children */ Children le(boolean condition, SFunction column, SFunction val); - - /** - * ignore - */ - default Children between(SFunction column, SFunction val1, SFunction val2) { - return between(true, column, val1, val2); - } - - /** - * BETWEEN 值1 AND 值2 - * - * @param condition 执行条件 - * @param column 字段 - * @param val1 值1 - * @param val2 值2 - * @return children - */ - Children between(boolean condition, SFunction column, SFunction val1, SFunction val2); - - /** - * ignore - */ - default Children notBetween(SFunction column, SFunction val1, SFunction val2) { - return notBetween(true, column, val1, val2); - } - - /** - * NOT BETWEEN 值1 AND 值2 - * - * @param condition 执行条件 - * @param column 字段 - * @param val1 值1 - * @param val2 值2 - * @return children - */ - Children notBetween(boolean condition, SFunction column, SFunction val1, SFunction val2); } From e14f9b90d1c8f393d3d5acef49c66320f18026eb Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 17 Aug 2021 09:05:04 +0800 Subject: [PATCH 15/33] =?UTF-8?q?MPJLambdaWrapper=E6=94=AF=E6=8C=81select?= =?UTF-8?q?=E5=AD=90=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index 9e770b1..664d57d 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -1,6 +1,6 @@ # mybatis-plus-join -* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta1 +* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta2 * 点个Star支持一下吧 :) @@ -15,12 +15,12 @@ QQ群:1022221898 com.github.yulichang mybatis-plus-join - 1.2.0.Beta1 + 1.2.0.Beta2 ``` - Gradle ``` - implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta1' + implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta2' ``` 或者clone代码到本地执行 mvn install, 再引入以上依赖
From 5eaef3807621197f3faf02dae329c3f7cce23bcd Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 17 Aug 2021 10:23:49 +0800 Subject: [PATCH 16/33] =?UTF-8?q?mapper=20=E6=94=AF=E6=8C=81=E5=85=B3?= =?UTF-8?q?=E7=B3=BB=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 18 +- .../github/yulichang/base/MPJBaseMapper.java | 113 +---------- .../github/yulichang/base/MPJBaseService.java | 9 +- .../yulichang/base/mapper/MPJDeepMapper.java | 179 ++++++++++++++++++ .../yulichang/base/mapper/MPJJoinMapper.java | 76 ++++++++ .../MPJDeepService.java} | 91 ++------- .../MPJJoinService.java} | 5 +- 7 files changed, 291 insertions(+), 200 deletions(-) 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 rename src/main/java/com/github/yulichang/base/{MPJBaseDeepService.java => service/MPJDeepService.java} (71%) rename src/main/java/com/github/yulichang/base/{MPJBaseJoinService.java => service/MPJJoinService.java} (92%) diff --git a/MAPPING.md b/MAPPING.md index 664d57d..d96b136 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -30,8 +30,8 @@ QQ群:1022221898 ### 使用 * mapper继承MPJBaseMapper -* service继承MPJBaseService -* serviceImpl继承MPJBaseServiceImpl +* service继承MPJBaseService (可选) +* serviceImpl继承MPJBaseServiceImpl (可选) #### @MPJMapping注解 @@ -67,18 +67,17 @@ public class UserDO { 使用 ```java - /** * 一对一,一对多关系映射查询 * 映射只对MPJBaseDeepService中的方法有效果 ,一般以Deep结尾,比如 getByIdDeep listByIdsDeep 等 * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 getById listByIds 等 * - * @see com.github.yulichang.base.MPJBaseDeepService + * @see com.github.yulichang.base.service.MPJDeepService */ @SpringBootTest class MappingTest { @Resource - private UserService userService; + private UserMapper userMapper; /** * 根据id查询 @@ -88,10 +87,11 @@ class MappingTest { * 第一次查询目标UserDO * 第二次根据pid查询上级用户 * 第三次根据自身id查询下级用户 + * */ @Test void test1() { - UserDO deep = userService.getByIdDeep(2); + UserDO deep = userMapper.selectByIdDeep(1); System.out.println(deep); } @@ -103,10 +103,11 @@ class MappingTest { * 第一次查询目标UserDO集合 * 第二次根据pid查询上级用户(不会一条记录一条记录的去查询,对pid进行汇总,用in语句一次性查出来,然后进行匹配) * 第三次根据自身id查询下级用户(不会一条记录一条记录的去查询,对id进行汇总,用in语句一次性查出来,然后进行匹配) + * */ @Test void test2() { - List list = userService.listDeep(); + List list = userMapper.selectListDeep(Wrappers.emptyWrapper()); list.forEach(System.out::println); } @@ -117,10 +118,11 @@ class MappingTest { */ @Test void test3() { - Page page = userService.pageDeep(new Page<>(2, 2)); + Page page = userMapper.selectPageDeep(new Page<>(2, 2), Wrappers.emptyWrapper()); page.getRecords().forEach(System.out::println); } + } ``` diff --git a/src/main/java/com/github/yulichang/base/MPJBaseMapper.java b/src/main/java/com/github/yulichang/base/MPJBaseMapper.java index 7ee7bcc..0d43424 100644 --- a/src/main/java/com/github/yulichang/base/MPJBaseMapper.java +++ b/src/main/java/com/github/yulichang/base/MPJBaseMapper.java @@ -1,121 +1,14 @@ package com.github.yulichang.base; -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.IPage; -import com.baomidou.mybatisplus.core.metadata.MPJMappingWrapper; -import com.baomidou.mybatisplus.core.metadata.MPJTableFieldInfo; -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; +import com.github.yulichang.base.mapper.MPJDeepMapper; +import com.github.yulichang.base.mapper.MPJJoinMapper; /** * @author yulichang * @see BaseMapper */ -public interface MPJBaseMapper 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); +public interface MPJBaseMapper extends MPJJoinMapper, MPJDeepMapper { - /** - * 映射 wrapper 构造器 - * 仅对使用 @MPJMapping 时使用 - */ - 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()) - .last(infoWrapper.isHasLast(), infoWrapper.getLast()); - if (SqlKeyword.IN == keyword) { - 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/MPJBaseService.java b/src/main/java/com/github/yulichang/base/MPJBaseService.java index e9092a6..77430d7 100644 --- a/src/main/java/com/github/yulichang/base/MPJBaseService.java +++ b/src/main/java/com/github/yulichang/base/MPJBaseService.java @@ -1,12 +1,15 @@ package com.github.yulichang.base; +import com.github.yulichang.base.service.MPJDeepService; +import com.github.yulichang.base.service.MPJJoinService; + /** * 基础service * 目前包含两个模块 连表查询 和 关系映射 * * @author yulichang - * @see MPJBaseJoinService - * @see MPJBaseDeepService + * @see MPJJoinService + * @see MPJDeepService */ -public interface MPJBaseService extends MPJBaseJoinService, MPJBaseDeepService { +public interface MPJBaseService extends MPJJoinService, MPJDeepService { } 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..cf89a4e --- /dev/null +++ b/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java @@ -0,0 +1,179 @@ +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.Constants; +import org.apache.ibatis.annotations.Param; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author yulichang + * @see BaseMapper + */ +@SuppressWarnings("unused") +public interface MPJDeepMapper extends BaseMapper { + + /** + * 根据 ID 查询 + * + * @param id 主键ID + */ + default T selectByIdDeep(Serializable id) { + return queryMapping(selectById(id)); + } + + /** + * 查询(根据ID 批量查询) + * + * @param idList 主键ID列表(不能为 null 以及 empty) + */ + default List selectBatchIdsDeep(@Param(Constants.COLLECTION) Collection idList) { + return queryMapping(selectBatchIds(idList)); + } + + /** + * 查询(根据 columnMap 条件) + * + * @param columnMap 表字段 map 对象 + */ + default List selectByMapDeep(@Param(Constants.COLUMN_MAP) Map columnMap) { + return queryMapping(selectByMap(columnMap)); + } + + /** + * 根据 entity 条件,查询一条记录 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default T selectOneDeep(@Param(Constants.WRAPPER) Wrapper queryWrapper) { + return queryMapping(selectOne(queryWrapper)); + } + + /** + * 根据 entity 条件,查询全部记录 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default List selectListDeep(@Param(Constants.WRAPPER) Wrapper queryWrapper) { + return queryMapping(selectList(queryWrapper)); + } + + + /** + * 根据 entity 条件,查询全部记录(并翻页) + * + * @param page 分页查询条件(可以为 RowBounds.DEFAULT) + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default > E selectPageDeep(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper) { + E e = selectPage(page, queryWrapper); + queryMapping(e.getRecords()); + return e; + } + + /** + * 查询映射关系 + * 对结果进行二次查询 + * 可以自行查询然后在通过此方法进行二次查询 + * + * @param t 第一次查询结果 + */ + default T queryMapping(T t) { + if (t == null) { + return null; + } + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass()); + if (tableInfo.isHasMapping()) { + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + Object get = fieldInfo.thisFieldGet(t); + if (get != null) { + List o = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(), + SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo); + MPJTableFieldInfo.bind(fieldInfo, t, o); + } + } + } + return t; + } + + /** + * 查询映射关系 + * 对结果进行二次查询 + * 可以自行查询然后在通过此方法进行二次查询 + * + * @param list 第一次查询结果 + */ + default List queryMapping(List list) { + if (CollectionUtils.isEmpty(list)) { + return list; + } + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(list.get(0).getClass()); + if (tableInfo.isHasMapping()) { + for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { + List itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(itemList)) { + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( + fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); + list.forEach(i -> { + List data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j) + .equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList()); + MPJTableFieldInfo.bind(fieldInfo, i, data); + }); + } else { + list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>())); + } + } + } + return list; + } + + /** + * 映射 wrapper 构造器 + * 仅对使用 @MPJMapping 时使用 + */ + 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()) + .last(infoWrapper.isHasLast(), infoWrapper.getLast()); + if (SqlKeyword.IN == keyword) { + 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/MPJBaseDeepService.java b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java similarity index 71% rename from src/main/java/com/github/yulichang/base/MPJBaseDeepService.java rename to src/main/java/com/github/yulichang/base/service/MPJDeepService.java index a984e3f..fb60767 100644 --- a/src/main/java/com/github/yulichang/base/MPJBaseDeepService.java +++ b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java @@ -1,4 +1,4 @@ -package com.github.yulichang.base; +package com.github.yulichang.base.service; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.enums.SqlKeyword; @@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.IService; import com.github.yulichang.annotation.MPJMapping; +import com.github.yulichang.base.MPJBaseMapper; import java.io.Serializable; import java.util.ArrayList; @@ -30,7 +31,7 @@ import java.util.stream.Collectors; * @since 1.2.0 */ @SuppressWarnings("unused") -public interface MPJBaseDeepService extends IService { +public interface MPJDeepService extends IService { Class currentModelClass(); @@ -40,7 +41,7 @@ public interface MPJBaseDeepService extends IService { * @param id 主键ID列表 */ default T getByIdDeep(Serializable id) { - return queryMapping(getById(id)); + return ((MPJBaseMapper) getBaseMapper()).selectByIdDeep(id); } @@ -50,7 +51,7 @@ public interface MPJBaseDeepService extends IService { * @param idList 主键ID列表 */ default List listByIdsDeep(Collection idList) { - return queryMapping(listByIds(idList)); + return ((MPJBaseMapper) getBaseMapper()).selectBatchIdsDeep(idList); } /** @@ -59,7 +60,7 @@ public interface MPJBaseDeepService extends IService { * @param columnMap 表字段 map 对象 */ default List listByMapDeep(Map columnMap) { - return queryMapping(listByMap(columnMap)); + return ((MPJBaseMapper) getBaseMapper()).selectByMapDeep(columnMap); } @@ -70,7 +71,7 @@ public interface MPJBaseDeepService extends IService { * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default T getOneDeep(Wrapper queryWrapper) { - return queryMapping(getOne(queryWrapper)); + return ((MPJBaseMapper) getBaseMapper()).selectOneDeep(queryWrapper); } @@ -81,7 +82,7 @@ public interface MPJBaseDeepService extends IService { * @param throwEx 有多个 result 是否抛出异常 */ default T getOneDeep(Wrapper queryWrapper, boolean throwEx) { - return queryMapping(getOne(queryWrapper, throwEx)); + return ((MPJBaseMapper) getBaseMapper()).queryMapping(getOne(queryWrapper, throwEx)); } /** @@ -114,7 +115,7 @@ public interface MPJBaseDeepService extends IService { * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default List listDeep(Wrapper queryWrapper) { - return queryMapping(list(queryWrapper)); + return ((MPJBaseMapper) getBaseMapper()).selectListDeep(queryWrapper); } /** @@ -123,7 +124,7 @@ public interface MPJBaseDeepService extends IService { * @see Wrappers#emptyWrapper() */ default List listDeep() { - return queryMapping(list()); + return ((MPJBaseMapper) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper()); } /** @@ -134,9 +135,7 @@ public interface MPJBaseDeepService extends IService { */ default > E pageDeep(E page, Wrapper queryWrapper) { E e = page(page, queryWrapper); - if (CollectionUtils.isNotEmpty(e.getRecords())) { - queryMapping(e.getRecords()); - } + ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords()); return e; } @@ -148,9 +147,7 @@ public interface MPJBaseDeepService extends IService { */ default > E pageDeep(E page) { E e = page(page); - if (CollectionUtils.isNotEmpty(e.getRecords())) { - queryMapping(e.getRecords()); - } + ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords()); return e; } @@ -181,9 +178,7 @@ public interface MPJBaseDeepService extends IService { */ default >> E pageMapsDeep(E page, Wrapper queryWrapper) { E e = pageMaps(page, queryWrapper); - if (CollectionUtils.isNotEmpty(e.getRecords())) { - queryMapMapping(e.getRecords()); - } + queryMapMapping(e.getRecords()); return e; } @@ -195,68 +190,10 @@ public interface MPJBaseDeepService extends IService { */ default >> E pageMapsDeep(E page) { E e = pageMaps(page); - if (CollectionUtils.isNotEmpty(e.getRecords())) { - queryMapMapping(e.getRecords()); - } + queryMapMapping(e.getRecords()); return e; } - /** - * 查询映射关系 - * 对结果进行二次查询 - * 可以自行查询然后在通过此方法进行二次查询 - * - * @param t 第一次查询结果 - */ - default T queryMapping(T t) { - if (t == null) { - return null; - } - MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); - if (tableInfo.isHasMapping()) { - for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { - Object get = fieldInfo.thisFieldGet(t); - if (get != null) { - List o = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(), - SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo); - MPJTableFieldInfo.bind(fieldInfo, t, o); - } - } - } - return t; - } - - /** - * 查询映射关系 - * 对结果进行二次查询 - * 可以自行查询然后在通过此方法进行二次查询 - * - * @param list 第一次查询结果 - */ - default List queryMapping(List list) { - if (CollectionUtils.isEmpty(list)) { - return list; - } - MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); - if (tableInfo.isHasMapping()) { - for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { - List itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(itemList)) { - List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( - fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); - list.forEach(i -> { - List data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j) - .equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList()); - MPJTableFieldInfo.bind(fieldInfo, i, data); - }); - } else { - list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>())); - } - } - } - return list; - } - /** * 查询映射关系 diff --git a/src/main/java/com/github/yulichang/base/MPJBaseJoinService.java b/src/main/java/com/github/yulichang/base/service/MPJJoinService.java similarity index 92% rename from src/main/java/com/github/yulichang/base/MPJBaseJoinService.java rename to src/main/java/com/github/yulichang/base/service/MPJJoinService.java index c475364..b68b87b 100644 --- a/src/main/java/com/github/yulichang/base/MPJBaseJoinService.java +++ b/src/main/java/com/github/yulichang/base/service/MPJJoinService.java @@ -1,7 +1,8 @@ -package com.github.yulichang.base; +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; @@ -12,7 +13,7 @@ import java.util.Map; * @see IService */ @SuppressWarnings("unused") -public interface MPJBaseJoinService extends IService { +public interface MPJJoinService extends IService { /** * 根据 Wrapper 条件,查询总记录数 From 0626dccb99b0e623fbe5d42cc01250bb579c9799 Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 17 Aug 2021 10:47:14 +0800 Subject: [PATCH 17/33] =?UTF-8?q?mapper=20=E6=94=AF=E6=8C=81=E5=85=B3?= =?UTF-8?q?=E7=B3=BB=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index d96b136..01adc3d 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -1,6 +1,6 @@ # mybatis-plus-join -* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta2 +* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta3 * 点个Star支持一下吧 :) @@ -15,12 +15,12 @@ QQ群:1022221898 com.github.yulichang mybatis-plus-join - 1.2.0.Beta2 + 1.2.0.Beta3 ``` - Gradle ``` - implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta2' + implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta3' ``` 或者clone代码到本地执行 mvn install, 再引入以上依赖
From a8f0c43464611b3922b31a6ada904a42b540f76f Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 17 Aug 2021 18:09:20 +0800 Subject: [PATCH 18/33] =?UTF-8?q?mapper=20=E6=94=AF=E6=8C=81=E5=85=B3?= =?UTF-8?q?=E7=B3=BB=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/github/yulichang/config/InterceptorConfig.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/yulichang/config/InterceptorConfig.java b/src/main/java/com/github/yulichang/config/InterceptorConfig.java index 8e864f0..e9b3099 100644 --- a/src/main/java/com/github/yulichang/config/InterceptorConfig.java +++ b/src/main/java/com/github/yulichang/config/InterceptorConfig.java @@ -1,8 +1,11 @@ package com.github.yulichang.config; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.github.yulichang.exception.MPJException; import com.github.yulichang.interceptor.MPJInterceptor; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.InterceptorChain; import org.apache.ibatis.session.Configuration; @@ -23,7 +26,9 @@ import java.util.List; @SuppressWarnings("SpringJavaAutowiredMembersInspection") public class InterceptorConfig implements ApplicationListener { - @Autowired + private static final Log logger = LogFactory.getLog(TableInfoHelper.class); + + @Autowired(required = false) private List sqlSessionFactoryList; @Autowired private MPJInterceptor mpjInterceptor; @@ -48,6 +53,8 @@ public class InterceptorConfig implements ApplicationListener Date: Fri, 20 Aug 2021 14:32:38 +0800 Subject: [PATCH 19/33] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/metadata/MPJTableFieldInfo.java | 39 +- .../yulichang/annotation/MPJMapping.java | 43 +- .../yulichang/base/mapper/MPJDeepMapper.java | 251 +++++++-- .../base/service/MPJDeepService.java | 506 ++++++++++++++++-- .../yulichang/injector/MPJSqlInjector.java | 14 +- 5 files changed, 718 insertions(+), 135 deletions(-) diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java index 5b23ed1..3aef77c 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java @@ -15,7 +15,6 @@ import lombok.ToString; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -40,6 +39,10 @@ public class MPJTableFieldInfo { * 属性 */ private Field field; + /** + * 属性名 + */ + private String property; /** * 数据结构是否是Map或者List */ @@ -67,7 +70,7 @@ public class MPJTableFieldInfo { /** * 映射实体类 */ - private final Class joinClass; + private Class joinClass; /** * 映射属性名 */ @@ -102,15 +105,17 @@ public class MPJTableFieldInfo { /** * 初始化关联字段信息 */ - public MPJTableFieldInfo(Class entityType, MPJMapping mapping, Field field1) { - initField(field1); + public MPJTableFieldInfo(Class entityType, MPJMapping mapping, Field field) { + initField(field); + if (mapping.tag() != Object.class) { + this.joinClass = mapping.tag(); + } this.entityType = entityType; - this.joinClass = mapping.tag(); this.isThrowExp = mapping.isThrowExp(); this.thisMapKey = StringUtils.isBlank(mapping.thisMapKey()) ? null : mapping.thisMapKey(); this.joinMapKey = StringUtils.isBlank(mapping.joinMapKsy()) ? null : mapping.joinMapKsy(); this.wrapper = new MPJMappingWrapper(mapping); - if (this.isCollection && this.field.getType() != List.class && this.field.getType() != ArrayList.class) { + if (this.isCollection && !List.class.isAssignableFrom(this.field.getType())) { throw new MPJException("对多关系的数据结构目前只支持 暂不支持其他Collection实现 " + this.field.getType().getTypeName()); } if (StringUtils.isNotBlank(mapping.joinField())) { @@ -132,6 +137,7 @@ public class MPJTableFieldInfo { private void initField(Field field) { field.setAccessible(true); this.field = field; + this.property = field.getName(); this.isCollection = Collection.class.isAssignableFrom(field.getType()); if (Map.class.isAssignableFrom(field.getType())) { @@ -149,6 +155,15 @@ public class MPJTableFieldInfo { this.fieldIsMap = false; } } + + 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(); + } } @SuppressWarnings("ConstantConditions") @@ -269,28 +284,28 @@ public class MPJTableFieldInfo { } public static void bind(MPJTableFieldInfo fieldInfo, T i, List data) { - if (!fieldInfo.isCollection()) { + 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)); } - } else { - fieldInfo.fieldSet(i, data); } } public static void bindMap(MPJTableFieldInfo fieldInfo, Map i, List data) { - if (!fieldInfo.isCollection()) { + 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)); } - } else { - i.put(fieldInfo.getField().getName(), data); } } diff --git a/src/main/java/com/github/yulichang/annotation/MPJMapping.java b/src/main/java/com/github/yulichang/annotation/MPJMapping.java index 8b381e9..3cec144 100644 --- a/src/main/java/com/github/yulichang/annotation/MPJMapping.java +++ b/src/main/java/com/github/yulichang/annotation/MPJMapping.java @@ -15,62 +15,63 @@ import java.lang.annotation.*; public @interface MPJMapping { /** - * 关联的数据库实体类 + * 关联的数据库实体类
+ * 默认获取此注解所对应的类 */ - Class tag(); + Class tag() default Object.class; /** - * 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称) + * 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称)
* 默认获取当前类上定义的主键 @TableId */ String thisField() default ""; /** - * 关联类的字段名称 (是实体类字段名称而不是数据库字段名称) + * 关联类的字段名称 (是实体类字段名称而不是数据库字段名称)
* 默认获取关联类上定义的主键 @TableId */ String joinField() default ""; /** - * 一对一查询时 如果查询到多条记录是否抛出异常 - * true 抛出异常 - * false 不抛异常,获取列表第一条数据 + * 一对一查询时 如果查询到多条记录是否抛出异常
+ * true 抛出异常
+ * false 不抛异常,获取列表第一条数据
*/ boolean isThrowExp() default true; /** - * 针对查询结果map的时候使用 - * 默认为thisField对应的数据库列名 + * 针对查询结果map的时候使用
+ * 默认为thisField对应的数据库列名
*

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

- * 如果此类是以map方式查询的 - * 并且查询出来的map的key不是thisField对应的数据库列名就需要设置 + * 如果此类是以map方式查询的
+ * 并且查询出来的map的key不是thisField对应的数据库列名就需要设置
*/ String joinMapKsy() default ""; /** - * 映射表查询条件之 select + * 映射表查询条件之 select
* 等效于 Wrappers.query().select(xxx); */ String select() default ""; /** - * 映射表查询条件之 first + * 映射表查询条件之 first
* 等效于 Wrappers.query().first(xxx); */ String first() default ""; /** - * 映射表查询条件之 apply + * 映射表查询条件之 apply
* 等效于 Wrappers.query().apply(xxx); */ MPJMappingApply[] apply() default {}; @@ -81,8 +82,8 @@ public @interface MPJMapping { MPJMappingCondition[] condition() default {}; /** - * 映射表查询条件之 last - * 建议不要在这使用分页语句,会导致关联查的时候查询不全 + * 映射表查询条件之 last
+ * 建议不要在这使用分页语句,会导致关联查的时候查询不全
* 等效于 Wrappers.query().last(xxx); */ String last() default ""; diff --git a/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java b/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java index cf89a4e..6f9cc69 100644 --- a/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java +++ b/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java @@ -6,30 +6,52 @@ 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.Constants; -import org.apache.ibatis.annotations.Param; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; +import com.github.yulichang.toolkit.LambdaUtils; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** * @author yulichang * @see BaseMapper */ -@SuppressWarnings("unused") +@SuppressWarnings({"unused", "unchecked"}) public interface MPJDeepMapper extends BaseMapper { /** - * 根据 ID 查询 + * 根据 ID 查询 并关联全部映射 * * @param id 主键ID */ default T selectByIdDeep(Serializable id) { - return queryMapping(selectById(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); } /** @@ -37,8 +59,33 @@ public interface MPJDeepMapper extends BaseMapper { * * @param idList 主键ID列表(不能为 null 以及 empty) */ - default List selectBatchIdsDeep(@Param(Constants.COLLECTION) Collection idList) { - return queryMapping(selectBatchIds(idList)); + 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); } /** @@ -46,8 +93,33 @@ public interface MPJDeepMapper extends BaseMapper { * * @param columnMap 表字段 map 对象 */ - default List selectByMapDeep(@Param(Constants.COLUMN_MAP) Map columnMap) { - return queryMapping(selectByMap(columnMap)); + 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); } /** @@ -55,8 +127,33 @@ public interface MPJDeepMapper extends BaseMapper { * * @param queryWrapper 实体对象封装操作类(可以为 null) */ - default T selectOneDeep(@Param(Constants.WRAPPER) Wrapper queryWrapper) { - return queryMapping(selectOne(queryWrapper)); + 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); } /** @@ -64,8 +161,33 @@ public interface MPJDeepMapper extends BaseMapper { * * @param queryWrapper 实体对象封装操作类(可以为 null) */ - default List selectListDeep(@Param(Constants.WRAPPER) Wrapper queryWrapper) { - return queryMapping(selectList(queryWrapper)); + 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); } @@ -75,31 +197,68 @@ public interface MPJDeepMapper extends BaseMapper { * @param page 分页查询条件(可以为 RowBounds.DEFAULT) * @param queryWrapper 实体对象封装操作类(可以为 null) */ - default > E selectPageDeep(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper) { + default > E selectPageDeep(E page, Wrapper queryWrapper) { E e = selectPage(page, queryWrapper); - queryMapping(e.getRecords()); + 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; + } + + /** + * 查询映射关系
+ * 对结果进行二次查询
+ * 可以自行查询然后在通过此方法进行二次查询
+ * list为null或空,会查询全部映射关系
* * @param t 第一次查询结果 */ - default T queryMapping(T t) { + default T queryMapping(T t, List> property) { if (t == null) { return null; } MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass()); if (tableInfo.isHasMapping()) { + boolean hasProperty = CollectionUtils.isNotEmpty(property); + List list = hasProperty ? property.stream().map(LambdaUtils::getName).collect( + Collectors.toList()) : null; for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { - Object get = fieldInfo.thisFieldGet(t); - if (get != null) { - List o = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(), - SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo); - MPJTableFieldInfo.bind(fieldInfo, t, o); + if (!hasProperty || list.contains(fieldInfo.getProperty())) { + Object get = fieldInfo.thisFieldGet(t); + if (get != null) { + List o = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(), + SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo); + MPJTableFieldInfo.bind(fieldInfo, t, o); + } } } } @@ -107,30 +266,36 @@ public interface MPJDeepMapper extends BaseMapper { } /** - * 查询映射关系 - * 对结果进行二次查询 - * 可以自行查询然后在通过此方法进行二次查询 + * 查询映射关系
+ * 对结果进行二次查询
+ * 可以自行查询然后在通过此方法进行二次查询
+ * list为null或空,会查询全部映射关系
* * @param list 第一次查询结果 */ - default List queryMapping(List list) { + default List queryMapping(List list, List> property) { if (CollectionUtils.isEmpty(list)) { return list; } MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(list.get(0).getClass()); if (tableInfo.isHasMapping()) { + boolean hasProperty = CollectionUtils.isNotEmpty(property); + List listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect( + Collectors.toList()) : null; for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { - List itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(itemList)) { - List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( - fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); - list.forEach(i -> { - List data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j) - .equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList()); - MPJTableFieldInfo.bind(fieldInfo, i, data); - }); - } else { - list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>())); + 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.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); + list.forEach(i -> { + List data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j) + .equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList()); + MPJTableFieldInfo.bind(fieldInfo, i, data); + }); + } else { + list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>())); + } } } } diff --git a/src/main/java/com/github/yulichang/base/service/MPJDeepService.java b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java index fb60767..a2fe8c1 100644 --- a/src/main/java/com/github/yulichang/base/service/MPJDeepService.java +++ b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java @@ -8,15 +8,14 @@ import com.baomidou.mybatisplus.core.metadata.MPJTableInfo; import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 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.MPJMapping; import com.github.yulichang.base.MPJBaseMapper; +import com.github.yulichang.toolkit.LambdaUtils; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -30,7 +29,7 @@ import java.util.stream.Collectors; * @see MPJMapping * @since 1.2.0 */ -@SuppressWarnings("unused") +@SuppressWarnings({"unused", "unchecked"}) public interface MPJDeepService extends IService { Class currentModelClass(); @@ -40,10 +39,34 @@ public interface MPJDeepService extends IService { * * @param id 主键ID列表 */ - default T getByIdDeep(Serializable 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 批量查询) @@ -54,6 +77,31 @@ public interface MPJDeepService extends IService { 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 条件) * @@ -63,6 +111,31 @@ public interface MPJDeepService extends IService { 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,查询一条记录
@@ -74,6 +147,32 @@ public interface MPJDeepService extends IService { 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,查询一条记录 @@ -82,7 +181,34 @@ public interface MPJDeepService extends IService { * @param throwEx 有多个 result 是否抛出异常 */ default T getOneDeep(Wrapper queryWrapper, boolean throwEx) { - return ((MPJBaseMapper) getBaseMapper()).queryMapping(getOne(queryWrapper, 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); } /** @@ -91,23 +217,33 @@ public interface MPJDeepService extends IService { * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default Map getMapDeep(Wrapper queryWrapper) { - Map map = getMap(queryWrapper); - if (CollectionUtils.isNotEmpty(map)) { - MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); - if (tableInfo.isHasMapping()) { - for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { - Object o = map.get(fieldInfo.getThisMapKey()); - if (o != null) { - List data = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(), - SqlKeyword.EQ, fieldInfo.getJoinColumn(), o, fieldInfo); - MPJTableFieldInfo.bindMap(fieldInfo, map, data); - } - } - } - } - return map; + return queryMapMapping(getMap(queryWrapper), 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 queryMapMapping(getMap(queryWrapper), 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 queryMapMapping(getMap(queryWrapper), property); + } /** * 查询列表 @@ -118,6 +254,31 @@ public interface MPJDeepService extends IService { 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); + } + /** * 查询所有 * @@ -127,6 +288,31 @@ public interface MPJDeepService extends IService { 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); + } + /** * 翻页查询 * @@ -135,7 +321,38 @@ public interface MPJDeepService extends IService { */ default > E pageDeep(E page, Wrapper queryWrapper) { E e = page(page, queryWrapper); - ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords()); + ((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; } @@ -147,7 +364,38 @@ public interface MPJDeepService extends IService { */ default > E pageDeep(E page) { E e = page(page); - ((MPJBaseMapper) getBaseMapper()).queryMapping(e.getRecords()); + ((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; } @@ -157,7 +405,32 @@ public interface MPJDeepService extends IService { * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default List> listMapsDeep(Wrapper queryWrapper) { - return queryMapMapping(listMaps(queryWrapper)); + return queryMapMapping(listMaps(queryWrapper), 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 queryMapMapping(listMaps(queryWrapper), 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 queryMapMapping(listMaps(queryWrapper), property); } /** @@ -166,9 +439,33 @@ public interface MPJDeepService extends IService { * @see Wrappers#emptyWrapper() */ default List> listMapsDeep() { - return queryMapMapping(listMaps()); + return queryMapMapping(listMaps(), null); } + /** + * 查询所有列表 + *

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

+ * 例:listMapsDeep(Arrays.asList(User::getId, ... )) + * + * @param property 需要关联的字段 + * @see Wrappers#emptyWrapper() + */ + default List> listMapsDeep(List> property) { + return queryMapMapping(listMaps(), property); + } /** * 翻页查询 @@ -178,7 +475,38 @@ public interface MPJDeepService extends IService { */ default >> E pageMapsDeep(E page, Wrapper queryWrapper) { E e = pageMaps(page, queryWrapper); - queryMapMapping(e.getRecords()); + queryMapMapping(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 pageMapsDeep(E page, Wrapper queryWrapper, SFunction... property) { + E e = pageMaps(page, queryWrapper); + queryMapMapping(e.getRecords(), 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); + queryMapMapping(e.getRecords(), property); return e; } @@ -190,55 +518,121 @@ public interface MPJDeepService extends IService { */ default >> E pageMapsDeep(E page) { E e = pageMaps(page); - queryMapMapping(e.getRecords()); + queryMapMapping(e.getRecords(), 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); + queryMapMapping(e.getRecords(), 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); + queryMapMapping(e.getRecords(), property); + return e; + } + + /** + * 查询映射关系
+ * 对结果进行二次查询
+ * 可以自行查询然后在通过此方法进行二次查询
+ * list为null或空,会查询全部映射关系
+ * + * @param map 第一次查询结果 + */ + default Map queryMapMapping(Map map, List> property) { + if (CollectionUtils.isNotEmpty(map)) { + MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); + if (tableInfo.isHasMapping()) { + 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 o = map.get(fieldInfo.getThisMapKey()); + if (o != null) { + List data = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( + fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), o, fieldInfo); + MPJTableFieldInfo.bindMap(fieldInfo, map, data); + } + } + } + } + } + return map; + } + + /** + * 查询映射关系
+ * 对结果进行二次查询
+ * 可以自行查询然后在通过此方法进行二次查询
+ * list为null或空,会查询全部映射关系
* * @param list 第一次查询结果 */ @SuppressWarnings("unchecked") - default List> queryMapMapping(List> list) { + default List> queryMapMapping(List> list, List> property) { if (CollectionUtils.isEmpty(list)) { return list; } MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); if (tableInfo.isHasMapping()) { + boolean hasProperty = CollectionUtils.isNotEmpty(property); + List listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect( + Collectors.toList()) : null; for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) { - List itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey())).collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(itemList)) { - if (fieldInfo.isFieldIsMap()) { - List> joinList = (List>) fieldInfo.getJoinMapper() - .mappingWrapperConstructor(fieldInfo.isFieldIsMap(), SqlKeyword.IN, - fieldInfo.getJoinColumn(), itemList, fieldInfo); - list.forEach(i -> { - List> data = joinList.stream().filter(j -> j.containsKey(fieldInfo.getJoinMapKey()) - && j.get(fieldInfo.getJoinMapKey()).equals(i.get(fieldInfo.getThisMapKey()))).collect(Collectors.toList()); - MPJTableFieldInfo.bindMap(fieldInfo, i, data); - }); + if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) { + List itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey())) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(itemList)) { + if (fieldInfo.isFieldIsMap()) { + List> joinList = (List>) fieldInfo.getJoinMapper() + .mappingWrapperConstructor(fieldInfo.isFieldIsMap(), SqlKeyword.IN, + fieldInfo.getJoinColumn(), itemList, fieldInfo); + list.forEach(i -> { + List> data = joinList.stream().filter(j -> j.containsKey( + fieldInfo.getJoinMapKey()) && j.get(fieldInfo.getJoinMapKey()).equals( + i.get(fieldInfo.getThisMapKey()))).collect(Collectors.toList()); + MPJTableFieldInfo.bindMap(fieldInfo, i, data); + }); + } else { + List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( + fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); + list.forEach(i -> { + List data = joinList.stream().filter(j -> { + Object o = fieldInfo.joinFieldGet(j); + return o != null && o.equals(i.get(fieldInfo.getThisMapKey())); + }).collect(Collectors.toList()); + MPJTableFieldInfo.bindMap(fieldInfo, i, data); + }); + } } else { - List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( - fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); - list.forEach(i -> { - List data = joinList.stream().filter(j -> { - Object o = fieldInfo.joinFieldGet(j); - return o != null && o.equals(i.get(fieldInfo.getThisMapKey())); - }).collect(Collectors.toList()); - MPJTableFieldInfo.bindMap(fieldInfo, i, data); - }); + list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>())); } - } else { - list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>())); } } } return list; } - - } diff --git a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java index 6baeb1e..12b5d76 100644 --- a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java +++ b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java @@ -2,9 +2,11 @@ package com.github.yulichang.injector; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; +import com.baomidou.mybatisplus.core.mapper.Mapper; import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; 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.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils; import com.github.yulichang.method.*; @@ -12,6 +14,7 @@ import org.apache.ibatis.builder.MapperBuilderAssistant; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.core.GenericTypeResolver; import java.util.List; import java.util.Set; @@ -42,7 +45,7 @@ public class MPJSqlInjector extends DefaultSqlInjector { @Override public void inspectInject(MapperBuilderAssistant builderAssistant, Class mapperClass) { - Class modelClass = extractModelClass(mapperClass); + Class modelClass = getSuperClassGenericType(mapperClass, Mapper.class, 0); if (modelClass != null) { String className = mapperClass.toString(); Set mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration()); @@ -50,14 +53,19 @@ public class MPJSqlInjector extends DefaultSqlInjector { List methodList = this.getMethodList(mapperClass); if (CollectionUtils.isNotEmpty(methodList)) { TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass); - MPJTableInfoHelper.initTableInfo(builderAssistant, extractModelClass(mapperClass), mapperClass); + MPJTableInfoHelper.initTableInfo(builderAssistant, modelClass, mapperClass); // 循环注入自定义方法 methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo)); } else { - logger.debug(mapperClass + ", No effective injection method was found."); + logger.debug(mapperClass.toString() + ", No effective injection method was found."); } mapperRegistryCache.add(className); } } } + + public static Class getSuperClassGenericType(final Class clazz, final Class genericIfc, final int index) { + Class[] typeArguments = GenericTypeResolver.resolveTypeArguments(ClassUtils.getUserClass(clazz), genericIfc); + return null == typeArguments ? null : typeArguments[index]; + } } From 2659497f0a2af272026e37cd364cf3f46c93aaaf Mon Sep 17 00:00:00 2001 From: bjdys Date: Mon, 23 Aug 2021 16:37:17 +0800 Subject: [PATCH 20/33] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/metadata/MPJMappingWrapper.java | 24 +- .../core/metadata/MPJTableAliasHelper.java | 61 +++++ .../core/metadata/MPJTableFieldInfo.java | 238 +++++++++++------- .../core/metadata/MPJTableInfo.java | 16 +- .../core/metadata/MPJTableInfoHelper.java | 43 ++-- .../{MPJMapping.java => EntityMapping.java} | 6 +- .../yulichang/annotation/FieldMapping.java | 89 +++++++ .../yulichang/annotation/MPJTableAlias.java | 12 +- .../yulichang/base/mapper/MPJDeepMapper.java | 215 ++++++++++++++-- .../base/service/MPJDeepService.java | 132 ++-------- .../yulichang/injector/MPJSqlInjector.java | 31 +-- .../yulichang/method/MPJAbstractMethod.java | 6 +- .../query/MPJLambdaQueryWrapper.java | 1 + .../yulichang/query/MPJQueryWrapper.java | 1 + .../yulichang/query/interfaces/MPJJoin.java | 1 + .../github/yulichang/toolkit/Constant.java | 2 - .../github/yulichang/toolkit/LambdaUtils.java | 1 + .../yulichang/toolkit/ReflectionKit.java | 1 + .../github/yulichang/toolkit/Wrappers.java | 1 + .../toolkit/support/SerializedLambda.java | 2 +- .../wrapper/MPJAbstractLambdaWrapper.java | 4 +- .../yulichang/wrapper/MPJLambdaWrapper.java | 12 +- .../yulichang/wrapper/interfaces/Compare.java | 2 + .../yulichang/wrapper/interfaces/Func.java | 3 +- .../yulichang/wrapper/interfaces/Join.java | 1 + .../wrapper/interfaces/LambdaJoin.java | 65 +++++ 26 files changed, 663 insertions(+), 307 deletions(-) create mode 100644 src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java rename src/main/java/com/github/yulichang/annotation/{MPJMapping.java => EntityMapping.java} (95%) create mode 100644 src/main/java/com/github/yulichang/annotation/FieldMapping.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 index 24141b0..61a3b1e 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java @@ -3,7 +3,6 @@ package com.baomidou.mybatisplus.core.metadata; import com.baomidou.mybatisplus.core.enums.SqlKeyword; import com.baomidou.mybatisplus.core.toolkit.StringUtils; -import com.github.yulichang.annotation.MPJMapping; import com.github.yulichang.annotation.MPJMappingApply; import com.github.yulichang.annotation.MPJMappingCondition; import lombok.AllArgsConstructor; @@ -36,36 +35,37 @@ public class MPJMappingWrapper { private final boolean hasLast; private String last; - public MPJMappingWrapper(MPJMapping mapping) { - this.hasFirst = StringUtils.isNotBlank(mapping.first()); + public MPJMappingWrapper(String first, String select, MPJMappingApply[] applys, + MPJMappingCondition[] conditions, String last) { + this.hasFirst = StringUtils.isNotBlank(first); if (this.hasFirst) { - this.first = mapping.first(); + this.first = first; } - this.hasSelect = StringUtils.isNotBlank(mapping.select()); + this.hasSelect = StringUtils.isNotBlank(select); if (this.hasSelect) { - this.select = mapping.select(); + this.select = select; } - this.hasApply = mapping.apply().length > 0; + this.hasApply = applys.length > 0; if (this.hasApply) { this.applyList = new ArrayList<>(); - for (MPJMappingApply apply : mapping.apply()) { + for (MPJMappingApply apply : applys) { this.applyList.add(new Apply(apply.value(), apply.args())); } } - this.hasCondition = mapping.condition().length > 0; + this.hasCondition = conditions.length > 0; if (this.hasCondition) { this.conditionList = new ArrayList<>(); - for (MPJMappingCondition condition : mapping.condition()) { + for (MPJMappingCondition condition : conditions) { conditionList.add(new Condition(condition.keyWord(), condition.column(), condition.value())); } } - this.hasLast = StringUtils.isNotBlank(mapping.last()); + this.hasLast = StringUtils.isNotBlank(last); if (this.hasLast) { - this.last = mapping.last(); + this.last = last; } } diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java new file mode 100644 index 0000000..3652ba6 --- /dev/null +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java @@ -0,0 +1,61 @@ +package com.baomidou.mybatisplus.core.metadata; + +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.github.yulichang.annotation.MPJTableAlias; +import com.github.yulichang.toolkit.Constant; +import lombok.Data; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 全局表别名控制,默认表别名为 t t1 t2 ...
+ * 可以通过@MPJTableAlias注解指定表别名
+ * 仅对MPJLambdaWrapper有效 + * + * @author yulichang + * @see com.github.yulichang.wrapper.MPJLambdaWrapper + * @see MPJTableAlias + * @since 1.2.0 + */ +public class MPJTableAliasHelper { + + public static final Map, TableAlias> CACHE = new ConcurrentHashMap<>(); + + /** + * 用于生成别名的序号 + */ + private static final AtomicInteger index = new AtomicInteger(1); + + public static void init(Class clazz) { + TableAlias alias = new TableAlias(); + MPJTableAlias tableAlias = clazz.getAnnotation(MPJTableAlias.class); + if (tableAlias != null && StringUtils.isNotBlank(tableAlias.value())) { + alias.setAlias(tableAlias.value()); + } else { + alias.setAlias(Constant.TABLE_ALIAS + index.getAndIncrement()); + } + alias.setAliasDOT(alias.getAlias() + StringPool.DOT); + CACHE.put(clazz, alias); + } + + public static TableAlias get(Class clazz) { + return CACHE.get(clazz); + } + + @Data + public static class TableAlias { + /** + * 表别名 + */ + private String alias; + + /** + * 前缀 + */ + private String aliasDOT; + } + +} diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java index 3aef77c..c956c2c 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java @@ -1,10 +1,8 @@ package com.baomidou.mybatisplus.core.metadata; -import com.baomidou.mybatisplus.core.toolkit.Assert; -import com.baomidou.mybatisplus.core.toolkit.ClassUtils; -import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; -import com.baomidou.mybatisplus.core.toolkit.StringUtils; -import com.github.yulichang.annotation.MPJMapping; +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; @@ -15,6 +13,7 @@ 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; @@ -31,6 +30,22 @@ import java.util.Map; @EqualsAndHashCode public class MPJTableFieldInfo { + /** + * 是否是实体映射 + */ + private final boolean isMappingEntity; + /** + * 是否是属性映射 + */ + private final boolean isMappingField; + /** + * 字段映射是绑定的字段 + */ + private Field bindField; + /** + * 是否移除绑定字段 + */ + private final boolean isRemoveBindField; /** * 实体类 */ @@ -58,7 +73,7 @@ public class MPJTableFieldInfo { /** * 当前类实体属性 */ - private final String thisProperty; + private String thisProperty; /** * 当前字段信息 */ @@ -74,7 +89,7 @@ public class MPJTableFieldInfo { /** * 映射属性名 */ - private final String joinProperty; + private String joinProperty; /** * 映射属性数据库列名 */ @@ -105,33 +120,112 @@ public class MPJTableFieldInfo { /** * 初始化关联字段信息 */ - public MPJTableFieldInfo(Class entityType, MPJMapping mapping, Field field) { + 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(); - this.thisMapKey = StringUtils.isBlank(mapping.thisMapKey()) ? null : mapping.thisMapKey(); - this.joinMapKey = StringUtils.isBlank(mapping.joinMapKsy()) ? null : mapping.joinMapKsy(); - this.wrapper = new MPJMappingWrapper(mapping); + 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()); + } + + 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()); } - if (StringUtils.isNotBlank(mapping.joinField())) { - this.joinProperty = mapping.joinField(); + 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()); + 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(); } - if (StringUtils.isNotBlank(mapping.thisField())) { - this.thisProperty = mapping.thisField(); + + 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, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(), + StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); + Assert.notNull(this.joinColumn, "MPJMapping注解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, "MPJMapping注解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, "MPJMapping注解thisField不存在 %s , %s", entityType.getName(), + StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty); + assert fieldInfo != null; + 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) { @@ -139,7 +233,9 @@ public class MPJTableFieldInfo { 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 { @@ -156,83 +252,16 @@ public class MPJTableFieldInfo { } } - 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(); - } - } - - @SuppressWarnings("ConstantConditions") - public Field getThisField() { - if (this.thisField == null) { - 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, "MPJMapping注解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, "MPJMapping注解thisField不存在 %s , %s", entityType.getName(), - StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty); - this.thisField = fieldInfo.getField(); - this.thisColumn = fieldInfo.getColumn(); - } - this.thisField.setAccessible(true); - } - return this.thisField; - } - - public String getJoinColumn() { - if (StringUtils.isBlank(this.joinColumn)) { - 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); + 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.joinColumn = joinFieldInfo.getColumn(); - this.joinField = joinFieldInfo.getField(); + this.joinClass = field.getType(); } - Assert.notNull(this.joinField, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(), - StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); - Assert.notNull(this.joinColumn, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(), - StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); - this.joinField.setAccessible(true); } - return this.joinColumn; - } - - public String getThisMapKey() { - if (this.thisMapKey == null) { - this.thisMapKey = getJoinColumn(); - } - return this.thisMapKey; - } - - public Field getJoinField() { - if (this.joinField == null) { - this.getJoinColumn(); - } - return this.joinField; - } - - - public String getJoinMapKey() { - if (this.joinMapKey == null) { - this.joinMapKey = getJoinColumn(); - } - return joinMapKey; } public MPJBaseMapper getJoinMapper() { @@ -283,6 +312,35 @@ public class MPJTableFieldInfo { } } + 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); @@ -308,6 +366,4 @@ public class MPJTableFieldInfo { } } } - - } diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java index 3c0f543..54b015f 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java @@ -25,27 +25,27 @@ public class MPJTableInfo { private TableInfo tableInfo; /** - * 表别名 + * 是否包含 MPJMapping 或者 MPJMappingField */ - private String alias; - - /** - * 前缀 - */ - private String aliasDOT; + 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/MPJTableInfoHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java index c9b5ec3..564b4ed 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java @@ -3,9 +3,8 @@ package com.baomidou.mybatisplus.core.metadata; import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.core.config.GlobalConfig; import com.baomidou.mybatisplus.core.toolkit.*; -import com.github.yulichang.annotation.MPJMapping; -import com.github.yulichang.annotation.MPJTableAlias; -import com.github.yulichang.toolkit.Constant; +import com.github.yulichang.annotation.EntityMapping; +import com.github.yulichang.annotation.FieldMapping; import org.apache.ibatis.builder.MapperBuilderAssistant; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; @@ -19,7 +18,6 @@ import org.apache.ibatis.session.Configuration; import java.lang.reflect.Field; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; import static java.util.stream.Collectors.toList; @@ -37,10 +35,6 @@ import static java.util.stream.Collectors.toList; */ public class MPJTableInfoHelper { - /** - * 用于生成别名的序号 - */ - private static final AtomicInteger index = new AtomicInteger(1); private static final Log logger = LogFactory.getLog(TableInfoHelper.class); @@ -124,7 +118,6 @@ public class MPJTableInfoHelper { TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz); if (tableInfo != null) { mpjTableInfo.setTableInfo(tableInfo); - initTableAlias(mpjTableInfo); initMapping(mpjTableInfo); /* 添加缓存 */ TABLE_INFO_CACHE.put(clazz, mpjTableInfo); @@ -154,24 +147,11 @@ public class MPJTableInfoHelper { /* 缓存 lambda */ LambdaUtils.installCache(tableInfo); - /* 初始化表别名 */ - initTableAlias(mpjTableInfo); - /* 初始化映射关系 */ initMapping(mpjTableInfo); return mpjTableInfo; } - private static void initTableAlias(MPJTableInfo tableInfo) { - MPJTableAlias tableAlias = tableInfo.getTableInfo().getEntityType().getAnnotation(MPJTableAlias.class); - if (tableAlias != null && StringUtils.isNotBlank(tableAlias.value())) { - tableInfo.setAlias(tableAlias.value()); - return; - } - tableInfo.setAlias(Constant.TABLE_ALIAS + index.getAndIncrement()); - tableInfo.setAliasDOT(tableInfo.getAlias() + StringPool.DOT); - } - /** * 自动构建 resultMap 并注入(如果条件符合的话) */ @@ -371,7 +351,11 @@ public class MPJTableInfoHelper { } private static boolean isExistMapping(Class clazz) { - return ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz)).stream().anyMatch(field -> field.isAnnotationPresent(MPJMapping.class)); + return ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz)).stream().anyMatch(field -> field.isAnnotationPresent(EntityMapping.class)); + } + + private static boolean isExistMappingField(Class clazz) { + return ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz)).stream().anyMatch(field -> field.isAnnotationPresent(FieldMapping.class)); } /** @@ -512,12 +496,22 @@ public class MPJTableInfoHelper { // 是否存在 @MPJMapping 注解 boolean existMapping = isExistMapping(mpjTableInfo.getTableInfo().getEntityType()); mpjTableInfo.setHasMapping(existMapping); + // 是否存在 @MPJMappingField 注解 + boolean existMappingField = isExistMappingField(mpjTableInfo.getTableInfo().getEntityType()); + mpjTableInfo.setHasMappingField(existMappingField); + mpjTableInfo.setHasMappingOrField(existMapping || existMappingField); /* 关系映射初始化 */ List mpjFieldList = new ArrayList<>(); List fields = ReflectionKit.getFieldList(ClassUtils.getUserClass(mpjTableInfo.getTableInfo().getEntityType())); for (Field field : fields) { if (existMapping) { - MPJMapping mapping = field.getAnnotation(MPJMapping.class); + EntityMapping mapping = field.getAnnotation(EntityMapping.class); + if (mapping != null) { + mpjFieldList.add(new MPJTableFieldInfo(mpjTableInfo.getTableInfo().getEntityType(), mapping, field)); + } + } + if (existMappingField) { + FieldMapping mapping = field.getAnnotation(FieldMapping.class); if (mapping != null) { mpjFieldList.add(new MPJTableFieldInfo(mpjTableInfo.getTableInfo().getEntityType(), mapping, field)); } @@ -526,5 +520,4 @@ public class MPJTableInfoHelper { /* 映射字段列表 */ mpjTableInfo.setFieldList(mpjFieldList); } - } diff --git a/src/main/java/com/github/yulichang/annotation/MPJMapping.java b/src/main/java/com/github/yulichang/annotation/EntityMapping.java similarity index 95% rename from src/main/java/com/github/yulichang/annotation/MPJMapping.java rename to src/main/java/com/github/yulichang/annotation/EntityMapping.java index 3cec144..33fa0e0 100644 --- a/src/main/java/com/github/yulichang/annotation/MPJMapping.java +++ b/src/main/java/com/github/yulichang/annotation/EntityMapping.java @@ -4,7 +4,7 @@ package com.github.yulichang.annotation; import java.lang.annotation.*; /** - * 关系映射注解 + * 实体类关系映射注解 * * @author yulichang * @since 1.2.0 @@ -12,7 +12,7 @@ import java.lang.annotation.*; @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) -public @interface MPJMapping { +public @interface EntityMapping { /** * 关联的数据库实体类
@@ -56,7 +56,7 @@ public @interface MPJMapping { * 如果此类是以map方式查询的
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置
*/ - String joinMapKsy() default ""; + String joinMapKey() default ""; /** * 映射表查询条件之 select
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..0832794 --- /dev/null +++ b/src/main/java/com/github/yulichang/annotation/FieldMapping.java @@ -0,0 +1,89 @@ +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 {}; + + /** + * 映射表查询条件之 last
+ * 建议不要在这使用分页语句,会导致关联查的时候查询不全
+ * 等效于 Wrappers.query().last(xxx); + */ + String last() default ""; +} diff --git a/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java b/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java index b4a89f3..0a5f067 100644 --- a/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java +++ b/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java @@ -3,12 +3,12 @@ package com.github.yulichang.annotation; import java.lang.annotation.*; /** - * 关联查询时的表别名 - * 框架默认会随机生成 一般是 t1 t2 t3 ... - * 不要在程序中使用随机别名,运行期间是不变的,但是重启就不一定了 - * 如需使用请配合此注解一起使用 + * 关联查询时的表别名
+ * 框架默认会随机生成 一般是 t1 t2 t3 ...
+ * 不要在程序中使用随机别名,运行期间是不变的,但是重启就不一定了
+ * 如需使用请配合此注解一起使用
*

- * 这个注解定义的表别名或者随机生成的别名只对MPJLambdaWrapper生效 + * 这个注解定义的表别名或者随机生成的别名只对MPJLambdaWrapper生效
* 对MPJQueryWrapper不生效, * * @author yulichang @@ -21,5 +21,5 @@ import java.lang.annotation.*; @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) public @interface MPJTableAlias { - String value() default ""; + 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 index 6f9cc69..85c8dc5 100644 --- a/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java +++ b/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java @@ -190,6 +190,40 @@ public interface MPJDeepMapper extends BaseMapper { 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 条件,查询全部记录(并翻页) @@ -234,6 +268,54 @@ public interface MPJDeepMapper extends BaseMapper { 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; + } + /** * 查询映射关系
* 对结果进行二次查询
@@ -247,17 +329,18 @@ public interface MPJDeepMapper extends BaseMapper { return null; } MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass()); - if (tableInfo.isHasMapping()) { + 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 get = fieldInfo.thisFieldGet(t); - if (get != null) { - List o = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(), - SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo); - MPJTableFieldInfo.bind(fieldInfo, t, o); + 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); } } } @@ -265,6 +348,38 @@ public interface MPJDeepMapper extends BaseMapper { 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; + } + /** * 查询映射关系
* 对结果进行二次查询
@@ -278,7 +393,7 @@ public interface MPJDeepMapper extends BaseMapper { return list; } MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(list.get(0).getClass()); - if (tableInfo.isHasMapping()) { + if (tableInfo.isHasMappingOrField()) { boolean hasProperty = CollectionUtils.isNotEmpty(property); List listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect( Collectors.toList()) : null; @@ -287,12 +402,10 @@ public interface MPJDeepMapper extends BaseMapper { List itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(itemList)) { List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( - fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); - list.forEach(i -> { - List data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j) - .equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList()); - MPJTableFieldInfo.bind(fieldInfo, i, data); - }); + 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<>())); } @@ -302,9 +415,83 @@ public interface MPJDeepMapper extends BaseMapper { 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 构造器 - * 仅对使用 @MPJMapping 时使用 + * 仅对使用映射注解时使用 */ default Object mappingWrapperConstructor(boolean selectMap, SqlKeyword keyword, String column, Object val, MPJTableFieldInfo fieldInfo) { diff --git a/src/main/java/com/github/yulichang/base/service/MPJDeepService.java b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java index a2fe8c1..52d425e 100644 --- a/src/main/java/com/github/yulichang/base/service/MPJDeepService.java +++ b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java @@ -1,22 +1,18 @@ package com.github.yulichang.base.service; import com.baomidou.mybatisplus.core.conditions.Wrapper; -import com.baomidou.mybatisplus.core.enums.SqlKeyword; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.core.metadata.MPJTableFieldInfo; -import com.baomidou.mybatisplus.core.metadata.MPJTableInfo; -import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; -import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 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.MPJMapping; +import com.github.yulichang.annotation.EntityMapping; import com.github.yulichang.base.MPJBaseMapper; -import com.github.yulichang.toolkit.LambdaUtils; import java.io.Serializable; -import java.util.*; -import java.util.stream.Collectors; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; /** * 深度查询 @@ -26,7 +22,7 @@ import java.util.stream.Collectors; * 多级查询可能存在循环引用的问题,也可能会导致全量查询 * * @author yulichang - * @see MPJMapping + * @see EntityMapping * @since 1.2.0 */ @SuppressWarnings({"unused", "unchecked"}) @@ -217,7 +213,8 @@ public interface MPJDeepService extends IService { * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default Map getMapDeep(Wrapper queryWrapper) { - return queryMapMapping(getMap(queryWrapper), null); + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(), + null); } /** @@ -229,7 +226,8 @@ public interface MPJDeepService extends IService { * @param property 需要关联的字段 */ default Map getMapDeep(Wrapper queryWrapper, SFunction... property) { - return queryMapMapping(getMap(queryWrapper), Arrays.asList(property)); + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(), + Arrays.asList(property)); } /** @@ -242,7 +240,7 @@ public interface MPJDeepService extends IService { * @param property 需要关联的字段 */ default Map getMapDeep(Wrapper queryWrapper, List> property) { - return queryMapMapping(getMap(queryWrapper), property); + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(), property); } /** @@ -405,7 +403,7 @@ public interface MPJDeepService extends IService { * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} */ default List> listMapsDeep(Wrapper queryWrapper) { - return queryMapMapping(listMaps(queryWrapper), null); + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), null); } /** @@ -417,7 +415,8 @@ public interface MPJDeepService extends IService { * @param property 需要关联的字段 */ default List> listMapsDeep(Wrapper queryWrapper, SFunction... property) { - return queryMapMapping(listMaps(queryWrapper), Arrays.asList(property)); + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), + Arrays.asList(property)); } /** @@ -430,7 +429,7 @@ public interface MPJDeepService extends IService { * @param property 需要关联的字段 */ default List> listMapsDeep(Wrapper queryWrapper, List> property) { - return queryMapMapping(listMaps(queryWrapper), property); + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), property); } /** @@ -439,7 +438,7 @@ public interface MPJDeepService extends IService { * @see Wrappers#emptyWrapper() */ default List> listMapsDeep() { - return queryMapMapping(listMaps(), null); + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), null); } /** @@ -451,7 +450,7 @@ public interface MPJDeepService extends IService { * @see Wrappers#emptyWrapper() */ default List> listMapsDeep(SFunction... property) { - return queryMapMapping(listMaps(), Arrays.asList(property)); + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), Arrays.asList(property)); } /** @@ -464,7 +463,7 @@ public interface MPJDeepService extends IService { * @see Wrappers#emptyWrapper() */ default List> listMapsDeep(List> property) { - return queryMapMapping(listMaps(), property); + return ((MPJBaseMapper) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), property); } /** @@ -475,7 +474,7 @@ public interface MPJDeepService extends IService { */ default >> E pageMapsDeep(E page, Wrapper queryWrapper) { E e = pageMaps(page, queryWrapper); - queryMapMapping(e.getRecords(), null); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), null); return e; } @@ -490,7 +489,7 @@ public interface MPJDeepService extends IService { */ default >> E pageMapsDeep(E page, Wrapper queryWrapper, SFunction... property) { E e = pageMaps(page, queryWrapper); - queryMapMapping(e.getRecords(), Arrays.asList(property)); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property)); return e; } @@ -506,7 +505,7 @@ public interface MPJDeepService extends IService { */ default >> E pageMapsDeep(E page, Wrapper queryWrapper, List> property) { E e = pageMaps(page, queryWrapper); - queryMapMapping(e.getRecords(), property); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), property); return e; } @@ -518,7 +517,7 @@ public interface MPJDeepService extends IService { */ default >> E pageMapsDeep(E page) { E e = pageMaps(page); - queryMapMapping(e.getRecords(), null); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), null); return e; } @@ -533,7 +532,7 @@ public interface MPJDeepService extends IService { */ default >> E pageMapsDeep(E page, SFunction... property) { E e = pageMaps(page); - queryMapMapping(e.getRecords(), Arrays.asList(property)); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property)); return e; } @@ -549,90 +548,7 @@ public interface MPJDeepService extends IService { */ default >> E pageMapsDeep(E page, List> property) { E e = pageMaps(page); - queryMapMapping(e.getRecords(), property); + ((MPJBaseMapper) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), property); return e; } - - /** - * 查询映射关系
- * 对结果进行二次查询
- * 可以自行查询然后在通过此方法进行二次查询
- * list为null或空,会查询全部映射关系
- * - * @param map 第一次查询结果 - */ - default Map queryMapMapping(Map map, List> property) { - if (CollectionUtils.isNotEmpty(map)) { - MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); - if (tableInfo.isHasMapping()) { - 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 o = map.get(fieldInfo.getThisMapKey()); - if (o != null) { - List data = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( - fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), o, fieldInfo); - MPJTableFieldInfo.bindMap(fieldInfo, map, data); - } - } - } - } - } - return map; - } - - /** - * 查询映射关系
- * 对结果进行二次查询
- * 可以自行查询然后在通过此方法进行二次查询
- * list为null或空,会查询全部映射关系
- * - * @param list 第一次查询结果 - */ - @SuppressWarnings("unchecked") - default List> queryMapMapping(List> list, List> property) { - if (CollectionUtils.isEmpty(list)) { - return list; - } - MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); - if (tableInfo.isHasMapping()) { - 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)) { - if (fieldInfo.isFieldIsMap()) { - List> joinList = (List>) fieldInfo.getJoinMapper() - .mappingWrapperConstructor(fieldInfo.isFieldIsMap(), SqlKeyword.IN, - fieldInfo.getJoinColumn(), itemList, fieldInfo); - list.forEach(i -> { - List> data = joinList.stream().filter(j -> j.containsKey( - fieldInfo.getJoinMapKey()) && j.get(fieldInfo.getJoinMapKey()).equals( - i.get(fieldInfo.getThisMapKey()))).collect(Collectors.toList()); - MPJTableFieldInfo.bindMap(fieldInfo, i, data); - }); - } else { - List joinList = (List) fieldInfo.getJoinMapper().mappingWrapperConstructor( - fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); - list.forEach(i -> { - List data = joinList.stream().filter(j -> { - Object o = fieldInfo.joinFieldGet(j); - return o != null && o.equals(i.get(fieldInfo.getThisMapKey())); - }).collect(Collectors.toList()); - MPJTableFieldInfo.bindMap(fieldInfo, i, data); - }); - } - } else { - list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>())); - } - } - } - } - return list; - } } diff --git a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java index 12b5d76..441e1ca 100644 --- a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java +++ b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java @@ -3,21 +3,17 @@ package com.github.yulichang.injector; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; import com.baomidou.mybatisplus.core.mapper.Mapper; +import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper; import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; -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.CollectionUtils; -import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils; import com.github.yulichang.method.*; import org.apache.ibatis.builder.MapperBuilderAssistant; -import org.apache.ibatis.logging.Log; -import org.apache.ibatis.logging.LogFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.core.GenericTypeResolver; import java.util.List; -import java.util.Set; +import java.util.Objects; /** * SQL 注入器 @@ -28,8 +24,6 @@ import java.util.Set; @ConditionalOnMissingBean(DefaultSqlInjector.class) public class MPJSqlInjector extends DefaultSqlInjector { - private static final Log logger = LogFactory.getLog(MPJSqlInjector.class); - @Override public List getMethodList(Class mapperClass) { List list = super.getMethodList(mapperClass); @@ -45,23 +39,10 @@ public class MPJSqlInjector extends DefaultSqlInjector { @Override public void inspectInject(MapperBuilderAssistant builderAssistant, Class mapperClass) { - Class modelClass = getSuperClassGenericType(mapperClass, Mapper.class, 0); - if (modelClass != null) { - String className = mapperClass.toString(); - Set mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration()); - if (!mapperRegistryCache.contains(className)) { - List methodList = this.getMethodList(mapperClass); - if (CollectionUtils.isNotEmpty(methodList)) { - TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass); - MPJTableInfoHelper.initTableInfo(builderAssistant, modelClass, mapperClass); - // 循环注入自定义方法 - methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo)); - } else { - logger.debug(mapperClass.toString() + ", No effective injection method was found."); - } - mapperRegistryCache.add(className); - } - } + MPJTableAliasHelper.init(Objects.requireNonNull(getSuperClassGenericType(mapperClass, Mapper.class, 0))); + super.inspectInject(builderAssistant, mapperClass); + TableInfoHelper.getTableInfos().forEach(i -> + MPJTableInfoHelper.initTableInfo(builderAssistant, i.getEntityType(), mapperClass)); } public static Class getSuperClassGenericType(final Class clazz, final Class genericIfc, final int index) { diff --git a/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java b/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java index 2a1ed19..e40254d 100644 --- a/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java +++ b/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java @@ -1,7 +1,7 @@ package com.github.yulichang.method; import com.baomidou.mybatisplus.core.injector.AbstractMethod; -import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; +import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils; @@ -40,7 +40,7 @@ public abstract class MPJAbstractMethod extends AbstractMethod { String[] columns = selectColumns.split(StringPool.COMMA); List selectColumnList = new ArrayList<>(); for (String c : columns) { - selectColumnList.add(MPJTableInfoHelper.getTableInfo(table.getEntityType()).getAlias() + StringPool.DOT + c); + selectColumnList.add(MPJTableAliasHelper.get(table.getEntityType()).getAlias() + StringPool.DOT + c); } selectColumns = String.join(StringPool.COMMA, selectColumnList); } @@ -60,7 +60,7 @@ public abstract class MPJAbstractMethod extends AbstractMethod { protected String sqlAlias(Class modelClass) { return SqlScriptUtils.convertChoose(String.format("%s != null and %s != ''", "ew.autoAlias", "ew.autoAlias"), - MPJTableInfoHelper.getTableInfo(modelClass).getAlias(), "${ew.alias}"); + MPJTableAliasHelper.get(modelClass).getAlias(), "${ew.alias}"); } protected String sqlFrom() { diff --git a/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java b/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java index 835d066..2d85f55 100644 --- a/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java +++ b/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java @@ -194,6 +194,7 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper selectAll(Class clazz, String as) { TableInfo info = TableInfoHelper.getTableInfo(clazz); Assert.notNull(info, "can not find table info"); diff --git a/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java b/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java index de650a0..07b7ebc 100644 --- a/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java +++ b/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java @@ -189,6 +189,7 @@ public class MPJQueryWrapper extends AbstractWrapper lambda() { return new MPJLambdaQueryWrapper<>(getEntity(), getEntityClass(), from, sqlSelect, paramNameSeq, paramNameValuePairs, expression, lastSql, sqlComment, sqlFirst, selectColumns, ignoreColumns); diff --git a/src/main/java/com/github/yulichang/query/interfaces/MPJJoin.java b/src/main/java/com/github/yulichang/query/interfaces/MPJJoin.java index 6c101cd..3a6c1e2 100644 --- a/src/main/java/com/github/yulichang/query/interfaces/MPJJoin.java +++ b/src/main/java/com/github/yulichang/query/interfaces/MPJJoin.java @@ -6,6 +6,7 @@ import com.github.yulichang.toolkit.Constant; /** * @author yulichang */ +@SuppressWarnings("unused") public interface MPJJoin extends MPJBaseJoin { default Children leftJoin(String joinSql) { diff --git a/src/main/java/com/github/yulichang/toolkit/Constant.java b/src/main/java/com/github/yulichang/toolkit/Constant.java index 76035ed..4520fb3 100644 --- a/src/main/java/com/github/yulichang/toolkit/Constant.java +++ b/src/main/java/com/github/yulichang/toolkit/Constant.java @@ -11,8 +11,6 @@ public interface Constant { */ String TABLE_ALIAS = "t"; - String AS = " AS "; - String ON = " ON "; String JOIN = "JOIN"; diff --git a/src/main/java/com/github/yulichang/toolkit/LambdaUtils.java b/src/main/java/com/github/yulichang/toolkit/LambdaUtils.java index 84332c2..7efc9a1 100644 --- a/src/main/java/com/github/yulichang/toolkit/LambdaUtils.java +++ b/src/main/java/com/github/yulichang/toolkit/LambdaUtils.java @@ -84,6 +84,7 @@ public final class LambdaUtils { * * @param tableInfo 表信息 */ + @SuppressWarnings("unused") public static void installCache(TableInfo tableInfo) { COLUMN_CACHE_MAP.put(tableInfo.getEntityType().getName(), createColumnCacheMap(tableInfo)); } diff --git a/src/main/java/com/github/yulichang/toolkit/ReflectionKit.java b/src/main/java/com/github/yulichang/toolkit/ReflectionKit.java index f08daf4..63e99a3 100644 --- a/src/main/java/com/github/yulichang/toolkit/ReflectionKit.java +++ b/src/main/java/com/github/yulichang/toolkit/ReflectionKit.java @@ -39,6 +39,7 @@ import static java.util.stream.Collectors.toMap; * @author hcl * @since 2016-09-22 */ +@SuppressWarnings("unused") public final class ReflectionKit { private static final Log logger = LogFactory.getLog(ReflectionKit.class); /** diff --git a/src/main/java/com/github/yulichang/toolkit/Wrappers.java b/src/main/java/com/github/yulichang/toolkit/Wrappers.java index 9db4abc..fd9892a 100644 --- a/src/main/java/com/github/yulichang/toolkit/Wrappers.java +++ b/src/main/java/com/github/yulichang/toolkit/Wrappers.java @@ -8,6 +8,7 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper; * * @author yulichang */ +@SuppressWarnings("unused") public class Wrappers { /** diff --git a/src/main/java/com/github/yulichang/toolkit/support/SerializedLambda.java b/src/main/java/com/github/yulichang/toolkit/support/SerializedLambda.java index 98c9c5d..c1d5195 100644 --- a/src/main/java/com/github/yulichang/toolkit/support/SerializedLambda.java +++ b/src/main/java/com/github/yulichang/toolkit/support/SerializedLambda.java @@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import java.io.*; /** - * copy mp before 3.4.3 {@link com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda} + * copy mp before 3.4.3 */ @SuppressWarnings("unused") public class SerializedLambda implements Serializable { diff --git a/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java b/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java index 9b68c19..d4ab2f3 100644 --- a/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java +++ b/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java @@ -1,6 +1,6 @@ package com.github.yulichang.wrapper; -import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; +import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; @@ -42,7 +42,7 @@ public abstract class MPJAbstractLambdaWrapper column, boolean hasAlias) { - return (hasAlias ? MPJTableInfoHelper.getTableInfo(LambdaUtils.getEntityClass(column)).getAliasDOT() : + return (hasAlias ? MPJTableAliasHelper.get(LambdaUtils.getEntityClass(column)).getAliasDOT() : StringPool.EMPTY) + getCache(column).getColumn(); } diff --git a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java index c278d9a..571ac51 100644 --- a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java +++ b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java @@ -72,7 +72,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper entityClass, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, boolean hasAlias) { - this.entityClass =entityClass; + this.entityClass = entityClass; this.paramNameSeq = paramNameSeq; this.paramNameValuePairs = paramNameValuePairs; this.expression = mergeSegments; @@ -107,9 +107,9 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper select(Class entityClass, Predicate predicate) { TableInfo info = TableInfoHelper.getTableInfo(entityClass); Assert.notNull(info, "table can not be find"); - MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(entityClass); + MPJTableAliasHelper.TableAlias alias = MPJTableAliasHelper.get(entityClass); info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(i -> - selectColumns.add((hasAlias ? tableInfo.getAliasDOT() : StringPool.EMPTY) + i.getColumn())); + selectColumns.add((hasAlias ? alias.getAliasDOT() : StringPool.EMPTY) + i.getColumn())); return typedThis; } @@ -139,7 +139,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper selectAll(Class clazz) { TableInfo info = TableInfoHelper.getTableInfo(clazz); Assert.notNull(info, "table can not be find -> %s", clazz); - String dot = hasAlias ? MPJTableInfoHelper.getTableInfo(clazz).getAliasDOT() : StringPool.EMPTY; + String dot = hasAlias ? MPJTableAliasHelper.get(clazz).getAliasDOT() : StringPool.EMPTY; if (info.havePK()) { selectColumns.add(dot + info.getKeyColumn()); } @@ -211,14 +211,14 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper join(String keyWord, boolean condition, Class clazz, OnFunction function) { if (condition) { joinSql.add(keyWord + TableInfoHelper.getTableInfo(clazz).getTableName() + - Constants.SPACE + MPJTableInfoHelper.getTableInfo(clazz).getAlias() + + Constants.SPACE + MPJTableAliasHelper.get(clazz).getAlias() + Constant.ON + function.apply(instance()).getExpression().getNormal().getSqlSegment()); } return typedThis; } private String getThisAlias(SFunction function) { - return hasAlias ? MPJTableInfoHelper.getTableInfo(LambdaUtils.getEntityClass(function)).getAliasDOT() : + return hasAlias ? MPJTableAliasHelper.get(LambdaUtils.getEntityClass(function)).getAliasDOT() : StringPool.EMPTY; } } diff --git a/src/main/java/com/github/yulichang/wrapper/interfaces/Compare.java b/src/main/java/com/github/yulichang/wrapper/interfaces/Compare.java index 0e9da66..1d3b191 100644 --- a/src/main/java/com/github/yulichang/wrapper/interfaces/Compare.java +++ b/src/main/java/com/github/yulichang/wrapper/interfaces/Compare.java @@ -11,6 +11,7 @@ import java.util.function.BiPredicate; *

* {@link com.baomidou.mybatisplus.core.conditions.interfaces.Compare} */ +@SuppressWarnings("unused") public interface Compare extends Serializable { /** @@ -65,6 +66,7 @@ public interface Compare extends Serializable { /** * ignore */ + @SuppressWarnings("UnusedReturnValue") default Children eq(SFunction column, Object val) { return eq(true, column, val); } diff --git a/src/main/java/com/github/yulichang/wrapper/interfaces/Func.java b/src/main/java/com/github/yulichang/wrapper/interfaces/Func.java index a3a29b1..93fbb71 100644 --- a/src/main/java/com/github/yulichang/wrapper/interfaces/Func.java +++ b/src/main/java/com/github/yulichang/wrapper/interfaces/Func.java @@ -11,12 +11,13 @@ import java.util.function.Consumer; *

* copy {@link com.baomidou.mybatisplus.core.conditions.interfaces.Func} */ -@SuppressWarnings("unchecked") +@SuppressWarnings({"unchecked", "unused"}) public interface Func extends Serializable { /** * ignore */ + @SuppressWarnings("UnusedReturnValue") default Children isNull(SFunction column) { return isNull(true, column); } diff --git a/src/main/java/com/github/yulichang/wrapper/interfaces/Join.java b/src/main/java/com/github/yulichang/wrapper/interfaces/Join.java index b45fee0..b77bbe0 100644 --- a/src/main/java/com/github/yulichang/wrapper/interfaces/Join.java +++ b/src/main/java/com/github/yulichang/wrapper/interfaces/Join.java @@ -8,6 +8,7 @@ import java.io.Serializable; * 无改动 在mybatis 3.4.2 升级 3.4.3 后有改动 exists 和 not exists * 为了保证 mybatis plus 3.4.3之前的也能正常使用 */ +@SuppressWarnings("unused") public interface Join extends Serializable { /** diff --git a/src/main/java/com/github/yulichang/wrapper/interfaces/LambdaJoin.java b/src/main/java/com/github/yulichang/wrapper/interfaces/LambdaJoin.java index 2b278c7..ddb4d81 100644 --- a/src/main/java/com/github/yulichang/wrapper/interfaces/LambdaJoin.java +++ b/src/main/java/com/github/yulichang/wrapper/interfaces/LambdaJoin.java @@ -8,55 +8,120 @@ import com.github.yulichang.wrapper.interfaces.on.OnFunction; /** * @author yulichang */ +@SuppressWarnings("unused") public interface LambdaJoin extends MPJBaseJoin { + /** + * left join + * + * @param clazz 关联的实体类 + * @param left 条件 + * @param right 条件 + */ default Children leftJoin(Class clazz, SFunction left, SFunction right) { return leftJoin(true, clazz, left, right); } + /** + * left join + *

+ * 例 leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...) + * + * @param clazz 关联的实体类 + * @param function 条件 + */ default Children leftJoin(Class clazz, OnFunction function) { return leftJoin(true, clazz, function); } + /** + * left join + * + * @param condition 是否执行 + * @param clazz 关联的实体类 + * @param left 条件 + * @param right 条件 + */ default Children leftJoin(boolean condition, Class clazz, SFunction left, SFunction right) { return leftJoin(condition, clazz, on -> on.eq(left, right)); } + /** + * left join + *

+ * 例 leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...) + * + * @param condition 是否执行 + * @param clazz 关联实体类 + * @param function 条件 + */ default Children leftJoin(boolean condition, Class clazz, OnFunction function) { return join(Constant.LEFT_JOIN, condition, clazz, function); } + /** + * ignore 参考 left join + */ default Children rightJoin(Class clazz, SFunction left, SFunction right) { return rightJoin(true, clazz, left, right); } + /** + * ignore 参考 left join + */ default Children rightJoin(Class clazz, OnFunction function) { return rightJoin(true, clazz, function); } + /** + * ignore 参考 left join + */ default Children rightJoin(boolean condition, Class clazz, SFunction left, SFunction right) { return rightJoin(condition, clazz, on -> on.eq(left, right)); } + /** + * ignore 参考 left join + */ default Children rightJoin(boolean condition, Class clazz, OnFunction function) { return join(Constant.RIGHT_JOIN, condition, clazz, function); } + /** + * ignore 参考 left join + */ default Children innerJoin(Class clazz, SFunction left, SFunction right) { return innerJoin(true, clazz, left, right); } + /** + * ignore 参考 left join + */ default Children innerJoin(Class clazz, OnFunction function) { return innerJoin(true, clazz, function); } + /** + * ignore 参考 left join + */ default Children innerJoin(boolean condition, Class clazz, SFunction left, SFunction right) { return innerJoin(condition, clazz, on -> on.eq(left, right)); } + /** + * ignore 参考 left join + */ default Children innerJoin(boolean condition, Class clazz, OnFunction function) { return join(Constant.INNER_JOIN, condition, clazz, function); } + /** + * 查询基类 可以直接调用此方法实现以上所有功能 + * + * @param keyWord 连表关键字 + * @param condition 是否执行 + * @param clazz 连表实体类 + * @param function 关联条件 + */ Children join(String keyWord, boolean condition, Class clazz, OnFunction function); } From c6a861d9f0c002a7db1ec8abe3e6885cca86f83e Mon Sep 17 00:00:00 2001 From: bjdys Date: Mon, 23 Aug 2021 18:09:23 +0800 Subject: [PATCH 21/33] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E5=8D=87=E7=BA=A7=20mybatis=20plus=20->=203.?= =?UTF-8?q?4.3.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yulichang/injector/MPJSqlInjector.java | 44 ++++++++++++++++++- .../query/MPJLambdaQueryWrapper.java | 2 +- .../yulichang/toolkit/ReflectionKit.java | 12 ----- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java index 441e1ca..b975274 100644 --- a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java +++ b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java @@ -2,9 +2,11 @@ package com.github.yulichang.injector; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; +import com.baomidou.mybatisplus.core.injector.methods.*; import com.baomidou.mybatisplus.core.mapper.Mapper; import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper; import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; +import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.ClassUtils; import com.github.yulichang.method.*; @@ -12,8 +14,12 @@ import org.apache.ibatis.builder.MapperBuilderAssistant; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.core.GenericTypeResolver; +import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toList; /** * SQL 注入器 @@ -24,9 +30,43 @@ import java.util.Objects; @ConditionalOnMissingBean(DefaultSqlInjector.class) public class MPJSqlInjector extends DefaultSqlInjector { - @Override + @SuppressWarnings("unused") public List getMethodList(Class mapperClass) { - List list = super.getMethodList(mapperClass); + List list = Stream.of( + new Insert(), + new Delete(), + new DeleteByMap(), + new DeleteById(), + new DeleteBatchByIds(), + new Update(), + new UpdateById(), + new SelectById(), + new SelectBatchByIds(), + new SelectByMap(), + new SelectOne(), + new SelectCount(), + new SelectMaps(), + new SelectMapsPage(), + new SelectObjs(), + new SelectList(), + new SelectPage() + ).collect(toList()); + list.addAll(getJoinMethod()); + return list; + } + + /** + * mybatis plus 3.4.3.2 + */ + @Override + public List getMethodList(Class mapperClass, TableInfo tableInfo) { + List list = super.getMethodList(mapperClass, tableInfo); + list.addAll(getJoinMethod()); + return list; + } + + private List getJoinMethod() { + List list = new ArrayList<>(); list.add(new SelectJoinCount()); list.add(new SelectJoinOne()); list.add(new SelectJoinList()); diff --git a/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java b/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java index 2d85f55..ad949f6 100644 --- a/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java +++ b/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java @@ -138,7 +138,7 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper selectIgnore(SFunction... columns) { if (ArrayUtils.isNotEmpty(columns)) { for (SFunction s : columns) { - ignoreColumns.add(this.alias + StringPool.DOT + getColumnCache(s).getColumn()); + ignoreColumns.add(this.alias + StringPool.DOT + super.columnToString(s, false)); } } return typedThis; diff --git a/src/main/java/com/github/yulichang/toolkit/ReflectionKit.java b/src/main/java/com/github/yulichang/toolkit/ReflectionKit.java index 63e99a3..ff371e9 100644 --- a/src/main/java/com/github/yulichang/toolkit/ReflectionKit.java +++ b/src/main/java/com/github/yulichang/toolkit/ReflectionKit.java @@ -182,16 +182,4 @@ public final class ReflectionKit { public static Class resolvePrimitiveIfNecessary(Class clazz) { return (clazz.isPrimitive() && clazz != void.class ? PRIMITIVE_TYPE_TO_WRAPPER_MAP.get(clazz) : clazz); } - - /** - * 设置可访问对象的可访问权限为 true - * - * @param object 可访问的对象 - * @param 类型 - * @return 返回设置后的对象 - */ - public static T setAccessible(T object) { - return AccessController.doPrivileged(new SetAccessibleAction<>(object)); - } - } From d1eb0eb1aca16f839f593b8425719359169c6352 Mon Sep 17 00:00:00 2001 From: bjdys Date: Mon, 23 Aug 2021 18:18:42 +0800 Subject: [PATCH 22/33] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E5=8D=87=E7=BA=A7=20mybatis=20plus=20->=203.?= =?UTF-8?q?4.3.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6aa51a1..d342399 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.yulichang mybatis-plus-join - 1.1.8 + 1.2.0.Beta4 mybatis-plus-join An enhanced toolkit of Mybatis-Plus to simplify development. https://github.com/yulichang/mybatis-plus-join @@ -41,7 +41,7 @@ com.baomidou mybatis-plus-boot-starter - 3.4.3 + 3.4.3.2 provided From 3dd1caa51d4c835e8f8450516bcb19688a87a05b Mon Sep 17 00:00:00 2001 From: bjdys Date: Mon, 23 Aug 2021 18:33:37 +0800 Subject: [PATCH 23/33] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E5=8D=87=E7=BA=A7=20mybatis=20plus=20->=203.?= =?UTF-8?q?4.3.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index 01adc3d..a6e56bd 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -1,6 +1,6 @@ # mybatis-plus-join -* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta3 +* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta4 * 点个Star支持一下吧 :) @@ -15,12 +15,12 @@ QQ群:1022221898 com.github.yulichang mybatis-plus-join - 1.2.0.Beta3 + 1.2.0.Beta4 ``` - Gradle ``` - implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta3' + implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta4' ``` 或者clone代码到本地执行 mvn install, 再引入以上依赖
@@ -45,22 +45,36 @@ public class UserDO { @TableId private Integer id; - private Integer pid;//父id + private Integer pid; /* 其他属性略 */ /** - * 一对一 + * 查询上级 一对一 */ @TableField(exist = false) - @MPJMapping(tag = UserDO.class, thisField = "pid", joinField = "id") + @EntityMapping(thisField = "pid", joinField = "id") private UserDO pUser; /** - * 一对多 + * 查询下级 一对多 */ @TableField(exist = false) - @MPJMapping(tag = UserDO.class, thisField = "id", joinField = "pid") - private List childUserList; + @EntityMapping(thisField = "id", joinField = "pid") + private List childUser; + + /** + * 查询地址 (一对多) + */ + @TableField(exist = false) + @EntityMapping(thisField = "id", joinField = "userId") + private List addressList; + + /** + * 绑定字段 (一对多) + */ + @TableField(exist = false) + @FieldMapping(tag = UserDO.class, thisField = "id", joinField = "pid", select = "id") + private List childIds; } ``` @@ -69,8 +83,8 @@ public class UserDO { ```java /** * 一对一,一对多关系映射查询 - * 映射只对MPJBaseDeepService中的方法有效果 ,一般以Deep结尾,比如 getByIdDeep listByIdsDeep 等 - * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 getById listByIds 等 + * 映射查询一般以Deep结尾,比如 selectByIdDeep selectListDeep 等 + * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 electById selectList 等 * * @see com.github.yulichang.base.service.MPJDeepService */ From deb6678687b193fbe48c790eedf789956491e482 Mon Sep 17 00:00:00 2001 From: bjdys Date: Mon, 23 Aug 2021 18:36:15 +0800 Subject: [PATCH 24/33] =?UTF-8?q?Revert=20"=E6=94=AF=E6=8C=81=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=98=A0=E5=B0=84=E5=8D=87=E7=BA=A7=20mybatis=20plus?= =?UTF-8?q?=20->=203.4.3.2"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 3dd1caa5 --- MAPPING.md | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index a6e56bd..01adc3d 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -1,6 +1,6 @@ # mybatis-plus-join -* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta4 +* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta3 * 点个Star支持一下吧 :) @@ -15,12 +15,12 @@ QQ群:1022221898 com.github.yulichang mybatis-plus-join - 1.2.0.Beta4 + 1.2.0.Beta3 ``` - Gradle ``` - implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta4' + implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta3' ``` 或者clone代码到本地执行 mvn install, 再引入以上依赖
@@ -45,36 +45,22 @@ public class UserDO { @TableId private Integer id; - private Integer pid; + private Integer pid;//父id /* 其他属性略 */ /** - * 查询上级 一对一 + * 一对一 */ @TableField(exist = false) - @EntityMapping(thisField = "pid", joinField = "id") + @MPJMapping(tag = UserDO.class, thisField = "pid", joinField = "id") private UserDO pUser; /** - * 查询下级 一对多 + * 一对多 */ @TableField(exist = false) - @EntityMapping(thisField = "id", joinField = "pid") - private List childUser; - - /** - * 查询地址 (一对多) - */ - @TableField(exist = false) - @EntityMapping(thisField = "id", joinField = "userId") - private List addressList; - - /** - * 绑定字段 (一对多) - */ - @TableField(exist = false) - @FieldMapping(tag = UserDO.class, thisField = "id", joinField = "pid", select = "id") - private List childIds; + @MPJMapping(tag = UserDO.class, thisField = "id", joinField = "pid") + private List childUserList; } ``` @@ -83,8 +69,8 @@ public class UserDO { ```java /** * 一对一,一对多关系映射查询 - * 映射查询一般以Deep结尾,比如 selectByIdDeep selectListDeep 等 - * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 electById selectList 等 + * 映射只对MPJBaseDeepService中的方法有效果 ,一般以Deep结尾,比如 getByIdDeep listByIdsDeep 等 + * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 getById listByIds 等 * * @see com.github.yulichang.base.service.MPJDeepService */ From 33f69777c6526397c39997fb38dd82c1d4e097d5 Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 24 Aug 2021 09:34:14 +0800 Subject: [PATCH 25/33] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E5=8D=87=E7=BA=A7=20mybatis=20plus=20->=203.?= =?UTF-8?q?4.3.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/metadata/MPJTableAliasHelper.java | 2 +- .../core/metadata/MPJTableInfoHelper.java | 25 +++++++++++++++++++ .../core/metadata/MPJTableMapperHelper.java | 24 ++++++++++++++++++ .../yulichang/config/InterceptorConfig.java | 3 +-- .../yulichang/config/MappingConfig.java | 22 ++++++++++++++++ .../yulichang/injector/MPJSqlInjector.java | 14 ++++++----- src/main/resources/META-INF/spring.factories | 1 + 7 files changed, 82 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableMapperHelper.java create mode 100644 src/main/java/com/github/yulichang/config/MappingConfig.java diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java index 3652ba6..7bba5b6 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java @@ -22,7 +22,7 @@ import java.util.concurrent.atomic.AtomicInteger; */ public class MPJTableAliasHelper { - public static final Map, TableAlias> CACHE = new ConcurrentHashMap<>(); + private static final Map, TableAlias> CACHE = new ConcurrentHashMap<>(); /** * 用于生成别名的序号 diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java index 564b4ed..9daf6b8 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java @@ -33,6 +33,7 @@ import static java.util.stream.Collectors.toList; * @author yulichang * @see TableInfoHelper */ +@SuppressWarnings("deprecation") public class MPJTableInfoHelper { @@ -73,6 +74,7 @@ public class MPJTableInfoHelper { * @param clazz 反射实体类 * @param mapperClass mapperClass */ + @SuppressWarnings("unused") public synchronized static void initTableInfo(MapperBuilderAssistant builderAssistant, Class clazz, Class mapperClass) { MPJTableInfo targetTableInfo = TABLE_INFO_CACHE.get(clazz); final Configuration configuration = builderAssistant.getConfiguration(); @@ -152,6 +154,29 @@ public class MPJTableInfoHelper { return mpjTableInfo; } + /** + *

+ * 实体类反射获取表信息【初始化】 + *

+ * + * @param clazz 反射实体类 + */ + public synchronized static void initTableInfo(Class clazz, Class mapperClass) { + MPJTableInfo info = TABLE_INFO_CACHE.get(clazz); + if (info != null) { + return; + } + MPJTableInfo mpjTableInfo = new MPJTableInfo(); + mpjTableInfo.setMapperClass(mapperClass); + TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz); + if (tableInfo == null) { + return; + } + mpjTableInfo.setTableInfo(tableInfo); + initMapping(mpjTableInfo); + TABLE_INFO_CACHE.put(clazz, mpjTableInfo); + } + /** * 自动构建 resultMap 并注入(如果条件符合的话) */ 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/config/InterceptorConfig.java b/src/main/java/com/github/yulichang/config/InterceptorConfig.java index e9b3099..deac6f0 100644 --- a/src/main/java/com/github/yulichang/config/InterceptorConfig.java +++ b/src/main/java/com/github/yulichang/config/InterceptorConfig.java @@ -1,6 +1,5 @@ package com.github.yulichang.config; -import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.github.yulichang.exception.MPJException; import com.github.yulichang.interceptor.MPJInterceptor; @@ -26,7 +25,7 @@ import java.util.List; @SuppressWarnings("SpringJavaAutowiredMembersInspection") public class InterceptorConfig implements ApplicationListener { - private static final Log logger = LogFactory.getLog(TableInfoHelper.class); + private static final Log logger = LogFactory.getLog(InterceptorConfig.class); @Autowired(required = false) private List sqlSessionFactoryList; 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/injector/MPJSqlInjector.java b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java index b975274..f51c0a1 100644 --- a/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java +++ b/src/main/java/com/github/yulichang/injector/MPJSqlInjector.java @@ -5,9 +5,8 @@ import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; import com.baomidou.mybatisplus.core.injector.methods.*; import com.baomidou.mybatisplus.core.mapper.Mapper; import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper; -import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; +import com.baomidou.mybatisplus.core.metadata.MPJTableMapperHelper; import com.baomidou.mybatisplus.core.metadata.TableInfo; -import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.ClassUtils; import com.github.yulichang.method.*; import org.apache.ibatis.builder.MapperBuilderAssistant; @@ -30,7 +29,10 @@ import static java.util.stream.Collectors.toList; @ConditionalOnMissingBean(DefaultSqlInjector.class) public class MPJSqlInjector extends DefaultSqlInjector { - @SuppressWarnings("unused") + /** + * 升级到 mybatis plus 3.4.3.2 后对之前的版本兼容 + */ + @SuppressWarnings({"unused", "deprecation"}) public List getMethodList(Class mapperClass) { List list = Stream.of( new Insert(), @@ -79,10 +81,10 @@ public class MPJSqlInjector extends DefaultSqlInjector { @Override public void inspectInject(MapperBuilderAssistant builderAssistant, Class mapperClass) { - MPJTableAliasHelper.init(Objects.requireNonNull(getSuperClassGenericType(mapperClass, Mapper.class, 0))); + Class modelClass = getSuperClassGenericType(mapperClass, Mapper.class, 0); + MPJTableAliasHelper.init(Objects.requireNonNull(modelClass)); super.inspectInject(builderAssistant, mapperClass); - TableInfoHelper.getTableInfos().forEach(i -> - MPJTableInfoHelper.initTableInfo(builderAssistant, i.getEntityType(), mapperClass)); + MPJTableMapperHelper.init(modelClass, mapperClass); } public static Class getSuperClassGenericType(final Class clazz, final Class genericIfc, final int index) { diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories index 2ba1665..327caa0 100644 --- a/src/main/resources/META-INF/spring.factories +++ b/src/main/resources/META-INF/spring.factories @@ -2,4 +2,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.github.yulichang.interceptor.MPJInterceptor,\ com.github.yulichang.injector.MPJSqlInjector,\ com.github.yulichang.config.InterceptorConfig,\ + com.github.yulichang.config.MappingConfig,\ com.github.yulichang.toolkit.SpringContentUtils From f4df72c74785c587dfe7248d2299098825c7dc7d Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 24 Aug 2021 09:45:21 +0800 Subject: [PATCH 26/33] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E5=8D=87=E7=BA=A7=20mybatis=20plus=20->=203.?= =?UTF-8?q?4.3.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 37 +++++++++++++++++++++++-------------- pom.xml | 2 +- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index 01adc3d..7517f9c 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -1,6 +1,6 @@ # mybatis-plus-join -* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta3 +* 本页功能只能在1.2.0测试版中使用,最新版本 1.2.0.Beta5 * 点个Star支持一下吧 :) @@ -15,12 +15,12 @@ QQ群:1022221898 com.github.yulichang mybatis-plus-join - 1.2.0.Beta3 + 1.2.0.Beta5 ``` - Gradle ``` - implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta3' + implementation group: 'com.github.yulichang', name: 'mybatis-plus-join', version: '1.2.0.Beta5' ``` 或者clone代码到本地执行 mvn install, 再引入以上依赖
@@ -49,18 +49,32 @@ public class UserDO { /* 其他属性略 */ /** - * 一对一 + * 查询上级 一对一 */ @TableField(exist = false) - @MPJMapping(tag = UserDO.class, thisField = "pid", joinField = "id") + @EntityMapping(thisField = "pid", joinField = "id") private UserDO pUser; /** - * 一对多 + * 查询下级 一对多 */ @TableField(exist = false) - @MPJMapping(tag = UserDO.class, thisField = "id", joinField = "pid") - private List childUserList; + @EntityMapping(thisField = "id", joinField = "pid") + private List childUser; + + /** + * 查询地址 (一对多) + */ + @TableField(exist = false) + @EntityMapping(thisField = "id", joinField = "userId") + private List addressList; + + /** + * 绑定字段 (一对多) + */ + @TableField(exist = false) + @FieldMapping(tag = UserDO.class, thisField = "id", joinField = "pid", select = "id") + private List childIds; } ``` @@ -87,11 +101,10 @@ class MappingTest { * 第一次查询目标UserDO * 第二次根据pid查询上级用户 * 第三次根据自身id查询下级用户 - * */ @Test void test1() { - UserDO deep = userMapper.selectByIdDeep(1); + UserDO deep = userMapper.selectByIdDeep(2); System.out.println(deep); } @@ -103,7 +116,6 @@ class MappingTest { * 第一次查询目标UserDO集合 * 第二次根据pid查询上级用户(不会一条记录一条记录的去查询,对pid进行汇总,用in语句一次性查出来,然后进行匹配) * 第三次根据自身id查询下级用户(不会一条记录一条记录的去查询,对id进行汇总,用in语句一次性查出来,然后进行匹配) - * */ @Test void test2() { @@ -122,9 +134,6 @@ class MappingTest { page.getRecords().forEach(System.out::println); } - -} - ``` MPJMapping 说明: diff --git a/pom.xml b/pom.xml index d342399..bc8def3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.yulichang mybatis-plus-join - 1.2.0.Beta4 + 1.2.0.Beta5 mybatis-plus-join An enhanced toolkit of Mybatis-Plus to simplify development. https://github.com/yulichang/mybatis-plus-join From a4ab8a3b512cc93f783cb9cbf06b2a66c2dff0db Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 24 Aug 2021 09:47:12 +0800 Subject: [PATCH 27/33] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E5=8D=87=E7=BA=A7=20mybatis=20plus=20->=203.?= =?UTF-8?q?4.3.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAPPING.md b/MAPPING.md index 7517f9c..155b5dc 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -33,7 +33,7 @@ QQ群:1022221898 * service继承MPJBaseService (可选) * serviceImpl继承MPJBaseServiceImpl (可选) -#### @MPJMapping注解 +#### @EntityMapping 和 @FieldMapping 注解 UserDO.java From 214260ff991bedb3f3449f7ea79e16531c6ed1f8 Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 24 Aug 2021 10:35:26 +0800 Subject: [PATCH 28/33] =?UTF-8?q?=E6=98=A0=E5=B0=84=E6=B3=A8=E8=A7=A3?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20order=20by?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 15 +++++++------- .../core/metadata/MPJMappingWrapper.java | 20 ++++++++++++++++++- .../core/metadata/MPJTableFieldInfo.java | 12 +++++------ .../core/metadata/MPJTableInfo.java | 2 +- .../core/metadata/MPJTableInfoHelper.java | 4 ++-- .../yulichang/annotation/EntityMapping.java | 12 +++++++++++ .../yulichang/annotation/FieldMapping.java | 12 +++++++++++ .../yulichang/base/mapper/MPJDeepMapper.java | 3 +++ .../base/service/MPJDeepService.java | 6 ++++-- 9 files changed, 67 insertions(+), 19 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index 155b5dc..967c2ea 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -83,7 +83,7 @@ public class UserDO { ```java /** * 一对一,一对多关系映射查询 - * 映射只对MPJBaseDeepService中的方法有效果 ,一般以Deep结尾,比如 getByIdDeep listByIdsDeep 等 + * 映射只对以Deep结尾,比如 getByIdDeep listByIdsDeep 等 * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 getById listByIds 等 * * @see com.github.yulichang.base.service.MPJDeepService @@ -133,18 +133,19 @@ class MappingTest { Page page = userMapper.selectPageDeep(new Page<>(2, 2), Wrappers.emptyWrapper()); page.getRecords().forEach(System.out::println); } - +} ``` MPJMapping 说明: -* MPJMapping tag 关联实体类 -* MPJMapping thisField 当前类关联对应的字段的属性名,可以不填,默认为当前类的主键 -* MPJMapping joinField 关联类对应的字段的属性名,可以不填,默认为关联类的主键 -* MPJMapping isThrowExp 一对一查询时,如果查询到多条记录是否抛出异常,true:抛出异常,false:获取列表第一条数据 +* @EntityMapping / @FieldMapping tag 关联实体类 +* @EntityMapping / @FieldMapping thisField 当前类关联对应的字段的属性名,可以不填,默认为当前类的主键 +* @EntityMapping / @FieldMapping joinField 关联类对应的字段的属性名,可以不填,默认为关联类的主键 +* @EntityMapping / @FieldMapping isThrowExp 一对一查询时,如果查询到多条记录是否抛出异常,true:抛出异常,false:获取列表第一条数据 * -更多功能请看代码注释 [MPJMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/MPJMapping.java) +更多功能请看代码注释 [EntityMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/EntityMapping.java) +[FieldMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/FieldMapping.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 index 61a3b1e..cb029ac 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJMappingWrapper.java @@ -2,6 +2,7 @@ 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; @@ -9,6 +10,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -35,8 +37,14 @@ public class MPJMappingWrapper { 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) { + MPJMappingCondition[] conditions, String last, String orderByAsc, String orderByDesc) { this.hasFirst = StringUtils.isNotBlank(first); if (this.hasFirst) { this.first = first; @@ -67,6 +75,16 @@ public class MPJMappingWrapper { 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 diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java index c956c2c..b2385fc 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableFieldInfo.java @@ -135,7 +135,7 @@ public class MPJTableFieldInfo { 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.apply(), mapping.condition(), mapping.last(), mapping.orderByAsc(), mapping.orderByDesc()); } public MPJTableFieldInfo(Class entityType, FieldMapping mappingField, Field field) { @@ -156,7 +156,7 @@ public class MPJTableFieldInfo { 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.condition(), mappingField.last(), mappingField.orderByAsc(), mappingField.orderByDesc()); initBindField(mappingField.select()); } @@ -191,9 +191,9 @@ public class MPJTableFieldInfo { this.joinColumn = joinFieldInfo.getColumn(); this.joinField = joinFieldInfo.getField(); } - Assert.notNull(this.joinField, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(), + Assert.notNull(this.joinField, "注解属性thisField不存在 %s , %s", this.joinClass.getName(), StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); - Assert.notNull(this.joinColumn, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(), + 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; @@ -212,13 +212,13 @@ public class MPJTableFieldInfo { 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, "MPJMapping注解thisField不存在 %s , %s", entityType.getName(), + 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, "MPJMapping注解thisField不存在 %s , %s", entityType.getName(), + Assert.notNull(fieldInfo, "注解属性thisField不存在 %s , %s", entityType.getName(), StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty); assert fieldInfo != null; this.thisField = fieldInfo.getField(); diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java index 54b015f..5cfff19 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfo.java @@ -25,7 +25,7 @@ public class MPJTableInfo { private TableInfo tableInfo; /** - * 是否包含 MPJMapping 或者 MPJMappingField + * 是否包含 EntityMapping 或者 FieldMapping */ private boolean hasMappingOrField; diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java index 9daf6b8..c32aa01 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java @@ -518,10 +518,10 @@ public class MPJTableInfoHelper { * 初始化映射相关 */ public static void initMapping(MPJTableInfo mpjTableInfo) { - // 是否存在 @MPJMapping 注解 + // 是否存在 @EntityMapping 注解 boolean existMapping = isExistMapping(mpjTableInfo.getTableInfo().getEntityType()); mpjTableInfo.setHasMapping(existMapping); - // 是否存在 @MPJMappingField 注解 + // 是否存在 @FieldMapping 注解 boolean existMappingField = isExistMappingField(mpjTableInfo.getTableInfo().getEntityType()); mpjTableInfo.setHasMappingField(existMappingField); mpjTableInfo.setHasMappingOrField(existMapping || existMappingField); diff --git a/src/main/java/com/github/yulichang/annotation/EntityMapping.java b/src/main/java/com/github/yulichang/annotation/EntityMapping.java index 33fa0e0..5d6ffdd 100644 --- a/src/main/java/com/github/yulichang/annotation/EntityMapping.java +++ b/src/main/java/com/github/yulichang/annotation/EntityMapping.java @@ -81,6 +81,18 @@ public @interface EntityMapping { */ MPJMappingCondition[] condition() default {}; + /** + * 映射表查询条件之 orderBy
+ * 等效于 Wrappers.query().orderByAsc(xxx); + */ + String orderByAsc() default ""; + + /** + * 映射表查询条件之 orderByDesc
+ * 等效于 Wrappers.query().orderByDesc(xxx); + */ + String orderByDesc() default ""; + /** * 映射表查询条件之 last
* 建议不要在这使用分页语句,会导致关联查的时候查询不全
diff --git a/src/main/java/com/github/yulichang/annotation/FieldMapping.java b/src/main/java/com/github/yulichang/annotation/FieldMapping.java index 0832794..a61c7db 100644 --- a/src/main/java/com/github/yulichang/annotation/FieldMapping.java +++ b/src/main/java/com/github/yulichang/annotation/FieldMapping.java @@ -80,6 +80,18 @@ public @interface FieldMapping { */ MPJMappingCondition[] condition() default {}; + /** + * 映射表查询条件之 orderBy
+ * 等效于 Wrappers.query().orderByAsc(xxx); + */ + String orderByAsc() default ""; + + /** + * 映射表查询条件之 orderByDesc
+ * 等效于 Wrappers.query().orderByDesc(xxx); + */ + String orderByDesc() default ""; + /** * 映射表查询条件之 last
* 建议不要在这使用分页语句,会导致关联查的时候查询不全
diff --git a/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java b/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java index 85c8dc5..c1e5479 100644 --- a/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java +++ b/src/main/java/com/github/yulichang/base/mapper/MPJDeepMapper.java @@ -503,8 +503,11 @@ public interface MPJDeepMapper extends BaseMapper { } 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()) { diff --git a/src/main/java/com/github/yulichang/base/service/MPJDeepService.java b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java index 52d425e..e2c2fd1 100644 --- a/src/main/java/com/github/yulichang/base/service/MPJDeepService.java +++ b/src/main/java/com/github/yulichang/base/service/MPJDeepService.java @@ -6,6 +6,7 @@ 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; @@ -17,12 +18,13 @@ import java.util.Map; /** * 深度查询 *

- * 对配置了@MPJMapping注解的字段进行查询 - * 目前查询深度只支持2级(只解析当前实体类的MPJMapping注解,不会对查询结果再次解析注解) + * 对配置了映射注解的字段进行查询 + * 目前查询深度只支持2级(只解析当前实体类的映射注解,不会对查询结果再次解析注解) * 多级查询可能存在循环引用的问题,也可能会导致全量查询 * * @author yulichang * @see EntityMapping + * @see FieldMapping * @since 1.2.0 */ @SuppressWarnings({"unused", "unchecked"}) From e77710a8a5b4f8c77d1d5b1ab22e0a330608ecee Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 24 Aug 2021 10:56:42 +0800 Subject: [PATCH 29/33] mapping --- MAPPING.md | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/MAPPING.md b/MAPPING.md index 967c2ea..6422fed 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -86,53 +86,35 @@ public class UserDO { * 映射只对以Deep结尾,比如 getByIdDeep listByIdsDeep 等 * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 getById listByIds 等 * - * @see com.github.yulichang.base.service.MPJDeepService + * 注意:关系映射不会去关联查询,而是执行多次单表查询(使用in语句查询后对结果进行匹配) */ @SpringBootTest class MappingTest { @Resource private UserMapper userMapper; - /** - * 根据id查询 - *

- * 查询过程: - * 一共查询了3次 - * 第一次查询目标UserDO - * 第二次根据pid查询上级用户 - * 第三次根据自身id查询下级用户 - */ @Test void test1() { UserDO deep = userMapper.selectByIdDeep(2); System.out.println(deep); } - /** - * 查询全部 - *

- * 查询过程: - * 一共查询了3次 - * 第一次查询目标UserDO集合 - * 第二次根据pid查询上级用户(不会一条记录一条记录的去查询,对pid进行汇总,用in语句一次性查出来,然后进行匹配) - * 第三次根据自身id查询下级用户(不会一条记录一条记录的去查询,对id进行汇总,用in语句一次性查出来,然后进行匹配) - */ @Test void test2() { List list = userMapper.selectListDeep(Wrappers.emptyWrapper()); list.forEach(System.out::println); } - /** - * 分页查询 - *

- * 查询过程与上面一致 - */ @Test void test3() { Page page = userMapper.selectPageDeep(new Page<>(2, 2), Wrappers.emptyWrapper()); page.getRecords().forEach(System.out::println); } + + /** + * 跟多方法请查阅 MPJDeepMapper 或者 MPJDeepService + * 使用方式与 mybatis plus 一致 + */ } ``` From 2b639c44c41db370555d3bf6c4acd41181f195c8 Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 24 Aug 2021 10:57:40 +0800 Subject: [PATCH 30/33] mapping --- MAPPING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAPPING.md b/MAPPING.md index 6422fed..6297ce3 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -112,7 +112,7 @@ class MappingTest { } /** - * 跟多方法请查阅 MPJDeepMapper 或者 MPJDeepService + * 更多方法请查阅 MPJDeepMapper 或者 MPJDeepService * 使用方式与 mybatis plus 一致 */ } From 2740936d94b0ddfbd48b4ce5f3a40245e5b83e44 Mon Sep 17 00:00:00 2001 From: bjdys Date: Tue, 24 Aug 2021 11:56:37 +0800 Subject: [PATCH 31/33] =?UTF-8?q?=E6=98=A0=E5=B0=84=E6=B3=A8=E8=A7=A3?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20order=20by?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAPPING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAPPING.md b/MAPPING.md index 6297ce3..8fb8ebb 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -86,7 +86,7 @@ public class UserDO { * 映射只对以Deep结尾,比如 getByIdDeep listByIdsDeep 等 * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 getById listByIds 等 * - * 注意:关系映射不会去关联查询,而是执行多次单表查询(使用in语句查询后对结果进行匹配) + * 注意:关系映射不会去关联查询,而是执行多次单表查询(对结果汇总后使用in语句查询,再对结果进行匹配) */ @SpringBootTest class MappingTest { From c69bab3e853e97cba706945d1dda2a060a5f4609 Mon Sep 17 00:00:00 2001 From: jera <570810310@qq.com> Date: Wed, 1 Sep 2021 10:51:14 +0000 Subject: [PATCH 32/33] update MAPPING.md. --- MAPPING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAPPING.md b/MAPPING.md index 8fb8ebb..a91185c 100644 --- a/MAPPING.md +++ b/MAPPING.md @@ -83,7 +83,7 @@ public class UserDO { ```java /** * 一对一,一对多关系映射查询 - * 映射只对以Deep结尾,比如 getByIdDeep listByIdsDeep 等 + * 映射只对以Deep结尾有效,比如 getByIdDeep listByIdsDeep 等 * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 getById listByIds 等 * * 注意:关系映射不会去关联查询,而是执行多次单表查询(对结果汇总后使用in语句查询,再对结果进行匹配) From 33e09f201ff627d935d282e517eca95f68de3ec9 Mon Sep 17 00:00:00 2001 From: yulichang <570810310@qq.com> Date: Tue, 19 Oct 2021 22:12:46 +0800 Subject: [PATCH 33/33] =?UTF-8?q?fix=20bug=20=E5=88=AB=E5=90=8D=E4=B8=8D?= =?UTF-8?q?=E5=AF=B9=E5=BA=94=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatisplus/core/metadata/MPJTableAliasHelper.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java index 7bba5b6..654f347 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java @@ -7,6 +7,7 @@ import com.github.yulichang.toolkit.Constant; import lombok.Data; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -30,6 +31,10 @@ public class MPJTableAliasHelper { private static final AtomicInteger index = new AtomicInteger(1); public static void init(Class clazz) { + TableAlias as = CACHE.get(clazz); + if (Objects.nonNull(as)) { + return; + } TableAlias alias = new TableAlias(); MPJTableAlias tableAlias = clazz.getAnnotation(MPJTableAlias.class); if (tableAlias != null && StringUtils.isNotBlank(tableAlias.value())) {