使用IntelliJ IDEA自动生成Spring Boot代码 根据数据库自动生成Entity、DynamicSql、Dao、Service、Controller各层代码及swagger注解

写项目总是要花很多时间去写实体层,尽管可以直接把变量名一个个拖过去,还是很容易出错,很费神。
这几天发现可以用spring boot生成Entity代码,尝试了一把,发现挺好用的。
后来突发奇想,干脆让它生成所有基础代码算了,说干就干!

先看看生成效果

生成前的项目目录,配置好项目结构,此时不到一千行Java代码
在这里插入图片描述

现在进行所有数据表对应代码的一键生成。注意!前方高能!!!!!

在这里插入图片描述
两秒钟过后。。。
在这里插入图片描述
瞬间生成了七千多行spring boot代码
在这里插入图片描述

来看看各层的效果

实体层 生成了各成员变量、swagger注解、toString方法、get和set方法,能够满足所有需要了
在这里插入图片描述
动态sql 根据项目的需要,生成了动态插入、多条件查询、部分更新、全部更新四个动态SQL方法语句
在这里插入图片描述
数据库接口Dao层、业务Service层 暂时只设置了id查询、动态插入,可以根据自己需要自行修改配置,把有必要的方法自动生成
在这里插入图片描述
控制Controller层 完备的swagger api注解
在这里插入图片描述
现在运行一下项目
在这里插入图片描述
因为自动生成了swagger注释,所以直接可以在swagger看到生成的接口

上面详细介绍了生成的代码,如果跟自己习惯不符,可以根据自己的需要动手定制

现在开始正题,怎么让电脑自己写代码

1.大家可以看到上面的变量和每个实体都有中文注释,这些注释当然不是自动翻译的,是在设计数据库的时候写上去的。
所以要先设计一个符合规范的数据库,注释一定要齐全
在这里插入图片描述
还要有对表的注释
在这里插入图片描述
我这里每张表加了个前缀,大家如果没有前缀,可以把生成类名时去除前缀的代码去掉
在这里插入图片描述

2.用ideal自带的database工具连上数据库,在数据表上点鼠标右键
在这里插入图片描述
点Go to Scripts Driectory,进入一个目录,一般大家打开只有最后一个groovy文件,前两个是我自己仿照最后一个写的
在这里插入图片描述
.groovy文件就是生成数据库的脚本语言文件

我们先打开自带的Generate POJOs.groovy文件(自己做了些改动,原文件没保留下来,跟大家的又不太一样了)
可以看到语法跟python差不多,又有些地方跟Java很像。
遇到这样陌生的代码,不要怕它,找规律,稍微细心观察一下它的结构,试着去按照自己的想法修改几行看看
在这里插入图片描述

用自带的groovy代码生成文件试试,然后改几个参数,看看有什么变化,改多了就会发现,自己好像又学会了一个新的语言,没错,确实是另外一门语言:groovy语言
在这里插入图片描述
这里的选项就是脚本文件名了
备注:这里可以选中多张表,同时生成

自动生成以后大概就是这样了,有成员变量和get、set方法,没有注释什么的
在这里插入图片描述

3.了解了groovy脚本后,我们来改写适应自己项目所需的groovy脚本,按照上面方法运行就可以了
下面我附上刚才生成代码的完整groovy脚本
注意:运行需谨慎,代码不备份,被删两行泪,是以文件的形式生成,会覆盖同名文件!

package com.example

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 com.intellij.database.model.ObjectKind

/*
 * Available context bindings:
 *   SELECTION   Iterable<DasObject>
 *   PROJECT     project
 *   FILES       files helper
 */

// 全局变量,在init()方法中生成(自动生成,无需修改)
fileEncoding = "utf-8"
creatTime = "" //
tableName = ""  // 数据表名(Java命名规则)
fields = [[]] // 数据表各列属性
/*  各层类名  在入口方法中设置命名规则  */
entityName = ""
daoName = ""
dynaSqlName = ""
serviceName = ""
controllerName = ""
/*  各层包名 根据设置目录自动生成  */
packageNameEntity = ""
packageNameDao = ""
packageNameDynaSql = ""
packageNameService = ""
packageNameController = ""

// 实体类所在文件夹(手动配置)
dirProject = "P:\\IdeaProjects\\gamaapp_server4" // 项目文件夹
dirEntity = dirProject + "\\src\\main\\java\\com\\example\\demo\\entity"  // 实体层文件夹
dirDao = dirProject + "\\src\\main\\java\\com\\example\\demo\\dao"  // Dao层文件夹
dirDynaSql = dirProject + "\\src\\main\\java\\com\\example\\demo\\dao\\dynaSql"  // 动态Sql文件夹
dirService = dirProject + "\\src\\main\\java\\com\\example\\demo\\service"  // Service层文件夹
dirController = dirProject + "\\src\\main\\java\\com\\example\\demo\\controller"  // Controller层文件夹
creatTag = "// Auto Created by Zeng" // 自动生产方法注释

