结合Groovy脚本在IDEA可以为所欲为——根据已有的entity信息使用freemarker模板

前言

网上有很多都是通过groovy从数据库表生成实体类,那可不可以通过groovy获取已经存在的实体类信息呢?答案当然是可以的。本文就是说明如何在IDEA的Groovy控制台,根据已有的entity,获取entity的信息,然后根据获取的信息使用freemarker模板进行输出。
对于已经存在的项目,它的实体类可能不是那么轻易能覆盖的(涉及字段的类型的确定、注解的组合…)。如何快速校验一个字段超多的实体类字段;如何通过已有的实体类生成DTO、BO、VO等等,从已有的实体获取字段信息无疑是完美的解决方案
不需要看步骤的直接跳到本文的总结
不需要看步骤的直接跳到本文的总结
不需要看步骤的直接跳到本文的总结

一个例子

下面将结合mybatis-plus的注解标注的实体类举例,如果是实体类是JPA的注解标注的,只需要将脚本中获取信息的注解换成JPA的注解即可;

已有一个UserInfo的实体类,其实体类代码假设如下:

package com.test.bean;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 用户信息详情
 * @author 
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("USER_INFO")
@ApiModel(value = "UserInfo 对象", description = "用户信息详情")
public class UserInfo {
	@ApiModelProperty(value = "主键ID")
	@TableId(value = "ID")
	private String id;
	
	/** 用户名 */
	@ApiModelProperty(value = "用户名name")
	@TableField(value = "USER_NAME")
	private String userName;

	/** 用户密码 */
	@ApiModelProperty(value = "用户密码")
	@TableField(value = "USER_PW")
	private String userPw;
}

由上可以看到,实体类的其他信息都由 TableName、TableId、TableField、ApiModelProperty等注解标注清楚了,在IDEA的groovy控制台就可以通过注解获取这些值,使用如下脚本获取实体的信息:
打开Groovy控制台
Groovy控制台截图
文件groovy_console.groovy内容:

import com.baomidou.mybatisplus.annotation.TableField
import com.baomidou.mybatisplus.annotation.TableId
import com.baomidou.mybatisplus.annotation.TableName
import com.test.bean.UserInfo
import freemarker.template.Configuration
import freemarker.template.Template
import io.swagger.annotations.ApiModel
import io.swagger.annotations.ApiModelProperty
import org.apache.commons.lang3.StringUtils

import java.lang.annotation.Annotation

// 获取entity
def entity = UserInfo

// 字段信息
class filedInfo {
    def String name; // 默认驼峰命名法
    def String capitalName; // 首字母大写
    def String dbName; // 数据库的名字
    def String type; // 类型名称
    def String typeFull; // 类型全称
    def String comment; // 字段注释
    def boolean ifPk = false;
}

def entityInfo = [
        dir: System.getProperty("user.dir"), // 获取工程的目录
        package : entity.getPackage().name, // 获取包名
        name: entity.getSimpleName(), // 获取类名
        tableName: "",
        tableComment: "",
        fieldName: entity.getDeclaredFields().name, // 获取所有字段名
        pkField: [], // 获取id字段
        field: [], // 字段
        fieldAll: [], // 全部字段
]

def model = entity.getAnnotation(ApiModel)
if (model != null) {
    entityInfo.tableComment = model.description()
}
def table = entity.getAnnotation(TableName)
if (table != null) {
    entityInfo.tableName = table.value()
}

// 填充 field
for(def field in entity.getDeclaredFields()) {
    def info = new filedInfo()
    info.name = field.name
    info.capitalName = StringUtils.upperCase(field.name[0]) + field.name[1..field.name.length()-1]
    info.type = field.type.simpleName
    info.typeFull = field.type.name

    def tableField = field.getAnnotation(TableField)
    def tableId = field.getAnnotation(TableId)
    if (tableField != null) {
        info.dbName = tableField.value()
        info.ifPk = false
        entityInfo.field.add(info)
    } else if (tableId != null) {
        info.dbName = tableId.value()
        info.ifPk = true
        entityInfo.pkField.add(info)
    } else {
        info.dbName = ""
    }
    def comment = field.getAnnotation(ApiModelProperty)
    if (comment != null) {
        info.comment = comment.value()
    }
    entityInfo.fieldAll.add(info)
}

