结合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脚本在IDEA可以为所欲为——根据已有的entity信息使用freemarker模板_第1张图片
文件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: "",
        filesName: entity.getDeclaredFields().name, // 获取所有字段名
        pkFiles: [], // 获取id字段
        files: [], // 字段
        filesAll: [], // 全部字段
]

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

// 填充 files
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.files.add(info)
    } else if (tableId != null) {
        info.dbName = tableId.value()
        info.ifPk = true
        entityInfo.pkFiles.add(info)
    } else {
        info.dbName = ""
    }
    def comment = field.getAnnotation(ApiModelProperty)
    if (comment != null) {
        info.comment = comment.value()
    }
    entityInfo.filesAll.add(info)
}

println(entityInfo)

控制台输出如下信息

[
	dir:D:\work\workspaces\workspace-an\test,
	package:com.test.bean,
	name:UserInfo,
	tableName:USER_INFO,
	tableComment:用户信息详情,
	filesName:[id, userName, userPw],
	pkFiles:[filedInfo@56f0cc85],
	files:[filedInfo@62e20a76, filedInfo@2cc44ad],
	filesAll:[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 files 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 files 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: "",
        filesName: entity.getDeclaredFields().name, // 获取所有字段名
        pkFiles: [], // 获取id字段
        files: [], // 字段
        filesAll: [], // 全部字段
]

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

// 填充 files
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.files.add(info)
    } else if (tableId != null) {
        info.dbName = tableId.value()
        info.ifPk = true
        entityInfo.pkFiles.add(info)
    } else {
        info.dbName = ""
    }
    def comment = field.getAnnotation(ApiModelProperty)
    if (comment != null) {
        info.comment = comment.value()
    }
    entityInfo.filesAll.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 files 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 files 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} 用户信息详情
filesName 字段名称 ${filesName} [id, userName, userPw]
pkFiles 主键字段 <#list pkFiles as f> [filedInfo]
files 非主键字段 <#list files as f> [filedInfo]
filesAll 全部字段(主键字段、非主键字段) <#list filesAll as f> [filedInfo]

files 字段信息 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 pkFiles as f>
    @ApiModelProperty(value = "${f.comment}")
    @TableId(value = "${f.dbName}")
    private ${f.type} ${f.name};
#list>
<#--循环非主键字段-->
<#list files 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 filesAll 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 files as f>
    {
        "name": "${f.name}",
        "type": "${f.type}",
        "comment": "${f.comment}"
    },
#list>
]

你可能感兴趣的:(工具使用,intellij-idea,java)