From eba38a018468677b1edd16fce0c700a68aa0fa45 Mon Sep 17 00:00:00 2001 From: yulichang <570810310@qq.com> Date: Tue, 15 Nov 2022 10:32:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E4=B8=80=E5=92=8C=E5=AF=B9=E5=A4=9A?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=B5=8C=E5=A5=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yulichang/interceptor/MPJInterceptor.java | 91 ++++++++------- .../yulichang/wrapper/MPJLambdaWrapper.java | 18 +-- .../wrapper/resultmap/LabelType.java | 5 - .../wrapper/resultmap/MPJResultMap.java | 12 -- .../wrapper/resultmap/MybatisLabel.java | 104 ++++++++++++++++-- 5 files changed, 156 insertions(+), 74 deletions(-) delete mode 100644 src/main/java/com/github/yulichang/wrapper/resultmap/LabelType.java delete mode 100644 src/main/java/com/github/yulichang/wrapper/resultmap/MPJResultMap.java diff --git a/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java b/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java index 94a860d..067353d 100644 --- a/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java +++ b/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java @@ -209,45 +209,57 @@ public class MPJInterceptor implements Interceptor { //移除result中不存在的标签 resultMappings.removeIf(i -> !fieldMap.containsKey(i.getProperty())); if (wrapper.isResultMap()) { - List> mybatisLabel = wrapper.getResultMapMybatisLabel(); - for (MybatisLabel mpjColl : mybatisLabel) { - List list = mpjColl.getResultList(); - if (CollectionUtils.isEmpty(list)) { - continue; - } - List childMapping = new ArrayList<>(list.size()); - for (Result r : list) { - String columnName = r.getColumn(); - //列名去重 - columnName = getColumn(columnSet, columnName); - columnList.add(SelectColumn.of(mpjColl.getEntityClass(), r.getColumn(), null, - Objects.equals(columnName, r.getColumn()) ? null : columnName, null, null, true, null)); - ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), r.getProperty(), - StringUtils.getTargetColumn(columnName), r.getJavaType()); - if (r.isId()) {//主键标记为id标签 - builder.flags(Collections.singletonList(ResultFlag.ID)); - } - childMapping.add(builder.build()); - } - String childId = id + StringPool.UNDERSCORE + mpjColl.getEntityClass().getName() + StringPool.UNDERSCORE + - mpjColl.getOfType().getName() + StringPool.UNDERSCORE + mpjColl.getLabelType() + StringPool.UNDERSCORE + - childMapping.stream().map(i -> (CollectionUtils.isEmpty(i.getFlags()) ? ResultFlag.CONSTRUCTOR : - i.getFlags().get(0)) + i.getProperty() + i.getColumn()).collect(Collectors.joining(StringPool.DASH)); - resultMappings.add(new ResultMapping.Builder(ms.getConfiguration(), mpjColl.getProperty()) - .javaType(mpjColl.getJavaType()) - .nestedResultMapId(childId) - .build()); - //双检 - if (!ms.getConfiguration().getResultMapNames().contains(childId)) { - ResultMap build = new ResultMap.Builder(ms.getConfiguration(), childId, mpjColl.getOfType(), childMapping).build(); - MPJInterceptor.addResultMap(ms, childId, build); - } - } + buildResult(ms, wrapper.getResultMapMybatisLabel(), columnSet, resultMappings, columnList); } result.add(new ResultMap.Builder(ms.getConfiguration(), id, resultType, resultMappings).build()); return result; } + private void buildResult(MappedStatement ms, List> mybatisLabel, Set columnSet, + List parentMappings, List columnList) { + for (MybatisLabel mpjColl : mybatisLabel) { + List list = mpjColl.getResultList(); + if (CollectionUtils.isEmpty(list)) { + continue; + } + List childMapping = new ArrayList<>(list.size()); + for (Result r : list) { + String columnName = r.getColumn(); + //列名去重 + columnName = getColumn(columnSet, columnName); + columnList.add(SelectColumn.of(mpjColl.getEntityClass(), r.getColumn(), null, + Objects.equals(columnName, r.getColumn()) ? null : columnName, null, null, true, null)); + ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), r.getProperty(), + StringUtils.getTargetColumn(columnName), r.getJavaType()); + if (r.isId()) {//主键标记为id标签 + builder.flags(Collections.singletonList(ResultFlag.ID)); + } + //TypeHandle + TableFieldInfo info = r.getTableFieldInfo(); + if (info != null && info.getTypeHandler() != null && info.getTypeHandler() != UnknownTypeHandler.class) { + builder.typeHandler(getTypeHandler(ms, info)); + } + childMapping.add(builder.build()); + } + //嵌套处理 + if (CollectionUtils.isNotEmpty(mpjColl.getMybatisLabels())) { + this.buildResult(ms, mpjColl.getMybatisLabels(), columnSet, childMapping, columnList); + } + String childId = "MPJ_" + mpjColl.getEntityClass().getName() + StringPool.UNDERSCORE + mpjColl.getOfType().getName() + + StringPool.UNDERSCORE + childMapping.stream().map(i -> (CollectionUtils.isEmpty(i.getFlags()) ? + ResultFlag.CONSTRUCTOR : i.getFlags().get(0)) + i.getProperty() + i.getColumn()).collect(Collectors.joining(StringPool.DASH)); + parentMappings.add(new ResultMapping.Builder(ms.getConfiguration(), mpjColl.getProperty()) + .javaType(mpjColl.getJavaType()) + .nestedResultMapId(childId) + .build()); + //双检 + if (!ms.getConfiguration().getResultMapNames().contains(childId)) { + ResultMap build = new ResultMap.Builder(ms.getConfiguration(), childId, mpjColl.getOfType(), childMapping).build(); + MPJInterceptor.addResultMap(ms, childId, build); + } + } + } + /** * 获取字段typeHandle */ @@ -268,12 +280,13 @@ public class MPJInterceptor implements Interceptor { * @return 唯一列名 */ private String getColumn(Set pool, String columnName) { - if (!pool.contains(columnName)) { - pool.add(columnName); - return columnName; + String tagName = StringUtils.getTargetColumn(columnName); + if (!pool.contains(tagName)) { + pool.add(tagName); + return tagName; } - columnName = "mpj_" + StringUtils.getTargetColumn(columnName); - return getColumn(pool, columnName); + tagName = "mpj_" + tagName; + return getColumn(pool, tagName); } /** diff --git a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java index 1fba22e..61d4050 100644 --- a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java +++ b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java @@ -11,14 +11,16 @@ import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.github.yulichang.exception.MPJException; -import com.github.yulichang.toolkit.*; +import com.github.yulichang.toolkit.Constant; +import com.github.yulichang.toolkit.LambdaUtils; +import com.github.yulichang.toolkit.MPJWrappers; +import com.github.yulichang.toolkit.ReflectionKit; import com.github.yulichang.toolkit.support.ColumnCache; import com.github.yulichang.toolkit.support.SelectColumn; 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 com.github.yulichang.wrapper.resultmap.LabelType; import com.github.yulichang.wrapper.resultmap.MFunc; import com.github.yulichang.wrapper.resultmap.MybatisLabel; import lombok.Getter; @@ -182,13 +184,13 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper builder; if (genericType == null || genericType.isAssignableFrom(child)) { //找不到集合泛型 List List List , 直接查询数据库实体 - builder = new MybatisLabel.Builder<>(LabelType.COLLECTION, dtoFieldName, child, field.getType()); + builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType()); } else { Class ofType = (Class) genericType; if (ReflectionKit.isPrimitiveOrWrapper(ofType)) { throw new MPJException("collection 不支持基本数据类型"); } - builder = new MybatisLabel.Builder<>(LabelType.COLLECTION, dtoFieldName, child, field.getType(), ofType, true); + builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), ofType, true); } this.resultMapMybatisLabel.add(builder.build()); return typedThis; @@ -231,7 +233,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper genericType = ReflectionKit.getGenericType(field); Class ofType = (Class) genericType; - MybatisLabel.Builder builder = new MybatisLabel.Builder<>(LabelType.COLLECTION, dtoFieldName, child, field.getType(), ofType, false); + MybatisLabel.Builder builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), ofType, false); this.resultMapMybatisLabel.add(collection.apply(builder).build()); return typedThis; } @@ -252,7 +254,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper builder; - builder = new MybatisLabel.Builder<>(LabelType.ASSOCIATION, dtoFieldName, child, field.getType(), (Class) field.getType(), true); + builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class) field.getType(), true); this.resultMapMybatisLabel.add(builder.build()); return typedThis; } @@ -272,7 +274,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper builder = new MybatisLabel.Builder<>(LabelType.ASSOCIATION, dtoFieldName, child, field.getType(), (Class) child, false); + MybatisLabel.Builder builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class) child, false); this.resultMapMybatisLabel.add(collection.apply(builder).build()); return typedThis; } @@ -420,4 +422,4 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper { - private LabelType labelType; - private String property; private Class entityClass; @@ -35,13 +38,15 @@ public class MybatisLabel { private List resultList; - //collection嵌套 - // private List collectionList; + /** + * wrapper里面的引用 + */ + private List> mybatisLabels; private MybatisLabel() { } - @SuppressWarnings("unused") + @SuppressWarnings({"unused", "unchecked"}) public static class Builder { private final MybatisLabel mybatisLabel; @@ -50,14 +55,14 @@ public class MybatisLabel { * 自动构建 */ @SuppressWarnings("unchecked") - public Builder(LabelType labelType, String property, Class entityClass, Class javaType) { + public Builder(String property, Class entityClass, Class javaType) { this.mybatisLabel = new MybatisLabel<>(); - mybatisLabel.labelType = labelType; mybatisLabel.property = property; mybatisLabel.entityClass = entityClass; mybatisLabel.javaType = javaType; mybatisLabel.ofType = (Class) entityClass; mybatisLabel.resultList = new ArrayList<>(); + mybatisLabel.mybatisLabels = new ArrayList<>(); autoBuild(true, entityClass, (Class) entityClass); } @@ -70,14 +75,14 @@ public class MybatisLabel { * @param ofType 映射类 * @param auto 自动映射数据库实体对应的字段 */ - public Builder(LabelType labelType, String property, Class entityClass, Class javaType, Class ofType, boolean auto) { + public Builder(String property, Class entityClass, Class javaType, Class ofType, boolean auto) { this.mybatisLabel = new MybatisLabel<>(); - mybatisLabel.labelType = labelType; mybatisLabel.property = property; mybatisLabel.entityClass = entityClass; mybatisLabel.javaType = javaType; mybatisLabel.ofType = ofType; mybatisLabel.resultList = new ArrayList<>(); + mybatisLabel.mybatisLabels = new ArrayList<>(); autoBuild(auto, entityClass, ofType); } @@ -109,7 +114,85 @@ public class MybatisLabel { return this; } + /** + * 嵌套 + */ + public > Builder collection(Class entityClass, SFunction func) { + String dtoFieldName = LambdaUtils.getName(func); + Class dtoClass = LambdaUtils.getEntityClass(func); + Map fieldMap = ReflectionKit.getFieldMap(dtoClass); + Field field = fieldMap.get(dtoFieldName); + Class genericType = ReflectionKit.getGenericType(field); + MybatisLabel.Builder builder; + if (genericType == null || genericType.isAssignableFrom(entityClass)) { + //找不到集合泛型 List List List , 直接查询数据库实体 + builder = new Builder<>(dtoFieldName, entityClass, field.getType()); + } else { + Class ofType = (Class) genericType; + if (ReflectionKit.isPrimitiveOrWrapper(ofType)) { + throw new MPJException("collection 不支持基本数据类型"); + } + builder = new Builder<>(dtoFieldName, entityClass, field.getType(), ofType, true); + } + mybatisLabel.mybatisLabels.add(builder.build()); + return this; + } + + /** + * 嵌套 + */ + public > Builder collection(Class entityClass, SFunction func, MFunc> mFunc) { + String dtoFieldName = LambdaUtils.getName(func); + Class dtoClass = LambdaUtils.getEntityClass(func); + Field field = ReflectionKit.getFieldMap(dtoClass).get(dtoFieldName); + //获取集合泛型 + Class genericType = ReflectionKit.getGenericType(field); + Class ofType = (Class) genericType; + MybatisLabel.Builder builder = new MybatisLabel.Builder<>(dtoFieldName, entityClass, field.getType(), ofType, false); + mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build()); + return this; + } + + /** + * 嵌套 + */ + public Builder association(Class child, SFunction dtoField) { + Class dtoClass = LambdaUtils.getEntityClass(dtoField); + Map fieldMap = ReflectionKit.getFieldMap(dtoClass); + String dtoFieldName = LambdaUtils.getName(dtoField); + Field field = fieldMap.get(dtoFieldName); + Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类"); + if (ReflectionKit.isPrimitiveOrWrapper(field.getType())) { + throw new MPJException("association 不支持基本数据类型"); + } + MybatisLabel.Builder builder; + builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class) field.getType(), true); + mybatisLabel.mybatisLabels.add(builder.build()); + return this; + } + + /** + * 嵌套 + */ + public Builder selectAssociation(Class child, SFunction dtoField, + MFunc> collection) { + String dtoFieldName = LambdaUtils.getName(dtoField); + Class dtoClass = LambdaUtils.getEntityClass(dtoField); + Field field = ReflectionKit.getFieldMap(dtoClass).get(dtoFieldName); + Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类"); + if (ReflectionKit.isPrimitiveOrWrapper(field.getType())) { + throw new MPJException("association 不支持基本数据类型"); + } + MybatisLabel.Builder builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class) child, false); + mybatisLabel.mybatisLabels.add(collection.apply(builder).build()); + return this; + } + + public MybatisLabel build() { + if (CollectionUtils.isEmpty(mybatisLabel.resultList)) { + autoBuild(true, mybatisLabel.entityClass, mybatisLabel.ofType); + } return mybatisLabel; } @@ -120,6 +203,7 @@ public class MybatisLabel { Function build = field -> { Result result = new Result(); result.setId(false); + result.setTableFieldInfo(field); result.setColumn(field.getColumn()); result.setProperty(field.getProperty()); result.setJavaType(field.getField().getType()); @@ -151,4 +235,4 @@ public class MybatisLabel { return result; } } -} +} \ No newline at end of file