日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

groovy定义变量获取当前时间_IDEA不愧为神器,结合Groovy脚本,简直无敌!

發(fā)布時(shí)間:2025/3/21 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 groovy定义变量获取当前时间_IDEA不愧为神器,结合Groovy脚本,简直无敌! 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者:人間哪有四月天

segmentfault.com/a/1190000020189801

導(dǎo)語

如今,有許許多多的插件或者編輯器都支持根據(jù)數(shù)據(jù)表自動(dòng)生成數(shù)據(jù)實(shí)體類了, 比如IDEA, 各種MyBatis的代碼生成工具, 等等. 本篇介紹一下如何使用IDEA的groovy腳本文件生成帶JPA注解的實(shí)體類

一, 使用IDEA連接數(shù)據(jù)庫

需注意:

正式版IDEA才有此功能, 社區(qū)版木有
演示圖片使用的IDEA版本為2018.3, 不同版本界面可能有細(xì)小差別

創(chuàng)建新的數(shù)據(jù)連接

  • 如果沒有, 可以上方菜單欄: 視圖-工具窗口-Database打開

  • 新建Oracle數(shù)據(jù)庫也是相同操作

配置數(shù)據(jù)連接

  • 填寫一個(gè)連接名,隨便填什么都行

  • 不用選擇,默認(rèn)就行

  • 填寫數(shù)據(jù)庫連接的 IP地址,比如本地?cái)?shù)據(jù)庫可以填寫:localhost或者127.0.0.1

  • 填寫數(shù)據(jù)庫開放的端口號(hào),一般沒設(shè)置的話默認(rèn)都是3306

  • 填寫你需要連接的數(shù)據(jù)庫名

  • 填寫數(shù)據(jù)庫的用戶名

  • 填寫數(shù)據(jù)庫密碼

  • 這里會(huì)有一個(gè)驅(qū)動(dòng)需要點(diǎn)擊下載,圖中是已經(jīng)下載好了

  • 填寫自己的數(shù)據(jù)庫連接url,然后可以點(diǎn)擊9所在按鈕進(jìn)行測(cè)試連接,本地連接失敗檢查是否開啟了mysql服務(wù)

二, IDEA自帶的兩種創(chuàng)建實(shí)體類的方法

(1), 如果只是創(chuàng)建簡單的, 只有屬性, getter, setter的實(shí)體類, 而不需要JPA/Hibernate的實(shí)體類注解

  • 單擊打開剛剛創(chuàng)建的數(shù)據(jù)連接

  • 打開schemas, 找到自己需要?jiǎng)?chuàng)建實(shí)體類的表(可以使用ctrl或shift多選)

  • 右鍵: Scripted Extensions - Generate POJOs.groovy

  • 選擇生成路徑就OK了

需注意

生成的包名可能有問題, 默認(rèn)是package com.sample, 需要自己手動(dòng)修改

(2), 使用了Hibernate/Jpa框架, 需要的是有注解的實(shí)體類, Idea也提供了相應(yīng)的方法

推薦:100期面試題匯總

添加JPA模塊

  • 打開項(xiàng)目結(jié)構(gòu)

  • 打開模塊, 點(diǎn)擊+號(hào)添加模塊

  • 選擇JPA

  • 點(diǎn)擊右下角確定后, 關(guān)閉項(xiàng)目結(jié)構(gòu)

使用Persistence工具生成帶注解的實(shí)體類-1

  • 如果上一步?jīng)]問題的話, IDEA左下角側(cè)邊欄會(huì)出現(xiàn)Persistence工具欄

  • 打開Persistence工具欄, 右鍵項(xiàng)目: Generate Persistence Mapping - By Database Schema

使用Persistence工具生成帶注解的實(shí)體類-2

  • 選擇數(shù)據(jù)庫連接

  • 選擇生成類所在包

  • 選擇要生成的表

  • 選擇要生成的字段(選擇表后字段默認(rèn)除了外鍵全選)

  • 修改要生成的屬性名

  • 修改要生成的屬性類型

  • 勾上即為生成帶注解的實(shí)體類

生成的類實(shí)例如下

三, 更進(jìn)一步, 使用自己的Groovy生成帶注解的實(shí)體類

上面介紹了兩個(gè)使用IDEA生成實(shí)體類的方法, 各有優(yōu)缺點(diǎn)

  • 生成不帶注解的實(shí)體類簡單高效, 但缺點(diǎn)就是如果使用的是Jpa/Hibernate框架就不適合

  • 生成帶注解的實(shí)體類能生成注解實(shí)體類, 但缺點(diǎn)就是生成的實(shí)體類的注解可能不太符合我們的注解, 只能生成到當(dāng)前項(xiàng)目包下, 面對(duì)一些復(fù)雜的數(shù)據(jù)庫如Oracle會(huì)顯示很多系統(tǒng)表而且表空間切換不太方便

我們知道Idea生成不帶注解的實(shí)體類是通過Groovy腳本文件生成的, 我們也能找到這個(gè)文件, 那我們能不能修改這個(gè)文件, 讓它生成帶注解的實(shí)體類呢?

(1), 使用自己的Groovy生成帶注解的實(shí)體類的好處

  • 在Database工具欄里, 操作簡單方便

  • 可以自己對(duì)腳本進(jìn)行一些編輯, 使生成的實(shí)體類達(dá)到自己的定制需求

  • 對(duì)Oracle這樣的數(shù)據(jù)庫生成實(shí)體類時(shí), 避免了系統(tǒng)表的影響, 可以自己選擇表空間進(jìn)行操作

  • 可以生成在電腦上的任何位置, 不受限制

