IDEA + Groovy腳本一鍵生成實(shí)體類,用法舒服,高效!

作者:悲涼的秋風(fēng)
blog.csdn.net/qq_34371461/article/details/80571281
idea 功能很強(qiáng)大,以前不知道有這樣的提升工作效率的方法,雖然有的工具確實(shí)可以直接生成實(shí)體類,mapper文件,還有dao接口,但是個(gè)人覺得涉及到復(fù)雜業(yè)務(wù)還是只生成實(shí)體類比較好,后面部分就自己搞定就可以了。
一、連接數(shù)據(jù)庫(kù)
打開項(xiàng)目:
1、點(diǎn)擊右側(cè)的datesource圖標(biāo),要是沒有該圖標(biāo),請(qǐng)去自行百度
2、點(diǎn)擊 + 號(hào)
3、選擇 datasource
4、選擇 mysql
1、填寫一個(gè)連接名,隨便填什么都行
2、不用選擇,默認(rèn)就行
3、填寫數(shù)據(jù)庫(kù)連接的 IP地址,比如本地?cái)?shù)據(jù)庫(kù)可以填寫:localhost或者127.0.0.1
4、填寫數(shù)據(jù)庫(kù)開放的端口號(hào),一般沒設(shè)置的話默認(rèn)都是3306
5、填寫你需要連接的數(shù)據(jù)庫(kù)名
6、填寫數(shù)據(jù)庫(kù)的用戶名
7、填寫數(shù)據(jù)庫(kù)密碼
8、這里會(huì)有一個(gè)驅(qū)動(dòng)需要點(diǎn)擊下載,圖中是已經(jīng)下載好了
9、填寫自己的數(shù)據(jù)庫(kù)連接url,然后可以點(diǎn)擊9所在按鈕進(jìn)行測(cè)試連接,本地連接失敗檢查是否開啟了mysql服務(wù)
連接好了如上圖所示,可以看到自己的數(shù)據(jù)庫(kù)和表,選擇一個(gè)表右鍵,網(wǎng)上教程一般到這里結(jié)束,都是選擇說Generate POJOs.groovy,然后在彈出窗口選擇需要生成的文件夾所在即可。

我選擇一張表進(jìn)行生成示例如下:
表明去除了“_”然后以駝峰方式生成了類名,而且開始的package 路徑也不對(duì),重點(diǎn)是沒有注釋,沒有注釋,沒有注釋!
網(wǎng)上搜了一些方法,都不太行,要不就是到處報(bào)錯(cuò),沒轍只能自己瞎琢磨。沒想到最后也不難,下面就是實(shí)現(xiàn):
右鍵選擇表,在選擇Generate POJOs.groovy 的下面那一項(xiàng):
進(jìn)來只有Generate POJOs.groovy,右鍵新建另外一個(gè)比如我的叫做:Generate MyPOJOs.groovy,里面內(nèi)容如下:
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.io.*
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?=?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.Column;"
????out.println?"import?javax.persistence.Entity;"
????out.println?"import?javax.persistence.Table;"
????out.println?"import?java.io.Serializable;"
????out.println?"import?lombok.Getter;"
????out.println?"import?lombok.Setter;"
????out.println?"import?lombok.ToString;"
????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??Hunter\n"?+
????????????"?*?@Date?"+?new?SimpleDateFormat("yyyy-MM-dd").format(new?Date())?+?"?\n"?+
????????????"?*/"
????out.println?""
????out.println?"@Setter"
????out.println?"@Getter"
????out.println?"@ToString"
????out.println?"@Entity"
????out.println?"@Table?(?name?=\""+table.getName()?+"\"?)"
????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?!=?"")?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}"
//????}
????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]
????}
}
?
//?處理類名(這里是因?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?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('')
????}
}
?
static?String?genSerialID()
{
????return?"\tprivate?static?final?long?serialVersionUID?=??"+Math.abs(new?Random().nextLong())+"L;"
}
完成后,點(diǎn)擊此處,選擇project 切換回來:

這時(shí),我們?cè)俅芜x擇表,右鍵,選擇我們自己新建的 groovy,然后選擇生成存放的文件夾路徑,生成:
可以看到,生成的類名,package路徑,以及已經(jīng)實(shí)現(xiàn)了序列化,也加上了注解,指明了每個(gè)屬性對(duì)應(yīng)的表字段,如果@Table和@Column沒有引入包,還請(qǐng)?jiān)趍aven中添加相關(guān)依賴:
????javax.persistence
????persistence-api
????1.0.2
關(guān)于 groovy ,個(gè)人也是懂得不多,很多東西都是照葫蘆畫瓢,歡迎各位拍磚共同交流,要是本文對(duì)你有所幫助,歡迎點(diǎn)贊支持一下,謝謝~~~
更多精彩推薦
?? ?Google 鼓勵(lì)的 13 條代碼審查標(biāo)準(zhǔn),建議收藏!????這些SQL錯(cuò)誤用法,如果經(jīng)常犯,說明你的水平還很low...?? ?為啥不能用uuid做MySQL的主鍵??? ?微信第 1 行代碼曝光!?? ?奇葩公司按代碼行數(shù)算工資,員工一個(gè)月提成2.6萬遭開除
最后,推薦給大家一個(gè)有趣有料的公眾號(hào):寫代碼的渣渣鵬,回復(fù) 面試 或 資源 送一你整套開發(fā)筆記

