在日常的项目开发过程中,大部分人可能都会遇到过想从表自动生成带有注释的Java Bean,在Jetbrains IDEA中通过DataBase工具也是可以生成的。Jetbrains IDEA的Database借助一个名称为Generate POJOs.groovy的groovy模板文件,可以帮我们做代码生成工作,但是原始的Generate POJOs.groovy文件生成的Java Bean是没有类注释和字段注释的,为了生成带有类注释和字段注释的Java Bean,我们需要对该文件做如下调整,具体内容如下:

import com.google.common.base.CaseFormat
import com.intellij.database.model.DasObject
import com.intellij.database.model.DasTable
import com.intellij.database.model.ObjectKind
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil

/**
 * modification of origin script :
 * - add comment support (if you are non native English user, it is very important)
 * - make names with underscore better: such as `t_my_table` -> `tMyTable`
 */

/*
 * Available context bindings:
 *   SELECTION   Iterable<DasObject>
 *   PROJECT     project
 *   FILES       files helper
 */

//packageName = "com.sample;"
packageName = "com.qwfys.sample.daopai.data.entity;"
//typeMapping = [
//        (~/(?i)int/)                      : "long",
//        (~/(?i)float|double|decimal|real/): "double",
//        (~/(?i)datetime|timestamp/)       : "java.sql.Timestamp",
//        (~/(?i)date/)                     : "java.sql.Date",
//        (~/(?i)time/)                     : "java.sql.Time",
//        (~/(?i)/)                         : "String"
//]

typeMapping = [
        (~/(?i)bigint/)                   : "BigInteger",
        (~/(?i)tinyint/)                  : "Byte",
        (~/(?i)int/)                      : "Integer",
        //(~/(?i)float|double|decimal|real/): "double",
        (~/(?i)float|double|decimal|real/): "BigDecimal",
        //  (~/(?i)datetime|timestamp/)       : "java.sql.Timestamp",
        (~/(?i)datetime|timestamp/)       : "LocalDateTime",
        //  (~/(?i)date/)                     : "java.sql.Date",
        (~/(?i)date/)                     : "LocalDate",
        (~/(?i)time/)                     : "LocalTime",
        (~/(?i)/)                         : "String"
]
FILES.chooseDirectoryAndSave("Choose directory", "Choose where to store generated files") { dir ->
    //assert SELECTION instanceof Iterable<DasObject> //no use
    SELECTION.filter { it instanceof DasTable && it.getKind() == ObjectKind.TABLE }.each { generate(it, dir) }
}

def generate(DasObject table, dir) {
    def tableComment = getTableComment(table)
    if (tableComment == null || "".equals(tableComment)) {
        tableComment = ""
    } else {
        tableComment = """
/**
 * $tableComment
 */"""
    }
    def className = javaName(table.name, true)
    def fields = calcFields(table)
    new File(dir, className + "Entity.java").withPrintWriter { out -> generate(out, className, tableComment, fields) }
}

def generate(out, className, tableComment, fields) {
    out.println "package $packageName"
    out.println ""

    def importPackages = [""] as HashSet
    fields.each() {
        if ("BigInteger".equals(it.type)) {
            importPackages += "java.math.BigInteger"
        }

        if ("BigDecimal".equals(it.type)) {
            importPackages += "java.math.BigDecimal"
        }

        if ("LocalDateTime".equals(it.type)) {
            importPackages += "java.time.LocalDateTime"
        }

        if ("LocalDateTime".equals(it.type)) {
            importPackages += "java.time.LocalDateTime"
        }
    }

    importPackages.each() {
        if (!"".equals(it)) {
            out.println "import $it;"
        }
    }

    out.println "import lombok.Data;"
    out.println ""
    //out.println ""
    if (tableComment != "") out.println "  $tableComment"
    out.println "@Data"
    out.println "public class ${className}Entity {"
    //out.println ""
    fields.each() {
        if (it.annos != "") out.println "  ${it.annos}"
        out.println "  private ${it.type} ${it.name};"
    }
    //out.println ""
    //fields.each() {
    //    out.println ""
    //    out.println "  public ${it.type} get${it.name.capitalize()}() {"
    //    out.println "    return ${it.name};"
    //    out.println "  }"
    //    out.println ""
    //    out.println "  public void set${it.name.capitalize()}(${it.type} ${it.name}) {"
    //    out.println "    this.${it.name} = ${it.name};"
    //    out.println "  }"
    //    out.println ""
    //}
    out.println "}"
}

