(一)插件开发生成自定的代码
(二)开发一个支持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;
}
}
|