java-MyBatisGenerator-(二)开发一个支持tkmybatis的插件

(一)插件开发生成自定的代码

(二)开发一个支持tkmybatis的插件


 

java-MyBatisGenerator-(二)开发一个支持tkmybatis的插件

现在大多数都是前后端分离的开发模式,这样就需要定义好多实体对象从前到后包含但不限于vo、bo、dto、do,一堆o ....
其实都是体力劳动,好吧,让我们把这些o交给生成器吧~~~~

一、上篇讲了怎么写插件,下载就直接上代码。
主要的功能有3个:
1.修改默认生成的接口文件,添加了注解和父类;
2.修改默认生成的类文件,为实体添加了tk.mybatis需要的注解,和一个select方法;
3.生成了一个vo实体,支持swagger的文档描述;

生成的接口内容如下:

package gen.inters;

import static java.util.List;
import static org.apache.ibatis.annotations.Mapper;
import static org.apache.ibatis.annotations.Select;
import static org.springframework.stereotype.Component;

import gen.models.BudgetAppCategoryRelDo;

/**
* 表:budget_app_category_rel
* 预算填报产品类别关系表
*/
@Mapper
@Component
public interface BudgetAppCategoryRelDao extends tk.mybatis.mapper.common.Mapper<BudgetAppCategoryRelDo> {
    /**
     *代码生成器生成内容
     */
    int insert(BudgetAppCategoryRelDo record);

    /**
     *代码生成器生成内容
     */
    int insertSelective(BudgetAppCategoryRelDo record);

    @Select("select * from budget_app_category_rel;")
    List<BudgetAppCategoryRelDo> getAll();
}


生成的实体内容如下:

package gen.models;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;

/**
 * 表名:budget_app_category_rel
 *   预算填报产品类别关系表
 * 生成时间:2022-03-29 19:12:19
 */
@Table(name = "budget_app_category_rel")
public class BudgetAppCategoryRelDo {
    /**
     * id:id
     */
    /** +注释内容 */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    /**
     * app_id:app_id
     */
    /** +注释内容 */
    @Column(name = "app_id")
    private Integer appId;

    /**
     * type_id:类别id
     */
    /** +注释内容 */
    @Column(name = "type_id")
    private Integer typeId;

    /**
     * sub_type_id:子类id
     */
    /** +注释内容 */
    @Column(name = "sub_type_id")
    private Integer subTypeId;

    ...
}

生成的vo对象如下:

package gen.tkmybatis;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

/**
* 预算填报产品类别关系表
* @author xxx
*/
@ApiModel(value = "预算填报产品类别关系表",description = "xx")
class BudgetAppCategoryRelVo {
    @ApiModelProperty("id")
    private Integer id;

    @ApiModelProperty("app_id")
    private Integer appId;

    @ApiModelProperty("类别id")
    private Integer typeId;

    @ApiModelProperty("子类id")
    private Integer subTypeId;
    ...
}

二、插件全部代码
配置
<plugin type="org.mybatis.generator.myplugins.TkMybatisPlugin"/>

TkMybatisPlugin类代码

package org.mybatis.generator.myplugins;

import org.mybatis.generator.api.*;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.internal.util.JavaBeansUtil;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/***
 * tk.mybatis 插件
 * @author xxj
 * @date 2022/3/21 20:07
 */
