MyBatis Generator高级技巧自定义插件开发实战指南【免费下载链接】generatorA code generator for MyBatis.项目地址: https://gitcode.com/gh_mirrors/ge/generatorMyBatis Generator是MyBatis框架的代码生成工具它可以根据数据库表结构自动生成实体类、Mapper接口和XML映射文件。虽然MyBatis Generator提供了丰富的内置插件但在实际开发中我们经常需要根据项目特定需求进行定制化扩展。本文将深入探讨如何开发自定义插件掌握MyBatis Generator高级扩展能力。为什么需要自定义插件MyBatis Generator的插件系统是其最强大的特性之一。通过插件你可以在代码生成的各个阶段介入实现以下功能修改生成的代码结构- 添加自定义注解、修改方法签名增强生成的功能- 添加额外的方法或字段过滤生成内容- 根据条件跳过某些表或字段集成第三方库- 自动添加Lombok、Swagger等注解自定义代码风格- 统一团队编码规范插件开发基础插件生命周期MyBatis Generator插件有明确的执行生命周期初始化阶段-setContext(),setProperties(),setCommentGenerator()方法被调用验证阶段-validate()方法验证插件配置表初始化-initialized()方法为每个表调用代码生成钩子- 各种clientXXX(),modelXXX(),sqlMapXXX()方法在相应代码生成时调用附加文件生成-contextGenerateAdditionalXXXFiles()方法用于生成额外文件核心接口和类Plugin接口- 定义了所有插件方法的接口PluginAdapter类- 提供了默认实现的抽象基类推荐继承此类IntrospectedTable- 包含表结构信息IntrospectedColumn- 包含列信息实战创建第一个自定义插件步骤1创建插件类让我们创建一个简单的插件为所有生成的实体类添加Lombok的Data注解package com.example.mybatis.plugins; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.PluginAdapter; import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType; import org.mybatis.generator.api.dom.java.TopLevelClass; import java.util.List; public class LombokDataPlugin extends PluginAdapter { Override public boolean validate(ListString warnings) { return true; } Override public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { // 添加Lombok的Data注解 topLevelClass.addImportedType(new FullyQualifiedJavaType(lombok.Data)); topLevelClass.addAnnotation(Data); // 添加Lombok的NoArgsConstructor和AllArgsConstructor注解 topLevelClass.addImportedType(new FullyQualifiedJavaType(lombok.NoArgsConstructor)); topLevelClass.addImportedType(new FullyQualifiedJavaType(lombok.AllArgsConstructor)); topLevelClass.addAnnotation(NoArgsConstructor); topLevelClass.addAnnotation(AllArgsConstructor); return true; } }步骤2配置插件使用在generatorConfig.xml中配置插件plugin typecom.example.mybatis.plugins.LombokDataPlugin !-- 可以添加自定义属性 -- property nameenableBuilder valuetrue/ /plugin高级插件开发技巧1. 处理不同生成阶段MyBatis Generator提供了丰富的钩子方法你可以在不同阶段介入public class CustomPlugin extends PluginAdapter { // 在模型类生成时添加自定义注解 Override public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { // 为特定类型的字段添加注解 if (introspectedColumn.getJdbcTypeName().equals(TIMESTAMP)) { field.addAnnotation(JsonFormat(pattern \yyyy-MM-dd HH:mm:ss\)); topLevelClass.addImportedType( new FullyQualifiedJavaType(com.fasterxml.jackson.annotation.JsonFormat)); } return true; } // 在Mapper接口生成时添加方法 Override public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) { // 添加自定义查询方法 Method method new Method(selectByCustomCondition); method.setReturnType(new FullyQualifiedJavaType(List introspectedTable.getBaseRecordType() )); method.addParameter(new Parameter(new FullyQualifiedJavaType(String), condition)); method.addAnnotation(Select(\SELECT * FROM introspectedTable.getFullyQualifiedTableNameAtRuntime() WHERE ${condition}\)); interfaze.addMethod(method); return true; } }2. 使用插件属性配置插件可以通过properties参数接收配置public class ConfigurablePlugin extends PluginAdapter { private boolean enableSwagger; private String version; Override public void setProperties(Properties properties) { super.setProperties(properties); enableSwagger Boolean.parseBoolean(properties.getProperty(enableSwagger, false)); version properties.getProperty(version, v1.0); } Override public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { if (enableSwagger) { topLevelClass.addImportedType( new FullyQualifiedJavaType(io.swagger.annotations.ApiModel)); topLevelClass.addAnnotation(ApiModel(description \ introspectedTable.getRemarks() \)); } return true; } }3. 生成额外文件插件可以生成额外的Java、Kotlin或XML文件public class AdditionalFilePlugin extends PluginAdapter { Override public ListGeneratedJavaFile contextGenerateAdditionalJavaFiles( IntrospectedTable introspectedTable) { ListGeneratedJavaFile files new ArrayList(); // 为每个表生成一个Service接口 Interface serviceInterface new Interface( introspectedTable.getBaseRecordType().replace(Model, Service)); serviceInterface.setVisibility(JavaVisibility.PUBLIC); serviceInterface.addMethod(createFindAllMethod(introspectedTable)); GeneratedJavaFile file new GeneratedJavaFile( serviceInterface, introspectedTable.getContext().getJavaModelGeneratorConfiguration() .getTargetProject(), introspectedTable.getContext().getJavaFormatter()); files.add(file); return files; } }内置插件源码分析MyBatis Generator提供了许多内置插件它们是最好的学习资源。让我们分析几个关键插件ToStringPlugin分析ToStringPlugin位于core/mybatis-generator-core/src/main/java/org/mybatis/generator/plugins/ToStringPlugin.java它为生成的模型类添加toString()方法public class ToStringPlugin extends PluginAdapter { private boolean useToStringFromRoot; Override public void setProperties(Properties properties) { super.setProperties(properties); useToStringFromRoot isTrue(properties.getProperty(useToStringFromRoot)); } Override public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { generateToString(introspectedTable, topLevelClass); return true; } // 其他方法... }SerializablePlugin分析SerializablePlugin为模型类添加序列化支持展示了如何处理不同模型类型Override public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { makeSerializable(topLevelClass, introspectedTable); return true; } Override public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { makeSerializable(topLevelClass, introspectedTable); return true; }插件配置最佳实践1. 插件执行顺序插件按照配置顺序执行第一个返回false的插件会阻止后续插件执行context iddefault targetRuntimeMyBatis3DynamicSql !-- 插件按顺序执行 -- plugin typeorg.mybatis.generator.plugins.SerializablePlugin/ plugin typeorg.mybatis.generator.plugins.ToStringPlugin property nameuseToStringFromRoot valuetrue/ /plugin plugin typecom.example.CustomPlugin/ /context2. 条件性插件执行通过validate()方法控制插件是否执行Override public boolean validate(ListString warnings) { // 只在特定条件下启用插件 String targetRuntime context.getTargetRuntime(); if (!MyBatis3DynamicSql.equals(targetRuntime)) { warnings.add(CustomPlugin requires MyBatis3DynamicSql runtime); return false; } return true; }3. 表级别配置覆盖插件属性可以在表级别被覆盖table tableNameuser property namevirtualKeyColumns valueID/ !-- 覆盖插件配置 -- property nameskipRecordBuilderPlugin valuetrue/ /table调试和测试插件1. 使用Maven测试plugin groupIdorg.mybatis.generator/groupId artifactIdmybatis-generator-maven-plugin/artifactId version1.4.2/version configuration configurationFilesrc/main/resources/generatorConfig.xml/configurationFile overwritetrue/overwrite verbosetrue/verbose /configuration dependencies dependency groupIdcom.example/groupId artifactIdmy-custom-plugins/artifactId version1.0.0/version /dependency /dependencies /plugin2. 日志输出调试启用详细日志查看插件执行过程java -jar mybatis-generator-core-x.x.x.jar \ -configfile generatorConfig.xml \ -overwrite \ -verbose常见问题解决问题1插件不生效检查插件类路径是否正确验证validate()方法返回true确认插件配置在正确的context中问题2生成的代码不符合预期检查钩子方法是否正确覆盖验证IntrospectedTable和IntrospectedColumn信息确认没有其他插件干扰问题3性能问题避免在插件中进行复杂计算使用缓存机制存储重复计算结果批量处理相似操作实际应用场景场景1自动添加审计字段public class AuditFieldPlugin extends PluginAdapter { Override public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { String columnName introspectedColumn.getActualColumnName(); // 为创建时间字段添加注解 if (CREATE_TIME.equalsIgnoreCase(columnName)) { field.addAnnotation(TableField(fill FieldFill.INSERT)); topLevelClass.addImportedType( new FullyQualifiedJavaType(com.baomidou.mybatisplus.annotation.FieldFill)); topLevelClass.addImportedType( new FullyQualifiedJavaType(com.baomidou.mybatisplus.annotation.TableField)); } return true; } }场景2多租户支持public class MultiTenantPlugin extends PluginAdapter { Override public boolean clientSelectByExampleWithoutBLOBsMethodGenerated( Method method, Interface interfaze, IntrospectedTable introspectedTable) { // 修改查询方法自动添加租户过滤条件 modifyMethodForTenant(method, interfaze, introspectedTable); return true; } Override public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated( XmlElement element, IntrospectedTable introspectedTable) { // 在XML中添加租户过滤条件 addTenantConditionToXml(element, introspectedTable); return true; } }总结MyBatis Generator的插件系统提供了强大的扩展能力通过自定义插件你可以统一代码规范- 确保生成的代码符合团队标准减少重复工作- 自动添加常用注解和配置集成第三方框架- 无缝集成Spring Boot、MyBatis-Plus等实现业务特定逻辑- 根据业务需求定制生成逻辑掌握插件开发技能可以让MyBatis Generator真正成为你项目开发的得力助手而不是简单的代码生成工具。通过合理的插件设计你可以显著提升开发效率保证代码质量实现真正的自动化开发流程。图MyBatis Generator插件架构示意图展示了插件在代码生成流程中的介入点记住最好的插件是那些能够解决你团队特定痛点的插件。从简单的需求开始逐步积累经验你会发现插件开发并不复杂但带来的价值却是巨大的。开始你的第一个自定义插件开发吧【免费下载链接】generatorA code generator for MyBatis.项目地址: https://gitcode.com/gh_mirrors/ge/generator创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考