gormcrud5分钟快速上手(代码片段)

爱码大鲤鱼 爱码大鲤鱼     2022-12-13     625

关键词:

文章目录

1.ORM 是什么

ORM(Object Relational Mapping),中文名为对象关系映射。

使用 ORM 组件,可以让开发者通过操作对象的方式完成对数据库的操作(读写),避免手动书写 SQL 和完成数据到对象的转换,让我们更方便的操作数据库。

理论上 ORM 可以让我们脱离 SQL,但实际上还是需要懂 SQL 才能更好地使用 ORM。

2.GORM 是什么

GORM 是一个流行的 Golang ORM 库。

类似于 Java 生态里大家听到过的 Mybatis、Hibernate、SpringData 等。

GORM 由国人开发,中文文档齐全,对开发者友好,支持主流关系型数据库。

  • MySQL
  • SQL Server
  • PostgreSQL
  • SQlite

GORM 功能丰富齐全:

  • 关联 (拥有一个,拥有多个,属于,多对多,多态,单表继承)
  • 钩子(before/after create/save/update/delete/find)
  • 支持 Preload、Joins 的预加载
  • 事务,嵌套事务,保存点,回滚到保存点
  • Context、预编译模式、DryRun 模式
  • 批量插入,FindInBatches,使用 Map Find/Create,使用 SQL 表达式、Context Valuer 进行 CRUD
  • SQL 构建器,Upsert,锁,Optimizer/Index/Comment Hint,命名参数,子查询
  • 复合主键,索引,约束
  • 自动迁移
  • 自定义 Logger
  • 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…
  • 每个特性都经过了测试的重重考验
  • 开发者友好

GORM 最新源码地址:go-gorm/gorm

GORM V1 版本地址:jinzhu/gorm

GORM 中文文档地址:这里

本文将对 GORM 中常用的功能进行讲解,帮助你快速上手。

当然除了 GORM,你还有其他选择,比如 facebook-entsqlxsqlc 等。

3.安装

基于 Go Module 开发,import 最新包然后 go get 即可。

go get -u gorm.io/gorm

// 不同 DB 对应的驱动
go get -u gorm.io/driver/sqlite
go get -u gorm.io/driver/mysql
go get -u gorm.io/driver/postgres
go get -u gorm.io/driver/sqlserver

驱动包按照自己实际使用的 DB 选择即可。

本文将以 MySQL 为例,讲解 GORM 的使用。

4.连接 DB

以 MySQL 为例,建立数据库连接。

import (
	"fmt"

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

// MySQLConn GORM MySQL 连接。
var MySQLConn *gorm.DB

// Init gorm mysql connnection.
// 依赖服务配置初始化完成。
func InitMySQLConn() error 
	// data source name.
	dsn := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", Conf.Mysql.User, Conf.Mysql.Passwd, Conf.Mysql.IP, Conf.Mysql.Port, Conf.Mysql.Dbname)
	var err error
	MySQLConn, err = gorm.Open(mysql.Open(dsn))
	return err

填入 DB 对应的正确的用户名、密码、地址、端口、数据库名称等信息后,便可建立对应数据源的连接。相关配置一般在服务启动时,事先从配置文件中加载。

5.创建数据表

在进行增查改删(CRUD)之前,需要先创建一个数据表。

GORM 中一个 struct 对应一张数据库表,对应的 struct 被称为模型。

假如我们要创建一张商品(goods)表,那么 struct 可定义为:

// Good 商品。
type Good struct 
	gorm.Model
	Name  string `gorm:"type:varchar(255) not null"`
	Price int    `gorm:"type:bigint not null"`

其中 gorm.Model 时 GORM 预先定义的一些基础字段,我们可以嵌入直接拿来用。

// Model a basic GoLang struct which includes the following fields: ID, CreatedAt, UpdatedAt, DeletedAt
// It may be embedded into your model or you may build your own model without it
//
//	type User struct 
//	  gorm.Model
//	
type Model struct 
	ID        uint `gorm:"primarykey"`
	CreatedAt time.Time
	UpdatedAt time.Time
	DeletedAt DeletedAt `gorm:"index"`

字段后的 tag 用来定义字段在 DB 中的相关属性,如 primarykey 表示主键,index 表示索引,type 表示字段类型。

除此以外,还有更加丰富的标签定义参见官方文档:字段标签

一般在服务启动时创建数据表,如建立 DB 连接后只执行一次来完成数据表的创建。

db.AutoMigrate(&User)

db.AutoMigrate(&User, &Product, &Order)

// 创建表时添加后缀
db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User)

