在日常的项目开发过程中,大部分人可能都会遇到过想从表自动生成带有注释的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
* 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 //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的生成工作。
接下来,我们通过一个具体的例子给大家介绍一下。
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 ='行政区基本信息';
通过执行如下操作即可生成我们要的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的反编译功能就可能看到这些类的大致结构了。
DataBase 插件相关组件类图 |