// mysql中数据类型和Java数据类型映射
typeMapping = [
  (~/(?i)int|tinyint/)                       : "Integer",
  (~/(?i)bigint|timestamp/)                  : "Long",
  (~/(?i)float|double|decimal|real/)         : "Double",
  (~/(?i)date|datetime|time/)                : "Date",
  (~/(?i)/)                                  : "String"
]

// 入口函数,选择数据库后进入
SELECTION.filter { it instanceof DasTable }.each {
  init(it)  // 初始化全局变量数据

  // 设置类名规则
  entityName = tableName
  daoName = tableName + "Dao"
  dynaSqlName = tableName + "Sql"
  serviceName = tableName + "Service"
  controllerName = tableName + "Controller"

  /**  把以下不需要生成的注释掉即可  **/
  creatEntity(it) // 生成实体类
  creatDao(it)  // 生成Dao
  creatDynaSql(it)  // 生成动态Sql
  creatService(it)  // 生成Service
  creatController(it) // 生成Controller
}


// 初始化全局变量
def init(table){
  creatTime = new Date().format("yyyy-MM-dd HH:mm:ss")
  tableName = javaName(removePrefixName(table.getName()), true)
  fields = calcFields(table)

  packageNameEntity = getPackageName(dirEntity)
  packageNameDao = getPackageName(dirDao)
  packageNameDynaSql = getPackageName(dirDynaSql)
  packageNameService = getPackageName(dirService)
  packageNameController = getPackageName(dirController)
}


// 创建Controller
def creatController(table){
  new File(dirController, controllerName + ".java").withPrintWriter(fileEncoding) { out ->
    out.println "package ${packageNameController};\n"
    out.println "import ${packageNameEntity}.${entityName};"
    out.println "import ${packageNameService}.${serviceName};"
    out.println "import com.example.demo.utils.Result;"
    out.println "import com.example.demo.utils.UserUtils;"
    out.println "import io.swagger.annotations.ApiImplicitParam;"
    out.println "import io.swagger.annotations.ApiImplicitParams;"
    out.println "import io.swagger.annotations.Api;"
    out.println "import io.swagger.annotations.ApiOperation;"
    out.println "import org.springframework.beans.factory.annotation.Autowired;"
    out.println "import org.springframework.web.bind.annotation.*;"
    out.println "\n\n//  Created on ${creatTime}\n"
    out.println "@Api(tags = \"${isNotEmpty(table.getComment())?table.getComment():controllerName}\")"
    out.println "@CrossOrigin"
    out.println "@RestController"
    out.println "@RequestMapping(\"/${javaName(tableName,false)}/\")"
    out.println "public class ${controllerName} {\n"
    out.println "    @Autowired"
    out.println "    ${serviceName} ${javaName(serviceName,false)};\n\n"
    out.println "    ${creatTag}"
    out.println "    @ApiOperation(value = \"selectById\",httpMethod = \"GET\",notes = \"Auto Creat\")"
    out.println "    @ApiImplicitParams({"
    out.println "        @ApiImplicitParam(name = \"id\",value = \"${javaName(tableName,false)}Id\",required = true ,dataType=\"int\")"
    out.println "    })"
    out.println "    @GetMapping(\"selectById\")"
    out.println "    public Result selectById(Integer id){"
    out.println "        if(id == null){"
    out.println "            return Result.error(\"Not required id!\");"
    out.println "        }else {"
    out.println "            return Result.ok(${javaName(serviceName,false)}.selectById(id));"
    out.println "        }"
    out.println "    }"
    out.println "\n    ${creatTag}"
    out.println "    @ApiOperation(value = \"insert\",httpMethod = \"POST\",notes = \"Auto Creat\")"
    out.println "    @ApiImplicitParams({"
    fields.each() { // 不插入主键
      if(!it.isAutoGenerated){
        out.println "        @ApiImplicitParam(name = \"${it.name}\",value = \"${isNotEmpty(it.commoent)?it.commoent:""}\"${it.isNotNull?",required = true":""}),"
      }
    }
    out.println "    })"
    out.println "    @PostMapping(\"insert\")"
    out.println "    public Result insert(${entityName} ${javaName(entityName,false)}){"
    out.println "        int num = ${javaName(serviceName,false)}.insert(${javaName(entityName,false)});"
    out.println "        if(num == 1){"
    out.println "            return Result.ok(\"Successful!\",\"\");"
    out.println "        }else {"
    out.println "            return Result.error(\"Failure!\",\"\");"
    out.println "        }"
    out.println "    }"
    out.println "\n\n\n}"
  }
}