比如创建我们上面的商品表。

// 自动创建表,如果表已经存在不会有任何动作。
err := MySQLConn.AutoMigrate(&Good)

创建好后的数据表名为 struct 名称的 snake_case 复数形式,字段名为 struct 字段的 sanke_case 形式。

创建好的表结构如下:

6.增加(Create)

// createGood 插入商品。
func createGood(name string, price int) 
	task := &Good
		Name:   name,
		Price: price,
	
	result := MySQLConn.Create(task)
	if result.Error != nil 
		return 
	
	return nil

主键 ID 会自增,此外 GORM 还会自动维护 created_at、updated_ad 和 deleted_at 三个字段。

7.查询(Read)

比如按照主键查询。

// getGoodByID 根据主键检索。
func getGoodByID (id int) (Good, error) 
	var good Good
	result := MySQLConn.First(&good, id)
	return good, result.Error

如果查不到,将报 “not found error” 错误。

再如按照其他字段进行 and 查询。

// getGoods 根据商品信息分页拉取。
func getTaskTypesByInfo(name string, price int, last_id uint) ([]Good, error) 
	db := internal.MySQLConn
	if name != "" 
		db = db.Where("name = ?", req.TypeInfo.Name)
	
	db = db.Where("price >= ?", price)
	
	// 按照每页大小 50 拉取商品。
	db.Where("id > ?", last_id).Order("id asc").Limit(50)

	var goods []Good
	result := db.Find(&goods)
	return goods, result.Error

还有很多查询方式,比如按照 struct、map 指定查询字段以及 or 和 not 条件等,具体请参考官方文档 GORM 查询

8.更新(Update)

比如更新所有字段。

使用 Save 方法更新所有字段,即使是零值也会更新。

// 先根据 ID  查询。
db.First(&good, 1)

// 再修改值。
good.Name = "小米"

// 最后写回。
db.Save(&user)

再如更新单列。

注意,当使用 Model 方法且其值具有主键时,主键将用于构建条件。

// 条件更新
db.Model(&User).Where("active = ?", true).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE active=true;

// User 的 ID 是 `111`
db.Model(&user).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;

// 根据条件和 model 的值进行更新
db.Model(&user).Where("active = ?", true).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;

再如更新多列。

Updates 方法支持 structmap[string]interface 参数。当使用 struct 更新时,默认情况下,GORM 只会更新非零值的字段。

// 根据 `struct` 更新属性,只会更新非零值的字段
db.Model(&user).Updates(UserName: "hello", Age: 18, Active: false)
// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;

// 根据 `map` 更新属性
db.Model(&user).Updates(map[string]interface"name": "hello", "age": 18, "active": false)
// UPDATE users SET name='hello', age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;

9.删除(Delete)

如删除一条记录。

删除一条记录时,删除对象需要指定主键,否则会触发 批量 Delete,例如:

// Email 的 ID 是 `10`
db.Delete(&email)
// DELETE from emails where id = 10;

// 带额外条件的删除
db.Where("name = ?", "jinzhu").Delete(&email)
// DELETE from emails where id = 10 AND name = "jinzhu";

再如根据主键删除。

GORM 允许通过主键(可以是复合主键)和内联条件来删除对象,它可以使用数字,也可以使用字符串。

