From a73e969431961040c3b3bdbad7a7db27fa89da50 Mon Sep 17 00:00:00 2001 From: iqudoo Date: Fri, 17 Apr 2026 13:15:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=A1=A8=E7=BA=A7=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 154 +++++++----- ...-mybatis-generator-plugin-1.0-SNAPSHOT.jar | Bin 38828 -> 40097 bytes .../mybatis/TapeMybatisGeneratorPlugin.java | 52 +++- .../TapeRepositoryGeneratorPlugin.java | 231 +++++++++++------- .../mybatis/TapeRepoviewGeneratorPlugin.java | 43 +++- 5 files changed, 317 insertions(+), 163 deletions(-) diff --git a/README.md b/README.md index 4f1c971..28fec14 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # tape-mybatis-generator-plugin + > MyBatis 代码生成插件 ## 功能特性 @@ -12,17 +13,22 @@ ## 插件说明 ### TapeMybatisGeneratorPlugin + 扩展 MyBatis Mapper,添加以下功能: + - 在 Mapper 接口中添加 `selectPrimaryKeyByExample` 方法 - 在 Mapper XML 中生成对应的 SQL 查询语句 ### TapeRepositoryGeneratorPlugin + 为非视图表生成 Repository 层代码: + - **接口位置**: `{facadeRepositoryPackage}.I{TableName}Repository` - **实现类位置**: `{domainRepositoryPackage}.{TableName}RepositoryImpl` - **视图表过滤**: 根据 `viewKeyWords` 配置自动识别并跳过视图表 **生成的方法**: + - `trashById(long id)` - 移动到回收站(单个) - `trashAll({Example} example)` - 移动到回收站(批量) - `deleteById(long id, boolean release)` - 删除(单个,支持物理删除) @@ -46,20 +52,25 @@ - `update({Model} record)` - 更新记录(支持乐观锁) ### TapeRepoviewGeneratorPlugin + 为视图表生成 RepoView 层代码: + - **接口位置**: `{facadeRepoviewPackage}.I{TableName}Repo` - **实现类位置**: `{domainRepoviewPackage}.{TableName}RepoImpl` - **视图表识别**: 仅处理包含 `viewKeyWords` 关键字的表 **生成的方法**: + - `findOne({Example} example)` - 查找单条记录 - `getList({Example} example)` - 获取记录列表(支持分页) - `count({Example} example)` - 统计记录数 ### 其他功能 + 通过 `TapeMybatisGeneratorPlugin` 为所有 Example 类添加支持: **添加的字段**: + - `offset` - 偏移量 - `rows` - 每页数量 - `startPageNum` - 最小页码(默认 1) @@ -68,6 +79,7 @@ - `withBLOBs` - 是否返回BLOBs列的数据 **添加的方法**: + - `limit(int rows)` - 设置每页数量 - `limit(int offset, int rows)` - 设置偏移量和每页数量 - `usePage(int pageNum, int pageSize)` - 使用页码和每页数量(自动计算 offset) @@ -79,9 +91,11 @@ - `getRows()` - 获取当前分页limit的rows ## 使用方法 + ### 1. 在 `pom.xml` 中配置插件 ```xml + application @@ -162,29 +176,65 @@ ### 3. 配置参数说明 | 参数名 | 说明 | 默认值 | 必需 | -|--------------------------------|-------------------------------|---------------------------------------------------------|------| -| `targetProject` | 生成代码的目标项目路径 | `src/main/java` | 否 | -| `mapperPackage` | Mapper 接口的包路径 | `com.iqudoo.platform.application.database.mapper` | 是 | -| `modelPackage` | Model 类的包路径 | `com.iqudoo.platform.application.database.model` | 是 | -| `facadeRepositoryPackage` | Repository 接口的包路径 | `com.iqudoo.platform.application.facade.repository` | 否 | -| `domainRepositoryPackage` | Repository 实现类的包路径 | `com.iqudoo.platform.application.domain.repository` | 否 | -| `facadeViewRepositoryPackage` | RepoView 接口的包路径 | `com.iqudoo.platform.application.facade.repoview` | 否 | -| `domainViewRepositoryPackage` | RepoView 实现类的包路径 | `com.iqudoo.platform.application.domain.repoview` | 否 | -| `guidGeneratorClass` | GUID生成工具类 | `com.iqudoo.framework.tape.modules.utils.SnowflakeUtil` | 否 | -| `guidGeneratorCode` | GUID生成方法 | `SnowflakeUtil.nextId()` | 否 | -| `changeLogContextClassPackage` | 变更日志上下文包路径 | `com.iqudoo.platform.application.domain.changeLog` | 否 | -| `changeLogContextClassName` | 变更日志上下文类 | `ChangeLogContext` | 否 | -| `changeLogEnable` | 变更日志监听开关 | `false` | 否 | -| `slowQueryLoggerTime` | 慢查询日志时间阈值 | `300` | 否 | -| `slowQueryLoggerLevel` | 慢查询日志类型:error,warn,debug,info | `error` | 否 | -| `optimisticLockEnable` | 乐观锁开关 | `true` | 否 | -| `ignorePageSize` | 忽略分页阈值 | `10000` | 否 | -| `startPageNum` | 分页开始页码 | `1` | 否 | -| `maxPageSize` | 最大每页数量 | `100` | 否 | +|--------------------------------|-------------------------------|---------------------------------------------------------|----| +| `targetProject` | 生成代码的目标项目路径 | `src/main/java` | 否 | +| `mapperPackage` | Mapper 接口的包路径 | `com.iqudoo.platform.application.database.mapper` | 是 | +| `modelPackage` | Model 类的包路径 | `com.iqudoo.platform.application.database.model` | 是 | +| `facadeRepositoryPackage` | Repository 接口的包路径 | `com.iqudoo.platform.application.facade.repository` | 否 | +| `domainRepositoryPackage` | Repository 实现类的包路径 | `com.iqudoo.platform.application.domain.repository` | 否 | +| `facadeViewRepositoryPackage` | RepoView 接口的包路径 | `com.iqudoo.platform.application.facade.repoview` | 否 | +| `domainViewRepositoryPackage` | RepoView 实现类的包路径 | `com.iqudoo.platform.application.domain.repoview` | 否 | +| `guidGeneratorClass` | GUID生成工具类 | `com.iqudoo.framework.tape.modules.utils.SnowflakeUtil` | 否 | +| `guidGeneratorCode` | GUID生成方法 | `SnowflakeUtil.nextId()` | 否 | +| `changeLogContextClassPackage` | 变更日志上下文包路径 | `com.iqudoo.platform.application.domain.changeLog` | 否 | +| `changeLogContextClassName` | 变更日志上下文类 | `ChangeLogContext` | 否 | +| `changeLogEnable` | 变更日志监听开关 | `false` | 否 | +| `slowQueryLoggerTime` | 慢查询日志时间阈值 | `300` | 否 | +| `slowQueryLoggerLevel` | 慢查询日志类型:error,warn,debug,info | `error` | 否 | +| `optimisticLockEnable` | 乐观锁开关 | `true` | 否 | +| `ignorePageSize` | 忽略分页阈值 | `10000` | 否 | +| `startPageNum` | 分页开始页码 | `1` | 否 | +| `maxPageSize` | 最大每页数量 | `100` | 否 | + +### 3. TABLE级配置,未配置时使用全局配置 + +| 参数名 | +|------------------------| +| `changeLogEnable` | +| `slowQueryLoggerTime` | +| `slowQueryLoggerLevel` | +| `optimisticLockEnable` | +| `ignorePageSize` | +| `startPageNum` | +| `maxPageSize` | + +```xml + + + + + + + + + + +
+``` ## 变更日志监听 ChangeLogContext应该提供以下实现的静态方法,供Repository实现中调用 + ```java public class ChangeLogContext { @@ -206,30 +256,33 @@ public class ChangeLogContext { ```mysql DROP TABLE IF EXISTS `your_table_name`; -CREATE TABLE `your_table_name` ( - `guid` bigint(0) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'GUID', - -- ---------------------------- - -- add your table other table field - -- ---------------------------- - `is_hidden` int(0) NOT NULL DEFAULT 0 COMMENT '隐藏标志', - `is_delete` int(0) NOT NULL DEFAULT 0 COMMENT '删除标志', - `delete_token` varchar(32) NULL DEFAULT '' COMMENT '删除令牌', - `data_version` int(0) NOT NULL DEFAULT 0 COMMENT '数据版本', - `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', - `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '更新时间', - PRIMARY KEY (`guid`) USING BTREE, - -- UNIQUE KEY `idx_unique_key` (`you unique key`,`delete_token`) USING BTREE, - -- KEY `idx_common_query` ( - -- 等值查询字段, - -- `is_hidden`,`is_delete`, - -- 其他参与排序字段, - -- `create_time` desc, - -- `guid`) USING BTREE - KEY `idx_common_query` (`is_hidden`,`is_delete`,`create_time` desc,`guid`) USING BTREE -) ENGINE = InnoDB COMMENT = '你的表格备注' ROW_FORMAT = Dynamic; +CREATE TABLE `your_table_name` +( + `guid` bigint(0) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'GUID', + -- ---------------------------- + -- add your table other table field + -- ---------------------------- + `is_hidden` int(0) NOT NULL DEFAULT 0 COMMENT '隐藏标志', + `is_delete` int(0) NOT NULL DEFAULT 0 COMMENT '删除标志', + `delete_token` varchar(32) NULL DEFAULT '' COMMENT '删除令牌', + `data_version` int(0) NOT NULL DEFAULT 0 COMMENT '数据版本', + `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '更新时间', + PRIMARY KEY (`guid`) USING BTREE, + -- UNIQUE KEY `idx_unique_key` (`you unique key`,`delete_token`) USING BTREE, + -- KEY `idx_common_query` ( + -- 等值查询字段, + -- `is_hidden`,`is_delete`, + -- 其他参与排序字段, + -- `create_time` desc, + -- `guid`) USING BTREE + KEY `idx_common_query` (`is_hidden`, `is_delete`, `create_time` desc, `guid`) USING BTREE +) ENGINE = InnoDB COMMENT = '你的表格备注' + ROW_FORMAT = Dynamic; ``` **必需字段说明**: + - `guid` - 主键,类型为 `bigint UNSIGNED` - `is_hidden` - 隐藏标志,用于回收站功能 - `is_delete` - 删除标志,用于软删除功能 @@ -258,31 +311,16 @@ CREATE TABLE `your_table_name` ( selectByExampleQueryId="false"> - - - - - -
``` -## 注意事项 +## 非视图表注意事项 1. **主键要求**:表必须有一个主键字段,且字段名为 `guid`,类型为 `bigint UNSIGNED` -2. **视图表识别**:视图表通过表名中的关键字识别,默认关键字为 `view_` 和 `v_` 不区分大小写 3. **分页功能**:所有 Example 类都自动包含分页功能,可通过 `usePage()` 方法使用 4. **乐观锁**:更新操作使用 `data_version` 字段实现乐观锁,更新时需要传入正确的版本号 5. **软删除**:删除操作默认是软删除(设置 `is_delete` 标志),可通过 `release=true` 参数执行物理删除 6. **回收站**:通过 `is_hidden` 字段实现回收站功能,`trash` 方法将记录移动到回收站,`recover` 方法恢复记录 -7. **自动字段**:插入记录时,插件会自动设置 `guid`(使用雪花算法)、`is_delete`、`is_hidden`、`delete_token`、`data_version`、`create_time`、`update_time` 等字段 +7. **自动字段**:插入记录时,插件会自动设置 `guid` + (使用雪花算法)、`is_delete`、`is_hidden`、`delete_token`、`data_version`、`create_time`、`update_time` 等字段 8. **BLOB 字段支持**:如果表包含 BLOB 字段,插件会自动使用 `selectByExampleWithBLOBs` 和 `updateByExampleWithBLOBs` 方法 9. **MyBatis Generator 版本**:本插件基于 MyBatis Generator 1.4.1 开发,建议使用 1.4.0 或更高版本 \ No newline at end of file diff --git a/releases/tape-mybatis-generator-plugin-1.0-SNAPSHOT.jar b/releases/tape-mybatis-generator-plugin-1.0-SNAPSHOT.jar index 44a4e020dcf878ed053ede731fd1fd18ea5debfc..03bf3d57310091d2a69e9bf5316e89f51b4d7864 100644 GIT binary patch delta 31151 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�=>W^RdEjn0 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 PRbWgu>KFIK|8V~g+@I8P diff --git a/src/main/java/com/iqudoo/framework/mybatis/TapeMybatisGeneratorPlugin.java b/src/main/java/com/iqudoo/framework/mybatis/TapeMybatisGeneratorPlugin.java index 912dec6..781632d 100644 --- a/src/main/java/com/iqudoo/framework/mybatis/TapeMybatisGeneratorPlugin.java +++ b/src/main/java/com/iqudoo/framework/mybatis/TapeMybatisGeneratorPlugin.java @@ -11,6 +11,7 @@ import org.mybatis.generator.api.dom.xml.Document; import org.mybatis.generator.api.dom.xml.TextElement; import org.mybatis.generator.api.dom.xml.XmlElement; import org.mybatis.generator.config.Context; +import org.mybatis.generator.config.TableConfiguration; import org.mybatis.generator.internal.util.StringUtility; import java.util.List; @@ -54,6 +55,51 @@ public class TapeMybatisGeneratorPlugin extends PluginAdapter { } } + private int getIgnorePageSize(IntrospectedTable introspectedTable) { + try { + TableConfiguration tableConfiguration = introspectedTable.getTableConfiguration(); + String getIgnorePageSize = tableConfiguration.getProperty("ignorePageSize"); + if (getIgnorePageSize != null && !getIgnorePageSize.isEmpty()) { + int value = Integer.parseInt(getIgnorePageSize); + if (value > 0) { + return value; + } + } + } catch (Throwable ignored) { + } + return ignorePageSize; + } + + public int getMaxPageSize(IntrospectedTable introspectedTable) { + try { + TableConfiguration tableConfiguration = introspectedTable.getTableConfiguration(); + String getMaxPageSize = tableConfiguration.getProperty("maxPageSize"); + if (getMaxPageSize != null && !getMaxPageSize.isEmpty()) { + int value = Integer.parseInt(getMaxPageSize); + if (value > 0) { + return value; + } + } + } catch (Throwable ignored) { + } + return maxPageSize; + } + + public int getStartPageNum(IntrospectedTable introspectedTable) { + try { + TableConfiguration tableConfiguration = introspectedTable.getTableConfiguration(); + String getStartPageNum = tableConfiguration.getProperty("startPageNum"); + if (getStartPageNum != null && !getStartPageNum.isEmpty()) { + int value = Integer.parseInt(getStartPageNum); + if (value > 0) { + return value; + } + } + } catch (Throwable ignored) { + } + return startPageNum; + } + @SuppressWarnings("DuplicatedCode") @Override public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { @@ -65,7 +111,7 @@ public class TapeMybatisGeneratorPlugin extends PluginAdapter { "maxPageSize", JavaVisibility.PROTECTED, integerType, - this.maxPageSize + "" + getMaxPageSize(introspectedTable) + "" ); topLevelClass.addField(maxPageSizeField); @@ -73,7 +119,7 @@ public class TapeMybatisGeneratorPlugin extends PluginAdapter { "ignorePageSize", JavaVisibility.PROTECTED, integerType, - this.ignorePageSize + "" + getIgnorePageSize(introspectedTable) + "" ); topLevelClass.addField(ignorePageSizeField); @@ -81,7 +127,7 @@ public class TapeMybatisGeneratorPlugin extends PluginAdapter { "startPageNum", JavaVisibility.PROTECTED, integerType, - startPageNum + "" + getStartPageNum(introspectedTable) + "" ); topLevelClass.addField(startPageNumField); diff --git a/src/main/java/com/iqudoo/framework/mybatis/TapeRepositoryGeneratorPlugin.java b/src/main/java/com/iqudoo/framework/mybatis/TapeRepositoryGeneratorPlugin.java index 518e68c..290cb44 100644 --- a/src/main/java/com/iqudoo/framework/mybatis/TapeRepositoryGeneratorPlugin.java +++ b/src/main/java/com/iqudoo/framework/mybatis/TapeRepositoryGeneratorPlugin.java @@ -6,6 +6,7 @@ import org.mybatis.generator.api.*; import org.mybatis.generator.api.dom.DefaultJavaFormatter; import org.mybatis.generator.api.dom.java.*; import org.mybatis.generator.config.Context; +import org.mybatis.generator.config.TableConfiguration; import org.mybatis.generator.internal.util.StringUtility; import java.io.File; @@ -66,10 +67,19 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { modelPackage = stringConfig("modelPackage", modelPackage); } - private boolean isChangeLogEnable() { + private boolean isChangeLogEnable(IntrospectedTable introspectedTable) { + String tableChangeLogEnable = changeLogEnable; try { - boolean b = Boolean.parseBoolean(changeLogEnable); - if (b && changeLogContextClassName != null && !changeLogContextClassName.isEmpty()) { + TableConfiguration tableConfiguration = introspectedTable.getTableConfiguration(); + String getChangeLogEnable = tableConfiguration.getProperty("changeLogEnable"); + if (getChangeLogEnable != null && !getChangeLogEnable.isEmpty()) { + tableChangeLogEnable = getChangeLogEnable; + } + } catch (Throwable ignored) { + } + try { + boolean b = Boolean.parseBoolean(tableChangeLogEnable); + if (b) { return true; } } catch (Throwable ignored) { @@ -77,9 +87,18 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { return false; } - private boolean isOptimisticLockEnable() { + private boolean isOptimisticLockEnable(IntrospectedTable introspectedTable) { + String tableOptimisticLockEnable = optimisticLockEnable; try { - boolean b = Boolean.parseBoolean(optimisticLockEnable); + TableConfiguration tableConfiguration = introspectedTable.getTableConfiguration(); + String getOptimisticLockEnable = tableConfiguration.getProperty("optimisticLockEnable"); + if (getOptimisticLockEnable != null && !getOptimisticLockEnable.isEmpty()) { + tableOptimisticLockEnable = getOptimisticLockEnable; + } + } catch (Throwable ignored) { + } + try { + boolean b = Boolean.parseBoolean(tableOptimisticLockEnable); if (b) { return true; } @@ -88,6 +107,30 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { return false; } + public String getSlowQueryLoggerLevel(IntrospectedTable introspectedTable) { + try { + TableConfiguration tableConfiguration = introspectedTable.getTableConfiguration(); + String tableSlowQueryLoggerLevel = tableConfiguration.getProperty("slowQueryLoggerLevel"); + if (tableSlowQueryLoggerLevel != null && !tableSlowQueryLoggerLevel.isEmpty()) { + return tableSlowQueryLoggerLevel; + } + } catch (Throwable ignored) { + } + return slowQueryLoggerLevel; + } + + public String getSlowQueryLoggerTime(IntrospectedTable introspectedTable) { + try { + TableConfiguration tableConfiguration = introspectedTable.getTableConfiguration(); + String tableSlowQueryLoggerTime = tableConfiguration.getProperty("slowQueryLoggerTime"); + if (tableSlowQueryLoggerTime != null && !tableSlowQueryLoggerTime.isEmpty()) { + return tableSlowQueryLoggerTime; + } + } catch (Throwable ignored) { + } + return slowQueryLoggerTime; + } + private String stringConfig(String key, String defaultValue) { String v = properties.getProperty(key); if (StringUtility.stringHasValue(v)) { @@ -381,7 +424,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addAnnotation("@SuppressWarnings(\"DuplicatedCode\")"); implClass.addAnnotation("@Repository"); - addImportPackages(implClass, modelClassName, exampleClassName, mapperClassName, interfaceName); + addImportPackages(implClass, introspectedTable, modelClassName, exampleClassName, mapperClassName, interfaceName); FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(facadeRepositoryPackage + "." + interfaceName); implClass.addSuperInterface(superInterface); @@ -404,23 +447,23 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { generateFindAnyByIdMethod(implClass, modelClassName, mapperFieldName, exampleClassName, hasBLOBColumns); generateFindValidByIdMethod(implClass, modelClassName, mapperFieldName, exampleClassName, hasBLOBColumns); generateFindTrashByIdMethod(implClass, modelClassName, mapperFieldName, exampleClassName, hasBLOBColumns); - generateInsertMethod(implClass, modelClassName, mapperFieldName, introspectedTable); - generateBatchInsertMethod(implClass, modelClassName, mapperFieldName, introspectedTable); - generateUpdateMethod(implClass, modelClassName, exampleClassName, mapperFieldName, introspectedTable, hasBLOBColumns); - generateUpdateByExampleSelectiveMethod(implClass, modelClassName, exampleClassName, mapperFieldName, introspectedTable, hasBLOBColumns); - generateDeleteByIdMethod(implClass, modelClassName, exampleClassName, mapperFieldName); - generateDeleteAllMethod(implClass, modelClassName, exampleClassName, mapperFieldName); - generateTrashByIdMethod(implClass, modelClassName, exampleClassName, mapperFieldName); - generateTrashAllMethod(implClass, modelClassName, exampleClassName, mapperFieldName); - generateRecoverByIdMethod(implClass, modelClassName, exampleClassName, mapperFieldName); - generateRecoverAllMethod(implClass, modelClassName, exampleClassName, mapperFieldName); + generateInsertMethod(implClass, introspectedTable, modelClassName, mapperFieldName); + generateBatchInsertMethod(implClass, introspectedTable, modelClassName, mapperFieldName); + generateUpdateMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName, hasBLOBColumns); + generateUpdateByExampleSelectiveMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName, hasBLOBColumns); + generateDeleteByIdMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName); + generateDeleteAllMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName); + generateTrashByIdMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName); + generateTrashAllMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName); + generateRecoverByIdMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName); + generateRecoverAllMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName); generateFindValidOneMethod(implClass, modelClassName, exampleClassName); generateFindTrashOneMethod(implClass, modelClassName, exampleClassName); - generateGetValidListMethod(implClass, modelClassName, exampleClassName, mapperFieldName, hasBLOBColumns); - generateGetTrashListMethod(implClass, modelClassName, exampleClassName, mapperFieldName, hasBLOBColumns); - generateCountByValidMethod(implClass, modelClassName, exampleClassName, mapperFieldName); + generateGetValidListMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName, hasBLOBColumns); + generateGetTrashListMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName, hasBLOBColumns); + generateCountByValidMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName); generateCountByValidWithPageMethod(implClass, modelClassName, exampleClassName, mapperFieldName); - generateCountByTrashMethod(implClass, modelClassName, exampleClassName, mapperFieldName); + generateCountByTrashMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName); generateCountByTrashWithPageMethod(implClass, modelClassName, exampleClassName, mapperFieldName); return implClass; @@ -469,9 +512,9 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { } } - private void addImportPackages(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperClassName, String interfaceName) { + private void addImportPackages(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperClassName, String interfaceName) { implClass.addImportedType(new FullyQualifiedJavaType(guidGeneratorClass)); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { implClass.addImportedType(new FullyQualifiedJavaType(changeLogContextClassPackage + "." + changeLogContextClassName)); } implClass.addImportedType(new FullyQualifiedJavaType(mapperPackage + "." + mapperClassName)); @@ -562,7 +605,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateInsertMethod(TopLevelClass implClass, String modelClassName, String mapperFieldName, IntrospectedTable introspectedTable) { + private void generateInsertMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String mapperFieldName) { Method method = new Method("insert"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -601,8 +644,8 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("int count = " + mapperFieldName + ".insert(aDo);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] insert " + modelClassName + " long time\" +"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] insert " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); @@ -613,7 +656,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("record.setDataVersion(aDo.getDataVersion());"); method.addBodyLine("record.setCreateTime(aDo.getCreateTime());"); method.addBodyLine("record.setUpdateTime(aDo.getUpdateTime());"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine(changeLogContextClassName + ".addLog(\"" + modelClassName + "\","); method.addBodyLine(" \"insert\", aDo.getGuid(), new HashMap<>());"); } @@ -623,7 +666,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateBatchInsertMethod(TopLevelClass implClass, String modelClassName, String mapperFieldName, IntrospectedTable introspectedTable) { + private void generateBatchInsertMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String mapperFieldName) { Method method = new Method("batchInsert"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -668,14 +711,14 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("int count = " + mapperFieldName + ".batchInsert(batch);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] batch insert " + modelClassName + " long time\" +"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] batch insert " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); method.addBodyLine("}"); method.addBodyLine("if (count == batch.size()) {"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("for (" + modelClassName + " aDo : batch) {"); method.addBodyLine(changeLogContextClassName + ".addLog(\"" + modelClassName + "\","); method.addBodyLine(" \"batchInsert\", aDo.getGuid(), new HashMap<>());"); @@ -688,8 +731,8 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateUpdateMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, - String mapperFieldName, IntrospectedTable introspectedTable, boolean hasBLOBColumns) { + private void generateUpdateMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, + String mapperFieldName, boolean hasBLOBColumns) { Method method = new Method("update"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -702,7 +745,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("if (aDo == null || aDo.getIsDelete() == 1) {"); method.addBodyLine("throw new Throwable(\"Record not found, " + modelClassName + " GUID:\" + record.getGuid());"); method.addBodyLine("}"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("Map changeDiff = new HashMap<>();"); } for (IntrospectedColumn column : introspectedTable.getAllColumns()) { @@ -715,7 +758,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { continue; } method.addBodyLine("if (record." + getterMethod + "() != null) {"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("if (!Objects.equals(record." + getterMethod + "(), aDo." + getterMethod + "())) {"); method.addBodyLine("changeDiff.put(\"" + fieldName + "\", new Object[]{aDo." + getterMethod + "(), record." + getterMethod + "()});"); method.addBodyLine("}"); @@ -724,7 +767,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("}"); } method.addBodyLine(exampleClassName + " updateWhere = new " + exampleClassName + "();"); - if (isOptimisticLockEnable()) { + if (isOptimisticLockEnable(introspectedTable)) { method.addBodyLine("Integer lockDataVersion = record.getDataVersion();"); method.addBodyLine("if (lockDataVersion == null) {"); method.addBodyLine("lockDataVersion = aDo.getDataVersion();"); @@ -746,13 +789,13 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { String updateMethod = hasBLOBColumns ? "updateByExampleWithBLOBs" : "updateByExample"; method.addBodyLine("int update = " + mapperFieldName + "." + updateMethod + "(aDo, updateWhere);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] update " + modelClassName + " long time\" +"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] update " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); method.addBodyLine("}"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("if (update > 0 && !changeDiff.isEmpty()) {"); method.addBodyLine(changeLogContextClassName + ".addLog(\"" + modelClassName + "\","); method.addBodyLine(" \"update\", aDo.getGuid(), changeDiff);"); @@ -762,8 +805,8 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateUpdateByExampleSelectiveMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, - String mapperFieldName, IntrospectedTable introspectedTable, boolean hasBLOBColumns) { + private void generateUpdateByExampleSelectiveMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, + String mapperFieldName, boolean hasBLOBColumns) { Method method = new Method("updateByExampleSelective"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -784,7 +827,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("}"); method.addBodyLine("example = new " + exampleClassName + "();"); method.addBodyLine("example.createCriteria().andGuidIn(guidList);"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { String selectByExampleMethod = hasBLOBColumns ? "selectByExampleWithBLOBs" : "selectByExample"; method.addBodyLine("List<" + modelClassName + "> recordList"); method.addBodyLine(" = " + mapperFieldName + "." + selectByExampleMethod + "(example);"); @@ -807,7 +850,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("diffGroup.put(aDo.getGuid(), changeDiff);"); method.addBodyLine("}"); } - if (isOptimisticLockEnable()) { + if (isOptimisticLockEnable(introspectedTable)) { method.addBodyLine("// reset data version, with optimistic locking"); method.addBodyLine("record.setDataVersion((int) (new Date().getTime() % 1000));"); } @@ -821,18 +864,18 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("int update = " + mapperFieldName + ".updateByExampleSelective(record, example);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); method.addBodyLine("String exampleString = \"\";"); method.addBodyLine("if (example.getWhereString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> where: \" + example.getWhereString();"); method.addBodyLine("}"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] updateByExampleSelective " + modelClassName + " long time\" +"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] updateByExampleSelective " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" exampleString +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); method.addBodyLine("}"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("if (update > 0) {"); method.addBodyLine("for (Map.Entry> diffEntry : diffGroup.entrySet()) {"); method.addBodyLine("if (diffEntry.getValue() != null && !diffEntry.getValue().isEmpty()) {"); @@ -846,7 +889,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateDeleteByIdMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) { + private void generateDeleteByIdMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName) { Method method = new Method("deleteById"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -863,8 +906,8 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("}"); method.addBodyLine(exampleClassName + " updateWhere"); method.addBodyLine(" = new " + exampleClassName + "();"); - method.addBodyLine("Integer lockDataVersion = aDo.getDataVersion();"); - if (isOptimisticLockEnable()) { + if (isOptimisticLockEnable(introspectedTable)) { + method.addBodyLine("Integer lockDataVersion = aDo.getDataVersion();"); method.addBodyLine("updateWhere.createCriteria()"); method.addBodyLine(" .andGuidEqualTo(aDo.getGuid())"); method.addBodyLine(" .andDataVersionEqualTo(lockDataVersion);"); @@ -879,13 +922,13 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("int update = " + mapperFieldName + ".updateByExampleSelective(aDo, updateWhere);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] deleteById " + modelClassName + " long time\" +"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] deleteById " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); method.addBodyLine("}"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("if (update > 0) {"); method.addBodyLine(changeLogContextClassName + ".addLog(\"" + modelClassName + "\","); method.addBodyLine(" \"deleteById\", aDo.getGuid(), new HashMap<>());"); @@ -895,7 +938,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateTrashByIdMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) { + private void generateTrashByIdMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName) { Method method = new Method("trashById"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -910,8 +953,8 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine(exampleClassName + " updateWhere"); method.addBodyLine(" = new " + exampleClassName + "();"); - method.addBodyLine("Integer lockDataVersion = aDo.getDataVersion();"); - if (isOptimisticLockEnable()) { + if (isOptimisticLockEnable(introspectedTable)) { + method.addBodyLine("Integer lockDataVersion = aDo.getDataVersion();"); method.addBodyLine("updateWhere.createCriteria()"); method.addBodyLine(" .andGuidEqualTo(aDo.getGuid())"); method.addBodyLine(" .andDataVersionEqualTo(lockDataVersion);"); @@ -927,13 +970,13 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("int update = " + mapperFieldName + ".updateByExampleSelective(aDo, updateWhere);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] trashById " + modelClassName + " long time\" +"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] trashById " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); method.addBodyLine("}"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("if (update > 0) {"); method.addBodyLine(changeLogContextClassName + ".addLog(\"" + modelClassName + "\","); method.addBodyLine(" \"trashById\", aDo.getGuid(), new HashMap<>());"); @@ -943,7 +986,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateRecoverByIdMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) { + private void generateRecoverByIdMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName) { Method method = new Method("recoverById"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -961,8 +1004,8 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine(exampleClassName + " updateWhere"); method.addBodyLine(" = new " + exampleClassName + "();"); - method.addBodyLine("Integer lockDataVersion = aDo.getDataVersion();"); - if (isOptimisticLockEnable()) { + if (isOptimisticLockEnable(introspectedTable)) { + method.addBodyLine("Integer lockDataVersion = aDo.getDataVersion();"); method.addBodyLine("updateWhere.createCriteria()"); method.addBodyLine(" .andGuidEqualTo(aDo.getGuid())"); method.addBodyLine(" .andDataVersionEqualTo(lockDataVersion);"); @@ -977,13 +1020,13 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("int update = " + mapperFieldName + ".updateByExampleSelective(aDo, updateWhere);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] recoverById " + modelClassName + " long time\" +"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] recoverById " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); method.addBodyLine("}"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("if (update > 0) {"); method.addBodyLine(changeLogContextClassName + ".addLog(\"" + modelClassName + "\","); method.addBodyLine(" \"recoverById\", aDo.getGuid(), new HashMap<>());"); @@ -993,7 +1036,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateDeleteAllMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) { + private void generateDeleteAllMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName) { Method method = new Method("deleteAll"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -1016,7 +1059,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("example = new " + exampleClassName + "();"); method.addBodyLine("example.createCriteria().andGuidIn(guidList);"); method.addBodyLine(modelClassName + " " + lowerFirst(modelClassName) + " = new " + modelClassName + "();"); - if (isOptimisticLockEnable()) { + if (isOptimisticLockEnable(introspectedTable)) { method.addBodyLine("// reset data version, with optimistic locking"); method.addBodyLine(lowerFirst(modelClassName) + ".setDataVersion((int) (new Date().getTime() % 1000));"); } @@ -1026,13 +1069,13 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("int update = " + mapperFieldName + ".updateByExampleSelective(" + lowerFirst(modelClassName) + ", example);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] deleteAll " + modelClassName + " long time\" +"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] deleteAll " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); method.addBodyLine("}"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("if (update > 0) {"); method.addBodyLine("for (Long guid : guidList) {"); method.addBodyLine(changeLogContextClassName + ".addLog(\"" + modelClassName + "\","); @@ -1044,7 +1087,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateTrashAllMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) { + private void generateTrashAllMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName) { Method method = new Method("trashAll"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -1063,7 +1106,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("example = new " + exampleClassName + "();"); method.addBodyLine("example.createCriteria().andGuidIn(guidList);"); method.addBodyLine(modelClassName + " " + lowerFirst(modelClassName) + " = new " + modelClassName + "();"); - if (isOptimisticLockEnable()) { + if (isOptimisticLockEnable(introspectedTable)) { method.addBodyLine("// reset data version, with optimistic locking"); method.addBodyLine(lowerFirst(modelClassName) + ".setDataVersion((int) (new Date().getTime() % 1000));"); } @@ -1074,13 +1117,13 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("int update = " + mapperFieldName + ".updateByExampleSelective(" + lowerFirst(modelClassName) + ", example);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] trashAll " + modelClassName + " long time\" +"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] trashAll " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); method.addBodyLine("}"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("if (update > 0) {"); method.addBodyLine("for (Long guid : guidList) {"); method.addBodyLine(changeLogContextClassName + ".addLog(\"" + modelClassName + "\","); @@ -1092,7 +1135,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateRecoverAllMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) { + private void generateRecoverAllMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName) { Method method = new Method("recoverAll"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -1111,7 +1154,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("example = new " + exampleClassName + "();"); method.addBodyLine("example.createCriteria().andGuidIn(guidList);"); method.addBodyLine(modelClassName + " " + lowerFirst(modelClassName) + " = new " + modelClassName + "();"); - if (isOptimisticLockEnable()) { + if (isOptimisticLockEnable(introspectedTable)) { method.addBodyLine("// reset data version, with optimistic locking"); method.addBodyLine(lowerFirst(modelClassName) + ".setDataVersion((int) (new Date().getTime() % 1000));"); } @@ -1122,13 +1165,13 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("int update = " + mapperFieldName + ".updateByExampleSelective(" + lowerFirst(modelClassName) + ", example);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] recoverAll " + modelClassName + " long time\" +"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] recoverAll " + modelClassName + " long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); method.addBodyLine(");"); method.addBodyLine("}"); - if (isChangeLogEnable()) { + if (isChangeLogEnable(introspectedTable)) { method.addBodyLine("if (update > 0) {"); method.addBodyLine("for (Long guid : guidList) {"); method.addBodyLine(changeLogContextClassName + ".addLog(\"" + modelClassName + "\","); @@ -1177,7 +1220,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateGetValidListMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, + private void generateGetValidListMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName, boolean hasBLOBColumns) { Method method = new Method("getValidList"); method.addAnnotation("@Override"); @@ -1198,7 +1241,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("return new ArrayList<>();"); method.addBodyLine("}"); method.addBodyLine("long findPrimaryKeyTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (findPrimaryKeyTime > " + slowQueryLoggerTime + ") {"); + method.addBodyLine("if (findPrimaryKeyTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); method.addBodyLine("String exampleString = \"\";"); method.addBodyLine("if (example.getWhereString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> where: \" + example.getWhereString();"); @@ -1209,7 +1252,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("if (example.getLimitString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> limit: \" + example.getLimitString();"); method.addBodyLine("}"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] select " + modelClassName + " valid list primary key long time\" +"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] select " + modelClassName + " valid list primary key long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + findPrimaryKeyTime + \"ms\" +"); method.addBodyLine(" exampleString +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); @@ -1233,7 +1276,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("result = " + mapperFieldName + ".selectByExample(example);"); } method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); method.addBodyLine("String exampleString = \"\";"); method.addBodyLine("if (example.getWhereString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> where: \" + example.getWhereString();"); @@ -1244,7 +1287,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("if (example.getLimitString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> limit: \" + example.getLimitString();"); method.addBodyLine("}"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] select " + modelClassName + " valid list long time\" +"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] select " + modelClassName + " valid list long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" exampleString +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); @@ -1254,7 +1297,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateGetTrashListMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, + private void generateGetTrashListMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName, boolean hasBLOBColumns) { Method method = new Method("getTrashList"); method.addAnnotation("@Override"); @@ -1275,7 +1318,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("return new ArrayList<>();"); method.addBodyLine("}"); method.addBodyLine("long findPrimaryKeyTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (findPrimaryKeyTime > " + slowQueryLoggerTime + ") {"); + method.addBodyLine("if (findPrimaryKeyTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); method.addBodyLine("String exampleString = \"\";"); method.addBodyLine("if (example.getWhereString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> where: \" + example.getWhereString();"); @@ -1286,7 +1329,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("if (example.getLimitString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> limit: \" + example.getLimitString();"); method.addBodyLine("}"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] select " + modelClassName + " trash list primary key long time\" +"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] select " + modelClassName + " trash list primary key long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + findPrimaryKeyTime + \"ms\" +"); method.addBodyLine(" exampleString +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); @@ -1310,7 +1353,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("result = " + mapperFieldName + ".selectByExample(example);"); } method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); method.addBodyLine("String exampleString = \"\";"); method.addBodyLine("if (example.getWhereString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> where: \" + example.getWhereString();"); @@ -1321,7 +1364,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("if (example.getLimitString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> limit: \" + example.getLimitString();"); method.addBodyLine("}"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] select " + modelClassName + " trash list long time\" +"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] select " + modelClassName + " trash list long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" exampleString +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); @@ -1331,7 +1374,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateCountByValidMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) { + private void generateCountByValidMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName) { Method method = new Method("countByValid"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -1345,7 +1388,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("long count = " + mapperFieldName + ".countByExample(example);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); method.addBodyLine("String exampleString = \"\";"); method.addBodyLine("if (example.getWhereString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> where: \" + example.getWhereString();"); @@ -1353,7 +1396,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("if (example.getOrderByClause() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> order by: \" + example.getOrderByClause();"); method.addBodyLine("}"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] select " + modelClassName + " valid count long time\" +"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] select " + modelClassName + " valid count long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" exampleString +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); @@ -1381,7 +1424,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { implClass.addMethod(method); } - private void generateCountByTrashMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) { + private void generateCountByTrashMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName) { Method method = new Method("countByTrash"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -1395,7 +1438,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("long count = " + mapperFieldName + ".countByExample(example);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); method.addBodyLine("String exampleString = \"\";"); method.addBodyLine("if (example.getWhereString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> where: \" + example.getWhereString();"); @@ -1403,7 +1446,7 @@ public class TapeRepositoryGeneratorPlugin extends PluginAdapter { method.addBodyLine("if (example.getOrderByClause() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> order by: \" + example.getOrderByClause();"); method.addBodyLine("}"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] select " + modelClassName + " trash count long time\" +"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] select " + modelClassName + " trash count long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" exampleString +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); diff --git a/src/main/java/com/iqudoo/framework/mybatis/TapeRepoviewGeneratorPlugin.java b/src/main/java/com/iqudoo/framework/mybatis/TapeRepoviewGeneratorPlugin.java index 8289424..e63abbe 100644 --- a/src/main/java/com/iqudoo/framework/mybatis/TapeRepoviewGeneratorPlugin.java +++ b/src/main/java/com/iqudoo/framework/mybatis/TapeRepoviewGeneratorPlugin.java @@ -9,6 +9,7 @@ import org.mybatis.generator.api.PluginAdapter; import org.mybatis.generator.api.dom.DefaultJavaFormatter; import org.mybatis.generator.api.dom.java.*; import org.mybatis.generator.config.Context; +import org.mybatis.generator.config.TableConfiguration; import org.mybatis.generator.internal.util.StringUtility; import java.io.File; @@ -71,6 +72,30 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { return defaultValue; } + public String getSlowQueryLoggerLevel(IntrospectedTable introspectedTable) { + try { + TableConfiguration tableConfiguration = introspectedTable.getTableConfiguration(); + String tableSlowQueryLoggerLevel = tableConfiguration.getProperty("slowQueryLoggerLevel"); + if (tableSlowQueryLoggerLevel != null && !tableSlowQueryLoggerLevel.isEmpty()) { + return tableSlowQueryLoggerLevel; + } + } catch (Throwable ignored) { + } + return slowQueryLoggerLevel; + } + + public String getSlowQueryLoggerTime(IntrospectedTable introspectedTable) { + try { + TableConfiguration tableConfiguration = introspectedTable.getTableConfiguration(); + String tableSlowQueryLoggerTime = tableConfiguration.getProperty("slowQueryLoggerTime"); + if (tableSlowQueryLoggerTime != null && !tableSlowQueryLoggerTime.isEmpty()) { + return tableSlowQueryLoggerTime; + } + } catch (Throwable ignored) { + } + return slowQueryLoggerTime; + } + /** * 核心方法:仅为视图表生成 RepoView 代码 */ @@ -102,6 +127,7 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { // 3. 生成视图Repo实现类 TopLevelClass repoImpl = generateRepoViewImpl( + introspectedTable, repoImplName, repoInterfaceName, domainObjectName, @@ -179,6 +205,7 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { * 生成视图Repo实现类(逻辑不变,仅适配新接口) */ private TopLevelClass generateRepoViewImpl( + IntrospectedTable introspectedTable, String implClassName, String interfaceName, String modelClassName, @@ -215,8 +242,8 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { implClass.addField(mapperField); generateFindOneMethod(implClass, modelClassName, exampleClassName); - generateGetListMethod(implClass, modelClassName, exampleClassName, mapperFieldName, hasBLOBColumns); - generateCountMethod(implClass, modelClassName, exampleClassName, mapperFieldName); + generateGetListMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName, hasBLOBColumns); + generateCountMethod(implClass, introspectedTable, modelClassName, exampleClassName, mapperFieldName); generateCountWithPageMethod(implClass, modelClassName, exampleClassName, mapperFieldName); return implClass; @@ -268,7 +295,7 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { /** * 生成getList方法 */ - private void generateGetListMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName, boolean hasBLOBColumns) { + private void generateGetListMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName, boolean hasBLOBColumns) { Method method = new Method("getList"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -288,7 +315,7 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { method.addBodyLine("result = " + mapperFieldName + ".selectByExample(example);"); } method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); method.addBodyLine("String exampleString = \"\";"); method.addBodyLine("if (example.getWhereString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> where: \" + example.getWhereString();"); @@ -299,7 +326,7 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { method.addBodyLine("if (example.getLimitString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> limit: \" + example.getLimitString();"); method.addBodyLine("}"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] select " + modelClassName + " view list long time\" +"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] select " + modelClassName + " view list long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" exampleString +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\""); @@ -312,7 +339,7 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { /** * 生成count方法 */ - private void generateCountMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) { + private void generateCountMethod(TopLevelClass implClass, IntrospectedTable introspectedTable, String modelClassName, String exampleClassName, String mapperFieldName) { Method method = new Method("count"); method.addAnnotation("@Override"); method.setVisibility(JavaVisibility.PUBLIC); @@ -325,7 +352,7 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { method.addBodyLine("long startTime = new Date().getTime();"); method.addBodyLine("long count = " + mapperFieldName + ".countByExample(example);"); method.addBodyLine("long useTime = new Date().getTime() - startTime;"); - method.addBodyLine("if (useTime > " + slowQueryLoggerTime + ") {"); + method.addBodyLine("if (useTime > " + getSlowQueryLoggerTime(introspectedTable) + ") {"); method.addBodyLine("String exampleString = \"\";"); method.addBodyLine("if (example.getWhereString() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> where: \" + example.getWhereString();"); @@ -333,7 +360,7 @@ public class TapeRepoviewGeneratorPlugin extends PluginAdapter { method.addBodyLine("if (example.getOrderByClause() != null) {"); method.addBodyLine("exampleString += \"\\n\\t|-> order by: \" + example.getOrderByClause();"); method.addBodyLine("}"); - method.addBodyLine("LOGGER." + slowQueryLoggerLevel + "(\"[SQL] select " + modelClassName + " view count long time\" +"); + method.addBodyLine("LOGGER." + getSlowQueryLoggerLevel(introspectedTable) + "(\"[SQL] select " + modelClassName + " view count long time\" +"); method.addBodyLine(" \"\\n\\t|-> use time:\" + useTime + \"ms\" +"); method.addBodyLine(" exampleString +"); method.addBodyLine(" \"\\n\\t|-----------------------------------\"");