From ebbc53847d6b9e106f299647b127dc8db70f046d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=81=E5=9F=B9=E5=9F=B9?= Date: Sat, 17 Aug 2024 23:11:45 +0800 Subject: [PATCH] mybatis-plus demo --- .../mmegpGeneratorConfig.xml | 16 ++ .../pom.xml | 11 ++ .../demo/mybatisplus/MybatisPlusEntity.java | 68 +++++++ .../mybatisplus/MybatisPlusEntityTest.java | 45 +++++ mmegp-maven-plugin-demo/pom.xml | 12 ++ .../DefaultIntrospectedTableBuilder.java | 173 ++++++++++++++++-- .../java/me/ningpp/mmegp/JavaParserUtil.java | 168 +++-------------- .../me/ningpp/mmegp/MmeCompileUtilTest.java | 2 +- mmegp-mybatis-plus/pom.xml | 76 ++++++++ .../MyBatisPlusIntrospectedTableBuilder.java | 163 +++++++++++++++++ pom.xml | 9 + 11 files changed, 591 insertions(+), 152 deletions(-) create mode 100644 mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/src/main/java/me/ningpp/mmegp/demo/mybatisplus/MybatisPlusEntity.java create mode 100644 mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/src/test/java/me/ningpp/mmegp/demo/mybatisplus/MybatisPlusEntityTest.java create mode 100644 mmegp-mybatis-plus/pom.xml create mode 100644 mmegp-mybatis-plus/src/main/java/me/ningpp/mmegp/mybatisplus/generator/MyBatisPlusIntrospectedTableBuilder.java diff --git a/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/mmegpGeneratorConfig.xml b/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/mmegpGeneratorConfig.xml index 657e76f..2267cc5 100644 --- a/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/mmegpGeneratorConfig.xml +++ b/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/mmegpGeneratorConfig.xml @@ -38,4 +38,20 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/pom.xml b/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/pom.xml index dd5d028..85beb33 100644 --- a/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/pom.xml +++ b/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/pom.xml @@ -30,6 +30,10 @@ mmegp-maven-plugin-demo-xmlmapper ${project.version} + + com.baomidou + mybatis-plus-annotation + org.springframework spring-jdbc @@ -88,6 +92,13 @@ io.github.ningpp mmegp-maven-plugin ${project.version} + + + io.github.ningpp + mmegp-mybatis-plus + ${project.version} + + ${basedir}/mmegpGeneratorConfig.xml diff --git a/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/src/main/java/me/ningpp/mmegp/demo/mybatisplus/MybatisPlusEntity.java b/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/src/main/java/me/ningpp/mmegp/demo/mybatisplus/MybatisPlusEntity.java new file mode 100644 index 0000000..4a08860 --- /dev/null +++ b/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/src/main/java/me/ningpp/mmegp/demo/mybatisplus/MybatisPlusEntity.java @@ -0,0 +1,68 @@ +/* + * Copyright 2021-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.ningpp.mmegp.demo.mybatisplus; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +@TableName +public class MybatisPlusEntity { + + @TableId(type = IdType.AUTO) + private Integer id; + + private String title; + + @TableField("mp_content") + private String content; + + @TableField(exist = false) + private String notExistColumn; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getNotExistColumn() { + return notExistColumn; + } + + public void setNotExistColumn(String notExistColumn) { + this.notExistColumn = notExistColumn; + } +} diff --git a/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/src/test/java/me/ningpp/mmegp/demo/mybatisplus/MybatisPlusEntityTest.java b/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/src/test/java/me/ningpp/mmegp/demo/mybatisplus/MybatisPlusEntityTest.java new file mode 100644 index 0000000..9dc08b7 --- /dev/null +++ b/mmegp-maven-plugin-demo/mmegp-maven-plugin-demo-allservices/src/test/java/me/ningpp/mmegp/demo/mybatisplus/MybatisPlusEntityTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2021-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.ningpp.mmegp.demo.mybatisplus; + +import me.ningpp.mmegp.demo.mybatisplusmapper.MybatisPlusEntityDynamicSqlSupport; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static me.ningpp.mmegp.demo.mybatisplusmapper.MybatisPlusEntityDynamicSqlSupport.content; +import static me.ningpp.mmegp.demo.mybatisplusmapper.MybatisPlusEntityDynamicSqlSupport.id; +import static me.ningpp.mmegp.demo.mybatisplusmapper.MybatisPlusEntityDynamicSqlSupport.mybatisPlusEntity; +import static me.ningpp.mmegp.demo.mybatisplusmapper.MybatisPlusEntityDynamicSqlSupport.title; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class MybatisPlusEntityTest { + + @Test + void parseTest() { + assertEquals("id", id.name()); + assertEquals("title", title.name()); + assertEquals("mp_content", content.name()); + assertEquals("mybatis_plus_entity", mybatisPlusEntity.tableNameAtRuntime()); + Field[] fields = MybatisPlusEntityDynamicSqlSupport.MybatisPlusEntity.class.getFields(); + // 需要禁止掉jacoco + assertEquals("id,title,content", + Stream.of(fields).map(Field::getName).collect(Collectors.joining(","))); + } + +} diff --git a/mmegp-maven-plugin-demo/pom.xml b/mmegp-maven-plugin-demo/pom.xml index 3a7eecb..766396f 100644 --- a/mmegp-maven-plugin-demo/pom.xml +++ b/mmegp-maven-plugin-demo/pom.xml @@ -30,4 +30,16 @@ + + + + org.jacoco + jacoco-maven-plugin + + true + + + + + \ No newline at end of file diff --git a/mmegp-mbg-ext/src/main/java/me/ningpp/mmegp/DefaultIntrospectedTableBuilder.java b/mmegp-mbg-ext/src/main/java/me/ningpp/mmegp/DefaultIntrospectedTableBuilder.java index 2a1c112..373febf 100644 --- a/mmegp-mbg-ext/src/main/java/me/ningpp/mmegp/DefaultIntrospectedTableBuilder.java +++ b/mmegp-mbg-ext/src/main/java/me/ningpp/mmegp/DefaultIntrospectedTableBuilder.java @@ -19,13 +19,26 @@ import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.ImportDeclaration; import com.github.javaparser.ast.Modifier; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.TypeDeclaration; +import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.AnnotationExpr; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.MemberValuePair; +import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations; +import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; +import com.github.javaparser.ast.nodeTypes.NodeWithType; +import com.github.javaparser.ast.type.Type; +import me.ningpp.mmegp.annotations.Generated; +import me.ningpp.mmegp.annotations.GeneratedColumn; +import me.ningpp.mmegp.enums.AggregateFunction; import me.ningpp.mmegp.enums.ModelType; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; +import org.apache.ibatis.type.JdbcType; import org.mybatis.generator.api.FullyQualifiedTable; import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedTable; @@ -39,16 +52,43 @@ import org.mybatis.generator.internal.util.StringUtility; import java.io.File; +import java.lang.annotation.Annotation; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; + +import static me.ningpp.mmegp.JavaParserUtil.AGGREGATES_NAME; +import static me.ningpp.mmegp.JavaParserUtil.COUNT_GROUP_BY_COLUMNS_NAME; +import static me.ningpp.mmegp.JavaParserUtil.getClassByType; +import static me.ningpp.mmegp.JavaParserUtil.parseArray; +import static me.ningpp.mmegp.JavaParserUtil.parseArrayString; +import static me.ningpp.mmegp.JavaParserUtil.parseBoolean; +import static me.ningpp.mmegp.JavaParserUtil.parseColumnName; +import static me.ningpp.mmegp.JavaParserUtil.parseJdbcType; +import static me.ningpp.mmegp.JavaParserUtil.parseTableName; +import static me.ningpp.mmegp.JavaParserUtil.parseTypeHandler; public class DefaultIntrospectedTableBuilder implements IntrospectedTableBuilder { + protected GeneratedTableInfo buildGeneratedTable(Context context, + TypeDeclaration modelDeclaration, NodeList importDeclarations) { + if (modelDeclaration == null || modelDeclaration.getFullyQualifiedName().isEmpty()) { + return null; + } + var annotationMembers = getNormalAnnotationMembers(modelDeclaration, Generated.class); + + String tableName = parseTableName(annotationMembers, modelDeclaration.getNameAsString(), context); + List countGroupByColumns = parseArrayString(annotationMembers, COUNT_GROUP_BY_COLUMNS_NAME); + return new GeneratedTableInfo(tableName, countGroupByColumns); + } + @Override public Pair buildFromSourceFile(Context context, File file, MetaInfoHandler metaInfoHandler) { @@ -71,9 +111,8 @@ public Pair buildFromSourceFile(Context context, File f return Pair.of(null, file); } - public static IntrospectedTable buildIntrospectedTable(Context context, - CompilationUnit compilationUnit, - MetaInfoHandler metaInfoHandler) { + public IntrospectedTable buildIntrospectedTable(Context context, + CompilationUnit compilationUnit, MetaInfoHandler metaInfoHandler) { TypeDeclaration typeDeclaration = compilationUnit.getTypes().stream() .filter(typeDeclar -> typeDeclar.hasModifier(Modifier.Keyword.PUBLIC)) .findFirst().orElse(null); @@ -91,11 +130,11 @@ public static IntrospectedTable buildIntrospectedTable(Context context, return null; } - private static IntrospectedTable buildIntrospectedTable(Context context, + private IntrospectedTable buildIntrospectedTable(Context context, TypeDeclaration modelDeclaration, NodeList importDeclarations, MetaInfoHandler metaInfoHandler) { - GeneratedTableInfo tableInfo = JavaParserUtil.getTableValue(modelDeclaration, context); + GeneratedTableInfo tableInfo = buildGeneratedTable(context, modelDeclaration, importDeclarations); if (tableInfo == null || StringUtils.isEmpty(tableInfo.getName())) { return null; } @@ -152,7 +191,7 @@ private static TableConfiguration buildTableConfiguration(Context context, Model "mapperNameSuffix", "Mapper"); tableConfiguration.setMapperName(domainObjectName + mapperSuffix); } - tableConfiguration.addProperty(JavaParserUtil.COUNT_GROUP_BY_COLUMNS_NAME, + tableConfiguration.addProperty(COUNT_GROUP_BY_COLUMNS_NAME, String.join(";", tableInfo.getCountGroupByColumns())); tableConfiguration.getProperties() .setProperty( @@ -161,29 +200,137 @@ private static TableConfiguration buildTableConfiguration(Context context, Model return tableConfiguration; } - private static List> buildColumns(TypeDeclaration modelDeclaration, - Map importMappings, - Context context) { + private List> buildColumns(TypeDeclaration modelDeclaration, + Map importMappings, Context context) { List> pairs = new ArrayList<>(); if (modelDeclaration.isRecordDeclaration()) { NodeList parameters = modelDeclaration.asRecordDeclaration().getParameters(); if (parameters != null) { for (Parameter param : parameters) { - pairs.add(JavaParserUtil.buildColumn(modelDeclaration, importMappings, param, context)); + pairs.add(buildColumn(modelDeclaration, importMappings, param, context)); } } } else { List fields = modelDeclaration.getFields(); if (fields != null) { for (FieldDeclaration field : fields) { - pairs.add(JavaParserUtil.buildColumn(modelDeclaration, importMappings, field, context)); + pairs.add(buildColumn(modelDeclaration, importMappings, field, context)); } } } - return pairs; + return pairs.stream().filter(Objects::nonNull).toList(); + } + + private Pair buildColumn(TypeDeclaration modelDeclaration, + Map declarMappings, + Parameter param, + Context context) { + return buildColumn(modelDeclaration, declarMappings, context, param, param, param); + } + + private Pair buildColumn(TypeDeclaration modelDeclaration, + Map declarMappings, + FieldDeclaration field, + Context context) { + if (field.getVariables().size() > 1) { + throw new GenerateMyBatisExampleException("can't use multi variables declaration! Model=" + + modelDeclaration.getFullyQualifiedName().orElse(null) + + ", field = " + field.getVariables().stream() + .map(VariableDeclarator::getNameAsString) + .collect(Collectors.joining(", "))); + } + return buildColumn(modelDeclaration, declarMappings, context, + field, field.getVariable(0), field.getVariable(0)); + } + + protected Map> getNormalAnnotationMembers( + Optional optionalColumnAnno) { + if (optionalColumnAnno.isEmpty() + || !optionalColumnAnno.get().isNormalAnnotationExpr()) { + return Map.of(); + } + return optionalColumnAnno.get().asNormalAnnotationExpr() + .getPairs().stream().collect( + Collectors.groupingBy(MemberValuePair::getNameAsString)); + } + + private Map> getNormalAnnotationMembers( + NodeWithAnnotations annotationNode, Class annotationClass) { + Optional optionalColumnAnno = annotationNode.getAnnotationByClass(annotationClass); + return getNormalAnnotationMembers(optionalColumnAnno); + } + + protected Pair buildColumn( + TypeDeclaration modelDeclaration, + Map declarMappings, + Context context, + NodeWithAnnotations annotationNode, + NodeWithType typeNode, + NodeWithSimpleName nameNode) { + Optional annoOptional = annotationNode.getAnnotationByClass(GeneratedColumn.class); + if (annoOptional.isEmpty()) { + return null; + } + var annotationMembers = getNormalAnnotationMembers(annoOptional); + + String typeClassName = getClassByType(declarMappings, typeNode.getType()); + if (StringUtils.isEmpty(typeClassName)) { + throw new GenerateMyBatisExampleException(String.format(Locale.ROOT, + "not supported Java Type, field = %s, type = %s, FullyQualifiedName = %s", + nameNode.getNameAsString(), typeNode.getType().toString(), + modelDeclaration.getFullyQualifiedName().orElse(null))); + } + + String javaProperty = nameNode.getNameAsString(); + String name = parseColumnName(annotationMembers, javaProperty, context); + JdbcType jdbcType = parseJdbcType(typeClassName, annotationMembers); + if (StringUtils.isEmpty(name) || jdbcType == null) { + throw new GenerateMyBatisExampleException(String.format(Locale.ROOT, + "can't get column name or jdbcType, field = %s, type = %s, FullyQualifiedName = %s", + javaProperty, typeNode.getType().toString(), + modelDeclaration.getFullyQualifiedName().orElse(null))); + } + + IntrospectedColumnMmegpImpl column = new IntrospectedColumnMmegpImpl(); + column.setContext(context); + column.setActualColumnName(name); + column.setJavaProperty(javaProperty); + + column.setBlobColumn(parseBoolean(annotationMembers, "blob", false)); + + boolean id = parseBoolean(annotationMembers, "id", false); + boolean generatedValue = parseBoolean(annotationMembers, "generatedValue", false); + column.setIdentity(id && generatedValue); + column.setAutoIncrement(generatedValue); + + column.setJdbcType(jdbcType.TYPE_CODE); + column.setJdbcTypeName(jdbcType.name()); + column.setFullyQualifiedJavaType(new FullyQualifiedJavaType(typeClassName)); + column.setTypeHandler(parseTypeHandler(annotationMembers, declarMappings)); + + column.getProperties().put(AGGREGATES_NAME, + parseAggregates(annotationMembers).stream() + .map(AggregateFunction::name) + .collect(Collectors.joining(","))); + + return Pair.of(column, id); + } + + private List parseAggregates(Map> annotationMembers) { + return parseArray(annotationMembers, AGGREGATES_NAME) + .stream().map(this::parseAggregate) + .filter(Objects::nonNull).toList(); + } + + private AggregateFunction parseAggregate(Expression exp) { + String value = null; + if (exp != null && exp.isFieldAccessExpr()) { + value = exp.asFieldAccessExpr().getNameAsString(); + } + return AggregateFunction.parse(value); } - private static void addTableColumns(IntrospectedTable introspectedTable, + private void addTableColumns(IntrospectedTable introspectedTable, TypeDeclaration modelDeclaration, NodeList importDeclarations, Context context) { diff --git a/mmegp-mbg-ext/src/main/java/me/ningpp/mmegp/JavaParserUtil.java b/mmegp-mbg-ext/src/main/java/me/ningpp/mmegp/JavaParserUtil.java index 897bfb2..51b527e 100644 --- a/mmegp-mbg-ext/src/main/java/me/ningpp/mmegp/JavaParserUtil.java +++ b/mmegp-mbg-ext/src/main/java/me/ningpp/mmegp/JavaParserUtil.java @@ -19,33 +19,17 @@ import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ParserConfiguration.LanguageLevel; import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.FieldDeclaration; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.body.TypeDeclaration; -import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.ast.expr.AnnotationExpr; import com.github.javaparser.ast.expr.ArrayInitializerExpr; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.MemberValuePair; -import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations; -import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; -import com.github.javaparser.ast.nodeTypes.NodeWithType; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.Type; -import me.ningpp.mmegp.annotations.Generated; -import me.ningpp.mmegp.annotations.GeneratedColumn; -import me.ningpp.mmegp.enums.AggregateFunction; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.ibatis.type.JdbcType; -import org.mybatis.generator.api.IntrospectedColumn; -import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType; import org.mybatis.generator.config.Context; import org.mybatis.generator.internal.ObjectFactory; -import java.lang.annotation.Annotation; import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; @@ -60,15 +44,19 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; public final class JavaParserUtil { private JavaParserUtil() { } + private static final String TABLE_NAMING_STRATEGY_INSTANCE_KEY = "tableNamingStrategyInstance"; + private static final String TABLE_NAMING_STRATEGY_KEY = "tableNamingStrategy"; + + private static final String COLUMN_NAMING_STRATEGY_INSTANCE_KEY = "columnNamingStrategyInstance"; + private static final String COLUMN_NAMING_STRATEGY_KEY = "columnNamingStrategy"; + private static final Map PREDEFINED_TYPES; private static final Map JDBC_TYPES = new HashMap<>(); public static final String COUNT_GROUP_BY_COLUMNS_NAME = "countGroupByColumns"; @@ -123,120 +111,38 @@ public static JavaParser newParser() { return new JavaParser(jpc); } - public static GeneratedTableInfo getTableValue(TypeDeclaration typeDeclar, Context context) { - if (typeDeclar == null || typeDeclar.getFullyQualifiedName().isEmpty()) { - return null; - } - var annotationMembers = getNormalAnnotationMembers(typeDeclar, Generated.class); - - String tableName = parseTableName(annotationMembers, typeDeclar.getNameAsString(), context); - List countGroupByColumns = parseArrayString(annotationMembers, COUNT_GROUP_BY_COLUMNS_NAME); - return new GeneratedTableInfo(tableName, countGroupByColumns); + public static String parseTableName(String name, String entityName, Context context) { + return parseNamingByStrategy(name, entityName, + TABLE_NAMING_STRATEGY_INSTANCE_KEY, TABLE_NAMING_STRATEGY_KEY, context); } - private static String parseTableName(Map> annotationMembers, + public static String parseTableName(Map> annotationMembers, String entityName, Context context) { return parseNamingByStrategy(annotationMembers, "table", entityName, - "tableNamingStrategyInstance", "tableNamingStrategy", context); - } - - private static String parseColumnName(Map> annotationMembers, - String javaProperty, Context context) { - return parseNamingByStrategy(annotationMembers, "name", javaProperty, - "columnNamingStrategyInstance", "columnNamingStrategy", context); + TABLE_NAMING_STRATEGY_INSTANCE_KEY, TABLE_NAMING_STRATEGY_KEY, context); } - public static Pair buildColumn(TypeDeclaration modelDeclaration, - Map declarMappings, - Parameter param, - Context context) { - return buildColumn(modelDeclaration, declarMappings, context, param, param, param); + public static String parseColumnName(String name, String javaProperty, Context context) { + return parseNamingByStrategy(name, javaProperty, + COLUMN_NAMING_STRATEGY_INSTANCE_KEY, COLUMN_NAMING_STRATEGY_KEY, context); } - public static Pair buildColumn(TypeDeclaration modelDeclaration, - Map declarMappings, - FieldDeclaration field, - Context context) { - if (field.getVariables().size() > 1) { - throw new GenerateMyBatisExampleException("can't use multi variables declaration! Model=" - + modelDeclaration.getFullyQualifiedName().orElse(null) - + ", field = " + field.getVariables().stream() - .map(VariableDeclarator::getNameAsString) - .collect(Collectors.joining(", "))); - } - return buildColumn(modelDeclaration, declarMappings, context, - field, field.getVariable(0), field.getVariable(0)); - } - - private static Map> getNormalAnnotationMembers( - NodeWithAnnotations annotationNode, Class annotationClass) { - Optional optionalColumnAnno = annotationNode.getAnnotationByClass(annotationClass); - if (optionalColumnAnno.isEmpty() - || !optionalColumnAnno.get().isNormalAnnotationExpr()) { - return Map.of(); - } - return optionalColumnAnno.get().asNormalAnnotationExpr() - .getPairs().stream().collect( - Collectors.groupingBy(MemberValuePair::getNameAsString)); - } - - private static Pair buildColumn( - TypeDeclaration modelDeclaration, - Map declarMappings, - Context context, - NodeWithAnnotations annotationNode, - NodeWithType typeNode, - NodeWithSimpleName nameNode) { - var annotationMembers = getNormalAnnotationMembers(annotationNode, GeneratedColumn.class); - - String typeClassName = getClassByType(declarMappings, typeNode.getType()); - if (StringUtils.isEmpty(typeClassName)) { - throw new GenerateMyBatisExampleException(String.format(Locale.ROOT, - "not supported Java Type, field = %s, type = %s, FullyQualifiedName = %s", - nameNode.getNameAsString(), typeNode.getType().toString(), - modelDeclaration.getFullyQualifiedName().orElse(null))); - } - - String javaProperty = nameNode.getNameAsString(); - String name = parseColumnName(annotationMembers, javaProperty, context); - JdbcType jdbcType = parseJdbcType(typeClassName, annotationMembers); - if (StringUtils.isEmpty(name) || jdbcType == null) { - throw new GenerateMyBatisExampleException(String.format(Locale.ROOT, - "can't get column name or jdbcType, field = %s, type = %s, FullyQualifiedName = %s", - javaProperty, typeNode.getType().toString(), - modelDeclaration.getFullyQualifiedName().orElse(null))); - } - - IntrospectedColumnMmegpImpl column = new IntrospectedColumnMmegpImpl(); - column.setContext(context); - column.setActualColumnName(name); - column.setJavaProperty(javaProperty); - - column.setBlobColumn(parseBoolean(annotationMembers, "blob", false)); - - boolean id = parseBoolean(annotationMembers, "id", false); - boolean generatedValue = parseBoolean(annotationMembers, "generatedValue", false); - column.setIdentity(id && generatedValue); - column.setAutoIncrement(generatedValue); - - column.setJdbcType(jdbcType.TYPE_CODE); - column.setJdbcTypeName(jdbcType.name()); - column.setFullyQualifiedJavaType(new FullyQualifiedJavaType(typeClassName)); - column.setTypeHandler(parseTypeHandler(annotationMembers, declarMappings)); - - column.getProperties().put(AGGREGATES_NAME, - parseAggregates(annotationMembers).stream() - .map(AggregateFunction::name) - .collect(Collectors.joining(","))); - - return Pair.of(column, id); + public static String parseColumnName(Map> annotationMembers, + String javaProperty, Context context) { + return parseNamingByStrategy(annotationMembers, "name", javaProperty, + COLUMN_NAMING_STRATEGY_INSTANCE_KEY, COLUMN_NAMING_STRATEGY_KEY, context); } private static String parseNamingByStrategy(Map> annotationMembers, String annotationMethod, String srcName, String instanceKey, String propertyKey, Context context) { - String name = parseString(annotationMembers, annotationMethod, ""); + return parseNamingByStrategy(parseString(annotationMembers, annotationMethod, ""), + srcName, instanceKey, propertyKey, context); + } + + private static String parseNamingByStrategy(String name, String srcName, + String instanceKey, String propertyKey, Context context) { if (StringUtils.isEmpty(name)) { NamingStrategy strategy = (NamingStrategy) context.getProperties().get(instanceKey); if (strategy == null) { @@ -250,7 +156,7 @@ private static String parseNamingByStrategy(Map> a return name; } - private static String parseTypeHandler(Map> annotationMembers, + public static String parseTypeHandler(Map> annotationMembers, Map declarMappings) { return parse(annotationMembers, "typeHandler") .filter(Expression::isClassExpr) @@ -258,7 +164,7 @@ private static String parseTypeHandler(Map> annota .orElse(null); } - private static JdbcType parseJdbcType(String typeClassName, + public static JdbcType parseJdbcType(String typeClassName, Map> annotationMembers) { var declarJdbcType = parseEnumValue("jdbcType", JDBC_TYPES, annotationMembers, JdbcType.UNDEFINED); if (declarJdbcType == JdbcType.UNDEFINED) { @@ -287,7 +193,7 @@ private static String getEnumTypeName(Expression memberValue) { return typeName; } - private static List parseArray(Map> annotationMembers, String name) { + public static List parseArray(Map> annotationMembers, String name) { Optional arrayInitExpr = parse(annotationMembers, name) .filter(Expression::isArrayInitializerExpr) .map(Expression::asArrayInitializerExpr); @@ -299,7 +205,7 @@ private static List parseArray(Map> an } } - private static List parseArrayString(Map> annotationMembers, String name) { + public static List parseArrayString(Map> annotationMembers, String name) { return parseArray(annotationMembers, name) .stream().filter(Expression::isStringLiteralExpr) .map(expr -> expr.asStringLiteralExpr().asString()) @@ -314,7 +220,7 @@ public static String parseString(Map> annotationMe .orElse(defaultValue); } - private static boolean parseBoolean(Map> annotationMembers, String name, + public static boolean parseBoolean(Map> annotationMembers, String name, boolean defaultValue) { return parse(annotationMembers, name) .filter(Expression::isBooleanLiteralExpr) @@ -330,20 +236,6 @@ private static Optional parse(Map> ann return Optional.empty(); } - private static List parseAggregates(Map> annotationMembers) { - return parseArray(annotationMembers, AGGREGATES_NAME) - .stream().map(JavaParserUtil::parseAggregate) - .filter(Objects::nonNull).toList(); - } - - private static AggregateFunction parseAggregate(Expression exp) { - String value = null; - if (exp != null && exp.isFieldAccessExpr()) { - value = exp.asFieldAccessExpr().getNameAsString(); - } - return AggregateFunction.parse(value); - } - private static final Set> PRIMITIVES_AND_BOXED_TYPES; static { Set> classes = new HashSet<>(); @@ -397,7 +289,7 @@ private static AggregateFunction parseAggregate(Expression exp) { MAPPING_TYPES = Map.copyOf(mappings); } - private static String getClassByType(Map declarMappings, Type type) { + public static String getClassByType(Map declarMappings, Type type) { Class clazz = MAPPING_TYPES.get(type.asString()); if (clazz != null) { if (clazz.isArray()) { diff --git a/mmegp-mbg-ext/src/test/java/me/ningpp/mmegp/MmeCompileUtilTest.java b/mmegp-mbg-ext/src/test/java/me/ningpp/mmegp/MmeCompileUtilTest.java index f66b2ba..1533417 100644 --- a/mmegp-mbg-ext/src/test/java/me/ningpp/mmegp/MmeCompileUtilTest.java +++ b/mmegp-mbg-ext/src/test/java/me/ningpp/mmegp/MmeCompileUtilTest.java @@ -242,7 +242,7 @@ private IntrospectedTable buildIntrospectedTable(Context context, ParseResult parseResult = JavaParserUtil.newParser().parse(fileContent); Optional cuOptional = parseResult.getResult(); if (parseResult.isSuccessful() && cuOptional.isPresent()) { - return DefaultIntrospectedTableBuilder.buildIntrospectedTable( + return new DefaultIntrospectedTableBuilder().buildIntrospectedTable( context, cuOptional.get(), metaInfoHandler diff --git a/mmegp-mybatis-plus/pom.xml b/mmegp-mybatis-plus/pom.xml new file mode 100644 index 0000000..d5d6f65 --- /dev/null +++ b/mmegp-mybatis-plus/pom.xml @@ -0,0 +1,76 @@ + + + + 4.0.0 + + io.github.ningpp + mmegp + 2.0.0-SNAPSHOT + + + mmegp-mybatis-plus + + + + com.baomidou + mybatis-plus-annotation + + + io.github.ningpp + mmegp-annotation-parser + ${project.version} + + + io.github.ningpp + mmegp-mbg-ext + ${project.version} + + + + + + + io.github.ningpp + mmegp-maven-plugin + ${project.version} + + + com.baomidou + mybatis-plus-annotation + ${mybatis-plus.version} + + + + com.baomidou.mybatisplus.annotation + me.ningpp.mmegp.mybatisplus.annotationmodel + + + + + generate-annotation-model + + + + + + + + \ No newline at end of file diff --git a/mmegp-mybatis-plus/src/main/java/me/ningpp/mmegp/mybatisplus/generator/MyBatisPlusIntrospectedTableBuilder.java b/mmegp-mybatis-plus/src/main/java/me/ningpp/mmegp/mybatisplus/generator/MyBatisPlusIntrospectedTableBuilder.java new file mode 100644 index 0000000..bd279a1 --- /dev/null +++ b/mmegp-mybatis-plus/src/main/java/me/ningpp/mmegp/mybatisplus/generator/MyBatisPlusIntrospectedTableBuilder.java @@ -0,0 +1,163 @@ +/* + * Copyright 2021-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.ningpp.mmegp.mybatisplus.generator; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.github.javaparser.ast.ImportDeclaration; +import com.github.javaparser.ast.Node; +import com.github.javaparser.ast.NodeList; +import com.github.javaparser.ast.body.TypeDeclaration; +import com.github.javaparser.ast.expr.MemberValuePair; +import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations; +import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; +import com.github.javaparser.ast.nodeTypes.NodeWithType; +import com.github.javaparser.ast.type.Type; +import me.ningpp.mmegp.DefaultIntrospectedTableBuilder; +import me.ningpp.mmegp.GeneratedTableInfo; +import me.ningpp.mmegp.IntrospectedColumnMmegpImpl; +import me.ningpp.mmegp.annotationparser.ModelBasedAnnotationParser; +import me.ningpp.mmegp.enums.SoftDeleteStrategy; +import me.ningpp.mmegp.meta.model.SoftDeleteModel; +import me.ningpp.mmegp.mybatisplus.annotationmodel.TableFieldModel; +import me.ningpp.mmegp.mybatisplus.annotationmodel.TableIdModel; +import me.ningpp.mmegp.mybatisplus.annotationmodel.TableLogicModel; +import me.ningpp.mmegp.mybatisplus.annotationmodel.TableNameModel; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.ibatis.type.JdbcType; +import org.mybatis.generator.api.IntrospectedColumn; +import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType; +import org.mybatis.generator.config.Context; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static me.ningpp.mmegp.JavaParserUtil.getClassByType; +import static me.ningpp.mmegp.JavaParserUtil.parseColumnName; +import static me.ningpp.mmegp.JavaParserUtil.parseJdbcType; +import static me.ningpp.mmegp.JavaParserUtil.parseTableName; +import static me.ningpp.mmegp.JavaParserUtil.parseTypeHandler; + +public class MyBatisPlusIntrospectedTableBuilder extends DefaultIntrospectedTableBuilder { + + @Override + protected GeneratedTableInfo buildGeneratedTable(Context context, + TypeDeclaration modelDeclaration, NodeList importDeclarations) { + + TableNameModel tableNameModel = ModelBasedAnnotationParser.parse(TableName.class, TableNameModel.class, + modelDeclaration, importDeclarations); + if (tableNameModel == null) { + return null; + } else { + return new GeneratedTableInfo( + parseTableName( + tableNameModel.value(), + modelDeclaration.getNameAsString(), + context + ), List.of()); + } + } + + @Override + protected Pair buildColumn( + TypeDeclaration modelDeclaration, + Map declarMappings, + Context context, + NodeWithAnnotations annotationNode, + NodeWithType typeNode, + NodeWithSimpleName nameNode) { + + var tableFieldModel = ModelBasedAnnotationParser.parse(TableField.class, TableFieldModel.class, + annotationNode, declarMappings.values()); + Map> annotationMembers; + if (tableFieldModel != null) { + if (! tableFieldModel.exist()) { + return null; + } + + annotationMembers = getNormalAnnotationMembers( + annotationNode.getAnnotationByClass(TableField.class)); + } else { + annotationMembers = new HashMap<>(0); + } + + String typeClassName = getClassByType(declarMappings, typeNode.getType()); + String javaProperty = nameNode.getNameAsString(); + String name = tableFieldModel == null ? null : tableFieldModel.value(); + if (StringUtils.isEmpty(name)) { + name = parseColumnName(name, javaProperty, context); + } + JdbcType jdbcType = parseJdbcType(typeClassName, annotationMembers); + + IntrospectedColumnMmegpImpl column = new IntrospectedColumnMmegpImpl(); + column.setContext(context); + column.setActualColumnName(name); + column.setJavaProperty(javaProperty); + + column.setBlobColumn(false); + + TableIdModel tableIdModel = ModelBasedAnnotationParser.parse( + TableId.class, TableIdModel.class, + annotationNode, declarMappings.values()); + boolean id = tableIdModel != null; + boolean generatedValue = tableIdModel != null + && IdType.AUTO == tableIdModel.type(); + column.setIdentity(id && generatedValue); + column.setAutoIncrement(generatedValue); + + column.setJdbcType(jdbcType.TYPE_CODE); + column.setJdbcTypeName(jdbcType.name()); + column.setFullyQualifiedJavaType(new FullyQualifiedJavaType(typeClassName)); + column.setTypeHandler(parseTypeHandler(annotationMembers, declarMappings)); + + handleSoftDelete(column, declarMappings, annotationNode); + + return Pair.of(column, id); + } + + private void handleSoftDelete(IntrospectedColumn column, + Map declarMappings, + NodeWithAnnotations annotationNode) { + TableLogicModel tableLogicModel = ModelBasedAnnotationParser.parse( + TableLogic.class, TableLogicModel.class, + annotationNode, declarMappings.values()); + if (tableLogicModel == null) { + return; + } + + String notDeletedValue = tableLogicModel.value(); + if (StringUtils.isEmpty(notDeletedValue)) { + notDeletedValue = (String) column.getContext().getProperties() + .getOrDefault("mybatisPlusNotDeletedValue", "0"); + } + + String deletedValue = tableLogicModel.delval(); + if (StringUtils.isEmpty(deletedValue)) { + deletedValue = (String) column.getContext().getProperties() + .getOrDefault("mybatisPlusDeletedValue", "1"); + } + + column.getIntrospectedTable().setAttribute(SoftDeleteModel.class.getName(), + new SoftDeleteModel(column, SoftDeleteStrategy.FIXED_VALUE, + notDeletedValue, deletedValue)); + } + +} diff --git a/pom.xml b/pom.xml index 967b7fc..c1c950f 100644 --- a/pom.xml +++ b/pom.xml @@ -102,6 +102,7 @@ 3.5.16 1.5.2 1.4.2 + 3.5.7 3.0.3 1.7.0 0.0.7 @@ -120,6 +121,7 @@ mmegp-maven-plugin-demo mmegp-mbg-ext mmegp-mybatis-ext + mmegp-mybatis-plus @@ -209,6 +211,13 @@ mybatis-generator-core ${mybatis-generator-core.version} + + com.baomidou/ + mybatis-plus-bom + ${mybatis-plus.version} + pom + import + org.mybatis.spring.boot mybatis-spring-boot-starter