每次写web项目,模板都是统一的,每次都要写大量冗余的代码会很烦,在Java中有很多逆向生成的工具,而Go语言我找了很久,也没有发现这样一个类似的工具,所以自己就开始造这样一个轮子了。现在这个项目已经完成了,分享出来供需要的人使用。

下面是此项目的README,现在已经写好了,可以直接使用了,项目仓库:github.com/ACking-you/quickstart_project

视频讲解(包括实现的讲解):视频讲解

go_project_quickstart

快速开始

要求

  • Go 1.18 及以上版本

安装

1.下载并安装 gin:

 go get -u github.com/ACking-you/quickstart_project

2.将 gin 引入到代码中:

 import "github.com/ACking-you/quickstart_project"

3.一键根据数据库快速逆向生成所有业务代码:

 import (
     "github.com/ACking-you/quickstart_project"
     "github.com/ACking-you/quickstart_project/util"
 )
 ​
 func autoQuickStart() {
     config := quickstart.DefaultConfig("项目名称", "root", "123", "127.0.0.1", 3306, "数据库名称").
     //打印出生成结果
     EnableDebug(true).
     //改变基本路径(默认为项目根目录)
     BasePath("./example")
     
     err := quickstart.Run(config)
     if err != nil {
         panic(err)
     }
 }
 ​
 func main() {
     autoQuickStart()
 }
 ​

上述代码,只更改了默认配置项中的两项,其他配置项的更改和作用请翻看源代码:./config

上述调用会一键生成 model、dao、service、vo、to、controller层的所有模板代码,且无法做到对每层代码生成的精确控制,如果本身项目已有model层的结构体,那么可以利用我提供的 dao_convertor 、service_convertor、controller_convertor 对整个代码生成做细化处理。

上述接口具体如何使用请点击以下文档进行查看:

项目实现

架构设计

对应的项目文件如下:

代码逻辑

上述架构设计阐述了,如何将四个单独的模块生成解耦,且同时数据也能产生关联,下面将详细介绍这一块。

统一的调用逻辑

如果细心的使用者会发现,所有模块的接口调用都是统一的形式。

ConfigconfigconvertorRunmodel_convertorAutoMigrate

代码复用

一、反射信息生成函数复用

最开始,在写 dao_convertor 的时候并未意识到解耦的重要性,但写到后面发现都要用到这个解析类型元信息的功能,而且代码十分重复,但是又不能直接抽离,因为此段逻辑与每个层级的代码产生了一定的耦合。

tag

二、文件保存动作的复用

这个行为在所有的层级都需要用到,在解析完信息并拼装生成好代码后,最后的动作就是要保存到文件了。
我这里对文件保存动作的复用分为三个级别:
code

SaveActioncommon_infosaveHelper.singleFileSaveSaveFilesaveHelper.multiFileSaveSaveFileSaveFile
SaveActionSaveFile

三、有意思的小工具轮子

Sscanf("hello( you)world)","$($)$",&s1,&s2,&s3) //s1:hello s2: you s3:world

写个这玩意是在使用fmt.Sscanf的时候被恶心到了,fmt版本的有分隔符的限制,所以不得不自己造个轮子了,这个主要用在tag的解析上面。

str_util
type StrHandleByChain struct {
   Str string
}

func (s *StrHandleByChain) ReplaceAll(old, new string) *StrHandleByChain {
   s.Str = strings.ReplaceAll(s.Str, old, new)
   return s
}

但是能简化我的代码效果如下:

strings.ReplaceAll(strings.ReplaceAll(content,"old","new"),"old","new") 
=> content.ReplaceAll("old","new").ReplaceAll("old","new")

很明显可读性变高了,而且这还只是套了两层的结果。。。