idea:jpa通过groovy脚本自动生成实体类

该博客介绍了如何通过Groovy脚本来自动化生成基于JPA的实体类。脚本从数据库表中读取信息,根据数据类型映射为对应的Java类型,并添加注解如@Id、@Column等。同时,脚本还包含了处理表前缀、生成序列化ID等功能,大大提高了开发效率。
摘要由CSDN通过智能技术生成

jpa通过groovy脚本自动生成实体类

import com.intellij.database.model.DasTable
import com.intellij.database.model.ObjectKind
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil

import java.text.SimpleDateFormat

/*
 * Available context bindings:
 *   SELECTION   Iterable<DasObject>
 *   PROJECT     project
 *   FILES       files helper
 */
packageName = ""
typeMapping = [
        (~/(?i)tinyint|smallint|mediumint/)      : "Integer",
        (~/(?i)int/)                             : "Long",
        (~/(?i)bool|bit/)                        : "Boolean",
        (~/(?i)float|double|decimal|real/)       : "BigDecimal",
        (~/(?i)datetime|timestamp|date|time/)    : "Date",
        (~/(?i)blob|binary|bfile|clob|raw|image/): "InputStream",
        (~/(?i)/)                                : "String"
]


FILES.chooseDirectoryAndSave("Choose directory", "Choose where to store generated files") { dir ->
    SELECTION.filter { it instanceof DasTable && it.getKind() == ObjectKind.TABLE }.each { generate(it, dir) }
}

def generate(table, dir) {
    def className = javaClassName(table.getName(), true)
    def fields = calcFields(table)
    packageName = getPackageName(dir)
    PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(dir, className + ".java")), "UTF-8"))
    printWriter.withPrintWriter { out -> generate(out, className, fields, table) }

//    new File(dir, className + ".java").withPrintWriter { out -> generate(out, className, fields,table) }
}

// 获取包所在文件夹路径
def getPackageName(dir) {
    return dir.toString().replaceAll("\\\\", ".").replaceAll("/", ".").replaceAll("^.*src(\\.main\\.java\\.)?", "") + ";"
}

def generate(out, className, fields, table) {
    out.println "package $packageName"
    out.println ""
    out.println "import javax.persistence.*;"
    out.println "import java.io.Serializable;"
    out.println "import lombok.*;"
    out.println "import org.springframework.data.jpa.domain.support.AuditingEntityListener;"
    Set types = new HashSet()

    fields.each() {
        types.add(it.type)
    }

    if (types.contains("Date")) {
        out.println "import java.util.Date;"
    }

    if (types.contains("BigDecimal")) {
        out.println "import java.math.BigDecimal;"
    }

    if (types.contains("InputStream")) {
        out.println "import java.io.InputStream;"
    }
    out.println ""
    out.println "/**\n" +
            " * @Author  deng yi cong\n" + //1. 修改idea为自己名字
            " * @Date " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " \n" +
            " */"
    out.println ""
    out.println "@Data"
    out.println "@ToString"
    out.println "@Entity"
    out.println "@EntityListeners(AuditingEntityListener.class)"
    out.println "@Table ( name =\"" + table.getName() + "\")" //2. schema = \"后面添加自己的表空间名称(mysql可以不添加, 不用这个schema属性也行)
    out.println "public class $className  implements Serializable {"
    out.println ""
    out.println genSerialID()
    def flag=false
    fields.each() {
        out.println ""
        // 输出注释
        if (isNotEmpty(it.commoent)) {
            out.println "\t/**"
            out.println "\t * ${it.commoent.toString()}"
            out.println "\t */"
        }

        if ((it.annos+"").indexOf("id") >= 0 && flag==false) {
            out.println "\t@Id"
            out.println "\t@GeneratedValue(strategy = GenerationType.IDENTITY)"
            flag=true
        }

        if (it.annos != "") out.println " ${it.annos.replace("[@id]", "")}"

        // 输出成员变量
        out.println "\tprivate ${it.type} ${it.name};"

    }


    out.println ""
    out.println "}"
}