db.Delete(&User, 10)
// DELETE FROM users WHERE id = 10;

db.Delete(&User, "10")
// DELETE FROM users WHERE id = 10;

db.Delete(&users, []int1,2,3)
// DELETE FROM users WHERE id IN (1,2,3);

注意:

如果您的模型包含了一个 gorm.DeletedAt 字段(gorm.Model 已经包含了该字段),它将自动获得软删除的能力!

如果您不想引入 gorm.Model,您也可以这样启用软删除特性:

type User struct 
  ID      int
  Deleted gorm.DeletedAt
  Name    string

拥有软删除能力的模型调用 Delete 时,记录不会被数据库。但 GORM 会将 DeletedAt 置为当前时间, 并且你不能再通过普通的查询方法找到该记录。

使用 Unscoped 方法查找被软删除的数据。

db.Unscoped().Where("user_name = gry").Find(&users)

要想物理删除,使用 Unscoped 方法永久删除数据。

user.ID = 14
db.Unscoped().Delete(&user)

10.小结

本文简单介绍了 ORM、GORM、以及 GORM 连接数据库,创建数据表和 CRUD 的简单操作,帮忙新手快速上手。

更多用法,请参见官方文档 GORM 指南,这里有你想要的一切。


参考文献

GORM 指南| GORM - GORM
GORM 极速入门- 卢振千的博客
19-Gorm入门到精通- 刘清政 - 博客园
Go组件学习——gorm四步带你搞定DB增删改查 - 掘金

三分钟上手markdown——基本语法快速入门(代码片段)

最近爱上了用Markdown写博客,哈哈!你问我为什么?主要是用不着鼠标,全凭手敲解决问题,爽呀~好吧,我只是小菜鸟,发现了新大陆,文中表述有误评论马上修改!1.标题标题的语法是这样的&... 查看详情

10分钟教你快速上手vue3中新增的api(代码片段)

1.初始化项目// ① npm i -g @vue/cli// ② vue create my-project// ③ npm install @vue/composition-api -S// ④ main,jsimport Vue from 'vue'import VueCompositionApi from '@vue/composition- 查看详情

10分钟教你快速上手vue3中新增的api(代码片段)

1.初始化项目// ① npm i -g @vue/cli// ② vue create my-project// ③ npm install @vue/composition-api -S// ④ main,jsimport Vue from 'vue'import VueCompositionApi from '@vue/composition- 查看详情

10分钟教你快速上手vue3中新增的api(代码片段)

1.初始化项目// ① npm i -g @vue/cli// ② vue create my-project// ③ npm install @vue/composition-api -S// ④ main,jsimport Vue from 'vue'import VueCompositionApi from '@vue/composition-api'Vue.use(VueCompositionApi)2.setup方法setup是vue3.... 查看详情

五分钟上手echarts教程(代码片段)

...案例:https://download.csdn.net/download/TroyeSivanlp/33199899五分钟上手ECharts教程1-Echarts-介绍2-了解Echarts的基础配置3-如何在页面上显示简单的图表首先,初始化echarts实例对象第二步,指定配置项和数据(option)第三步,将配... 查看详情

python+chatgpt编程5分钟快速上手,强烈推荐!!!(代码片段)

最近一段时间chatGPT火爆出圈!无论是在互联网行业,还是其他各行业都赚足了话题。俗话说:“外行看笑话,内行看门道”,今天从chatGPT个人体验感受以及如何用的角度来分享一下。1、chatGPT是个啥?chatG... 查看详情

学习git---20分钟git快速上手

...是苦于没有借口(契机)。好吧,机会就在今天。给我20分钟,是的,只要20分钟,让你快速用上git。我们废话不多说,直接来干货。我们将会介绍以下几点:一,什么是git二,使用git的一般开发流程三,快速安装新建项目。hollo... 查看详情

前端layui框架快速上手详解(代码片段)

