大家好,我是轩脉刃。

我们写业务的时候和db接触是少不了的,那么要生成model也是少不了的,如何自动生成model,想着要给hade框架增加个这样的命令。

看了下网上的几个开源项目,最终聚焦在两个项目中:

https://github.com/go-gorm/gen

https://github.com/xxjwxc/gormt

gormt的gui是非常强大的,看文档都支持终端gui和windows的gui。但是gormt是一个工具,无法在另外一个项目中引入。

但是gen项目是gorm官方推出的,有jinzhu作者的参与。

所以我尝试选择gen项目来。

gen

gen其实不只是工具,它更像一个全新的orm封装。gen项目生成出来的文件有其实有两个部分,一个是model,就是db的表和对应的model,以xxx.gen.go 命名。而另一个部分是每个model对应一套gen函数,这套gen函数基本上是对orm的二次封装了。

当然这套函数是基于gorm来封装的,不过你可以完全脱离gorm来使用这套函数。

生成的方法示例如下:

g := gen.NewGenerator(gen.Config{
OutPath: "/Users/yejianfeng/Documents/workspace/gohade/hade/app/dal",
ModelPkgPath: "/Users/yejianfeng/Documents/workspace/gohade/hade/app/dal/model",
WithUnitTest: true, FieldNullable: false,
FieldCoverable: true,
FieldWithIndexTag: false,
FieldWithTypeTag: false, Mode: gen.WithDefaultQuery,
})
gormService := container.MustMake(contract.ORMKey).(contract.ORMService)
db, err := gormService.GetDB(orm.WithConfigPath("database.default"))
if err != nil {
return err
} g.UseDB(db)
g.WithDataTypeMap(dataMap)
//g.WithJSONTagNameStrategy(func(c string) string { return "-" }) //g.ApplyBasic(model.Customer{})
//g.ApplyBasic(g.GenerateAllTable()...)
//g.GenerateModel("users")
//g.GenerateModel("answers")
//g.GenerateAllTable()
g.ApplyBasic(g.GenerateAllTable()...)
g.Execute()

使用起来像是这样:

u := query.Use(db).User

// Get first matched record
user, err := u.WithContext(ctx).Where(u.Name.Eq("modi")).First()
// SELECT * FROM users WHERE name = 'modi' ORDER BY id LIMIT 1; // Get all matched records
users, err := u.WithContext(ctx).Where(u.Name.Neq("modi")).Find()
// SELECT * FROM users WHERE name <> 'modi'; // IN
users, err := u.WithContext(ctx).Where(u.Name.In("modi", "zhangqiang")).Find()
// SELECT * FROM users WHERE name IN ('modi','zhangqiang'); // LIKE
users, err := u.WithContext(ctx).Where(u.Name.Like("%modi%")).Find()
// SELECT * FROM users WHERE name LIKE '%modi%';

最终生成的文件如下:

gen有一些高级的功能:

  • 自定义模型函数,且提供了通过sql语句的注释自实现函数的方法
  • 提供了单元测试框架,你可以自己定义TestCase,来实现对某个自实现函数的单测
  • 智能字段查询,在select语句的时候,可以根据输出对象自动生成select的field

其实gen更像是另一个orm框架了,和facebook的ent类似,为每个model生成一套orm方法。gen是字节跳动的无恒实验室开发的产品,据说字节内部正在将gorm切换到gen。gen的主打是安全,意思是,如果你的orm是完全使用gen来生成的,通过注释sql而不是自己裸写sql来生成,它更能保证安全性。(当然,因为所有的实现代码都是gen来自动生成的)。

我目前的认知还是觉得这套东西太重了一些,整个熟悉下来无异于需要了解另外一个orm框架的语法了。在使用gorm和gen上并没有什么太大的区别。

