From a446357b651ce8f8058345f37fff07831c66ff91 Mon Sep 17 00:00:00 2001
From: ZhengJin
Date: Tue, 25 Jun 2024 18:33:26 +0800
Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=9C=A8APT?=
=?UTF-8?q?=E4=B8=AD=E9=80=9A=E8=BF=87=E8=A1=A8=E8=BE=BE=E5=BC=8F=E9=80=89?=
=?UTF-8?q?=E6=8B=A9package=E5=B1=82=E7=BA=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 增加processor.tableDef.package配置
2. 支持在APT中通过表达式选择package层级,将`${entityPackage}`替换为实际实体包名, 表达式中如果存在一个`.parent`则缩减包名末尾的一位。
示例:`entityClass = com. test1.test2`
1. 对于`packageStr = ${entityPackage}`处理结果为 `com. test1.test2`
2. 对于`packageStr = ${entityPackage. parent}`处理结果为 `com. test1`
3. 对于`packageStr = ${entityPackage. parent}.customize`处理结果为 `com. test1.customize`
---
.../processor/MybatisFlexProcessor.java | 11 ++---
.../processor/config/ConfigurationKey.java | 5 +++
.../mybatisflex/processor/util/StrUtil.java | 41 ++++++++++++++++++-
3 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java
index 65c127c1..a2d9c458 100644
--- a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java
+++ b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java
@@ -125,6 +125,7 @@ public class MybatisFlexProcessor extends AbstractProcessor {
String mapperBaseClass = configuration.get(ConfigurationKey.MAPPER_BASE_CLASS);
// tableDef 配置
+ String tableDefPackage = configuration.get(ConfigurationKey.TABLE_DEF_PACKAGE);
String tableDefClassSuffix = configuration.get(ConfigurationKey.TABLE_DEF_CLASS_SUFFIX);
String tableDefInstanceSuffix = configuration.get(ConfigurationKey.TABLE_DEF_INSTANCE_SUFFIX);
String tableDefPropertiesNameStyle = configuration.get(ConfigurationKey.TABLE_DEF_PROPERTIES_NAME_STYLE);
@@ -180,12 +181,12 @@ public class MybatisFlexProcessor extends AbstractProcessor {
tableInfo.setEntityComment(elementUtils.getDocComment(entityClassElement));
// 生成 TableDef 文件
- String tableDefPackage = StrUtil.buildTableDefPackage(entityClass);
+ String realTableDefPackage = StrUtil.isBlank(tableDefPackage) ? StrUtil.buildTableDefPackage(entityClass) : StrUtil.processPackageExpression(entityClass, tableDefPackage);
String tableDefClassName = entityClassName.concat(tableDefClassSuffix);
- String tableDefContent = ContentBuilder.buildTableDef(tableInfo, allInTablesEnable, tableDefPackage, tableDefClassName
+ String tableDefContent = ContentBuilder.buildTableDef(tableInfo, allInTablesEnable, realTableDefPackage, tableDefClassName
, tableDefPropertiesNameStyle, tableDefInstanceSuffix, columnInfos, defaultColumns);
// 将文件所依赖的 Element 传入 Filer 中,表示此 TableDef 依赖这个类,以保证增量编译时不丢失内容。
- processGenClass(genPath, tableDefPackage, tableDefClassName, tableDefContent, entityClassElement);
+ processGenClass(genPath, realTableDefPackage, tableDefClassName, tableDefContent, entityClassElement);
if (allInTablesEnable) {
// 标记 entity 类,如果没有配置 Tables 生成位置,以 entity 位置为准
@@ -196,7 +197,7 @@ public class MybatisFlexProcessor extends AbstractProcessor {
// 是否生成 Mapper 文件
if ("true".equalsIgnoreCase(mapperGenerateEnable) && table.mapperGenerateEnable()) {
- String realMapperPackage = StrUtil.isBlank(mapperPackage) ? StrUtil.buildMapperPackage(entityClass) : mapperPackage;
+ String realMapperPackage = StrUtil.isBlank(mapperPackage) ? StrUtil.buildMapperPackage(entityClass) : StrUtil.processPackageExpression(entityClass, mapperPackage);
String mapperClassName = entityClassName.concat("Mapper");
boolean mapperAnnotationEnable = "true".equalsIgnoreCase(mapperAnnotation);
String mapperClassContent = ContentBuilder.buildMapper(tableInfo, realMapperPackage, mapperClassName, mapperBaseClass, mapperAnnotationEnable);
@@ -207,7 +208,7 @@ public class MybatisFlexProcessor extends AbstractProcessor {
// 确定了要生成 Tables 类,且拥有至少一个被 Table 注解的类时再生成 Tables 类。
if (allInTablesEnable && entityClassReference != null) {
// 生成 Tables 文件
- String realTablesPackage = StrUtil.isBlank(allInTablesPackage) ? StrUtil.buildTableDefPackage(entityClassReference) : allInTablesPackage;
+ String realTablesPackage = StrUtil.isBlank(allInTablesPackage) ? StrUtil.buildTableDefPackage(entityClassReference) : StrUtil.processPackageExpression(entityClassReference, allInTablesPackage);
String realTablesClassName = StrUtil.isBlank(allInTablesClassName) ? "Tables" : allInTablesClassName;
String tablesContent = ContentBuilder.buildTables(importBuilder, fieldBuilder, realTablesPackage, allInTablesClassName);
processGenClass(genPath, realTablesPackage, realTablesClassName, tablesContent, elementsAnnotatedWith.toArray(new Element[0]));
diff --git a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/config/ConfigurationKey.java b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/config/ConfigurationKey.java
index 40f4488f..0f5feb8a 100644
--- a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/config/ConfigurationKey.java
+++ b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/config/ConfigurationKey.java
@@ -77,6 +77,11 @@ public enum ConfigurationKey {
MAPPER_PACKAGE("processor.mapper.package", null),
+ /**
+ * 自定义 Class 生成的包名。
+ */
+ TABLE_DEF_PACKAGE("processor.tableDef.package", null),
+
/**
* 生成的 Class 的后缀。
*/
diff --git a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/util/StrUtil.java b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/util/StrUtil.java
index 8774f1b4..27f71364 100644
--- a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/util/StrUtil.java
+++ b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/util/StrUtil.java
@@ -16,6 +16,11 @@
package com.mybatisflex.processor.util;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
/**
* 字符串工具类。
*
@@ -28,6 +33,8 @@ public class StrUtil {
private StrUtil() {
}
+ private static final Pattern PACKAGE_REGEX = Pattern.compile("(?\\$\\{entityPackage[.parent]*\\})(?.*)");
+
/**
* com.mybatisflex.test.entity.Account -> Account
*/
@@ -111,6 +118,38 @@ public class StrUtil {
}
}
+ /**
+ * 解析包名表达式
+ * 将{@code `${entityPackage}`}替换为实际实体包名, 表达式中如果存在一个{@code `.parent`}则缩减包名末尾的一位。
+ * 示例:{@code `entityClass = com.test1.test2`}
+ * 1. 对于{@code `packageStr = ${entityPackage}`}处理结果为 {@code `com.test1.test2`}
+ * 2. 对于{@code `packageStr = ${entityPackage.parent}`}处理结果为 {@code `com.test1`}
+ * 3. 对于{@code `packageStr = ${entityPackage.parent}.customize`}处理结果为 {@code `com.test1.customize`}
+ *
+ */
+ public static String processPackageExpression(String entityClass, String packageStr) {
+ Matcher matcher = PACKAGE_REGEX.matcher(packageStr);
+ if (!matcher.find()) {
+ return entityClass;
+ }
+ String expression = matcher.group("expression");
+ expression = expression.substring(2, expression.length() - 1);
+ String subPackage = matcher.group("subPackage");
+ List entityPackage = Arrays.asList(entityClass.split("\\."));
+ while (expression.contains(".parent")) {
+ if (entityPackage.size() == 0) {
+ throw new RuntimeException("Expression [.parent] has exceeded the maximum limit.");
+ }
+ int index = expression.lastIndexOf(".parent");
+ if (index != -1) {
+ expression = expression.substring(0, index);
+ entityPackage = entityPackage.subList(0, entityPackage.size() - 1);
+ }
+ }
+ expression = expression.replace("entityPackage", String.join(".", entityPackage));
+ return expression + subPackage;
+ }
+
public static boolean isGetterMethod(String methodName, String property) {
if (methodName.startsWith("get") && methodName.length() > 3) {
@@ -122,4 +161,4 @@ public class StrUtil {
}
}
-}
\ No newline at end of file
+}
From 515e08da4b7371cb37f90ee23ea96d24078b6cd8 Mon Sep 17 00:00:00 2001
From: ZhengJin
Date: Wed, 26 Jun 2024 17:51:57 +0800
Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3tableDefPackage?=
=?UTF-8?q?=E7=94=9F=E6=88=90=E7=9A=84=E5=AE=9E=E4=BD=93=E5=BC=95=E7=94=A8?=
=?UTF-8?q?=E8=B7=AF=E5=BE=84=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/com/mybatisflex/processor/MybatisFlexProcessor.java | 2 +-
.../java/com/mybatisflex/processor/builder/ContentBuilder.java | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java
index a2d9c458..770630fc 100644
--- a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java
+++ b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java
@@ -192,7 +192,7 @@ public class MybatisFlexProcessor extends AbstractProcessor {
// 标记 entity 类,如果没有配置 Tables 生成位置,以 entity 位置为准
entityClassReference = entityClass;
// 构建 Tables 常量属性及其导包
- ContentBuilder.buildTablesField(importBuilder, fieldBuilder, tableInfo, tableDefClassSuffix, tableDefPropertiesNameStyle, tableDefInstanceSuffix);
+ ContentBuilder.buildTablesField(importBuilder, fieldBuilder, tableInfo, tableDefClassSuffix, tableDefPropertiesNameStyle, tableDefInstanceSuffix, realTableDefPackage);
}
// 是否生成 Mapper 文件
diff --git a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/builder/ContentBuilder.java b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/builder/ContentBuilder.java
index 3c5032af..4b3efa4a 100644
--- a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/builder/ContentBuilder.java
+++ b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/builder/ContentBuilder.java
@@ -168,8 +168,7 @@ public class ContentBuilder {
* 构建 Tables 文件常量属性。
*/
public static void buildTablesField(StringBuilder importBuilder, StringBuilder fieldBuilder, TableInfo tableInfo,
- String tableDefClassSuffix, String tableDefPropertiesNameStyle, String tableDefInstanceSuffix) {
- String tableDefPackage = StrUtil.buildTableDefPackage(tableInfo.getEntityName());
+ String tableDefClassSuffix, String tableDefPropertiesNameStyle, String tableDefInstanceSuffix, String tableDefPackage) {
String tableDefClassName = tableInfo.getEntitySimpleName().concat(tableDefClassSuffix);
importBuilder.append("import ").append(tableDefPackage).append('.').append(tableDefClassName).append(";\n");
String entityComment = tableInfo.getEntityComment();
From 360e4b509187c01f1b25c9c85801f4b84a31e1c0 Mon Sep 17 00:00:00 2001
From: ZhengJin
Date: Mon, 1 Jul 2024 10:41:02 +0800
Subject: [PATCH 3/3] =?UTF-8?q?docs:=20APT=E8=AE=BE=E7=BD=AE=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0=E8=A1=A8=E8=BE=BE=E5=BC=8F=E7=94=A8=E6=B3=95=E8=AF=B4?=
=?UTF-8?q?=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/others/apt.md | 54 ++++++++++++++-----
mybatis-flex-processor/pom.xml | 1 +
.../mybatisflex/processor/util/StrUtil.java | 11 ++--
3 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/docs/zh/others/apt.md b/docs/zh/others/apt.md
index 6537132c..edf58a11 100644
--- a/docs/zh/others/apt.md
+++ b/docs/zh/others/apt.md
@@ -5,7 +5,7 @@ MyBatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编

-> 从1.1.9版本开始,APT默认不生成 Mapper 类文件。如需开启,参考下方配置选项。
+> 从1.1.9版本开始,APT默认不生成 Mapper 类文件。如需开启,参考下方配置选项。
## 配置文件和选项
@@ -18,7 +18,7 @@ MyBatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编
| processor.enable | 全局启用apt开关 | true/false | true |
| processor.stopBubbling | 是否停止向上级合并配 | true/false | false |
| processor.genPath | APT 代码生成路径 | 合法的绝对或相对路径 | target/generated-sources/annotations |
-| processor.charset | APT 代码生成文件字符集 | 合法的字符集 | UTF-8 |
+| processor.charset | APT 代码生成文件字符集 | 合法的字符集 | UTF-8 |
| processor.allInTables.enable | 是否所有的类都生成在 Tables 类里 | true/false | false |
| processor.allInTables.package | Tables 包名 | 合法的包名 | ${entityPackage}.table |
| processor.allInTables.className | Tables 类名 | 合法的类名 | Tables |
@@ -26,12 +26,43 @@ MyBatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编
| processor.mapper.annotation | 开启 @Mapper 注解 | true/false | false |
| processor.mapper.baseClass | 自定义 Mapper 的父类 | 全路径类名 | com.mybatisflex.core.BaseMapper |
| processor.mapper.package | 自定义 Mapper 生成的包名 | 合法的包名 | ${entityPackage}.mapper |
+| processor.tableDef.package | 生成辅助类的包名 | 合法的包名 | ${entityPackage}.table |
| processor.tableDef.propertiesNameStyle | 生成辅助类的字段风格 | upperCase, lowerCase
upperCamelCase, lowerCamelCase | upperCase |
| processor.tableDef.instanceSuffix | 生成的表对应的变量后缀 | string | 空字符串 |
| processor.tableDef.classSuffix | 生成的 TableDef 类的后缀 | string | TableDef |
| processor.tableDef.ignoreEntitySuffixes | 过滤 Entity 后缀 | string | - |
+对于示例中的包名表达式,说明如下:
+1. 仅支持以下配置项使用表达式
+ ```text
+ processor.allInTables.package
+ processor.mapper.package
+ processor.tableDef.package
+ ```
+2. `${entityPackage}`: 表示 Entity 类所在的包名
+3. `${entityPackage.parent}`: 表示 Entity 类所在的上一级包名
+4. `parent` 参数的数量没有限制,但如果超出了可能的层级,则会导致异常
+
+**示例配置:**
+
+假设 Example 类的全限定类名为 `com.mybatisflex.entity.Example`
+
+配置内容如下:
+
+```properties
+processor.allInTables.package=${entityPackage}.table
+processor.mapper.package=${entityPackage.parent}.mapper
+processor.tableDef.package=${entityPackage.parent.parent}.table
+```
+
+生成类的全限定类名如下:
+
+```text
+com.mybatisflex.entity.table.Tables
+com.mybatisflex.mapper.ExampleMapper
+com.table.ExampleTableDef
+```
## APT 代码生成路径
@@ -42,12 +73,11 @@ MyBatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编
如果我们不想让生成的代码放在这些目录,这可以添加如下配置:
```properties
-processor.genPath = your-path
+processor.genPath=your-path
```
genPath 可以是绝对路径,也可以是相对路径,如果填写的是相对路径,那么则是相对 Maven 根模块的目录。
-
## APT 生成的 Tables 类名和包名
默认情况下, APT 生成的类名为 "Tables",而包名为 entity 的包添加上 ".table",假设 Account.java
@@ -87,8 +117,9 @@ public class AccountTableDef extends TableDef {
```properties
#upperCase, lowerCase, upperCamelCase, lowerCamelCase
-processor.tableDef.propertiesNameStyle = upperCase
+processor.tableDef.propertiesNameStyle=upperCase
```
+
风格支持 4 种配置,默认(未配置时)为 upperCase,支持的配置分别为:
- upperCase:大写 + 下划线,例如:USER_NAME
@@ -96,28 +127,25 @@ processor.tableDef.propertiesNameStyle = upperCase
- upperCamelCase:首字母大写的驼峰命名,例如:UserName
- lowerCamelCase:首字母小写的驼峰命名,例如:userName
-
-
## APT 过滤 Entity 后缀
+
在某些情况下,Entity 类可能会有某些通用的后缀,比如 `AccountModel` 或者 `AccountDto` 等,我们希望生成的代码,
不包含 `Model` `Dto` 等后缀,可以添加如下的配置:
```properties
-processor.tableDef.ignoreEntitySuffixes = Model, Dto
+processor.tableDef.ignoreEntitySuffixes=Model, Dto
```
-
## APT 开启 Mapper 生成
从 v1.1.9 开始, APT 的 Mapper 功能是关闭的,若需要开启 Mapper 的自动生成功能,需要添加以下配置。
```properties
-processor.mapper.generateEnable = true
+processor.mapper.generateEnable=true
```
以上的配置,会开启整个项目的 APT 生成,若我们想关闭某一个 Entity 的 APT 生成,那么可以通过配置注解 `@Table(mapperGenerateEnable = false)` 进行关闭。
-
## APT 生成的 Mapper 包名
默认情况下, APT 生成的 Mapper 类名为 "***Mapper",而包名为 entity 的包添加上 ".mapper",假设 Account.java
@@ -126,7 +154,7 @@ processor.mapper.generateEnable = true
添加如下配置,自定义 Mapper 生成的包名。
```properties
-processor.mapper.package = com.your-package
+processor.mapper.package=com.your-package
```
## 自定义 Mapper 的父类
@@ -135,7 +163,7 @@ processor.mapper.package = com.your-package
`BaseMapper`,然后通过 APT 配置生成。
```properties
-processor.mapper.baseClass = com.domain.mapper.MyBaseMapper
+processor.mapper.baseClass=com.domain.mapper.MyBaseMapper
```
## 实体类不在一个包中
diff --git a/mybatis-flex-processor/pom.xml b/mybatis-flex-processor/pom.xml
index d3d77d8b..4449b547 100644
--- a/mybatis-flex-processor/pom.xml
+++ b/mybatis-flex-processor/pom.xml
@@ -11,6 +11,7 @@
mybatis-flex-processor
jar
+ 1.9.3-fix3
diff --git a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/util/StrUtil.java b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/util/StrUtil.java
index 27f71364..b0638a71 100644
--- a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/util/StrUtil.java
+++ b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/util/StrUtil.java
@@ -128,25 +128,26 @@ public class StrUtil {
*
*/
public static String processPackageExpression(String entityClass, String packageStr) {
+ String entityPackage = entityClass.substring(0, entityClass.lastIndexOf("."));
Matcher matcher = PACKAGE_REGEX.matcher(packageStr);
if (!matcher.find()) {
- return entityClass;
+ return entityPackage;
}
String expression = matcher.group("expression");
expression = expression.substring(2, expression.length() - 1);
String subPackage = matcher.group("subPackage");
- List entityPackage = Arrays.asList(entityClass.split("\\."));
+ List entityPackageSplit = Arrays.asList(entityPackage.split("\\."));
while (expression.contains(".parent")) {
- if (entityPackage.size() == 0) {
+ if (entityPackageSplit.size() == 0) {
throw new RuntimeException("Expression [.parent] has exceeded the maximum limit.");
}
int index = expression.lastIndexOf(".parent");
if (index != -1) {
expression = expression.substring(0, index);
- entityPackage = entityPackage.subList(0, entityPackage.size() - 1);
+ entityPackageSplit = entityPackageSplit.subList(0, entityPackageSplit.size() - 1);
}
}
- expression = expression.replace("entityPackage", String.join(".", entityPackage));
+ expression = expression.replace("entityPackage", String.join(".", entityPackageSplit));
return expression + subPackage;
}