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); }