(2), 使用自己的Groovy生成帶注解的實(shí)體類的不足

  • @author 作者名需要自己修改腳本

  • @Table(Schema="") 的表空間名不能讀取, 需要自己修改腳本, 設(shè)定表空間名(mysql可以直接刪除這個(gè)屬性的定義)(IDEA的Persistence工具可以讀取(Schema=""屬性并生成, 但我們不知道它是怎么獲取的)

  • @Id的主鍵生成方式不可知, 需要生成后自己確定(mysql用戶可以直接修改腳本設(shè)定主鍵生成方式, 但Oracle用戶需要生成實(shí)體類后再逐個(gè)確認(rèn))

(3), 使用自己的Groovy生成帶注解的實(shí)體類可以繼續(xù)完善的地方

1, 如果需要hashcode()和equals()方法, 也修改腳本, 使其自動(dòng)生成

(4), 新建一個(gè)Groovy腳本文件

Database工具欄里, 右鍵右鍵: Scripted Extensions - Go to Scripts Directory

在目錄下新建一個(gè)Generate MyPOJOs.groovy

添加里面的內(nèi)容

  • 修改idea為自己名字 的地方可以修改作者名字為自己的

  • schema = \"后面添加自己的表空間名稱(mysql可以不添加, 不用這個(gè)schema屬性也行) 這里可以根據(jù)提示修改

  • 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
    ?*???PROJECT?????project
    ?*???FILES???????files?helper
    ?*/
    packageName?=?""
    typeMapping?=?[
    ????????(~/(?i)tinyint|smallint|mediumint/)??????:?"Integer",
    ????????(~/(?i)int/)?????????????????????????????:?"Long",
    ????????(~/(?i)bool|bit/)????????????????????????:?"Boolean",
    ????????(~/(?i)float|double|decimal|real/)???????:?"Double",
    ????????(~/(?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?=?javaName(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.Column;"
    ????out.println?"import?javax.persistence.Entity;"
    ????out.println?"import?javax.persistence.Table;"
    ????out.println?"import?javax.persistence.Id;"
    ????out.println?"import?javax.persistence.GeneratedValue;"
    ????out.println?"import?java.io.Serializable;"
    ????Set?types?=?new?HashSet()

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

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

    ????if?(types.contains("InputStream"))?{
    ????????out.println?"import?java.io.InputStream;"
    ????}
    ????out.println?""
    ????out.println?"/**\n"?+
    ????????????"?*?@Description??\n"?+
    ????????????"?*?@Author??idea\n"?+?//1.?修改idea為自己名字
    ????????????"?*?@Date?"?+?new?SimpleDateFormat("yyyy-MM-dd").format(new?Date())?+?"?\n"?+
    ????????????"?*/"
    ????out.println?""
    ????out.println?"@Entity"
    ????out.println?"@Table?(?name?=\""?+?table.getName()?+?"\"?,?schema?=?\"\")"?//2.?schema?=?\"后面添加自己的表空間名稱(mysql可以不添加,?不用這個(gè)schema屬性也行)
    ????out.println?"public?class?$className??implements?Serializable?{"
    ????out.println?""
    ????out.println?genSerialID()
    ????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)?out.println?"\t@Id"

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


    ????????//?輸出成員變量
    ????????out.println?"\tprivate?${it.type}?${it.name};"
    ????}

    ????//?輸出get/set方法
    ????fields.each()?{
    ????????out.println?""
    ????????out.println?"\tpublic?${it.type}?get${it.name.capitalize()}()?{"
    ????????out.println?"\t\treturn?this.${it.name};"
    ????????out.println?"\t}"
    ????????out.println?""

    ????????out.println?"\tpublic?void?set${it.name.capitalize()}(${it.type}?${it.name})?{"
    ????????out.println?"\t\tthis.${it.name}?=?${it.name};"
    ????????out.println?"\t}"
    ????}

    ????//?輸出toString方法
    ????out.println?""
    ????out.println?"\t@Override"
    ????out.println?"\tpublic?String?toString()?{"
    ????out.println?"\t\treturn?\"TpApiConfig{\"?+"
    ????fields.each()?{
    ????????out.println?"\t\t\t\t\"${it.name}='\"?+?${it.name}?+?'\\''?+"
    ????}
    ????out.println?"\t\t\t\t'}';"
    ????out.println?"\t}"

    ????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]
    ????}
    }

    //?已經(jīng)修改為使用javaName,?如果有需要可以在def?className?=?javaName(table.getName(),?true)中修改為javaClassName
    //?處理類名(這里是因?yàn)槲业谋矶际且詔_命名的,所以需要處理去掉生成類名時(shí)的開頭的T,
    //?如果你不需要那么請(qǐng)查找用到了?javaClassName這個(gè)方法的地方修改為?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?strif?(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('')
    ????}
    }

    static?String?genSerialID()?{
    ????return?"\tprivate?static?final?long?serialVersionUID?=??"?+?Math.abs(new?Random().nextLong())?+?"L;"
    }

    表上右鍵, 選擇自己寫的腳本生成實(shí)體類

    效果如下:

    瑣碎時(shí)間想看一些技術(shù)文章,可以去公眾號(hào)菜單欄翻一翻我分類好的內(nèi)容,應(yīng)該對(duì)部分童鞋有幫助。同時(shí)看的過程中發(fā)現(xiàn)問題歡迎留言指出,不勝感謝~。另外,有想多了解哪些方面內(nèi)容的可以留言(什么時(shí)候,哪篇文章下留言都行),附菜單欄截圖(PS:很多人不知道公眾號(hào)菜單欄是什么)

    END

    我知道你 “在看

    總結(jié)

    以上是生活随笔為你收集整理的groovy定义变量获取当前时间_IDEA不愧为神器,结合Groovy脚本,简直无敌!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。