def getTableComment(table) {
    return table.getComment();
}

def calcFields(DasObject table) {
    DasUtil.getColumns(table).reduce([]) { fields, col ->
        def spec = Case.LOWER.apply(col.dataType.specification)
        def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
        fields += [
                name : javaName(col.name, false),
                type : typeStr,
                annos: col.comment ? """
    /**
     * $col.comment
     */""" : ""
        ]
    }
}

static String javaName(String str, boolean capitalize) {
    def s = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, str);
    capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
}

//def javaName(str, capitalize) {
//    def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
//            .collect { Case.LOWER.apply(it).capitalize() }
//            .join("")
//            .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
//    capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
//}

将该文件个性为上述内容以后,就以完成由表到Java Bean的生成工作。

  接下来,我们通过一个具体的例子给大家介绍一下。

  • 步骤1:基于如下脚本创建一张表
DROP TABLE IF EXISTS `region`;
CREATE TABLE `region` (
    `id`             bigint       NOT NULL AUTO_INCREMENT COMMENT '标识符',
    `code`           varchar(128) NOT NULL COMMENT '编码',
    `parent_code`    varchar(128) NOT NULL COMMENT '上级编码',
    `name`           varchar(128) NOT NULL COMMENT '名称',
    `full_name`      varchar(128) NOT NULL COMMENT '全称',
    `level`          int          NOT NULL COMMENT '层级',
    `province`       varchar(128) NOT NULL COMMENT '省份',
    `city`           varchar(128) NOT NULL COMMENT '地市',
    `district`       varchar(128) NOT NULL COMMENT '区县',
    `township`       varchar(128) NOT NULL COMMENT '乡镇',
    `created_by`     bigint       NOT NULL COMMENT '添加者',
    `created_time`   datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
    `updated_by`     bigint       NOT NULL COMMENT '添加者',
    `updated_time`   datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    `removed_status` tinyint      NOT NULL DEFAULT '0' COMMENT '移除状态,0-未移除,1-已移除',
    `version`        int          NOT NULL DEFAULT '1' COMMENT '版本号',
    PRIMARY KEY (`id`)
) COMMENT ='行政区基本信息';
  • 步骤2:生成Java Bean

通过执行如下操作即可生成我们要的Java Bean:DataBase --> 大家自己的数据库 --> tabses --> 单击鼠标右键 --> Tools --> Scripted Extensions --> Generate POJO.groovy,在此过程中系统会弹出一个目录选择对话框要求我们选择生成的Java Bean存放的目录,操作完成以后,就会我们指定的目录下生成了一个对应的Java Bean,具体如下:

package com.qwfys.sample.daopai.data.entity;

import java.time.LocalDateTime;
import java.math.BigInteger;
import lombok.Data;

  
/**
 * 行政区基本信息
 */
@Data
public class RegionEntity {
  
    /**
     * 标识符
     */
  private BigInteger id;
  
    /**
     * 编码
     */
  private String code;
  
    /**
     * 上级编码
     */
  private String parentCode;
  
    /**
     * 名称
     */
  private String name;
  
    /**
     * 全称
     */
  private String fullName;
  
    /**
     * 层级
     */
  private Integer level;
  
    /**
     * 省份
     */
  private String province;
  
    /**
     * 地市
     */
  private String city;
  
    /**
     * 区县
     */
  private String district;
  
    /**
     * 乡镇
     */
  private String township;
  
    /**
     * 添加者
     */
  private BigInteger createdBy;
  
    /**
     * 添加时间
     */
  private LocalDateTime createdTime;
  
    /**
     * 添加者
     */
  private BigInteger updatedBy;
  
    /**
     * 更新时间
     */
  private LocalDateTime updatedTime;
  
    /**
     * 移除状态,0-未移除,1-已移除
     */
  private Byte removedStatus;
  
    /**
     * 版本号
     */
  private Integer version;
}

  相对来说,还是蛮方便的。基于同样的道理,如果大家在些基础上编写生成数据访问层的代码,也是可以实现的,如果大家有兴趣可以尝试一下。

  Groovy文件中引入的包com.intellij.database.*涉及的几个类文件放在了目录${Jetbrains_ IDEA_HOME}/plugin/DatabaseTools/lib中的database-plugin.jar中,将该文件添加到项目类路径下,借助Jetbrains IDEA的反编译功能就可能看到这些类的大致结构了。

IDEA根据wsdl生成java代码 idea生成javabean_IDEA

DataBase 插件相关组件类图