println(entityInfo)

控制台输出如下信息

[
	dir:D:\work\workspaces\workspace-an\test,
	package:com.test.bean,
	name:UserInfo,
	tableName:USER_INFO,
	tableComment:用户信息详情,
	fieldName:[id, userName, userPw],
	pkField:[filedInfo@56f0cc85],
	field:[filedInfo@62e20a76, filedInfo@2cc44ad],
	fieldAll:[filedInfo@56f0cc85, filedInfo@62e20a76, filedInfo@2cc44ad]
]

其中id的filedInfo信息如下
name id;
capitalName  Id;
dbName  ID;
type  String;
typeFull  java.lang.String;
comment  主键ID;
ifPk true;

其中userName的filedInfo信息如下
name userName;
capitalName  UserName;
dbName  USER_NAME;
type  String;
typeFull  java.lang.String;
comment  用户名name;
ifPk false;

使用FreeMarker模板

还可以使用模板输出信息

//1.创建freeMarker配置实例
Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
//2.设置模板加载器:开始加载模板 scratches 文件夹为IDEA的临时文件夹
cfg.setDirectoryForTemplateLoading(new File("C:\\Users\\admin\\AppData\\Roaming\\JetBrains\\IntelliJIdea2023.2\\scratches"));

//4.获取模板
Template template = cfg.getTemplate("scratch.ftl");
template.process(entityInfo, new PrintWriter(System.out)); //在控制台输出

scratch.ftl 模板

package ${package};

<#list field as f>
    name ${f.name}; capitalName  ${f.capitalName}; dbName  ${f.dbName}; type  ${f.type}; typeFull  ${f.typeFull}; comment  ${f.comment}; ifPk ${f.ifPk?c};
</#list>

${dir}
${name}

<#list field as f>
    @ApiModelProperty(value = "${f.comment}")
    @TableField(value = "${f.dbName}")
    private ${f.type} ${f.name};
</#list>

package ${package};
@TableName("${tableName}")
@ApiModel(value = "${name}对象", description = "${tableComment}")
public class ${name} {
}

输出信息如下

package com.test.bean;

    name userName; capitalName  UserName; dbName  USER_NAME; type  String; typeFull  java.lang.String; comment  用户名name; ifPk true;
    name userPw; capitalName  UserPw; dbName  USER_PW; type  String; typeFull  java.lang.String; comment  用户密码; ifPk true;

D:\work\workspaces\workspace-an\test
UserInfo

    @ApiModelProperty(value = "用户名name")
    @TableField(value = "USER_NAME")
    private String userName;
    @ApiModelProperty(value = "用户密码")
    @TableField(value = "USER_PW")
    private String userPw;

package com.test.bean;
@TableName("USER_INFO")
@ApiModel(value = "UserInfo对象", description = "用户信息详情")
public class UserInfo {
}

总结

完全的脚本,只需要更换entity的变量即可,在下面的注释获取entity处,加载自己的临时文件夹获取自己定义的模板文件。

groovy_console.groovy

import com.baomidou.mybatisplus.annotation.TableField
import com.baomidou.mybatisplus.annotation.TableId
import com.baomidou.mybatisplus.annotation.TableName
import com.test.bean.UserInfo
import freemarker.template.Configuration
import freemarker.template.Template
import io.swagger.annotations.ApiModel
import io.swagger.annotations.ApiModelProperty
import org.apache.commons.lang3.StringUtils

import java.lang.annotation.Annotation

// 获取entity
def entity = UserInfo

// 字段信息
class filedInfo {
    def String name; // 默认驼峰命名法
    def String capitalName; // 首字母大写
    def String dbName; // 数据库的名字
    def String type; // 类型名称
    def String typeFull; // 类型全称
    def String comment; // 字段注释
    def boolean ifPk = false;
}

def entityInfo = [
        dir: System.getProperty("user.dir"), // 获取工程的目录
        package : entity.getPackage().name, // 获取包名
        name: entity.getSimpleName(), // 获取类名
        tableName: "",
        tableComment: "",
        fieldName: entity.getDeclaredFields().name, // 获取所有字段名
        pkField: [], // 获取id字段
        field: [], // 字段
        fieldAll: [], // 全部字段
]

