GORM-GEN快速上手

2023-11-03

目录

1.什么是 GEN

2.GEN特性

3.快速使用GEN

3.1. 下载

3.2. 生成

4. 基础查询

5. 自定义 SQL 查询

6.demo源码


 

1.什么是 GEN

官方文档:Gen Guides | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

GEN 项目地址:https://github.com/go-gorm/gen

GEN 是一个基于 GORM 的安全 ORM 框架,其主要通过代码生成方式实现 GORM 代码封装。旨在安全上避免业务代码出现 SQL 注入,同时给研发带来最佳用户体验。由字节跳动无恒实验室与 GORM 作者(https://github.com/jinzhu)联合研发的开源。

2.GEN特性

   GEN 来告诉你,什么叫最佳用户体验:

  • 自动同步库表,省去繁琐复制

  • 代码一键生成,专注业务逻辑

  • 字段类型安全,执行 SQL 也安

  • 查询优雅返回,完美兼容 GORM

GEN 提供了自动同步数据表结构体到 GORM 模型,使用非常简单,即使数据库字段信息改变,可以一键同步,数据库查询相关代码可以一键生成,CRUD 只需要调用对应的方法,开发体验飞起。GEN 采用了类型安全限制,所有参数都做了安全限制,完全不用担心存在注入;最重要的是自定义 SQL 只需要通过模板注释到 interface 的方法上,自动帮助你生成安全的代码,是的,自定义 SQL 也不会出现 SQL 注入问题,而且工具完美兼容 GORM!

下面是 GORM 与 GEN 工具的对比

7567a405411c4c68ad2e7473d0be702a.png

GORM 和 GEN 查询对比案例

//GORM 需要先定义类型
var user model.User
err:=db.Where("id=?",5).Take(&user).Error

//GEN 可以直接查询,返回对应类型
user,err:= u.Where(u.ID.Eq(5)).Take()

3.快速使用GEN

3.1. 下载

go get gorm.io/gen

3.2. 生成

执行以下方法后即可在指定目录生成对应代码:

package main

import (
	"fmt"
	"strings"

	"gorm.io/driver/mysql"
	"gorm.io/gen"
	"gorm.io/gen/field"
	"gorm.io/gorm"
)

const MySQLDSN = "root:root@(localhost:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"

func main() {

	// 连接数据库
	db, err := gorm.Open(mysql.Open(MySQLDSN))
	if err != nil {
		panic(fmt.Errorf("cannot establish db connection: %w", err))
	}

	// 生成实例
	g := gen.NewGenerator(gen.Config{
		// 相对执行`go run`时的路径, 会自动创建目录
		OutPath: "./dal",

		// WithDefaultQuery 生成默认查询结构体(作为全局变量使用), 即`Q`结构体和其字段(各表模型)
		// WithoutContext 生成没有context调用限制的代码供查询
		// WithQueryInterface 生成interface形式的查询代码(可导出), 如`Where()`方法返回的就是一个可导出的接口类型
		Mode: gen.WithDefaultQuery | gen.WithQueryInterface | gen.WithoutContext,

		// 表字段可为 null 值时, 对应结体字段使用指针类型
		FieldNullable: true, // generate pointer when field is nullable

		// 表字段默认值与模型结构体字段零值不一致的字段, 在插入数据时需要赋值该字段值为零值的, 结构体字段须是指针类型才能成功, 即`FieldCoverable:true`配置下生成的结构体字段.
		// 因为在插入时遇到字段为零值的会被GORM赋予默认值. 如字段`age`表默认值为10, 即使你显式设置为0最后也会被GORM设为10提交.
		// 如果该字段没有上面提到的插入时赋零值的特殊需要, 则字段为非指针类型使用起来会比较方便.
		FieldCoverable: false, // generate pointer when field has default value, to fix problem zero value cannot be assign: https://gorm.io/docs/create.html#Default-Values

		// 模型结构体字段的数字类型的符号表示是否与表字段的一致, `false`指示都用有符号类型
		FieldSignable: false, // detect integer field's unsigned type, adjust generated data type
		// 生成 gorm 标签的字段索引属性
		FieldWithIndexTag: false, // generate with gorm index tag
		// 生成 gorm 标签的字段类型属性
		FieldWithTypeTag: true, // generate with gorm column type tag
	})
	// 设置目标 db
	g.UseDB(db)

	// 自定义字段的数据类型
	// 统一数字类型为int64,兼容protobuf
	dataMap := map[string]func(detailType string) (dataType string){
		"tinyint":   func(detailType string) (dataType string) { return "int64" },
		"smallint":  func(detailType string) (dataType string) { return "int64" },
		"mediumint": func(detailType string) (dataType string) { return "int64" },
		"bigint":    func(detailType string) (dataType string) { return "int64" },
		"int":       func(detailType string) (dataType string) { return "int64" },
	}
	// 要先于`ApplyBasic`执行
	g.WithDataTypeMap(dataMap)

	// 自定义模型结体字段的标签
	// 将特定字段名的 json 标签加上`string`属性,即 MarshalJSON 时该字段由数字类型转成字符串类型
	jsonField := gen.FieldJSONTagWithNS(func(columnName string) (tagContent string) {
		toStringField := `balance, `
		if strings.Contains(toStringField, columnName) {
			return columnName + ",string"
		}
		return columnName
	})
	// 将非默认字段名的字段定义为自动时间戳和软删除字段;
	// 自动时间戳默认字段名为:`updated_at`、`created_at, 表字段数据类型为: INT 或 DATETIME
	// 软删除默认字段名为:`deleted_at`, 表字段数据类型为: DATETIME
	autoUpdateTimeField := gen.FieldGORMTag("update_time", "column:update_time;type:int unsigned;autoUpdateTime")
	autoCreateTimeField := gen.FieldGORMTag("create_time", "column:create_time;type:int unsigned;autoCreateTime")
	softDeleteField := gen.FieldType("delete_time", "gorm.DeletedAt")
	// 模型自定义选项组
	fieldOpts := []gen.ModelOpt{jsonField, autoCreateTimeField, autoUpdateTimeField, softDeleteField}

	// 创建模型的结构体,生成文件在 model 目录; 先创建的结果会被后面创建的覆盖
	// 这里创建个别模型仅仅是为了拿到`*generate.QueryStructMeta`类型对象用于后面的模型关联操作中
	Address := g.GenerateModel("address")
	// 创建全部模型文件, 并覆盖前面创建的同名模型
	allModel := g.GenerateAllTable(fieldOpts...)

	// 创建有关联关系的模型文件
	User := g.GenerateModel("user",
		append(
			fieldOpts,
			// user 一对多 address 关联, 外键`uid`在 address 表中
			gen.FieldRelate(field.HasMany, "Address", Address, &field.RelateConfig{GORMTag: "foreignKey:UID"}),
		)...,
	)
	Address = g.GenerateModel("address",
		append(
			fieldOpts,
			gen.FieldRelate(field.BelongsTo, "User", User, &field.RelateConfig{GORMTag: "foreignKey:UID"}),
		)...,
	)

	// 创建模型的方法,生成文件在 query 目录; 先创建结果不会被后创建的覆盖
	g.ApplyBasic(User, Address)
	g.ApplyBasic(allModel...)

	g.Execute()
}

f6498e04344b4b76ac6c6a2527bd4bb0.png

更详细的配置示例可以参照:最佳实践 DEMO:https://github.com/idersec/gendemo

4. 基础查询

执行生成代码后,GEN 会帮助生成基础的查询方法,并且绑定到结构体上,可以直接调用函数查询获取查询结果,不需要提前定义变量,参数和结构体字段类型绑定,防止研发过程中误用。

package main

import (
	"fmt"
	"gorm-gen-demo/dal"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

const MySQLDSN = "root:root@(localhost:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"

func main() {
	// 连接数据库
	db, err := gorm.Open(mysql.Open(MySQLDSN))
	if err != nil {
		panic(fmt.Errorf("cannot establish db connection: %w", err))
	}
	dal.SetDefault(db)
    //查询User年龄为18的
	userDo := dal.User.Where(dal.User.Age.Eq(18))
	fmt.Print(userDo)
}

GEN 满足了基本上所有的日常使用的查询方法,包括事务、关联关系等高级用法,更多案例请参考:https://github.com/go-gorm/gen#readme

5. 自定义 SQL 查询

自定 SQL 的安全性是所有 ORM 最难解决的问题,GEN 使用模板注释的方法完美解决了这个问题,只需要将 SQL 注释到 interface 的方法上。SQL 支持简单的 where 查询和完整 SQL 查询,条件用Where()语法包住。Raw SQL 用sql()包住,也可省略直接写。

5.1占位符

  • gen.T
    用于返回数据的结构体,会根据生成结构体或者数据库表结构自动生成

  • gen.M
    表示map[string]interface{}用于返回数据

  • gen.RowsAffected
    用于执行 SQL 进行更新或删除时候,用于返回影响行数

  • @@table
     查询的表名,如果没有传参,会根据结构体或者表名自动生成

  • @@<name>
    当表名或者字段名可控时候,用@@占位,name 为可变参数名,需要函数传入。

  • @<name>
    当数据可控时候,用@占位,name 为可变参数名,需要函数传入

5.2子句

目前支持 if 、where 、set 子句,子句需要用{{}}括起来,并且需要用{{end}}
结束子句。where 和 set 子句会帮助做连接词补全和开头连接词删除。各个子句支持嵌套使用。

示例:

type Method interface {
    // Where("name=@name and age=@age")
    SimpleFindByNameAndAge(name string, age int) (gen.T, error)

    // select * from users where id=@id
    FindUserToMap(id int) (gen.M, error)

    // sql(insert into @@table (name,age) values (@name,@age) )
    InsertValue(age int, name string) error

    // select name from @@table where id=@id
    FindNameById(id int) string

    // select * from @@table
    //  {{where}}
    //      id>0
    //      {{if cond}}id=@id {{end}}
    //      {{if key!="" && value != ""}} or @@key=@value{{end}}
    //  {{end}}
    FindByIDOrCustom(cond bool, id int, key, value string) ([]gen.T, error)

    // update @@table
    //  {{set}}
    //      update_time=now()
    //      {{if name != ""}}
    //          name=@name
    //      {{end}}
    //  {{end}}
    //  {{where}}
    //      id=@id
    //  {{end}}
    UpdateName(name string, id int) (gen.RowsAffected,error)
}

GEN 会自动生成安全的实现代码,并且和结构体绑定。使用时候直接调用对应的函数即可。

user,err := u.SimpleFindByNameAndAge("zhangqiang",18)

resultMap,err:= u.FindUserToMap(2)

name := u.FindNameById(5)

users,err := u.FindByIDOrCustom(true, 10, "name", "modi")

rows,err := UpdateName("jinzhu", 12)

 

6.demo源码

项目地址:gorm-gen-demo: gorm-gen-demo小示例

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GORM-GEN快速上手 的相关文章

  • 【计算机毕业设计】毕业生就业管理微信小程序_lm9q0

    腾讯公司在2017年1月19日发布了一款不需要下载 不需要卸载 不需要存储的软件叫微信小程序 受到了很多人的喜欢 微信小程序自2017年发布至今 依托微信的社交属性和庞大的用户基数 已经渗透到生活的方方面面 1 微信小程序可以将基于微信平台
  • Python自动化测试 | 如何使用Robot Framework进行自动化测试?

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 华为OD统一考试 Python【数字转化】

    描述 我们想要一种特殊的整数编码方式 让数字小的时候 编码占的空间也小 编码的方法如下 我们每7位组成一部分来编码 在每个字节里 用前7位来存数字 如果后面还有数据 最高的那一位就是1 否则就是0 数据要按小端序保存 也就是说 小的数据部分
  • Android Navigation的四大要点你都知道吗?

    在JetPack中有一个组件是Navigation 顾名思义它是一个页面导航组件 相对于其他的第三方导航 不同的是它是专门为Fragment的页面管理所设计的 它对于单个Activity的App来说非常有用 因为以一个Activity为架构
  • SpringBoot中整合ElasticSearch快速入门以及踩坑记录

    场景 若依前后端分离版手把手教你本地搭建环境并运行项目 若依前后端分离版手把手教你本地搭建环境并运行项目 本地运行若依前后端分离 CSDN博客 参考上面搭建项目 ElaticSearch Elasticsearch 是java开发的 基于
  • 最新整理Java面试八股文,大厂必备神器

    在看这篇文章之前 我想我们需要先搞明白八股文是什么 明清科举考试的一种文体 也称制义 制艺 时文 八比文 八股文章就四书五经取题 内容必须用古人的语气 绝对不允许自由发挥 而句子的长短 字的繁简 声调高低等也都要相对成文 字数也有限制 八股
  • 计算机Java项目|基于SSM的微课学习系统

    作者主页 编程指南针 作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智
  • Python 文件的复制重命名以及xlsx文件中表格分开保存

    1 需要的头文件 import shutil import os import openpyxl 2 复制文件以及重命名 直接使用shutil库复制 重命名 移动即可 函数封装示例 source path 为全局变量被复制文件路径 dest
  • 计算机Java项目|基于SpringBoot个人空间平台的设计与实现

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 2024史上最全Java面试八股文(带全部答案)

    今天要谈的主题是关于求职 求职是在每个技术人员的生涯中都要经历多次 对于我们大部分人而言 在进入自己心仪的公司之前少不了准备工作 有一份全面细致 面试题 将帮助我们减少许多麻烦 在跳槽季来临之前 特地做这个系列的文章 一方面帮助自己巩固下基
  • JCMsuite应用:光学环形谐振腔模拟

    本案程演示了环形谐振腔的模拟 这种类型的集成光子器件 例如用作升 降滤波器或在传感应用中 当物质或粒子附着在环上时 通过测量其共振频率的位移来检测 对于集成光子电路中的无源光器件 s矩阵通常是研究的热点 它描述了通过端口 波导进入设备的电磁
  • 【卡尔曼滤波】具有梯度流的一类系统的扩散映射卡尔曼滤波器研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据 文章
  • 【go语言】读取toml文件

    一 简介 TOML 全称为Tom s Obvious Minimal Language 是一种易读的配置文件格式 旨在成为一个极简的数据序列化语言 TOML的设计原则之一是保持简洁性 易读性 同时提供足够的灵活性以满足各种应用场景 TOML
  • 【go语言】AST抽象语法树详解&实践之扫描代码生成错误码文档

    背景 为了能识别出代码中抛出错误码的地址和具体的错误码值 再根据错误码文件获取到错误码的具体值和注释 方便后续的排错 这里使用AST进行语法分析获取到代码中的目标对象 一 编译过程 在开始解析代码之前先补充了解一下编译过程 编译过程是将高级
  • 【心电图基线估计和去噪方法的群稀疏正则化】带有群稀疏正则化的心电图基线估计和去噪(Matlab实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 2024年华为OD机试真题-靠谱的车-Python-OD统一考试(C卷)

    题目描述 程序员小明打了一辆出租车去上班 出于职业敏感 他注意到这辆出租车的计费表有点问题 总是偏大 出租车司机解释说他不喜欢数字4 所以改装了计费表 任何数字位置遇到数字4就直接跳过 其余功能都正常 比如 1 23再多一块钱就变为25 2
  • 计算机Java项目|有机蔬菜商城

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 【js学习之路】遍历数组api之 `filter `和 `map`的区别

    一 前言 数组是我们在项目中经常使用的数据类型 今天我们主要简述作用于遍历数组的api filter 和 map 的区别 二 filter和map的共同点 首先 我们主要阐述一下 filter 和 map 的共同点 api的参数都是回调函数
  • 计算机Java项目|人体健康信息管理系统

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 计算机Java项目|java游戏账号交易系统

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板

随机推荐

  • ML算法——梯度下降随笔【机器学习】

    文章目录 2 1 梯度下降 2 1 梯度下降 梯度下降如何帮助参数优化 梯度下降是一种用于参数优化的常见方法 它的基本思想是通过迭代地更新参数 以减小损失函数 代价函数的值 从而找到一个最优解 梯度方向 向右 正向 向左 反方向 梯度方向是
  • 《机器学习(周志华)》 西瓜数据集3.0(含规范化以后数据)

    书上的一个常用数据集 plain view plain copy 编号 色泽 根蒂 敲声 纹理 脐部 触感 密度 含糖率 好瓜 1 青绿 蜷缩 浊响 清晰 凹陷 硬滑 0 697 0 46 是 2 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 0 7
  • 【vue3】锚点定位(两种实现方式)

    方法1 利用ref实现锚点定位 前面的废话文学 说到锚点定位 很多人第一时间会想到 a标签 但是a标签实现的锚点定位并不是那么的完美 特别是在hash模式下 对我而言 vue3的ref就实在是太完美了 解决问题的方法 很多情况下 我们会循环
  • 五层网络协议,各层功能,各层协议

    一 OSI七层模型 OSI七层协议模型主要是 应用层 Application 表示层 Presentation 会话层 Session 传输层 Transport 网络层 Network 数据链路层 Data Link 物理层 Physic
  • 使用 gfortran 编译 CALPUFF

    1 升级gfortran 7 默认gortran的版本是4 8 gfortran version GNU Fortran GCC 4 8 5 20150623 Red Hat 4 8 5 39 Copyright 2015 Free Sof
  • 美化VC界面(用户登录界面)

    源码下载 http download csdn net source 2840164 代码运行效果图如下 VC开发程序单调的界面相信大家都是深有感触 提到界面美化编程 人们都会说做界面不要用VC写 太难了 一句俗语 难者不会 会者不难 VC
  • Jmeter使用HTTP代理服务器无法打开网页问题的解决方法

    大家都知道Jmeter有录制HTTP请求的功能 HTTP代理服务器中 但是在操作中却会提示如下页面 Root CA certificate ApacheJMeterTemporaryRootCA created in JMeter bin
  • Apache Tomcat 8.5安装配置教程

    一 安装JDK步骤及配置JDK环境变量步骤省略 二 安装Tomcat 提前请先安装JDK 三 安装官网 直接点击 Tomcat很特殊 各个版本之间可能会相互不兼容 这里示例安装8 5的版本 点击tomcat8后根据自己的电脑选择相应的型号
  • git终端显示分支名称

    在使用git操作的时候 有时候会记错当前自己是在哪个分支上 从而造成一些不必要的麻烦 比如需要在某个分支上开发某个特性 结果误在master分支上进行了相关的操作 并且还push到了远端仓库 事后自己有可能还并不知晓 从而给自己带来了不必要
  • HTML基本标签

    文章目录 前言 一 HTML简介 二 HTML标签介绍 1 标题标签 2 段落标签 3 换行标签 4 hr标签 5 span标签 6 div标签 7 img标签 8 超链接标签 9 注释标签 10 特殊字符 11 格式化标签 12 sup上
  • 解决qt在线安装慢的方法

    iso mirrors ustc edu cn qtproject official releases online installers qt unified windows x64 online exe 步骤 1 点击上面链接 下载qt
  • web操作系统开发的_哪种操作系统更适合Web开发

    web操作系统开发的 If you re new to web development and are in the market for a new laptop you might be wondering which operatin
  • 17.linuxGPIO应用编程

    除了LED类设备可以通过sysfs文件系统控制以外 还可以使用该虚拟文件系统控制GPIO的高低电平 输入以及中断检测 一 GPIO控制高低电平 进入目录sys class gpio下可以看到有如下文件 其中gpiochip0对应硬件的GPI
  • 导入数据出错With the Partitioning, OLAP and Data Mining options

    因为oracle没有启动分区Partitioning 启动方法 pl sql执行 select from v option where parameter Partitioning
  • mybatis 遍历map实例

    mybatis 遍历map实例 map 数据如下 Map
  • 2021年6月程序员工资统计,平均15052元,你拖后腿了吗?

    2021年6月全国招收程序员435501人 2021年6月全国程序员平均工资15052元 工资中位数13000元 其中96 的人的工资介于1750元到150000元 这两年虽然平均工资涨了不少 但是工资中位数没怎么变 这说明什么呢 一 主要
  • 数据库文件怎么查看服务器,服务器如何查看文件个数据库文件

    服务器如何查看文件个数据库文件 内容精选 换一换 通常在将数据导入数据库前 即将入库的数据已经在相关主机上了 我们称这种保存着待入库数据的服务器为数据服务器 此时 只需检测以确认数据服务器和GaussDB for openGauss 集群能
  • 【Posts阅读】关于 Deep Sets 和 Neural Processes的简单介绍

    A Gentle Introduction to Deep Sets and Neural Processes 关于 Deep Sets 和 Neural Processes的简单介绍 Link https gordonjo github
  • 无法定位软件包:libappindicator3-1_libappindicator3-1软件包安装失败

    libappindicator3 1 所依赖的软件包 libindicator3 7 上链接 libindicator3 7 官网地址 http ftp cn debian org debian pool main libi libindi
  • GORM-GEN快速上手

    目录 1 什么是 GEN 2 GEN特性 3 快速使用GEN 3 1 下载 3 2 生成 4 基础查询 5 自定义 SQL 查询 6 demo源码 1 什么是 GEN 官方文档 Gen Guides GORM The fantastic O