// 创建Service
def creatService(table){
  new File(dirService, serviceName + ".java").withPrintWriter(fileEncoding) { out ->
    out.println "package ${packageNameService};\n"
    out.println "import ${packageNameDao}.${daoName};"
    out.println "import ${packageNameEntity}.${entityName};"
    out.println "import org.springframework.beans.factory.annotation.Autowired;"
    out.println "import org.springframework.stereotype.Service;"
    out.println "\n\n//  Created on ${creatTime}\n"
    out.println "@Service"
    out.println "public class ${serviceName} {\n"
    out.println "    @Autowired"
    out.println "    $daoName ${javaName(daoName,false)};\n\n"
    out.println "    ${creatTag}"
    out.println "    public $entityName selectById(Integer id){"
    out.println "        return ${javaName(daoName,false)}.selectById(id);"
    out.println "    }"
    out.println "\n    ${creatTag}"
    out.println "    public int insert(${entityName} ${javaName(entityName,false)}){"
    out.println "        return ${javaName(daoName,false)}.insert(${javaName(entityName,false)});"
    out.println "    }"
    out.println "\n\n\n}"
  }
}


// 创建动态sql
def creatDynaSql(table){
  new File(dirDynaSql, dynaSqlName + ".java").withPrintWriter(fileEncoding) { out ->
    out.println "package ${packageNameDynaSql};\n"
    out.println "import ${packageNameEntity}.${entityName};"
    out.println "import org.apache.ibatis.jdbc.SQL;"
    out.println "\n\n// Created on ${creatTime}\n"
    out.println "public class $dynaSqlName {\n"

    // 插入数据库动态sql
    out.println "    ${creatTag}"
    out.println "    public String insert(${entityName} ${javaName(entityName,false)}){"
    out.println "        return new SQL(){"
    out.println "            {"
    out.println "                INSERT_INTO(\"${table.getName()}\");"
    fields.each() { // 非空变量
      if(!it.isAutoGenerated && it.isNotNull && !it.zerofill){
        out.println "                VALUES(\"${it.colName}\",\"#{${it.name}}\");"
      }
    }
    fields.each() { // 可以为空的变量
      if(!it.isNotNull || it.zerofill){
        out.println "                if(${javaName(entityName,false)}.get${it.name.capitalize()}() != null){"
        out.println "                    VALUES(\"${it.colName}\",\"#{${it.name}}\");"
        out.println "                }"
      }
    }
    out.println "             }"
    out.println "        }.toString();"
    out.println "    }\n"

    // 多条件查询动态sql
    out.println "    ${creatTag}"
    out.println "    public String selectByMutiParams${tableName}(${entityName} ${javaName(entityName,false)}){"
    out.println "        return new SQL(){"
    out.println "            {"
    out.println "                SELECT(\"*\");"
    out.println "                FROM(\"${table.getName()}\");"
    fields.each() { // 查询条件
      out.println "                if(${javaName(entityName,false)}.get${it.name.capitalize()}() != null){"
      out.println "                    WHERE(\"${it.colName} = #{${it.name}}\");"
      out.println "                }"
    }
    out.println "             }"
    out.println "        }.toString();"
    out.println "    }\n"

    // 部分更新动态sql
    out.println "    ${creatTag}"
    out.println "    public String updatePart${tableName}(${entityName} ${javaName(entityName,false)}){"
    out.println "        return new SQL(){"
    out.println "            {"
    out.println "                UPDATE(\"${table.getName()}\");"
    fields.each() {
      if(!it.isAutoGenerated){
        out.println "                if(${javaName(entityName,false)}.get${it.name.capitalize()}() != null){"
        out.println "                    SET(\"${it.colName} = #{${it.name}}\");"
        out.println "                }"
      }
    }
    out.println "                WHERE(\"id = #{id}\");"
    out.println "             }"
    out.println "        }.toString();"
    out.println "    }\n"

    // 全部更新动态sql
    out.println "    ${creatTag}"
    out.println "    public String updateALL${tableName}(${entityName} ${javaName(entityName,false)}){"
    out.println "        return new SQL(){"
    out.println "            {"
    out.println "                UPDATE(\"${table.getName()}\");"
    fields.each() {
      if(!it.isAutoGenerated){
        out.println "                if(${javaName(entityName,false)}.get${it.name.capitalize()}() != null){"
        out.println "                    SET(\"${it.colName} = #{${it.name}}\");"
        out.print "                }"
        if(!it.isNotNull){
          out.println "else {"
          out.println "                    SET(\"${it.colName} = null\");"
          out.print "                }"
        }
        out.println ""
      }
    }
    out.println "                WHERE(\"id = #{id}\");"
    out.println "             }"
    out.println "        }.toString();"
    out.println "    }\n"

    out.println "}"

  }
}


