init commit

This commit is contained in:
Jeremy Liang
2026-02-04 03:21:09 +08:00
commit ea0efee074
74 changed files with 9853 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
package com.iqudoo.framework.mybatis;
import com.iqudoo.framework.mybatis.abstracts.AbstractWithLimitPlugin;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
@SuppressWarnings("unused")
public class TapeMybatisGeneratorPlugin extends AbstractWithLimitPlugin {
// ============================================ selectPrimaryKeyByExample ==========================================
@Override
public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {
if (introspectedTable.getTargetRuntime() != IntrospectedTable.TargetRuntime.MYBATIS3) {
return true;
}
// 添加接口方法
if (introspectedTable.getPrimaryKeyColumns().size() <= 0) {
return true;
}
// 获取主键列类型
FullyQualifiedJavaType primaryType = introspectedTable.getPrimaryKeyColumns().get(0)
.getFullyQualifiedJavaType();
// 创建返回类型
FullyQualifiedJavaType returnType = FullyQualifiedJavaType.getNewListInstance();
returnType.addTypeArgument(primaryType);
// 创建参数类型
FullyQualifiedJavaType exampleType = new FullyQualifiedJavaType(introspectedTable.getExampleType());
// selectPrimaryKeyByExample(example)
Method method = new Method("selectPrimaryKeyByExample");
method.setAbstract(true);
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(returnType);
method.addParameter(new Parameter(exampleType, "example"));
interfaze.addMethod(method);
return super.clientGenerated(interfaze, introspectedTable);
}
@Override
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
if (introspectedTable.getTargetRuntime() != IntrospectedTable.TargetRuntime.MYBATIS3) {
return true;
}
if (introspectedTable.getPrimaryKeyColumns().size() <= 0) {
return true;
}
// 获取主键列名
String primaryKeyColumn = introspectedTable.getPrimaryKeyColumns().get(0)
.getActualColumnName();
// 获取主键列类型
String primaryKeyType = introspectedTable.getPrimaryKeyColumns().get(0)
.getFullyQualifiedJavaType().getFullyQualifiedName();
// 获取对应的 Example 类名
String exampleType = introspectedTable.getExampleType();
// 创建 selectPrimaryKeyByExample 元素
XmlElement selectPrimaryKeyByExample = new XmlElement("select");
selectPrimaryKeyByExample.addAttribute(new Attribute("id", "selectPrimaryKeyByExample"));
selectPrimaryKeyByExample.addAttribute(new Attribute("parameterType", exampleType));
selectPrimaryKeyByExample.addAttribute(new Attribute("resultType", primaryKeyType));
// 添加selectPrimaryKeyByExample语句
String selectPrimaryKeyByExampleSql = "select\n" +
" <if test=\"distinct\">\n" +
" distinct\n" +
" </if>\n" +
" " + primaryKeyColumn + " from " + introspectedTable.getFullyQualifiedTableNameAtRuntime() + "\n" +
" <if test=\"_parameter != null\"> \n" +
" <include refid=\"Example_Where_Clause\"/>\n" +
" </if>\n" +
" <if test=\"orderByClause != null\">\n" +
" order by ${orderByClause}\n" +
" </if>";
selectPrimaryKeyByExample.addElement(new TextElement(selectPrimaryKeyByExampleSql));
// with limit
generateLimitElement(selectPrimaryKeyByExample);
// 将 select 元素添加到 mapper.xml 中
document.getRootElement().addElement(selectPrimaryKeyByExample);
return super.sqlMapDocumentGenerated(document, introspectedTable);
}
}

View File