✍LayUI🔥前端框架LayUI详解地址🔥前端LayUI框架快速上手详解(一)https://blog.csdn.net/Augenstern_QXL/article/details/119748962🔥前端LayUI框架快速上手详解(二)https://blog.csdn.net/Augenstern_QXL/article/details/119 查看详情

三分钟快速上手tensorflow2.0再学习总结回顾(代码片段)

https://www.bilibili.com/video/av89601743哔哩哔哩上面有一位道友专门针对《简单粗暴》分享了他的个人经验,我也跟着复习了一遍,挑一些重点的记录一下这是一个工程师的角度,从开发的角度理解tf的构建 其实求梯度、导数、斜... 查看详情

学一点git--20分钟git快速上手

...是苦于没有借口(契机)。好吧,机会就在今天。给我20分钟,是的,只要20分钟,让你快速用上git。我们废话不多说,直接来干货。我们将会介绍以下几点:一,什么是git二,使用git的一般开发流程三,快速安装新建项目。hollo... 查看详情

2分钟快速上手流水线的创建与运行

...布常用流水线的创建与执行。本文分享自华为云社区《2分钟快速上手流水线的创建与运行》,作者:华为云PaaS服务小智。体验简介涉及服务简介软件持续交付流水线CodeArtsPipeline是华为云软件开发生产线CodeArts的一个子服务,是... 查看详情

前端layui框架快速上手详解(代码片段)

✍目录总览🔥LayUI🔥前端框架LayUI详解地址🔥前端LayUI框架快速上手详解(一)https://blog.csdn.net/Augenstern_QXL/article/details/119748962🔥前端LayUI框架快速上手详解(二)https://blog.csdn.net/Augenstern_QXL/articl 查看详情

nvm快速上手(代码片段)

...nodejs版本管理工具,下面记录一些常用的使用方式。快速上手1.安装nvmnpminstallnvm2.常用命令只有这两个命令常用,也基本只用得上这两个命令。nvmlist//判断nvm版本nvmuse16.6.0//使用16.6.0版本注意:在打开DOS命令窗口的时候一定... 查看详情

nativefier快速上手(代码片段)

...app的插件,写这篇博客仅仅是因为怕自己忘记了怎么快速调用,下面将介绍一些常用的语法。快速上手1.安装nativefiernativefier依赖于nodejs,因此只要在有nodejs的环境中运行以下命令即可npminstallnativefier-g2.创建app如果你... 查看详情

cookiesessionstoragelocalstorage快速上手(代码片段)

cookie、Sessionstorage、Localstorage快速上手先说区别cookie:数据大小不能超过4KB。不管是否有需求,cookie数据都会在HTTP请求中携带,在浏览器和服务器中来回传递,占用资源。可以在后端设置修改,数据仅在本地浏览器保存。cookie数... 查看详情

reactnative快速上手(代码片段)

工欲善其事,必先利其器。搭建ReactNative开发环境,需要安装以下辅助工具。Node.js:ReactNative需要借助Node.js来创建和运行JavaScript代码。原生开发工具及环境:ReactNative的运行需要依赖原生Android和iOS环境,因此需要分别安装原生An... 查看详情

elasticsearchik分词器快速上手(代码片段)

简介: ElasticSearchIK分词器快速上手一、安装IK分词器1.分配伪终端我的ElasticSearch是使用Docker安装的,所以先给容器分配一个伪终端.之后就可以像登录服务器一样直接操作docker中的内容了dockerexec-it容器ID/bin/bash2.使用elasticsearch-... 查看详情

前端echarts可视化框架快速上手详解(代码片段)

✍前端ECharts可视化框架完结🔥前端ECharts可视化框架完结地址🔥前端ECharts可视化框架快速上手详解(一)https://blog.csdn.net/Augenstern_QXL/article/details/119850486🔥前端ECharts可视化框架快速上手详解(二)https://blog.csdn.net/Augenste 查看详情