def calcFields(table) {
    DasUtil.getColumns(table).reduce([]) { fields, col ->
        def spec = Case.LOWER.apply(col.getDataType().getSpecification())

        def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
        def comm = [
                colName : col.getName(),
                name    : javaName(col.getName(), false),
                type    : typeStr,
                commoent: col.getComment(),
                annos   : "\t@Column(name = \"" + col.getName() + "\" )"]
        if ("id".equals(Case.LOWER.apply(col.getName())))
            comm.annos += ["@Id"]
        fields += [comm]
    }
}

// 这里是处理数据库表前缀的方法,这里处理的是t_xxx命名的表
// 已经修改为使用javaName, 如果有需要可以在def className = javaName(table.getName(), true)中修改为javaClassName
// 处理类名(这里是因为我的表都是以t_命名的,所以需要处理去掉生成类名时的开头的T,
// 如果你不需要去掉表的前缀,那么请查找用到了 javaClassName这个方法的地方修改为 javaName 即可)
def javaClassName(str, capitalize) {
    def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
            .collect { Case.LOWER.apply(it).capitalize() }
            .join("")
            .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
    // 去除开头的T  http://developer.51cto.com/art/200906/129168.htm
    s = s[1..s.size() - 1]
    capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
}

def javaName(str, capitalize) {
//    def s = str.split(/(?<=[^\p{IsLetter}])/).collect { Case.LOWER.apply(it).capitalize() }
//            .join("").replaceAll(/[^\p{javaJavaIdentifierPart}]/, "_")
//    capitalize || s.length() == 1? s : Case.LOWER.apply(s[0]) + s[1..-1]
    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]
}

def isNotEmpty(content) {
    return content != null && content.toString().trim().length() > 0
}

static String changeStyle(String str, boolean toCamel) {
    if (!str || str.size() <= 1)
        return str

    if (toCamel) {
        String r = str.toLowerCase().split('_').collect { cc -> Case.LOWER.apply(cc).capitalize() }.join('')
        return r[0].toLowerCase() + r[1..-1]
    } else {
        str = str[0].toLowerCase() + str[1..-1]
        return str.collect { cc -> ((char) cc).isUpperCase() ? '_' + cc.toLowerCase() : cc }.join('')
    }
}

//生成序列化的serialVersionUID
static String genSerialID() {
    return "\tprivate static final long serialVersionUID =  " + Math.abs(new Random().nextLong()) + "L;"
}


