SpringBootJPA⾃动⽣成代码(⼀)⽣成实体类
之前做SSM项⽬时,⼀直使⽤的是Mybatis的Generator⾃动⽣成代码⼯具,也是蛮好使的。现在换了SpringBoot,⾃动⽣成代码使⽤的是⼈⼈开源项⽬修改来的,可以直接⽣成简单的CRUD代码和HTML页⾯。
⼀次偶然的机会,帮⾥⼀个⽼弟看代码时,发现他们⾃动⽣成代码是⽤的JPA,之前听说过这个,但是没有⽤过,所以也是⼀脸懵逼的。于是查了查怎么⽤,之后发现也是很神奇的,也是可以直接⽣成实体类,然后Dao层和Service直接继承就可以完成简单的CRUD了,⾃⼰刚接触,这⾥记录⼀下简单的使⽤过程。
今天是第⼀次使⽤JPA⽣成代码,在查了半天之后,发现⾃动⽣成的脚本的样式是千奇百怪的,那个⽼弟还⾮要按照别⼈的代码格式⽣成,但是⼈家⼜不给他⽣成代码的脚本,让他⾃⼰百度,对于⼩⽩的我就很懵逼了。
这⾥使⽤的是IDEA,其⾃带的⽣成实体类的脚本vy有点过于简单了,那么下⾯先看看⾃带的这个脚本怎么⽤。
⾸先是打开DataSource
这时会在右边弹出如下图的窗⼝,由于我这⾥已经添加过数据库了,第⼀次打开会提⽰使⽤Alt + Insert 进⾏添加数据库,我这⾥使⽤的是MySQL。
输⼊需要连接的数据库的信息,然后点击左下⾓的下载⼯具,然后点击Test Connection,如果提⽰Success 证明连接成功了,这时点击Apply,ok即可。
下⾯还是使⽤的之前添加的jpa-demo这个数据库,可以看到这⾥只有⼀张User表,我们就拿这个来⽣成。
右键我们需要⽣成实体类的表格,这⾥可以多选,可以看到如下图。如果使⽤默认的脚本,可以直接点击最后的vy,这⾥我们简单的扩展⼀下,⾃定义我们⾃⼰的脚本。
可以看到,IDEA跳转到这个页⾯了,这个⽂件的内容就是系统⾃动带的⽣成实体类的脚本。
第⼀次⽤的时候没有仔细看,直接按照⽹上的博客直接⽣成了,感觉蛮神奇的,后来发现⽣成的跟那个项⽬⾥⾯别⼈写的不⼀样,这才反应过来,看⼀下这个脚本⽂件的内容,发现这个脚本也是有固定的套路的。
这⾥贴上⼀个简单的⽣成实体类的脚本,可以随意⾃⼰定制:
import com.del.DasTable
import com.del.ObjectKind
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil
SimpleDateFormat
/*
* Available context bindings:
*  SELECTION  Iterable<DasObject>
*  PROJECT    project
*  FILES      files helper
*/
packageName =""
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 = Name(), 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){
String().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.pe)
}
ains("Date")){
out.println "import java.util.Date;"
}
ains("BigDecimal")){
out.println "import java.math.BigDecimal;"jpa mybatis
}
ains("InputStream")){
out.println "import java.io.InputStream;"
}
out.println ""
out.println "/**\n" +
" * @Description  \n" +
" * @Author  linmengmeng\n" + //1. 修改idea为⾃⼰名字
" * @Date " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " \n" +
" */"
out.println ""
out.println "@Entity"
out.println "@Table ( name =\"" + Name() + "\" , schema = \"\")" //2. schema = \"后⾯添加⾃⼰的表空间名称(mysql可以不添加, 不⽤这个schema属
out.println "@Table ( name =\"" + Name() + "\" , schema = \"\")" //2. schema = \"后⾯添加⾃⼰的表空间名称(mysql可以不添加, 不⽤这个schema属性也⾏)
out.println "public class $className  implements Serializable {"
out.println ""
out.println genSerialID()
fields.each() {
out.println ""
// 输出注释
if (isNotEmpty(itmoent)) {
out.println "\t/**"
out.println "\t * ${String()}"
out.println "\t */"
}
if ((it.annos+"").indexOf("[@Id]") >= 0) out.println "\t@Id"
if (it.annos != "") out.println "  ${place("[@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 \"{\" +"
fields.each(){
out.println "\t\t\t\t\t\"${it.name}='\" + ${it.name} + '\\'' +"
}
out.println "\t\t\t\t'}';"
out.println "\t}"
out.println ""
out.println "}"
}
def calcFields(table){
def spec = Case.LOWER.DataType().getSpecification())
def typeStr = typeMapping.find { p, t -> p.matcher(spec).find()}.value
def comm=[
colName : Name(),
name    : Name(), false),
type: typeStr,
commoent: Comment(),
annos  :"\t@Column(name = \"" + Name() + "\" )"]
if("id".equals(Case.LOWER.Name())))
comm.annos +=["@Id"]
fields +=[comm]
}
}
// 这⾥是处理数据库表前缀的⽅法,这⾥处理的是t_xxx命名的表
// 已经修改为使⽤javaName, 如果有需要可以在def className = Name(), true)中修改为javaClassName