def model = entity.getAnnotation(ApiModel)
if (model != null) {
    entityInfo.tableComment = model.description()
}
def table = entity.getAnnotation(TableName)
if (table != null) {
    entityInfo.tableName = table.value()
}

// 填充 field
for(def field in entity.getDeclaredFields()) {
    def info = new filedInfo()
    info.name = field.name
    info.capitalName = StringUtils.upperCase(field.name[0]) + field.name[1..field.name.length()-1]
    info.type = field.type.simpleName
    info.typeFull = field.type.name

    def tableField = field.getAnnotation(TableField)
    def tableId = field.getAnnotation(TableId)
    if (tableField != null) {
        info.dbName = tableField.value()
        info.ifPk = false
        entityInfo.field.add(info)
    } else if (tableId != null) {
        info.dbName = tableId.value()
        info.ifPk = true
        entityInfo.pkField.add(info)
    } else {
        info.dbName = ""
    }
    def comment = field.getAnnotation(ApiModelProperty)
    if (comment != null) {
        info.comment = comment.value()
    }
    entityInfo.fieldAll.add(info)
}

println(entityInfo)

//1.创建freeMarker配置实例
Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
//2.设置模板加载器:开始加载模板
cfg.setDirectoryForTemplateLoading(new File("C:\\Users\\admin\\AppData\\Roaming\\JetBrains\\IntelliJIdea2023.2\\scratches"));

//4.获取模板
Template template = cfg.getTemplate("scratch.ftl");
template.process(entityInfo, new PrintWriter(System.out)); //在控制台输出

scratch.ftl模板

可以根据自己需要进行定制

package ${package};

<#list field as f>
    name ${f.name}; capitalName  ${f.capitalName}; dbName  ${f.dbName}; type  ${f.type}; typeFull  ${f.typeFull}; comment  ${f.comment}; ifPk ${f.ifPk?c};
</#list>

<#--项目工程的主目录-->
${dir}
${name}

<#--循环非主键字段-->
<#list field as f>
    @ApiModelProperty(value = "${f.comment}")
    @TableField(value = "${f.dbName}")
    private ${f.type} ${f.name};
</#list>

package ${package};
@TableName("${tableName}")
@ApiModel(value = "${name}对象", description = "${tableComment}")
public class ${name} {
}

一些 entity 的信息

变量名称使用举例
dir获取工程的目录${dir}D:\work\workspaces\workspace-an\test
package获取包名${package}com.test.bean
name类名${name}UserInfo
tableName表名${tableName}USER_INFO
tableComment表注释${tableComment}用户信息详情
fieldName字段名称${fieldName}[id, userName, userPw]
pkField主键字段<#list pkField as f></#list>[filedInfo]
field非主键字段<#list field as f></#list>[filedInfo]
fieldAll全部字段(主键字段、非主键字段)<#list fieldAll as f></#list>[filedInfo]

field 字段信息 filedInfo

变量名称使用举例
name字段名称${f.name}userName
capitalName首字母大写${f.capitalName}UserName
dbName数据库字段名${f.dbName}USER_NAME
type类型名称${f.type}String
typeFull类型全称${f.typeFull}java.lang.String
comment字段注释${f.comment}用户名name
ifPk是否主键${f.ifPk?c}true|false

一些常用的模板

<#--循环主键字段-->
<#list pkField as f>
    @ApiModelProperty(value = "${f.comment}")
    @TableId(value = "${f.dbName}")
    private ${f.type} ${f.name};
</#list>
<#--循环非主键字段-->
<#list field as f>
    @ApiModelProperty(value = "${f.comment}")
    @TableField(value = "${f.dbName}")
    private ${f.type} ${f.name};
</#list>
<#--类class-->
package ${package};

@TableName("${tableName}")
@ApiModel(value = "${name}对象", description = "${tableComment}")
public class ${name} {
}
<#--getter和setter-->
<#list fieldAll as f>
	public ${f.type} get${f.capitalName}() {
        return ${f.name};
    }
    public void set${f.capitalName}(${f.type} ${f.name}) {
        this.${f.name}= ${f.name};
    }
</#list>
<#--生成json信息-->
[
<#list field as f>
    {
        "name": "${f.name}",
        "type": "${f.type}",
        "comment": "${f.comment}"
    },
</#list>
]
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值