@@ -0,0 +1,870 @@
package com.iqudoo.framework.mybatis;
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.internal.util.StringUtility;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
* MyBatis Generator 1.4.1
*/
@SuppressWarnings({"DuplicatedCode", "unused"})
public class TapeRepositoryGeneratorPlugin extends PluginAdapter {
// 固定配置项
private String facadeRepositoryPackage = "com.iqudoo.platform.application.facade.repository";
private String domainRepositoryPackage = "com.iqudoo.platform.application.domain.repository";
private String modelPackage = "com.iqudoo.platform.application.database.model";
private String mapperPackage = "com.iqudoo.platform.application.database.mapper";
private String targetProject = "src/main/java";
private String viewKeyWords = "VIEW_,V_";
// 1.4.1版本专用Java格式化器
private JavaFormatter javaFormatter;
@Override
public void setContext(Context context) {
super.setContext(context);
this.javaFormatter = new DefaultJavaFormatter();
this.javaFormatter.setContext(context);
}
@Override
public boolean validate(List<String> warnings) {
return true;
}
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
// 读取自定义配置
if (StringUtility.stringHasValue(properties.getProperty("facadeRepositoryPackage"))) {
facadeRepositoryPackage = properties.getProperty("facadeRepositoryPackage");
}
if (StringUtility.stringHasValue(properties.getProperty("domainRepositoryPackage"))) {
domainRepositoryPackage = properties.getProperty("domainRepositoryPackage");
}
if (StringUtility.stringHasValue(properties.getProperty("modelPackage"))) {
modelPackage = properties.getProperty("modelPackage");
}
if (StringUtility.stringHasValue(properties.getProperty("mapperPackage"))) {
mapperPackage = properties.getProperty("mapperPackage");
}
if (StringUtility.stringHasValue(properties.getProperty("targetProject"))) {
targetProject = properties.getProperty("targetProject");
}
if (StringUtility.stringHasValue(properties.getProperty("viewKeyWords"))) {
viewKeyWords = properties.getProperty("viewKeyWords").toUpperCase();
}
}
/**
* 核心方法:视图表过滤 + 生成完整Repository代码
*/
@Override
public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
List<GeneratedJavaFile> generatedJavaFiles = new ArrayList<>();
// 视图表过滤逻辑
String tableName = introspectedTable.getFullyQualifiedTable().getIntrospectedTableName().toUpperCase();
if (isViewTable(tableName)) {
return generatedJavaFiles;
}
// 非视图表,正常生成
String domainObjectName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
String exampleClassName = domainObjectName + "Example";
String mapperClassName = domainObjectName + "Mapper";
String repositoryInterfaceName = "I" + domainObjectName + "Repository";
String repositoryImplName = domainObjectName + "RepositoryImpl";
boolean hasBLOBColumns = hasBLOBColumns(introspectedTable);
// 生成Repository接口核心修改手动添加所有方法不再继承父接口
Interface repositoryInterface = generateRepositoryInterface(repositoryInterfaceName, domainObjectName, exampleClassName);
GeneratedJavaFile interfaceFile = new GeneratedJavaFile(
repositoryInterface,
targetProject,
"UTF-8",
javaFormatter
);
generatedJavaFiles.add(interfaceFile);
// 生成Repository实现类逻辑不变
TopLevelClass repositoryImpl = generateRepositoryImpl(
repositoryImplName,
repositoryInterfaceName,
domainObjectName,
exampleClassName,
mapperClassName,
introspectedTable,
hasBLOBColumns
);
GeneratedJavaFile implFile = new GeneratedJavaFile(
repositoryImpl,
targetProject,
"UTF-8",
javaFormatter
);
generatedJavaFiles.add(implFile);
// 手动写入磁盘
generateJavaFileToDisk(repositoryInterface, facadeRepositoryPackage);
generateJavaFileToDisk(repositoryImpl, domainRepositoryPackage);
return generatedJavaFiles;
}
/**
* 判断是否为视图表(支持多关键字匹配)
*/
private boolean isViewTable(String tableName) {
if (StringUtility.stringHasValue(viewKeyWords)) {
String[] keywords = viewKeyWords.split(",");
for (String keyword : keywords) {
if (tableName.contains(keyword.trim().toUpperCase())) {
return true;
}
}
}
return false;
}
/**
* 核心修改生成Repository接口手动添加所有方法无继承匹配指定格式
*/
private Interface generateRepositoryInterface(String interfaceName, String modelClassName, String exampleClassName) {
Interface repositoryInterface = new Interface(facadeRepositoryPackage + "." + interfaceName);
repositoryInterface.setVisibility(JavaVisibility.PUBLIC);
// 添加必要的导入仅保留model和example移除ModelDataRepository
repositoryInterface.addImportedType(new FullyQualifiedJavaType(modelPackage + "." + modelClassName));
repositoryInterface.addImportedType(new FullyQualifiedJavaType(modelPackage + "." + exampleClassName));
repositoryInterface.addImportedType(new FullyQualifiedJavaType("java.util.List"));
// 定义方法参数名(首字母小写)
String exampleParamName = lowerFirst(exampleClassName);
// 1. trashById
Method trashByIdMethod = new Method("trashById");
trashByIdMethod.setVisibility(JavaVisibility.PUBLIC);
trashByIdMethod.setReturnType(new FullyQualifiedJavaType("int"));
trashByIdMethod.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
trashByIdMethod.addException(new FullyQualifiedJavaType("Throwable"));
trashByIdMethod.setAbstract(true);
repositoryInterface.addMethod(trashByIdMethod);
// 2. trashAll
Method trashAllMethod = new Method("trashAll");
trashAllMethod.setVisibility(JavaVisibility.PUBLIC);
trashAllMethod.setReturnType(new FullyQualifiedJavaType("int"));
trashAllMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
trashAllMethod.addException(new FullyQualifiedJavaType("Throwable"));
trashAllMethod.setAbstract(true);
repositoryInterface.addMethod(trashAllMethod);
// 3. deleteById
Method deleteByIdMethod = new Method("deleteById");
deleteByIdMethod.setVisibility(JavaVisibility.PUBLIC);
deleteByIdMethod.setReturnType(new FullyQualifiedJavaType("int"));
deleteByIdMethod.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
deleteByIdMethod.addParameter(new Parameter(new FullyQualifiedJavaType("boolean"), "release"));
deleteByIdMethod.addException(new FullyQualifiedJavaType("Throwable"));
deleteByIdMethod.setAbstract(true);
repositoryInterface.addMethod(deleteByIdMethod);
// 4. deleteAll
Method deleteAllMethod = new Method("deleteAll");
deleteAllMethod.setVisibility(JavaVisibility.PUBLIC);
deleteAllMethod.setReturnType(new FullyQualifiedJavaType("int"));
deleteAllMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
deleteAllMethod.addParameter(new Parameter(new FullyQualifiedJavaType("boolean"), "release"));
deleteAllMethod.addException(new FullyQualifiedJavaType("Throwable"));
deleteAllMethod.setAbstract(true);
repositoryInterface.addMethod(deleteAllMethod);
// 5. recoverById
Method recoverByIdMethod = new Method("recoverById");
recoverByIdMethod.setVisibility(JavaVisibility.PUBLIC);
recoverByIdMethod.setReturnType(new FullyQualifiedJavaType("int"));
recoverByIdMethod.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
recoverByIdMethod.addException(new FullyQualifiedJavaType("Throwable"));
recoverByIdMethod.setAbstract(true);
repositoryInterface.addMethod(recoverByIdMethod);
// 6. recoverAll
Method recoverAllMethod = new Method("recoverAll");
recoverAllMethod.setVisibility(JavaVisibility.PUBLIC);
recoverAllMethod.setReturnType(new FullyQualifiedJavaType("int"));
recoverAllMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
recoverAllMethod.addException(new FullyQualifiedJavaType("Throwable"));
recoverAllMethod.setAbstract(true);
repositoryInterface.addMethod(recoverAllMethod);
// 7. findNoWhereById
Method findNoWhereByIdMethod = new Method("findNoWhereById");
findNoWhereByIdMethod.setVisibility(JavaVisibility.PUBLIC);
findNoWhereByIdMethod.setReturnType(new FullyQualifiedJavaType(modelClassName));
findNoWhereByIdMethod.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
findNoWhereByIdMethod.addException(new FullyQualifiedJavaType("Throwable"));
findNoWhereByIdMethod.setAbstract(true);
repositoryInterface.addMethod(findNoWhereByIdMethod);
// 8. findValidById
Method findValidByIdMethod = new Method("findValidById");
findValidByIdMethod.setVisibility(JavaVisibility.PUBLIC);
findValidByIdMethod.setReturnType(new FullyQualifiedJavaType(modelClassName));
findValidByIdMethod.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
findValidByIdMethod.addException(new FullyQualifiedJavaType("Throwable"));
findValidByIdMethod.setAbstract(true);
repositoryInterface.addMethod(findValidByIdMethod);
// 9. findTrashById
Method findTrashByIdMethod = new Method("findTrashById");
findTrashByIdMethod.setVisibility(JavaVisibility.PUBLIC);
findTrashByIdMethod.setReturnType(new FullyQualifiedJavaType(modelClassName));
findTrashByIdMethod.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
findTrashByIdMethod.addException(new FullyQualifiedJavaType("Throwable"));
findTrashByIdMethod.setAbstract(true);
repositoryInterface.addMethod(findTrashByIdMethod);
// 10. findValidOne
Method findValidOneMethod = new Method("findValidOne");
findValidOneMethod.setVisibility(JavaVisibility.PUBLIC);
findValidOneMethod.setReturnType(new FullyQualifiedJavaType(modelClassName));
findValidOneMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
findValidOneMethod.addException(new FullyQualifiedJavaType("Throwable"));
findValidOneMethod.setAbstract(true);
repositoryInterface.addMethod(findValidOneMethod);
// 11. findTrashOne
Method findTrashOneMethod = new Method("findTrashOne");
findTrashOneMethod.setVisibility(JavaVisibility.PUBLIC);
findTrashOneMethod.setReturnType(new FullyQualifiedJavaType(modelClassName));
findTrashOneMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
findTrashOneMethod.addException(new FullyQualifiedJavaType("Throwable"));
findTrashOneMethod.setAbstract(true);
repositoryInterface.addMethod(findTrashOneMethod);
// 12. getValidList
Method getValidListMethod = new Method("getValidList");
getValidListMethod.setVisibility(JavaVisibility.PUBLIC);
getValidListMethod.setReturnType(new FullyQualifiedJavaType("List<" + modelClassName + ">"));
getValidListMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
getValidListMethod.addException(new FullyQualifiedJavaType("Throwable"));
getValidListMethod.setAbstract(true);
repositoryInterface.addMethod(getValidListMethod);
// 13. getTrashList
Method getTrashListMethod = new Method("getTrashList");
getTrashListMethod.setVisibility(JavaVisibility.PUBLIC);
getTrashListMethod.setReturnType(new FullyQualifiedJavaType("List<" + modelClassName + ">"));
getTrashListMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
getTrashListMethod.addException(new FullyQualifiedJavaType("Throwable"));
getTrashListMethod.setAbstract(true);
repositoryInterface.addMethod(getTrashListMethod);
// 14. countByValid
Method countByValidMethod = new Method("countByValid");
countByValidMethod.setVisibility(JavaVisibility.PUBLIC);
countByValidMethod.setReturnType(new FullyQualifiedJavaType("long"));
countByValidMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
countByValidMethod.addException(new FullyQualifiedJavaType("Throwable"));
countByValidMethod.setAbstract(true);
repositoryInterface.addMethod(countByValidMethod);
// 15. countByTrash
Method countByTrashMethod = new Method("countByTrash");
countByTrashMethod.setVisibility(JavaVisibility.PUBLIC);
countByTrashMethod.setReturnType(new FullyQualifiedJavaType("long"));
countByTrashMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
countByTrashMethod.addException(new FullyQualifiedJavaType("Throwable"));
countByTrashMethod.setAbstract(true);
repositoryInterface.addMethod(countByTrashMethod);
// 16. insert
Method insertMethod = new Method("insert");
insertMethod.setVisibility(JavaVisibility.PUBLIC);
insertMethod.setReturnType(new FullyQualifiedJavaType(modelClassName));
insertMethod.addParameter(new Parameter(new FullyQualifiedJavaType(modelClassName), "record"));
insertMethod.addException(new FullyQualifiedJavaType("Throwable"));
insertMethod.setAbstract(true);
repositoryInterface.addMethod(insertMethod);
// 17. update
Method updateMethod = new Method("update");
updateMethod.setVisibility(JavaVisibility.PUBLIC);
updateMethod.setReturnType(new FullyQualifiedJavaType("int"));
updateMethod.addParameter(new Parameter(new FullyQualifiedJavaType(modelClassName), "record"));
updateMethod.addException(new FullyQualifiedJavaType("Throwable"));
updateMethod.setAbstract(true);
repositoryInterface.addMethod(updateMethod);
return repositoryInterface;
}
/**
* 生成Repository实现类逻辑无修改
*/
private TopLevelClass generateRepositoryImpl(
String implClassName,
String interfaceName,
String modelClassName,
String exampleClassName,
String mapperClassName,
IntrospectedTable introspectedTable,
boolean hasBLOBColumns) {
TopLevelClass implClass = new TopLevelClass(domainRepositoryPackage + "." + implClassName);
implClass.setVisibility(JavaVisibility.PUBLIC);
implClass.addAnnotation("@SuppressWarnings(\"DuplicatedCode\")");
implClass.addAnnotation("@Repository");
addImportPackages(implClass, modelClassName, exampleClassName, mapperClassName, interfaceName);
FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(facadeRepositoryPackage + "." + interfaceName);
implClass.addSuperInterface(superInterface);
// 修复Logger字段添加static final修饰符
Field loggerField = new Field("LOGGER", new FullyQualifiedJavaType("org.slf4j.Logger"));
loggerField.setVisibility(JavaVisibility.PRIVATE);
loggerField.setStatic(true);
loggerField.setFinal(true);
loggerField.setInitializationString("Tape.getLogger(" + implClassName + ".class)");
implClass.addField(loggerField);
String mapperFieldName = lowerFirst(mapperClassName);
Field mapperField = new Field(mapperFieldName, new FullyQualifiedJavaType(mapperPackage + "." + mapperClassName));
mapperField.setVisibility(JavaVisibility.PRIVATE);
mapperField.addAnnotation("@Resource");
implClass.addField(mapperField);
// 原有方法生成逻辑(无修改)
generateFindNoWhereByIdMethod(implClass, modelClassName, exampleClassName);
generateFindValidByIdMethod(implClass, modelClassName, exampleClassName);
generateFindTrashByIdMethod(implClass, modelClassName, exampleClassName);
generateInsertMethod(implClass, modelClassName, mapperFieldName, introspectedTable);
generateUpdateMethod(implClass, modelClassName, exampleClassName, mapperFieldName, introspectedTable, hasBLOBColumns);
generateDeleteByIdMethod(implClass, modelClassName, mapperFieldName);
generateDeleteAllMethod(implClass, modelClassName, exampleClassName, mapperFieldName);
generateTrashByIdMethod(implClass, modelClassName, mapperFieldName);
generateTrashAllMethod(implClass, modelClassName, exampleClassName, mapperFieldName);
generateRecoverByIdMethod(implClass, modelClassName, mapperFieldName);
generateRecoverAllMethod(implClass, 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, exampleClassName, mapperFieldName);
generateCountByTrashMethod(implClass, exampleClassName, mapperFieldName);
return implClass;
}
// ------------------------ 所有原有方法(无修改) ------------------------
private void generateDeleteAllMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) {
Method method = new Method("deleteAll");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("int"));
String exampleParamName = lowerFirst(exampleClassName);
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
method.addParameter(new Parameter(new FullyQualifiedJavaType("boolean"), "release"));
method.addException(new FullyQualifiedJavaType("Throwable"));
// 方法体
method.addBodyLine("if (release) {");
method.addBodyLine(" return " + mapperFieldName + ".deleteByExample(" + exampleParamName + ");");
method.addBodyLine("}");
method.addBodyLine("for (" + exampleClassName + ".Criteria criteria : " + exampleParamName + ".getOredCriteria()) {");
method.addBodyLine(" criteria.andIsDeleteEqualTo(DatabaseCommonDataIsDeleteEnum.NONE.getValue());");
method.addBodyLine("}");
method.addBodyLine(modelClassName + " " + lowerFirst(modelClassName) + " = new " + modelClassName + "();");
method.addBodyLine(lowerFirst(modelClassName) + ".setIsDelete(DatabaseCommonDataIsDeleteEnum.DELETED.getValue());");
method.addBodyLine(lowerFirst(modelClassName) + ".setUpdateTime(new Date());");
method.addBodyLine("return " + mapperFieldName + ".updateByExampleSelective(" + lowerFirst(modelClassName) + ", " + exampleParamName + ");");
implClass.addMethod(method);
}
private void generateTrashAllMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) {
Method method = new Method("trashAll");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("int"));
String exampleParamName = lowerFirst(exampleClassName);
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
method.addException(new FullyQualifiedJavaType("Throwable"));
// 方法体
method.addBodyLine("for (" + exampleClassName + ".Criteria criteria : " + exampleParamName + ".getOredCriteria()) {");
method.addBodyLine(" criteria.andIsDeleteEqualTo(DatabaseCommonDataIsDeleteEnum.NONE.getValue());");
method.addBodyLine(" criteria.andIsHiddenEqualTo(DatabaseCommonDataIsHiddenEnum.NONE.getValue());");
method.addBodyLine("}");
method.addBodyLine(modelClassName + " " + lowerFirst(modelClassName) + " = new " + modelClassName + "();");
method.addBodyLine(lowerFirst(modelClassName) + ".setIsHidden(DatabaseCommonDataIsHiddenEnum.HIDDEN.getValue());");
method.addBodyLine(lowerFirst(modelClassName) + ".setDeleteToken(" + lowerFirst(modelClassName) + ".getGuid() + \"\");");
method.addBodyLine(lowerFirst(modelClassName) + ".setUpdateTime(new Date());");
method.addBodyLine("return " + mapperFieldName + ".updateByExampleSelective(" + lowerFirst(modelClassName) + ", " + exampleParamName + ");");
implClass.addMethod(method);
}
private void generateRecoverAllMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) {
Method method = new Method("recoverAll");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("int"));
String exampleParamName = lowerFirst(exampleClassName);
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
method.addException(new FullyQualifiedJavaType("Throwable"));
// 方法体
method.addBodyLine("for (" + exampleClassName + ".Criteria criteria : " + exampleParamName + ".getOredCriteria()) {");
method.addBodyLine(" criteria.andIsDeleteEqualTo(DatabaseCommonDataIsDeleteEnum.NONE.getValue());");
method.addBodyLine(" criteria.andIsHiddenEqualTo(DatabaseCommonDataIsHiddenEnum.HIDDEN.getValue());");
method.addBodyLine("}");
method.addBodyLine(modelClassName + " " + lowerFirst(modelClassName) + " = new " + modelClassName + "();");
method.addBodyLine(lowerFirst(modelClassName) + ".setIsHidden(DatabaseCommonDataIsHiddenEnum.NONE.getValue());");
method.addBodyLine(lowerFirst(modelClassName) + ".setDeleteToken(\"VALID\");");
method.addBodyLine(lowerFirst(modelClassName) + ".setUpdateTime(new Date());");
method.addBodyLine("return " + mapperFieldName + ".updateByExampleSelective(" + lowerFirst(modelClassName) + ", " + exampleParamName + ");");
implClass.addMethod(method);
}
private void generateJavaFileToDisk(Interface intf, String packageName) {
try {
String packagePath = packageName.replace('.', File.separatorChar);
File targetDir = new File(targetProject, packagePath);
if (!targetDir.exists()) {
boolean mkdirs = targetDir.mkdirs();
if (!mkdirs) {
throw new RuntimeException("创建目录失败:" + targetDir.getAbsolutePath());
}
}
String className = intf.getType().getShortName();
File javaFile = new File(targetDir, className + ".java");
String content = javaFormatter.getFormattedContent(intf);
java.nio.file.Files.write(javaFile.toPath(), content.getBytes(StandardCharsets.UTF_8));
System.out.println("成功生成接口文件:" + javaFile.getAbsolutePath());
} catch (Exception e) {
throw new RuntimeException("生成Repository接口失败" + intf.getType().getShortName(), e);
}
}
private void generateJavaFileToDisk(TopLevelClass clazz, String packageName) {
try {
String packagePath = packageName.replace('.', File.separatorChar);
File targetDir = new File(targetProject, packagePath);
if (!targetDir.exists()) {
boolean mkdirs = targetDir.mkdirs();
if (!mkdirs) {
throw new RuntimeException("创建目录失败:" + targetDir.getAbsolutePath());
}
}
String className = clazz.getType().getShortName();
File javaFile = new File(targetDir, className + ".java");
String content = javaFormatter.getFormattedContent(clazz);
java.nio.file.Files.write(javaFile.toPath(), content.getBytes(StandardCharsets.UTF_8));
System.out.println("成功生成实现类文件:" + javaFile.getAbsolutePath());
} catch (Exception e) {
throw new RuntimeException("生成Repository实现类失败" + clazz.getType().getShortName(), e);
}
}
private boolean hasBLOBColumns(IntrospectedTable introspectedTable) {
for (IntrospectedColumn column : introspectedTable.getAllColumns()) {
if (column.isBLOBColumn()) {
return true;
}
}
return false;
}
private void addImportPackages(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperClassName, String interfaceName) {
implClass.addImportedType(new FullyQualifiedJavaType("com.iqudoo.framework.tape.Tape"));
implClass.addImportedType(new FullyQualifiedJavaType("com.iqudoo.framework.tape.modules.utils.SnowflakeUtil"));
implClass.addImportedType(new FullyQualifiedJavaType("com.iqudoo.framework.tape.modules.crud.DatabaseCommonDataIsDeleteEnum"));
implClass.addImportedType(new FullyQualifiedJavaType("com.iqudoo.framework.tape.modules.crud.DatabaseCommonDataIsHiddenEnum"));
implClass.addImportedType(new FullyQualifiedJavaType("com.iqudoo.framework.tape.modules.crud.DatabaseErrorConstants"));
implClass.addImportedType(new FullyQualifiedJavaType(mapperPackage + "." + mapperClassName));
implClass.addImportedType(new FullyQualifiedJavaType(modelPackage + "." + modelClassName));
implClass.addImportedType(new FullyQualifiedJavaType(modelPackage + "." + exampleClassName));
implClass.addImportedType(new FullyQualifiedJavaType(facadeRepositoryPackage + "." + interfaceName));
implClass.addImportedType(new FullyQualifiedJavaType("org.slf4j.Logger"));
implClass.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Repository"));
implClass.addImportedType(new FullyQualifiedJavaType("javax.annotation.Resource"));
implClass.addImportedType(new FullyQualifiedJavaType("java.util.ArrayList"));
implClass.addImportedType(new FullyQualifiedJavaType("java.util.Date"));
implClass.addImportedType(new FullyQualifiedJavaType("java.util.List"));
}
private void generateFindNoWhereByIdMethod(TopLevelClass implClass, String modelClassName, String exampleClassName) {
Method method = new Method("findNoWhereById");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType(modelClassName));
method.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(modelClassName + " aDo = findValidById(id);");
method.addBodyLine("if (aDo == null) {");
method.addBodyLine(" aDo = findTrashById(id);");
method.addBodyLine("}");
method.addBodyLine("return aDo;");
implClass.addMethod(method);
}
private void generateFindValidByIdMethod(TopLevelClass implClass, String modelClassName, String exampleClassName) {
Method method = new Method("findValidById");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType(modelClassName));
method.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(exampleClassName + " doExample = new " + exampleClassName + "();");
method.addBodyLine("doExample.createCriteria().andGuidEqualTo(id);");
method.addBodyLine("return findValidOne(doExample);");
implClass.addMethod(method);
}
private void generateFindTrashByIdMethod(TopLevelClass implClass, String modelClassName, String exampleClassName) {
Method method = new Method("findTrashById");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType(modelClassName));
method.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(exampleClassName + " doExample = new " + exampleClassName + "();");
method.addBodyLine("doExample.createCriteria().andGuidEqualTo(id);");
method.addBodyLine("return findTrashOne(doExample);");
implClass.addMethod(method);
}
private void generateInsertMethod(TopLevelClass implClass, String modelClassName, String mapperFieldName, IntrospectedTable introspectedTable) {
Method method = new Method("insert");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType(modelClassName));
method.addParameter(new Parameter(new FullyQualifiedJavaType(modelClassName), "record"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(modelClassName + " aDo = new " + modelClassName + "();");
method.addBodyLine("if (record.getGuid() != null) {");
method.addBodyLine(" aDo.setGuid(record.getGuid());");
method.addBodyLine("} else {");
method.addBodyLine(" Long guid = SnowflakeUtil.nextId();");
method.addBodyLine(" aDo.setGuid(guid);");
method.addBodyLine("}");
for (IntrospectedColumn column : introspectedTable.getAllColumns()) {
String fieldName = column.getJavaProperty();
String setterMethod = "set" + upperFirst(fieldName);
String getterMethod = "get" + upperFirst(fieldName);
if ("guid".equals(fieldName) || "isDelete".equals(fieldName) || "isHidden".equals(fieldName)
|| "deleteToken".equals(fieldName) || "dataVersion".equals(fieldName)
|| "createTime".equals(fieldName) || "updateTime".equals(fieldName)) {
continue;
}
method.addBodyLine("aDo." + setterMethod + "(record." + getterMethod + "());");
}
method.addBodyLine("aDo.setIsDelete(DatabaseCommonDataIsDeleteEnum.NONE.getValue());");
method.addBodyLine("aDo.setIsHidden(DatabaseCommonDataIsHiddenEnum.NONE.getValue());");
method.addBodyLine("aDo.setDeleteToken(\"VALID\");");
method.addBodyLine("aDo.setDataVersion(1);");
method.addBodyLine("aDo.setCreateTime(new Date());");
method.addBodyLine("aDo.setUpdateTime(new Date());");
method.addBodyLine("int count = " + mapperFieldName + ".insert(aDo);");
method.addBodyLine("if (count > 0) {");
method.addBodyLine(" return aDo;");
method.addBodyLine("}");
method.addBodyLine("// 更新当前数据版本号和GUID");
method.addBodyLine("record.setGuid(aDo.getGuid());");
method.addBodyLine("record.setDataVersion(aDo.getDataVersion());");
method.addBodyLine("record.setCreateTime(aDo.getCreateTime());");
method.addBodyLine("record.setUpdateTime(aDo.getUpdateTime());");
method.addBodyLine("LOGGER.error(\"Database write failed, " + modelClassName + ": {}\", aDo);");
method.addBodyLine("throw DatabaseErrorConstants.DATABASE_WRITE_ERROR;");
implClass.addMethod(method);
}
private void generateUpdateMethod(TopLevelClass implClass, String modelClassName, String exampleClassName,
String mapperFieldName, IntrospectedTable introspectedTable, boolean hasBLOBColumns) {
Method method = new Method("update");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("int"));
method.addParameter(new Parameter(new FullyQualifiedJavaType(modelClassName), "record"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(modelClassName + " aDo = findValidById(record.getGuid());");
method.addBodyLine("if (aDo == null) {");
method.addBodyLine(" throw DatabaseErrorConstants.DATABASE_RECORD_NOT_FOUND;");
method.addBodyLine("}");
for (IntrospectedColumn column : introspectedTable.getAllColumns()) {
String fieldName = column.getJavaProperty();
String setterMethod = "set" + upperFirst(fieldName);
String getterMethod = "get" + upperFirst(fieldName);
if ("guid".equals(fieldName) || "isDelete".equals(fieldName) || "isHidden".equals(fieldName)
|| "deleteToken".equals(fieldName) || "dataVersion".equals(fieldName)
|| "createTime".equals(fieldName) || "updateTime".equals(fieldName)) {
continue;
}
method.addBodyLine("if (record." + getterMethod + "() != null) {");
method.addBodyLine(" aDo." + setterMethod + "(record." + getterMethod + "());");
method.addBodyLine("}");
}
method.addBodyLine(exampleClassName + " updateWhere = new " + exampleClassName + "();");
method.addBodyLine("Integer lockDataVersion = record.getDataVersion();");
method.addBodyLine("if (lockDataVersion == null) {");
method.addBodyLine(" lockDataVersion = aDo.getDataVersion();");
method.addBodyLine("}");
method.addBodyLine("updateWhere.createCriteria()");
method.addBodyLine(" .andGuidEqualTo(aDo.getGuid())");
method.addBodyLine(" .andDataVersionEqualTo(lockDataVersion);");
method.addBodyLine("aDo.setDataVersion(aDo.getDataVersion() + 1);");
method.addBodyLine("aDo.setUpdateTime(new Date());");
method.addBodyLine("// 更新当前数据版本号");
method.addBodyLine("record.setDataVersion(aDo.getDataVersion());");
method.addBodyLine("record.setUpdateTime(aDo.getUpdateTime());");
String updateMethod = hasBLOBColumns ? "updateByExampleWithBLOBs" : "updateByExample";
method.addBodyLine("return " + mapperFieldName + "." + updateMethod + "(aDo, updateWhere);");
implClass.addMethod(method);
}
private void generateDeleteByIdMethod(TopLevelClass implClass, String modelClassName, String mapperFieldName) {
Method method = new Method("deleteById");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("int"));
method.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
method.addParameter(new Parameter(new FullyQualifiedJavaType("boolean"), "release"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(modelClassName + " aDo = findValidById(id);");
method.addBodyLine("if (aDo == null) {");
method.addBodyLine(" return 0;");
method.addBodyLine("}");
method.addBodyLine("if (release) {");
method.addBodyLine(" return " + mapperFieldName + ".deleteByPrimaryKey(aDo.getGuid());");
method.addBodyLine("}");
method.addBodyLine("aDo.setIsDelete(DatabaseCommonDataIsDeleteEnum.DELETED.getValue());");
method.addBodyLine("aDo.setUpdateTime(new Date());");
method.addBodyLine("return " + mapperFieldName + ".updateByPrimaryKey(aDo);");
implClass.addMethod(method);
}
private void generateTrashByIdMethod(TopLevelClass implClass, String modelClassName, String mapperFieldName) {
Method method = new Method("trashById");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("int"));
method.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(modelClassName + " aDo = findValidById(id);");
method.addBodyLine("if (aDo == null) {");
method.addBodyLine(" return 0;");
method.addBodyLine("}");
method.addBodyLine("aDo.setIsHidden(DatabaseCommonDataIsHiddenEnum.HIDDEN.getValue());");
method.addBodyLine("aDo.setDeleteToken(aDo.getGuid() + \"\");");
method.addBodyLine("aDo.setUpdateTime(new Date());");
method.addBodyLine("return " + mapperFieldName + ".updateByPrimaryKey(aDo);");
implClass.addMethod(method);
}
private void generateRecoverByIdMethod(TopLevelClass implClass, String modelClassName, String mapperFieldName) {
Method method = new Method("recoverById");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("int"));
method.addParameter(new Parameter(new FullyQualifiedJavaType("long"), "id"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(modelClassName + " aDo = findTrashById(id);");
method.addBodyLine("if (aDo == null) {");
method.addBodyLine(" return 0;");
method.addBodyLine("}");
method.addBodyLine("if (aDo.getIsDelete() == DatabaseCommonDataIsDeleteEnum.DELETED.getValue()) {");
method.addBodyLine(" return 0;");
method.addBodyLine("}");
method.addBodyLine("aDo.setIsHidden(DatabaseCommonDataIsHiddenEnum.NONE.getValue());");
method.addBodyLine("aDo.setDeleteToken(\"VALID\");");
method.addBodyLine("aDo.setUpdateTime(new Date());");
method.addBodyLine("return " + mapperFieldName + ".updateByPrimaryKey(aDo);");
implClass.addMethod(method);
}
private void generateFindValidOneMethod(TopLevelClass implClass, String modelClassName, String exampleClassName) {
Method method = new Method("findValidOne");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType(modelClassName));
String exampleParamName = exampleClassName.substring(0, 1).toLowerCase() + exampleClassName.substring(1);
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(exampleParamName + ".usePage(1, 1);");
method.addBodyLine("List<" + modelClassName + "> dataList = getValidList(" + exampleParamName + ");");
method.addBodyLine("if (dataList != null && dataList.size() > 0) {");
method.addBodyLine(" return dataList.get(0);");
method.addBodyLine("}");
method.addBodyLine("return null;");
implClass.addMethod(method);
}
private void generateFindTrashOneMethod(TopLevelClass implClass, String modelClassName, String exampleClassName) {
Method method = new Method("findTrashOne");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType(modelClassName));
String exampleParamName = exampleClassName.substring(0, 1).toLowerCase() + exampleClassName.substring(1);
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine(exampleParamName + ".usePage(1, 1);");
method.addBodyLine("List<" + modelClassName + "> dataList = getTrashList(" + exampleParamName + ");");
method.addBodyLine("if (dataList != null && dataList.size() > 0) {");
method.addBodyLine(" return dataList.get(0);");
method.addBodyLine("}");
method.addBodyLine("return null;");
implClass.addMethod(method);
}
private void generateGetValidListMethod(TopLevelClass implClass, String modelClassName, String exampleClassName,
String mapperFieldName, boolean hasBLOBColumns) {
Method method = new Method("getValidList");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("List<" + modelClassName + ">"));
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), "example"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine("for (" + exampleClassName + ".Criteria criteria : example.getOredCriteria()) {");
method.addBodyLine(" criteria.andIsDeleteEqualTo(DatabaseCommonDataIsDeleteEnum.NONE.getValue())");
method.addBodyLine(" .andIsHiddenEqualTo(DatabaseCommonDataIsHiddenEnum.NONE.getValue());");
method.addBodyLine("}");
method.addBodyLine("if (example.getRows() != null && example.getOffset() != null) {");
method.addBodyLine(" List<Long> primaryKeyList = " + mapperFieldName + ".selectPrimaryKeyByExample(example);");
method.addBodyLine(" if (primaryKeyList == null || primaryKeyList.size() == 0) {");
method.addBodyLine(" return new ArrayList<>();");
method.addBodyLine(" }");
method.addBodyLine(" String oldOrderByClause = example.getOrderByClause();");
method.addBodyLine(" example = new " + exampleClassName + "();");
method.addBodyLine(" example.createCriteria().andGuidIn(primaryKeyList);");
method.addBodyLine(" example.setOrderByClause(oldOrderByClause);");
method.addBodyLine("}");
String selectMethod = hasBLOBColumns ? "selectByExampleWithBLOBs" : "selectByExample";
method.addBodyLine("return " + mapperFieldName + "." + selectMethod + "(example);");
implClass.addMethod(method);
}
private void generateGetTrashListMethod(TopLevelClass implClass, String modelClassName, String exampleClassName,
String mapperFieldName, boolean hasBLOBColumns) {
Method method = new Method("getTrashList");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("List<" + modelClassName + ">"));
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), "example"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine("for (" + exampleClassName + ".Criteria criteria : example.getOredCriteria()) {");
method.addBodyLine(" criteria.andIsDeleteEqualTo(DatabaseCommonDataIsDeleteEnum.NONE.getValue())");
method.addBodyLine(" .andIsHiddenEqualTo(DatabaseCommonDataIsHiddenEnum.HIDDEN.getValue());");
method.addBodyLine("}");
method.addBodyLine("if (example.getRows() != null && example.getOffset() != null) {");
method.addBodyLine(" List<Long> primaryKeyList = " + mapperFieldName + ".selectPrimaryKeyByExample(example);");
method.addBodyLine(" if (primaryKeyList == null || primaryKeyList.size() == 0) {");
method.addBodyLine(" return new ArrayList<>();");
method.addBodyLine(" }");
method.addBodyLine(" String oldOrderByClause = example.getOrderByClause();");
method.addBodyLine(" example = new " + exampleClassName + "();");
method.addBodyLine(" example.createCriteria().andGuidIn(primaryKeyList);");
method.addBodyLine(" example.setOrderByClause(oldOrderByClause);");
method.addBodyLine("}");
String selectMethod = hasBLOBColumns ? "selectByExampleWithBLOBs" : "selectByExample";
method.addBodyLine("return " + mapperFieldName + "." + selectMethod + "(example);");
implClass.addMethod(method);
}
private void generateCountByValidMethod(TopLevelClass implClass, String exampleClassName, String mapperFieldName) {
Method method = new Method("countByValid");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("long"));
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), "example"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine("for (" + exampleClassName + ".Criteria criteria : example.getOredCriteria()) {");
method.addBodyLine(" criteria.andIsDeleteEqualTo(DatabaseCommonDataIsDeleteEnum.NONE.getValue())");
method.addBodyLine(" .andIsHiddenEqualTo(DatabaseCommonDataIsHiddenEnum.NONE.getValue());");
method.addBodyLine("}");
method.addBodyLine("return " + mapperFieldName + ".countByExample(example);");
implClass.addMethod(method);
}
private void generateCountByTrashMethod(TopLevelClass implClass, String exampleClassName, String mapperFieldName) {
Method method = new Method("countByTrash");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("long"));
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), "example"));
method.addException(new FullyQualifiedJavaType("Throwable"));
method.addBodyLine("for (" + exampleClassName + ".Criteria criteria : example.getOredCriteria()) {");
method.addBodyLine(" criteria.andIsDeleteEqualTo(DatabaseCommonDataIsDeleteEnum.NONE.getValue())");
method.addBodyLine(" .andIsHiddenEqualTo(DatabaseCommonDataIsHiddenEnum.HIDDEN.getValue());");
method.addBodyLine("}");
method.addBodyLine("return " + mapperFieldName + ".countByExample(example);");
implClass.addMethod(method);
}
private String upperFirst(String str) {
if (str == null || str.isEmpty()) {
return str;
}
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
private String lowerFirst(String str) {
if (str == null || str.isEmpty()) {
return str;
}
return str.substring(0, 1).toLowerCase() + str.substring(1);
}
}

