前言
日常的开发都用到 Mybatis Plus,但是每次开新功能都得设计表、映射实体代码,写相关service、mapper。这些过程都是繁琐而重复的,于是想通过逆向生成的方式,自动通过数据表,可以逆向生成相关的单表CRUD代码,IDEA上找了几个插件,都不太适合我,生成的东西还是得改。于是自己写了个Groovy脚本来生成
一、生成步骤
1、首先是设计数据库表,然后在IDEA的DataBase工具里连接对应的库
2、导入Groovy 脚本
3、选择要生成代码的表(支持多选),然后选择生成位置(一般放在与启动类同级的包下),点击生成即可
二、步骤图示
1、导入Groovy脚本到IDEA中
导入脚本,并放在如下位置(脚本在文末提供)
2、IDEA连接数据库,选择要导出的表,选择生成脚本
如图示步骤操作
3、选择要生成代码的存放位置
4、生成结果
三、Groovy脚本详情
此处给出脚本源码,如果生成的代码不满意,可以调整代码,改成合适自己的
如果不想复制粘贴,可以直接点击链接下载 https://download.csdn.net/download/m4330187/75543171
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
packageName = ""
className = ""
userName = "ZhiPeng.Lin"
entityPackage = "\\entity\\"
mapperPackage = "\\mapper\\"
servicePackage = "\\service\\"
serviceImplPackage = "\\service\\impl\\"
typeMapping = [
(~/(?i)int|tinyint|smallint|mediumint/) : "Integer",
(~/(?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 save the generate files !!!") { dir ->
SELECTION.filter { it instanceof DasTable && it.getKind() == ObjectKind.TABLE }.each { generate(it, dir) }
}
def generate(table, dir) {
className = javaName(table.getName(), true)
def fields = calcFields(table)
packageName = getPackageName(dir)
def entityName = className + ".java"
def newDir = dir.toString() + entityPackage
def dirFile = new File(newDir)
if (!dirFile.exists()) {
dirFile.mkdirs()
}
def file = new File(newDir, entityName)
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))
printWriter.withPrintWriter { out -> generate(out, className, fields, table) }
generateMapper(dir)
generateService(dir)
generateServiceImpl(dir)
}
def generateMapper(dir) {
def mapperName = className + "Mapper.java"
def newDir = dir.toString() + mapperPackage
def dirFile = new File(newDir)
if (!dirFile.exists()) {
dirFile.mkdirs()
}
def file = new File(newDir, mapperName)
PrintWriter printWriterMapper = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))
printWriterMapper.withPrintWriter { out -> generateMapper(out, className) }
}
def generateService(dir) {
def serviceName = "I" + className + "Service.java"
def newDir = dir.toString() + servicePackage
def dirFile = new File(newDir)
if (!dirFile.exists()) {
dirFile.mkdirs()
}
def file = new File(newDir, serviceName)
PrintWriter printWriterMapper = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))
printWriterMapper.withPrintWriter { out -> generateService(out, className) }
}
def generateServiceImpl(dir) {
def serviceImplName = className + "ServiceImpl.java"
def newDir = dir.toString() + serviceImplPackage
def dirFile = new File(newDir)
if (!dirFile.exists()) {
dirFile.mkdirs()
}
def file = new File(newDir, serviceImplName)
PrintWriter printWriterMapper = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))
printWriterMapper.withPrintWriter { out -> generateServiceImpl(out, className) }
}
def getPackageName(dir) {
return dir.toString().replaceAll("\\\\", ".").replaceAll("/", ".").replaceAll("^.*src(\\.main\\.java\\.)?", "") + ";"
}
def generateMapper(out, className) {
def entityName = packageName.replaceAll(";", ".") + "entity." + className + ";"
out.println "package " + packageName.replaceAll(";", ".") + "mapper;"
out.println ""
out.println "import org.apache.ibatis.annotations.Mapper;"
out.println "import com.baomidou.mybatisplus.core.mapper.BaseMapper;"
out.println "import $entityName"
out.println ""
out.println "/**\n" +
" * @Description \n" +
" * @Author $userName\n" +
" * @Date " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " \n" +
" */"
out.println "@Mapper"
out.println "public interface " + className + "Mapper extends BaseMapper<" + className + "> {\n" + "}"
}
def generateService(out, className) {
def entityName = packageName.replaceAll(";", ".") + "entity." + className + ";"
out.println "package " + packageName.replaceAll(";", ".") + "service;"
out.println ""
out.println "import com.baomidou.mybatisplus.extension.service.IService;"
out.println "import $entityName"
out.println ""
out.println "/**\n" +
" * @Description \n" +
" * @Author $userName\n" +
" * @Date " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " \n" +
" */"
out.println "public interface I" + className + "Service extends IService<" + className + "> {\n" + "}"
}
def generateServiceImpl(out, className) {
def entityName = packageName.replaceAll(";", ".") + "entity." + className + ";"
def mapperNameTemp = packageName.replaceAll(";", ".") + "mapper." + className + "Mapper;"
def serviceNameTemp = packageName.replaceAll(";", ".") + "service.I"+ className + "Service;"
out.println "package " + packageName.replaceAll(";", ".") + "service.impl;"
out.println ""
out.println "import lombok.extern.slf4j.Slf4j;"
out.println "import org.springframework.stereotype.Service;"
out.println "import org.springframework.transaction.annotation.Transactional;"
out.println "import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;"
out.println "import $mapperNameTemp"
out.println "import $serviceNameTemp"
out.println "import $entityName"
out.println ""
out.println "/**\n" +
" * @Description \n" +
" * @Author $userName\n" +
" * @Date " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " \n" +
" */"
out.println "@Slf4j"
out.println "@Service"
out.println "@Transactional(rollbackFor = Exception.class)"
out.println "public class " + className + "ServiceImpl extends ServiceImpl<" + className + "Mapper, " + className + "> implements I" + className + "Service {\n" + "}"
}
def generate(out, className, fields, table) {
out.println "package " + packageName.replaceAll(";", ".") + "entity" + ";"
out.println ""
out.println "import com.baomidou.mybatisplus.annotation.TableId;"
out.println "import com.baomidou.mybatisplus.annotation.TableField;"
out.println "import com.baomidou.mybatisplus.annotation.TableName;"
out.println "import java.io.Serializable;"
out.println "import lombok.Data;"
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 $userName\n" +
" * @Date " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " \n" +
" */"
out.println "@Data"
out.println "@TableName(value =\"" + 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 + "").indexOf("[@Id]") >= 0) out.println "\t@TableId(type = IdType.AUTO)"
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@TableField(value = \"" + col.getName() + "\")"]
if ("id".equals(Case.LOWER.apply(col.getName())))
comm.annos += ["@Id"]
fields += [comm]
}
}
def javaClassName(str, capitalize) {
def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
.collect { Case.LOWER.apply(it).capitalize() }
.join("")
.replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
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 = 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;"
}
PS:此文为原创文章,转载请注明出处
|