// 插入一条数据
email := "foo@gmail.com"
name := "foo"
user := &model.User{
ID: 0,
Username: name,
Password: "",
Email: email,
CreatedAt: time.Time{},
}
dal.SetDefault(db)
err := dal.User.WithContext(c).Create(user)
if err != nil {
c.AbortWithError(50001, err)
return
}
// 插入一条数据
email := "foo@gmail.com"
name := "foo"
age := uint8(25)
birthday := time.Date(2001, 1, 1, 1, 1, 1, 1, time.Local)
user := &User{
Name: name,
Email: &email,
Age: age,
Birthday: &birthday,
MemberNumber: sql.NullString{},
ActivatedAt: sql.NullTime{},
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
err = db.Create(user).Error
logger.Info(c, "insert user", map[string]interface{}{
"id": user.ID,
"err": err,
})

而且如果要写出官网给出的这么复杂的语句:

p := query.Use(db).Pizza

pizzas, err := p.WithContext(ctx).Where(
p.WithContext(ctx).Where(p.Pizza.Eq("pepperoni")).
Where(p.WithContext(ctx).Where(p.Size.Eq("small")).Or(p.Size.Eq("medium"))),
).Or(
p.WithContext(ctx).Where(p.Pizza.Eq("hawaiian")).Where(p.Size.Eq("xlarge")),
).Find() // SELECT * FROM `pizzas` WHERE (pizza = "pepperoni" AND (size = "small" OR size = "medium")) OR (pizza = "hawaiian" AND size = "xlarge")

我相信对新手来说真是一个不大容易的事情。

所以目前我还只倾向于使用gen的生成model的部分。

自动生成model命令设计

首先设计一下这个命令的产品形态。

./hade model gen --output=document/app/model/ --database=database.default

在命令行中的参数:

output: 必选,表示输出的路径
database: 可选,默认使用database.default

如果没有设置db,或者output没有设置,直接返回错误。

第一步是一个交互命令行工具,首先展示要生成的表列表选择:

请选择要生成模型的表格:
[] *
[] users
[] answers
[] questions

第二步确认要生成的目录和文件,以及覆盖提示:

继续下列操作会在目录(xxxx)生成下列文件:
user.gen.go(覆盖)
answer.gen.go(新文件) 请确认是否继续?(Y/N)

第三步选择后是一个生成模型的选项:

请选择模型规则:
[] FieldNullable, 对于数据库的可null字段设置指针
[] FieldCoverable, 根据数据库的Default设置字段的默认值
[] FieldWithIndexTag, 根据数据库的索引关系设置索引标签
[] FieldWithTypeTag, 生成类型字段

最后一步就是生成模型文件了。

自动生成model命令实现

了解了gen和命令的设计,实现就很简单了。

大概就分几步吧:

  • 获取数据库中的所有表
  • 让用户多选要生成model的表格
    • 和现有的目录中的文件进行比对
  • 让用户多选要生成的model的选项,比如是否可null,是否有default设置等
  • 使用gen生成模型文件

具体代码在 https://github.com/gohade/hade/blob/feature/model-gen/framework/command/model/model.go

其中代码实现方便稍微有几个地方要注意下:

如何查询一个数据库中的所有表

使用gorm很方便就实现了

dbTables, err := db.Migrator().GetTables()

当用户选择了要生成的表格,要和硬盘中已有的文件进行比对,如何操作

这里其实涉及到两个集合的交集和差集

我发现collection库之前已经实现了差集,但是没有实现交集。

这里我补充实现了colleciton的交集,Intersect,并且将collection库升级到1.4.1

// Intersect 比较两个数组,获取两个数组交集,仅对基础元素生效
Intersect (arr ICollection) ICollection

gen 库如何只生成model不生成gen文件?

g.UseDB(db)

for _, table := range genTables {
g.GenerateModel(table)
}
g.Execute()

model命令验证

验证一下要model/gen命令

第一步,使用 ./hade model gen --output=app/model

选择其中的两个表,answers和questions,提示目录文件

下一步确认y继续

最后生成模型成功

查看文件,确实生成了model

功能完结。

为hade增加model自动生成功能的更多相关文章

  1. 给dtcms增加模板自动生成功能

    作为dtcms的使用者你是不是像我一样,也在不停的修改模板之后要点击生成模板浪费了很多开发模板的时间? 那就跟我一起给dtcms增加一个开发者模式,当模板修改完成之后,直接刷新页面就能看到效果,而不再 ...

  2. Markdown 中的目录自动生成功能 TOC

    目录 Markdown 中的目录自动生成功能 TOC 1. 标题一 1.1 标题二 1.标题二 2. 标题一 2.1 标题二 2.2 标题二 Markdown 中的目录自动生成功能 TOC 1. 标题 ...

  3. 使用automake等命令自动生成Makefile文件 (转载)

    使用automake等命令自动生成Makefile文件   Linux下编程时,为了方便编译,往往使用Makefile文件自动完成编译,但是Makefile文件本身的书写十分复杂,规则很多.好在Lin ...

  4. 【Golang】 可以自动生成测试用例的库--gotests

    简介 gotests是一个Golang命令行工具,它可以使编写Go的测试代码变得容易.它能基于目标源文件的函数和方法生成数据驱动测试用例,并且在此过程会自动导入任何依赖. 下面是gotests在使用S ...

  5. Mybatis 如何自动生成bean dao xml 配置文件 generatorconfig.xml (main()方法自动生成更快捷)

    最近项目要用到mybatis中间件,中间涉及到要对表结构生成bean,dao,和sqlconfig.xml 所以记录一下学习过程 首先是准备工作,即准备需要的jar包:我们的数据库mysql,所以驱动 ...

  6. 痞子衡嵌入式:MCUXpresso IDE下工程链接文件配置管理与自动生成机制

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下工程链接文件配置管理与自动生成机制. 痞子衡在 2018 年初写过一个专题 <嵌入式开发文件系列&g ...

  7. spring和mybatis集成,自动生成model、mapper,增加mybatis分页功能

    软件简介 Spring是一个流行的控制反转(IoC)和面向切面(AOP)的容器框架,在java webapp开发中使用广泛.http://projects.spring.io/spring-frame ...

  8. springboot和mybatis集成,自动生成model、mapper,增加mybatis分页功能

    整体思路和http://www.cnblogs.com/mahuan2/p/5859921.html相同. 主要讲maven的pom.xml和一些配置变化,详细说明. 软件简介 Spring是一个流行 ...

  9. idea使用generator自动生成model、mapper、mapper.xml(转)

    原文链接:http://www.mamicode.com/info-detail-445217.html TEP 0.在Intellij IDEA创建maven项目(本过程比较简单,略) STEP 1 ...

随机推荐

  1. centos7 自动交互expect 安装使用

    1.安装 https://www.cnblogs.com/rocky-AGE-24/p/7256800.html 安装expect命令 两种方式yum安装 yum -y install expect ...

  2. xftp 6 的 使用

    1.前言 xftp是个向云服务器linux系统传输文件的软件,装载在window系统 简单易用 2.下载 官方下载地址:https://www.netsarang.com/zh/xftp-downlo ...

  3. Windows 10 如何在当前位置打开 CMD 命令窗口?

    方法一 Win + R 键召唤出运行窗口,然后输入 "CMD" 打开命令提示符. 使用 cd 命令更改当前命令提示符的工作环境. 注释 cd/ - 退到当前所在盘符 cd.. - ...

  4. Word2010制作电子印章

    原文链接: https://www.toutiao.com/i6488971642788643341/ 选择"插入"选项卡,"插图"功能组,"形状&q ...

  5. 微信小程序动画实现(API,css)

    微信小程序动画API实现 index.js clicktap:function(){ var Animation=wx.createAnimation({ duration: 2000, }) Ani ...

  6. Flowable实战(二)集成Springboot

    1.创建Springboot项目   打开IDEA,通过File -> New -> Project- -> Spring Initializr 创建一个新的Springboot项目 ...

  7. Git 的基本命令的使用

    1.获得Git仓库(克隆一份代码到本地仓库) git clone url 2.更新本地的代码 git pull 3.查看本地修改的文件 git status 4.将本地的修改加到stage中 git ...

  8. 安装DataX的管理控制台(转)

    原文地址 https://github.com/WeiYe-Jing/datax-web/blob/master/doc/datax-web/datax-web-deploy.md 环境准备 1)基础 ...

  9. Jquery操作文本内容(三个方法:html()、text()、var())

    Jquery操作文本内容(三个方法:html().text().var()) 一.html()获取和设置文本内容和标签 1.获取标签里的结构和内容 $("ul").html() / ...

  10. node.js和vue cli脚手架下载安装配置方法

    一.node.js安装以及环境配置 1.下载vue.js 下载地址: https://nodejs.org/en/ 2.安装node.js 下载完成后,双击安装包开始安装.安装地址最好换成自己指定的地 ...