View File

@@ -0,0 +1,368 @@
package com.iqudoo.framework.mybatis;
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.JavaFormatter;
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.internal.util.StringUtility;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
* MyBatis Generator 1.4.1 适配版:视图表专用 RepoView 生成插件
*/
@SuppressWarnings("DuplicatedCode")
public class TapeRepoviewGeneratorPlugin extends PluginAdapter {
// 视图Repo包配置可通过配置文件自定义
private String facadeRepoviewPackage = "com.iqudoo.platform.application.facade.repoview";
private String domainRepoviewPackage = "com.iqudoo.platform.application.domain.repoview";
private String modelPackage = "com.iqudoo.platform.application.database.model";
private String mapperPackage = "com.iqudoo.platform.application.database.mapper";
private String targetProject = "src/main/java";
// 视图名称关键字(可配置)
private String viewKeyWords = "VIEW_,V_";
// 1.4.1版本专用格式化器
private JavaFormatter javaFormatter;
@Override
public void setContext(Context context) {
super.setContext(context);
this.javaFormatter = new DefaultJavaFormatter();
this.javaFormatter.setContext(context);
}
@Override
public boolean validate(List<String> warnings) {
return true;
}
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
// 读取自定义配置
if (StringUtility.stringHasValue(properties.getProperty("facadeRepoviewPackage"))) {
facadeRepoviewPackage = properties.getProperty("facadeRepoviewPackage");
}
if (StringUtility.stringHasValue(properties.getProperty("domainRepoviewPackage"))) {
domainRepoviewPackage = properties.getProperty("domainRepoviewPackage");
}
if (StringUtility.stringHasValue(properties.getProperty("modelPackage"))) {
modelPackage = properties.getProperty("modelPackage");
}
if (StringUtility.stringHasValue(properties.getProperty("mapperPackage"))) {
mapperPackage = properties.getProperty("mapperPackage");
}
if (StringUtility.stringHasValue(properties.getProperty("targetProject"))) {
targetProject = properties.getProperty("targetProject");
}
if (StringUtility.stringHasValue(properties.getProperty("viewKeyWords"))) {
viewKeyWords = properties.getProperty("viewKeyWords").toUpperCase();
}
}
/**
* 核心方法:仅为视图表生成 RepoView 代码
*/
@Override
public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
List<GeneratedJavaFile> generatedJavaFiles = new ArrayList<>();
// 仅处理视图表,非视图表直接返回
String tableName = introspectedTable.getFullyQualifiedTable().getIntrospectedTableName().toUpperCase();
if (!isViewTable(tableName)) {
return generatedJavaFiles;
}
// 1. 获取视图表元数据
String domainObjectName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
String exampleClassName = domainObjectName + "Example";
String mapperClassName = domainObjectName + "Mapper";
String repoInterfaceName = "I" + domainObjectName + "Repo";
String repoImplName = domainObjectName + "RepoImpl";
// 2. 生成视图Repo接口核心修改移除继承手动添加方法
Interface repoInterface = generateRepoViewInterface(repoInterfaceName, domainObjectName, exampleClassName);
GeneratedJavaFile interfaceFile = new GeneratedJavaFile(
repoInterface,
targetProject,
"UTF-8",
javaFormatter
);
generatedJavaFiles.add(interfaceFile);
// 3. 生成视图Repo实现类
TopLevelClass repoImpl = generateRepoViewImpl(
repoImplName,
repoInterfaceName,
domainObjectName,
exampleClassName,
mapperClassName
);
GeneratedJavaFile implFile = new GeneratedJavaFile(
repoImpl,
targetProject,
"UTF-8",
javaFormatter
);
generatedJavaFiles.add(implFile);
// 4. 手动写入磁盘兼容1.4.1
generateJavaFileToDisk(repoInterface, facadeRepoviewPackage);
generateJavaFileToDisk(repoImpl, domainRepoviewPackage);
return generatedJavaFiles;
}
/**
* 判断是否为视图表(关键字匹配 + MBG原生视图配置
*/
private boolean isViewTable(String tableName) {
// 关键字匹配
if (StringUtility.stringHasValue(viewKeyWords)) {
String[] keywords = viewKeyWords.split(",");
for (String keyword : keywords) {
if (tableName.contains(keyword.trim().toUpperCase())) {
return true;
}
}
}
return false;
}
/**
* 核心修改生成视图Repo接口移除继承手动添加指定方法
*/
private Interface generateRepoViewInterface(String interfaceName, String modelClassName, String exampleClassName) {
Interface repoInterface = new Interface(facadeRepoviewPackage + "." + interfaceName);
repoInterface.setVisibility(JavaVisibility.PUBLIC);
// 添加必要的导入包仅保留model、example、List
repoInterface.addImportedType(new FullyQualifiedJavaType(modelPackage + "." + modelClassName));
repoInterface.addImportedType(new FullyQualifiedJavaType(modelPackage + "." + exampleClassName));
repoInterface.addImportedType(new FullyQualifiedJavaType("java.util.List"));
// 定义方法参数名(首字母小写)
String exampleParamName = lowerFirst(exampleClassName);
// 1. 添加findOne方法
Method findOneMethod = new Method("findOne");
findOneMethod.setVisibility(JavaVisibility.PUBLIC);
findOneMethod.setReturnType(new FullyQualifiedJavaType(modelClassName));
findOneMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
findOneMethod.addException(new FullyQualifiedJavaType("Throwable"));
findOneMethod.setAbstract(true);
repoInterface.addMethod(findOneMethod);
// 2. 添加getList方法
Method getListMethod = new Method("getList");
getListMethod.setVisibility(JavaVisibility.PUBLIC);
getListMethod.setReturnType(new FullyQualifiedJavaType("List<" + modelClassName + ">"));
getListMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
getListMethod.addException(new FullyQualifiedJavaType("Throwable"));
getListMethod.setAbstract(true);
repoInterface.addMethod(getListMethod);
// 3. 添加count方法
Method countMethod = new Method("count");
countMethod.setVisibility(JavaVisibility.PUBLIC);
countMethod.setReturnType(new FullyQualifiedJavaType("long"));
countMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
countMethod.addException(new FullyQualifiedJavaType("Throwable"));
countMethod.setAbstract(true);
repoInterface.addMethod(countMethod);
return repoInterface;
}
/**
* 生成视图Repo实现类逻辑不变仅适配新接口
*/
private TopLevelClass generateRepoViewImpl(
String implClassName,
String interfaceName,
String modelClassName,
String exampleClassName,
String mapperClassName) {
TopLevelClass implClass = new TopLevelClass(domainRepoviewPackage + "." + implClassName);
implClass.setVisibility(JavaVisibility.PUBLIC);
implClass.addAnnotation("@SuppressWarnings(\"DuplicatedCode\")");
implClass.addAnnotation("@Repository");
// 添加导入包移除ModelViewRepository相关导入
addImportPackages(implClass, modelClassName, exampleClassName, mapperClassName, interfaceName);
// 实现Repo接口
FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(facadeRepoviewPackage + "." + interfaceName);
implClass.addSuperInterface(superInterface);
// 添加Mapper字段
String mapperFieldName = lowerFirst(mapperClassName);
Field mapperField = new Field(mapperFieldName, new FullyQualifiedJavaType(mapperPackage + "." + mapperClassName));
mapperField.setVisibility(JavaVisibility.PRIVATE);
mapperField.addAnnotation("@Resource");
implClass.addField(mapperField);
// 生成findOne方法
generateFindOneMethod(implClass, modelClassName, exampleClassName, mapperFieldName);
// 生成getList方法
generateGetListMethod(implClass, modelClassName, exampleClassName, mapperFieldName);
// 生成count方法
generateCountMethod(implClass, exampleClassName, mapperFieldName);
return implClass;
}
/**
* 添加实现类所需的导入包移除ModelViewRepository相关
*/
private void addImportPackages(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperClassName, String interfaceName) {
// Mapper
implClass.addImportedType(new FullyQualifiedJavaType(mapperPackage + "." + mapperClassName));
// Model & Example
implClass.addImportedType(new FullyQualifiedJavaType(modelPackage + "." + modelClassName));
implClass.addImportedType(new FullyQualifiedJavaType(modelPackage + "." + exampleClassName));
// Repo接口
implClass.addImportedType(new FullyQualifiedJavaType(facadeRepoviewPackage + "." + interfaceName));
// 注解&工具类
implClass.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Repository"));
implClass.addImportedType(new FullyQualifiedJavaType("javax.annotation.Resource"));
implClass.addImportedType(new FullyQualifiedJavaType("java.util.List"));
}
/**
* 生成findOne方法
*/
private void generateFindOneMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) {
Method method = new Method("findOne");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType(modelClassName));
// 参数名匹配示例(首字母小写)
String exampleParamName = lowerFirst(exampleClassName);
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
method.addException(new FullyQualifiedJavaType("Throwable"));
// 方法体
method.addBodyLine(exampleParamName + ".usePage(1, 1);");
method.addBodyLine("List<" + modelClassName + "> dataList = getList(" + exampleParamName + ");");
method.addBodyLine("if (dataList != null && dataList.size() > 0) {");
method.addBodyLine(" return dataList.get(0);");
method.addBodyLine("}");
method.addBodyLine("return null;");
implClass.addMethod(method);
}
/**
* 生成getList方法
*/
private void generateGetListMethod(TopLevelClass implClass, String modelClassName, String exampleClassName, String mapperFieldName) {
Method method = new Method("getList");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("List<" + modelClassName + ">"));
// 参数名匹配示例(首字母小写)
String exampleParamName = lowerFirst(exampleClassName);
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
method.addException(new FullyQualifiedJavaType("Throwable"));
// 方法体
method.addBodyLine("return " + mapperFieldName + ".selectByExample(" + exampleParamName + ");");
implClass.addMethod(method);
}
/**
* 生成count方法
*/
private void generateCountMethod(TopLevelClass implClass, String exampleClassName, String mapperFieldName) {
Method method = new Method("count");
method.addAnnotation("@Override");
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType("long"));
// 参数名匹配示例(首字母小写)
String exampleParamName = lowerFirst(exampleClassName);
method.addParameter(new Parameter(new FullyQualifiedJavaType(exampleClassName), exampleParamName));
method.addException(new FullyQualifiedJavaType("Throwable"));
// 方法体
method.addBodyLine("return " + mapperFieldName + ".countByExample(" + exampleParamName + ");");
implClass.addMethod(method);
}
/**
* 手动将Java文件写入磁盘
*/
private void generateJavaFileToDisk(Interface intf, String packageName) {
try {
String packagePath = packageName.replace('.', File.separatorChar);
File targetDir = new File(targetProject, packagePath);
if (!targetDir.exists()) {
boolean mkdirs = targetDir.mkdirs();
if (!mkdirs) {
throw new RuntimeException("创建目录失败:" + targetDir.getAbsolutePath());
}
}
String className = intf.getType().getShortName();
File javaFile = new File(targetDir, className + ".java");
String content = javaFormatter.getFormattedContent(intf);
java.nio.file.Files.write(javaFile.toPath(), content.getBytes(StandardCharsets.UTF_8));
System.out.println("成功生成视图Repo接口" + javaFile.getAbsolutePath());
} catch (Exception e) {
throw new RuntimeException("生成视图Repo接口失败" + intf.getType().getShortName(), e);
}
}
private void generateJavaFileToDisk(TopLevelClass clazz, String packageName) {
try {
String packagePath = packageName.replace('.', File.separatorChar);
File targetDir = new File(targetProject, packagePath);
if (!targetDir.exists()) {
boolean mkdirs = targetDir.mkdirs();
if (!mkdirs) {
throw new RuntimeException("创建目录失败:" + targetDir.getAbsolutePath());
}
}
String className = clazz.getType().getShortName();
File javaFile = new File(targetDir, className + ".java");
String content = javaFormatter.getFormattedContent(clazz);
java.nio.file.Files.write(javaFile.toPath(), content.getBytes(StandardCharsets.UTF_8));
System.out.println("成功生成视图Repo实现类" + javaFile.getAbsolutePath());
} catch (Exception e) {
throw new RuntimeException("生成视图Repo实现类失败" + clazz.getType().getShortName(), e);
}
}
/**
* 字符串首字母小写
*/
private String lowerFirst(String str) {
if (str == null || str.isEmpty()) {
return str;
}
return str.substring(0, 1).toLowerCase() + str.substring(1);
}
/**
* 字符串首字母大写(备用)
*/
private String upperFirst(String str) {
if (str == null || str.isEmpty()) {
return str;
}
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}