public class TkMybatisPlugin extends PluginAdapter {
    private String _packageName = "gen.tkmybatis";
    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 操作表实体类的插件方法
    /** 表实体类添加注解,构造完成后的回调函数 */
    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass
            , IntrospectedTable introspectedTable) {
        //添加依赖包
        topLevelClass.addImportedType("org.apache.ibatis.annotations.Mapper");
        topLevelClass.addImportedType("org.apache.ibatis.annotations.Select");
        topLevelClass.addImportedType("org.springframework.stereotype.Component");
        //添加类注解
        topLevelClass.addAnnotation("@Table(name = \""+introspectedTable.getFullyQualifiedTableNameAtRuntime()+"\")");
        //添加类的父类
        //topLevelClass.setSuperClass("tk.mybatis.mapper.common.Mapper<MyTestDo>");
        return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable);
    }

    /** 表实体类的成员变量添加注解,构造完成后的回调函数 */
    @Override
    public boolean modelFieldGenerated(Field field //当前属性的对象
            , TopLevelClass topLevelClass  //属性的宿主类
            , IntrospectedColumn introspectedColumn //数据库表字段对象
            , IntrospectedTable introspectedTable //数据库表对象
            , ModelClassType modelClassType) {
        //为生成的方法添加 tk.mybatis 注解
        field.getJavaDocLines().add("/** +注释内容 */");
        //添加主键注解
        if(introspectedColumn.isAutoIncrement()) {
            field.addAnnotation("@Id");
            field.addAnnotation("@GeneratedValue(strategy = GenerationType.IDENTITY)");
            return true;
        }
        field.addAnnotation("@Column(name = \""+introspectedColumn.getActualColumnName()+"\")");

        return super.modelFieldGenerated(field, topLevelClass, introspectedColumn, introspectedTable, modelClassType);
    }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 操作表接口类的插件方法
    /** 当整个表对应的客户端代码对象生成完后,方法被调佣一次 */
    @Override
    public boolean clientGenerated(Interface interfaze
            , TopLevelClass topLevelClass
            , IntrospectedTable introspectedTable) {
        String tableName = introspectedTable.getFullyQualifiedTableNameAtRuntime();
        String domainObjectName = MessageFormat.format(
                introspectedTable.getTableConfiguration().getEntityName() //xml中table.entityName属性,修改过源码支持占位符
                ,introspectedTable.getFullyQualifiedTable().getDomainObjectName() //表实体对象名
        );
        //添加接口注释内容
        interfaze.addJavaDocLine("/**");
        interfaze.addJavaDocLine("* 表:"+introspectedTable.getFullyQualifiedTableNameAtRuntime());
        interfaze.addJavaDocLine("* "+introspectedTable.getRemarks());
        interfaze.addJavaDocLine("*/");
        //添加依赖包
        interfaze.addStaticImport("org.apache.ibatis.annotations.Mapper");
        interfaze.addStaticImport("org.apache.ibatis.annotations.Select");
        interfaze.addStaticImport("org.springframework.stereotype.Component");
        interfaze.addStaticImport("java.util.List");
        //添加注解
        interfaze.addAnnotation("@Mapper");
        interfaze.addAnnotation("@Component");
        //添加父类
        interfaze.addSuperInterface(new FullyQualifiedJavaType(
                "tk.mybatis.mapper.common.Mapper<"+domainObjectName+">"));
        //添加方法
        Method f = new Method();
        f.addAnnotation(String.format("@Select(\"select * from %s;\")",tableName));
        f.setReturnType(new FullyQualifiedJavaType("List<"+domainObjectName+">"));
        f.setName("getAll");
        interfaze.addMethod(f);
        return super.clientGenerated(interfaze, topLevelClass, introspectedTable);
    }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 操作表实体类的插件方法
    /** 可以生成自定义的文件 */
    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();
        answer.add(getTestJaveFile(introspectedTable));//测试用的
        answer.add(getTestJaveVoFile(introspectedTable));//生成一个vo对象
        return answer;
    }
    /** 生成一个Vo对象 */
    private GeneratedJavaFile getTestJaveVoFile(IntrospectedTable introspectedTable){
        String tableName = introspectedTable.getFullyQualifiedTableNameAtRuntime();
        String domainObjectName =introspectedTable.getFullyQualifiedTable().getDomainObjectName();
        String typeName = MessageFormat.format("{0}.{1}Vo",_packageName,domainObjectName);
        FullyQualifiedTable table = introspectedTable.getFullyQualifiedTable();
        //类的完全限定名(决定生成的文件的目录接口)
        TopLevelClass c = new TopLevelClass(typeName);
        //导入的依赖包
        c.addImportedType(new FullyQualifiedJavaType("io.swagger.annotations.ApiModel"));
        c.addImportedType(new FullyQualifiedJavaType("io.swagger.annotations.ApiModelProperty"));
        //添加注释
        c.addJavaDocLine("/**");
        c.addJavaDocLine("* "+introspectedTable.getRemarks());
        c.addJavaDocLine("* @author xxx");
        c.addJavaDocLine("*/");
        //添加注解
        c.addAnnotation(MessageFormat.format("@ApiModel(value = \"{0}\",description = \"xx\")"
                ,introspectedTable.getRemarks()));
        //类的成员属性
        for(IntrospectedColumn col : introspectedTable.getAllColumns()){
            Field f = new Field();
            f.setVisibility(JavaVisibility.PRIVATE);
            f.addAnnotation("@ApiModelProperty(\""+col.getRemarks()+"\")");
            f.setName(col.getJavaProperty());
            f.setType(col.getFullyQualifiedJavaType());
            c.addField(f);
        }
        //类的方法
        for(IntrospectedColumn col : introspectedTable.getAllColumns()){
            //get
            Method fun = new Method();
            fun.setName(JavaBeansUtil.getGetterMethodName(col.getJavaProperty(),col.getFullyQualifiedJavaType()));
            fun.setReturnType(col.getFullyQualifiedJavaType());
            fun.setVisibility(JavaVisibility.PUBLIC);
            fun.addBodyLine(MessageFormat.format("return {0};",col.getJavaProperty()));
            c.addMethod(fun);
            //get
            fun = new Method();
            fun.setName(JavaBeansUtil.getSetterMethodName(col.getJavaProperty()));
            fun.setVisibility(JavaVisibility.PUBLIC);
            Parameter pars = new Parameter(col.getFullyQualifiedJavaType(),col.getJavaProperty());
            fun.addParameter(pars);
            fun.addBodyLine(MessageFormat.format("return this.{0}={0};",col.getJavaProperty()));
            c.addMethod(fun);
        }
        //构建一个编译单元
        GeneratedJavaFile gjf = new GeneratedJavaFile(
                c,
                context.getJavaModelGeneratorConfiguration().getTargetProject(),
                context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                context.getJavaFormatter());
        return gjf;
    }

    /** 生成一个自定义文件 */
    private GeneratedJavaFile getTestJaveFile(IntrospectedTable introspectedTable){
        String typeName = MessageFormat.format("{0}.TestInfo",_packageName);
        //类的完全限定名(决定生成的文件的目录接口)
        TopLevelClass c = new TopLevelClass(typeName);
        //导入的依赖包
        c.addImportedType(new FullyQualifiedJavaType("java.io.File;//111"));
        c.addImportedType(new FullyQualifiedJavaType("java.io.File;//222"));
        //构建一个编译单元
        GeneratedJavaFile gjf = new GeneratedJavaFile(
                c,
                context.getJavaModelGeneratorConfiguration().getTargetProject(),
                context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                context.getJavaFormatter());
        //类的成员属性怎么标识??
        Field f = new Field();
        f.setVisibility(JavaVisibility.PRIVATE);
        f.setInitializationString("\"aaa\"");
        f.setComment("//my field");
        f.setName("id");
        f.setType(FullyQualifiedJavaType.getStringInstance());
        c.addField(f);
        //类的方法
        Method fun = new Method();
        fun.addBodyLine("//hello word");
        fun.addBodyLine("return \"xxx\";");
        fun.setName("getId");
        fun.setReturnType(FullyQualifiedJavaType.getStringInstance());
        fun.addAnnotation("//@Service(111)");
        fun.addJavaDocLine("/** hello function */");
        c.addMethod(fun);
        return gjf;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值