// 创建Dao
def creatDao(table){
  new File(dirDao, daoName + ".java").withPrintWriter(fileEncoding) { out ->
    out.println "package ${packageNameDao};\n"
    out.println "import ${packageNameEntity}.${entityName};"
    out.println "import ${packageNameDynaSql}.${dynaSqlName};"
    out.println "import org.apache.ibatis.annotations.InsertProvider;"
    out.println "import org.apache.ibatis.annotations.Mapper;"
    out.println "import org.apache.ibatis.annotations.Select;"
    out.println "import org.springframework.stereotype.Repository;"
    out.println "\n\n//  Created on ${creatTime}\n"
    out.println "@Mapper"
    out.println "@Repository"
    out.println "public interface ${daoName} {\n\n"
    out.println "    ${creatTag}"
    out.println "    @Select(\"SELECT * FROM ${table.getName()} WHERE id=#{id}\")"
    out.println "    ${entityName} selectById(Integer id);"
    out.println "\n    ${creatTag}"
    out.println "    @InsertProvider(type = ${dynaSqlName}.class,method = \"insert\")"
    out.println "    int insert(${entityName} ${javaName(entityName,false)});"
    out.println "\n\n\n}"
  }
}


// 创建实体类
def creatEntity(table){
  new File(dirEntity, entityName + ".java").withPrintWriter(fileEncoding) { out ->
    def fields = calcFields(table)

    out.println "package ${packageNameEntity};\n"
    out.println "import java.util.Date;"
    out.println "import io.swagger.annotations.ApiModel;"
    out.println "import io.swagger.annotations.ApiModelProperty;"
    out.println "\n\n// Created on ${creatTime}\n"
    out.println "@ApiModel(\"${isNotEmpty(table.getComment())?table.getComment():tableName}\")"
    out.println "public class ${entityName} {\n"

    //  输出成员变量
    fields.each() {
      // 输出注释
      if(isNotEmpty(it.commoent)){
        out.println "    @ApiModelProperty(value = \"${it.commoent}\")"
      }
      // 输出成员变量
      if (it.annos != "") out.println "    ${it.annos}"
      out.println "    private ${it.type} ${it.name};"
    }

    // 输出toString
    out.println "\n    @Override"
    out.println "    public String toString() {"
    out.println "        final StringBuilder sb = new StringBuilder(\"{\");"
    fields.each() {
      out.println "        sb.append(\"\\\"${it.name}\\\":\")"
      out.println "                .append(${it.name});"
    }
    out.println "        return sb.toString();"
    out.println "    }\n"

    // 输出get、set方法
    fields.each() {
      out.println "    public ${it.type} get${it.name.capitalize()}() {"
      out.println "        return ${it.name};"
      out.println "    }\n"
      out.println "    public void set${it.name.capitalize()}(${it.type} ${it.name}) {"
      out.println "        this.${it.name} = ${it.name};"
      out.println "    }"
    }
    out.println "\n\n}"
  }
}


// 获取数据表所有列属性,装入数组中
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
    fields += [[
                       /* 此处可根据自己需要引入 */
                       colName : col.getName(), // 列名
                       name : javaName(col.getName(), false), // 转化后的变量名
                       colType : col.getDataType(), // 数据库数据类型
                       type : typeStr,  // Java数据类型
                       commoent: col.getComment(),  // 备注
                       isPrimary : DasUtil.isPrimary(col), // 是否主键
                       isForeign : DasUtil.isForeign(col),  // 是否外键
                       isAutoGenerated : DasUtil.isAutoGenerated(col), // 是否自增
                       unsigned : col.getDataType().getSpecification().indexOf("unsigned") != -1?true:false, // 无符号
                       zerofill : col.getDataType().getSpecification().indexOf("zerofill") != -1?true:false, // 零填充
                       isNotNull : col.isNotNull(), // 非空
                       annos: ""]]
  }
}


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


// 转Java变量名
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.trim().length() > 0
}

// 去除数据库前缀后的类名
def removePrefixName(str){
  return str.substring(str.indexOf("_")+1)
}


新建一个groovy文件,把代码复制进去修改参数后即可运行自动生成代码
在这里插入图片描述
注意:以上代码生成后不会提示完成,刷新一下项目目录即可看见生成文件

关于groovy基础语法可参见 https://www.jianshu.com/p/8127742e0569

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值