View File

@@ -0,0 +1,229 @@
package com.iqudoo.framework.mybatis.abstracts;
import com.iqudoo.framework.mybatis.hook.ISelectSelectivePluginHook;
import com.iqudoo.framework.mybatis.utils.FormatTools;
import com.iqudoo.framework.mybatis.utils.ElementTools;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import java.util.List;
public abstract class AbstractWithLimitPlugin extends PluginAdapter implements ISelectSelectivePluginHook {
private final static int DEFAULT_START_PAGE = 1;
private int startPage = 1;
@Override
public boolean validate(List<String> list) {
return true;
}
@Override
public void initialized(IntrospectedTable introspectedTable) {
super.initialized(introspectedTable);
this.startPage = DEFAULT_START_PAGE;
}
@Override
public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper();
// 添加minPageNum、defaultPageSize和maxPageSize字段
Field maxPageSizeField = ElementTools.generateField(
"maxPageSize",
JavaVisibility.PROTECTED,
integerWrapper,
"100"
);
topLevelClass.addField(maxPageSizeField);
Field defaultPageSizeField = ElementTools.generateField(
"defaultPageSize",
JavaVisibility.PROTECTED,
integerWrapper,
"20"
);
topLevelClass.addField(defaultPageSizeField);
Field minPageNumField = ElementTools.generateField(
"minPageNum",
JavaVisibility.PROTECTED,
integerWrapper,
startPage + ""
);
topLevelClass.addField(minPageNumField);
// 添加offset和rows字段
Field offsetField = ElementTools.generateField(
"offset",
JavaVisibility.PROTECTED,
integerWrapper,
null
);
topLevelClass.addField(offsetField);
Field rowsField = ElementTools.generateField(
"rows",
JavaVisibility.PROTECTED,
integerWrapper,
null
);
topLevelClass.addField(rowsField);
// 增加getter && setter 方法
Method mSetMaxPageSize = ElementTools.generateSetterMethod(maxPageSizeField);
FormatTools.addMethodWithBestPosition(topLevelClass, mSetMaxPageSize);
Method mGetMaxPageSize = ElementTools.generateGetterMethod(maxPageSizeField);
FormatTools.addMethodWithBestPosition(topLevelClass, mGetMaxPageSize);
Method mSetDefaultPageSize = ElementTools.generateSetterMethod(defaultPageSizeField);
FormatTools.addMethodWithBestPosition(topLevelClass, mSetDefaultPageSize);
Method mGetDefaultPageSize = ElementTools.generateGetterMethod(defaultPageSizeField);
FormatTools.addMethodWithBestPosition(topLevelClass, mGetDefaultPageSize);
Method mSetMinPageNum = ElementTools.generateSetterMethod(minPageNumField);
FormatTools.addMethodWithBestPosition(topLevelClass, mSetMinPageNum);
Method mGetMinPageNum = ElementTools.generateGetterMethod(minPageNumField);
FormatTools.addMethodWithBestPosition(topLevelClass, mGetMinPageNum);
Method mSetOffset = ElementTools.generateSetterMethod(offsetField);
FormatTools.addMethodWithBestPosition(topLevelClass, mSetOffset);
Method mGetOffset = ElementTools.generateGetterMethod(offsetField);
FormatTools.addMethodWithBestPosition(topLevelClass, mGetOffset);
Method mSetRows = ElementTools.generateSetterMethod(rowsField);
FormatTools.addMethodWithBestPosition(topLevelClass, mSetRows);
Method mGetRows = ElementTools.generateGetterMethod(rowsField);
FormatTools.addMethodWithBestPosition(topLevelClass, mGetRows);
// 提供几个快捷方法
Method setLimit = ElementTools.generateMethod(
"limit",
JavaVisibility.PUBLIC,
topLevelClass.getType(),
new Parameter(integerWrapper, "rows")
);
setLimit = ElementTools.generateMethodBody(
setLimit,
"this.rows = rows;",
"return this;"
);
FormatTools.addMethodWithBestPosition(topLevelClass, setLimit);
Method setLimit2 = ElementTools.generateMethod(
"limit",
JavaVisibility.PUBLIC,
topLevelClass.getType(),
new Parameter(integerWrapper, "offset"),
new Parameter(integerWrapper, "rows")
);
setLimit2 = ElementTools.generateMethodBody(
setLimit2,
"this.offset = offset;",
"this.rows = rows;",
"return this;"
);
FormatTools.addMethodWithBestPosition(topLevelClass, setLimit2);
Method usePage = ElementTools.generateMethod(
"usePage",
JavaVisibility.PUBLIC,
topLevelClass.getType(),
new Parameter(integerWrapper, "pageNum"),
new Parameter(integerWrapper, "pageSize")
);
usePage = ElementTools.generateMethodBody(
usePage,
"pageSize = pageSize == null || pageSize <= 0 ? this.defaultPageSize : pageSize;",
"pageNum = pageNum == null || pageNum < this.minPageNum ? this.minPageNum : pageNum;",
"int cPageSize = pageSize > this.maxPageSize ? this.maxPageSize: pageSize;",
"this.offset = (pageNum - this.minPageNum) * cPageSize;",
"this.rows = cPageSize;",
"return this;"
);
FormatTools.addMethodWithBestPosition(topLevelClass, usePage);
// 计算获取当前页码
Method getPageNum = ElementTools.generateMethod(
"getPageNum",
JavaVisibility.PUBLIC,
integerWrapper
);
getPageNum = ElementTools.generateMethodBody(
getPageNum,
"if (this.rows == null || this.offset == null || this.rows == 0) {",
"return this.minPageNum;",
"}",
"return this.offset / this.rows + this.minPageNum;"
);
FormatTools.addMethodWithBestPosition(topLevelClass, getPageNum);
// 计算获取当前每页数量
Method getPageSize = ElementTools.generateMethod(
"getPageSize",
JavaVisibility.PUBLIC,
integerWrapper
);
getPageSize = ElementTools.generateMethodBody(
getPageSize,
"if (this.rows == null) {",
"return 0;",
"}",
"return this.rows;"
);
FormatTools.addMethodWithBestPosition(topLevelClass, getPageSize);
// !!! clear 方法增加 offset 和 rows的清理
List<Method> methodList = topLevelClass.getMethods();
for (Method method : methodList) {
if (method.getName().equals("clear")) {
method.addBodyLine("rows = null;");
method.addBodyLine("offset = null;");
}
}
return true;
}
@Override
public boolean sqlMapSelectAllElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
this.generateLimitElement(element);
return super.sqlMapSelectAllElementGenerated(element, introspectedTable);
}
@Override
public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
this.generateLimitElement(element);
return super.sqlMapSelectByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
}
@Override
public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
this.generateLimitElement(element);
return super.sqlMapSelectByExampleWithBLOBsElementGenerated(element, introspectedTable);
}
@Override
public void generateLimitElement(XmlElement element) {
XmlElement ifLimitNotNullElement = new XmlElement("if");
ifLimitNotNullElement.addAttribute(new Attribute("test", "rows != null"));
// rows
XmlElement ifOffsetNotNullElement = new XmlElement("if");
ifOffsetNotNullElement.addAttribute(new Attribute("test", "offset != null"));
ifOffsetNotNullElement.addElement(new TextElement("limit ${offset}, ${rows}"));
ifLimitNotNullElement.addElement(ifOffsetNotNullElement);
// offset
XmlElement ifOffsetNullElement = new XmlElement("if");
ifOffsetNullElement.addAttribute(new Attribute("test", "offset == null"));
ifOffsetNullElement.addElement(new TextElement("limit ${rows}"));
ifLimitNotNullElement.addElement(ifOffsetNullElement);
element.addElement(ifLimitNotNullElement);
}
}