生成的实体类效果图在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
POJOGenerator(POJO代码生成器 v1.3.3) 本POJO代码生成器采用Java的Swing技术编码实现,是绿色免费工具,可以自由传播。 由于本工具的内部实现较烂,所以还请反编译高手手下留情,让我留几分颜面。^_^ 由于本人只用过Oracle、DB2、MySQL、MS SQL Server这四款数据库产品,所以制作 成exe可执行文件时只添入了这四款数据库的驱动支持。如果您需要使用这款工具从 其它数据库中生成POJO,那么您可以联系我(Email:CodingMouse@gmail.com), 我会添加其它数据库的驱动支持后通过电子邮件发送给您。 简单的使用说明: 1、先将压缩档解压到任意文件夹,必须保留配置文件cmsdk4j.cfg.xml和generator .cfg.xml与可执行文件POJOGenerator.exe在同一目录,否则无法运行。 2、可以预先在配置档cmsdk4j.cfg.xml中设定您的数据库服务器配置,配置档中已经 提供了默认的配置信息,您仅需在此基础上修改部分参数(如:IP地址、端口号、 用户名、密码、数据库名等),这些参数将作为生成器的预设数据库连接配置参数。 3、可以预先在配置档generator.cfg.xml中设定您的数据类型映射方案,配置档中已经 提供了MS SQL Server/MySQL/DB2和Oracle两种映射方案,当然,可能有不太完整的地方 ,您可以根据实际情况稍作修改即可。需要注意的一点是ref属性表示引用同一映射方案 的另一映射,这样您便可以简化同一映射数据类型的配置;而import属性是指定需要在 最终生成的源代码中作为类最开始的package类型导入声明部分的导入类型名称,因此, 这个名称是完整带包名的类名称,否则不能正确生成最终代码。配置档中提供的默认配 置如果不能满足你的需要,也可以自行根据实际情况进行修改。最后,需要大家注意的 一点就是由于最终生成的代码要调用包装类型的equals和hashCode方法,因此,配置的 数据类型必须是包装类型,如果用基本类型生成的POJO代码是无法通过编译的。 4、所有配置档仅在工具启动初始读取一次并缓存到内存中,因此,如果您是在工具运行 时修改的配置档,请重新启动本工具以使新的配置生效。并且,所有配置档的XML结构均 不能修改,只能修改其节点间的文本值或属性值,以及添加新的标签组,否则会导致本 工具无法工作。选择“界面皮肤方案”后,默认会在当前目录生成名为skin.dat的文件, 这是一个Properties属性文件,用于保存您最后选择的皮肤名称,以便下次打开此工具 时加载您所选择的皮肤来渲染工具UI界面。 5、所有最终代码生成效果都可以在左边的代码预览区域中查看,可点击滑动箭头显示出 被隐藏的POJO代码卡片。点击“写入磁盘文件”按钮即可将POJO代码的Java源码文件写入 到指定文件夹中。POJO代码的equals方法重写完全符合《Core Java》所述规范,同时, 其中的hashCode方法重写则参考了Netbeans中JavaBean转换器的写法。为保障原有代码安 全,通常更好的做法是将最终代码生成后拷贝到您的项目对应文件夹中。最好不要直接指 向您的项目文件夹,因为本工具会直接覆盖掉指定目录中同名的文件。最终生成的代码文 件以.java为扩展名。 6、从1.3版开始生成的POJO代码目录中可自动添加一个名为pojo.ntf.xml的POJO映射通 知档,其中,ID列名默认使用主键名称(若为复合主键则采用次序排首位的主键列名) ,而Oracle环境下的sequence对象名称则为“seq_表名_id”格式的默认名称,请根据 实际情况修改。该配置档用于CmSdk4j-Core框架的ORM映射,不需要则请不要勾选此项或 在生成后直接删除即可。 7、目前1.3.3版与1.3版差异不大,仅修改了POJO类名与成员变量名的大小写处理策略。 即目标数据库服务器为Oracle时,才将表名除首字母外全部小写处理成POJO类名,同理, 成员变量名也只在Oracle数据库情况下才全小写处理。其余数据库如:DB2、MySQL、 MS SQL Server则直接处理为除首字母大写外,其余全部保留原始大小写。其中,对于 表名的处理还直接去掉了空格符和下划线,并且若为Oracle数据库时,下划线亦作为首 字母大写的分隔标志,如:HRM_HUMAN_RESOURCE,最终生成的POJO类名将直接去掉串中 的下划线,并以下划线作为首字母大写的起始,即:HrmHumanResource + POJO类名后缀。 同理,成员变量名的处理也是采用了相同的处理策略。最终处理效果详见生成写入到磁盘 的pojo.ntf.xml配置档。 8、此小工具一直均只写来自用,以便与自己的O/R Mapping简易版工具配套使用,目前 1.3.3这个版本已经能满足自己的需要,同时为了方便预览POJO代码生成的效果,特意添 加了语法着色功能,其着色色调搭配和关键字字典数据来源于EmEditor这款带语法着色的 纯文本编辑器,并且该色调搭配方案也被多款JS版本的语法着色器采用,色调可读性较高。 此小工具虽然GUI、功能这些都相对较弱,但自用已经足够。因此,后期可能就不再考虑 功能更新了,请见谅! 如果您有好的建议,请发送留言到作者博客:http://blog.csdn.net/CodingMouse 或发送邮件到:CodingMouse@gmail.com 本工具已经打包成exe可执行文件,便于在Window环境下运行,但仍需要你的机器上 安装至少1.6版本的jre环境(受打包工具的jre版本不兼容限制影响)。 By CodingMouse 2010年5月22日
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值