View File

@@ -0,0 +1,9 @@
package com.iqudoo.framework.mybatis.hook;
import org.mybatis.generator.api.dom.xml.XmlElement;
public interface ISelectSelectivePluginHook {
void generateLimitElement(XmlElement element);
}

View File

@@ -0,0 +1,152 @@
package com.iqudoo.framework.mybatis.utils;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.*;
import static org.mybatis.generator.internal.util.messages.Messages.getString;
@SuppressWarnings("unused")
public class ElementTools {
/**
* 生成静态常量
*
* @param fieldName 常量名称
* @param javaType 类型
* @param initString 初始化字段
* @return Field
*/
public static Field generateStaticFinalField(String fieldName, FullyQualifiedJavaType javaType, String initString) {
Field field = new Field(fieldName, javaType);
field.setVisibility(JavaVisibility.PUBLIC);
field.setStatic(true);
field.setFinal(true);
if (initString != null) {
field.setInitializationString(initString);
}
return field;
}
/**
* 生成属性
*
* @param fieldName 常量名称
* @param visibility 可见性
* @param javaType 类型
* @param initString 初始化字段
* @return Method
*/
public static Field generateField(String fieldName, JavaVisibility visibility, FullyQualifiedJavaType javaType, String initString) {
Field field = new Field(fieldName, javaType);
field.setVisibility(visibility);
if (initString != null) {
field.setInitializationString(initString);
}
return field;
}
/**
* 生成方法
*
* @param methodName 方法名
* @param visibility 可见性
* @param returnType 返回值类型
* @param parameters 参数列表
* @return Method
*/
public static Method generateMethod(String methodName, JavaVisibility visibility, FullyQualifiedJavaType returnType, Parameter... parameters) {
Method method = new Method(methodName);
method.setVisibility(visibility);
method.setReturnType(returnType);
if (parameters != null) {
for (Parameter parameter : parameters) {
method.addParameter(parameter);
}
}
return method;
}
/**
* 生成方法实现体
*
* @param method 方法
* @param bodyLines 方法实现行
* @return Method
*/
public static Method generateMethodBody(Method method, String... bodyLines) {
if (bodyLines != null) {
for (String bodyLine : bodyLines) {
method.addBodyLine(bodyLine);
}
}
return method;
}
/**
* 生成Filed的Set方法
*
* @param field field
* @return Method
*/
public static Method generateSetterMethod(Field field) {
Method method = generateMethod(
"set" + FormatTools.upFirstChar(field.getName()),
JavaVisibility.PUBLIC,
null,
new Parameter(field.getType(), field.getName())
);
return generateMethodBody(method, "this." + field.getName() + " = " + field.getName() + ";");
}
/**
* 生成Filed的Get方法
*
* @param field field
* @return Method
*/
public static Method generateGetterMethod(Field field) {
Method method = generateMethod(
"get" + FormatTools.upFirstChar(field.getName()),
JavaVisibility.PUBLIC,
field.getType()
);
return generateMethodBody(method, "return this." + field.getName() + ";");
}
/**
* 获取Model没有BLOBs类时的类型
*
* @param introspectedTable introspectedTable
* @return FullyQualifiedJavaType
*/
public static FullyQualifiedJavaType getModelTypeWithoutBLOBs(IntrospectedTable introspectedTable) {
FullyQualifiedJavaType type;
if (introspectedTable.getRules().generateBaseRecordClass()) {
type = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
} else if (introspectedTable.getRules().generatePrimaryKeyClass()) {
type = new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyType());
} else {
throw new RuntimeException(getString("RuntimeError.12"));
}
return type;
}
/**
* 获取Model有BLOBs类时的类型
*
* @param introspectedTable introspectedTable
* @return FullyQualifiedJavaType
*/
public static FullyQualifiedJavaType getModelTypeWithBLOBs(IntrospectedTable introspectedTable) {
FullyQualifiedJavaType type;
if (introspectedTable.getRules().generateRecordWithBLOBsClass()) {
type = new FullyQualifiedJavaType(introspectedTable.getRecordWithBLOBsType());
} else {
// the blob fields must be rolled up into the base class
type = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
}
return type;
}
}

View File

@@ -0,0 +1,234 @@
package com.iqudoo.framework.mybatis.utils;
import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.VisitableElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@SuppressWarnings("unused")
public class FormatTools {
/**
* 在最佳位置添加方法
*
* @param innerClass innerClass
* @param method method
*/
public static void addMethodWithBestPosition(InnerClass innerClass, Method method) {
addMethodWithBestPosition(method, innerClass.getMethods());
}
/**
* 在最佳位置添加方法
*
* @param anInterface anInterface
* @param method method
*/
public static void addMethodWithBestPosition(Interface anInterface, Method method) {
// import
Set<FullyQualifiedJavaType> importTypes = new TreeSet<>();
// 返回
if (method.getReturnType() != null && method.getReturnType().isPresent()) {
importTypes.add(method.getReturnType().get());
importTypes.addAll(method.getReturnType().get().getTypeArguments());
}
// 参数 比较特殊的是ModelColumn生成的Column
for (Parameter parameter : method.getParameters()) {
boolean flag = true;
for (String annotation : parameter.getAnnotations()) {
if (annotation.startsWith("@Param")) {
importTypes.add(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Param"));
if (annotation.matches(".*selective.*") && parameter.getType()
.getShortName().equals("Column")) {
flag = false;
}
}
}
if (flag) {
importTypes.add(parameter.getType());
importTypes.addAll(parameter.getType().getTypeArguments());
}
}
anInterface.addImportedTypes(importTypes);
addMethodWithBestPosition(method, anInterface.getMethods());
}
/**
* 在最佳位置添加方法
*
* @param innerEnum innerEnum
* @param method method
*/
public static void addMethodWithBestPosition(InnerEnum innerEnum, Method method) {
addMethodWithBestPosition(method, innerEnum.getMethods());
}
/**
* 在最佳位置添加方法
*
* @param topLevelClass topLevelClass
* @param method method
*/
public static void addMethodWithBestPosition(TopLevelClass topLevelClass, Method method) {
addMethodWithBestPosition(method, topLevelClass.getMethods());
}
/**
* 在最佳位置添加节点
*
* @param rootElement rootElement
* @param element element
*/
public static void addElementWithBestPosition(XmlElement rootElement, XmlElement element) {
// sql 元素都放在sql后面
if (element.getName().equals("sql")) {
int index = 0;
for (VisitableElement ele : rootElement.getElements()) {
if (ele instanceof XmlElement && ((XmlElement) ele).getName().equals("sql")) {
index++;
}
}
rootElement.addElement(index, element);
} else {
// 根据id 排序
String id = getIdFromElement(element);
if (id == null) {
rootElement.addElement(element);
} else {
List<VisitableElement> elements = rootElement.getElements();
int index = -1;
for (int i = 0; i < elements.size(); i++) {
VisitableElement ele = elements.get(i);
if (ele instanceof XmlElement) {
String eleId = getIdFromElement((XmlElement) ele);
if (eleId != null) {
if (eleId.startsWith(id)) {
if (index == -1) {
index = i;
}
} else if (id.startsWith(eleId)) {
index = i + 1;
}
}
}
}
if (index == -1 || index >= elements.size()) {
rootElement.addElement(element);
} else {
elements.add(index, element);
}
}
}
}
/**
* 找出节点ID值
*
* @param element element
* @return id
*/
private static String getIdFromElement(XmlElement element) {
for (Attribute attribute : element.getAttributes()) {
if (attribute.getName().equals("id")) {
return attribute.getValue();
}
}
return null;
}
/**
* 获取最佳添加位置
*
* @param method method
* @param methods methods
*/
private static void addMethodWithBestPosition(Method method, List<Method> methods) {
int index = -1;
for (int i = 0; i < methods.size(); i++) {
Method m = methods.get(i);
if (m.getName().equals(method.getName())) {
if (m.getParameters().size() <= method.getParameters().size()) {
index = i + 1;
} else {
index = i;
}
} else if (m.getName().startsWith(method.getName())) {
if (index == -1) {
index = i;
}
} else if (method.getName().startsWith(m.getName())) {
index = i + 1;
}
}
if (index == -1 || index >= methods.size()) {
methods.add(methods.size(), method);
} else {
methods.add(index, method);
}
}
/**
* 替换已有方法注释
*
* @param commentGenerator commentGenerator
* @param method method
* @param introspectedTable introspectedTable
*/
public static void replaceGeneralMethodComment(CommentGenerator commentGenerator, Method method, IntrospectedTable introspectedTable) {
method.getJavaDocLines().clear();
commentGenerator.addGeneralMethodComment(method, introspectedTable);
}
/**
* 替换已有注释
*
* @param commentGenerator commentGenerator
* @param element element
*/
public static void replaceComment(CommentGenerator commentGenerator, XmlElement element) {
Iterator<VisitableElement> elementIterator = element.getElements().iterator();
boolean flag = false;
while (elementIterator.hasNext()) {
VisitableElement ele = elementIterator.next();
if (ele instanceof TextElement && ((TextElement) ele).getContent().matches(".*<!--.*")) {
flag = true;
}
if (flag) {
elementIterator.remove();
}
if (ele instanceof TextElement && ((TextElement) ele).getContent().matches(".*-->.*")) {
flag = false;
}
}
XmlElement tmpEle = new XmlElement("tmp");
commentGenerator.addComment(tmpEle);
for (int i = tmpEle.getElements().size() - 1; i >= 0; i--) {
element.addElement(0, tmpEle.getElements().get(i));
}
}
/**
* 首字母大写
*
* @param str str
* @return str
*/
public static String upFirstChar(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}