Go框架三件套:Gorm的基本操作

2024-05-14 15:12

本文主要是介绍Go框架三件套:Gorm的基本操作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.概述

这里的Go框架三件套是指 WebRPCORM框架,具体如下:

Gorm框架

gorm框架是一个已经迭代了10+年的功能强大的ORM框架,在字节内部被广泛使用并且拥有非常丰富的开源扩展。

Kitex框架

Kitex是字节内部的Golang微服务RPC框架,具有高性能、强可扩展的主要特点,支持多协议且拥有丰富的开源扩展。

Hertz框架

Hertz是字节内部的HTTP框架,参考了其他开源框架的优势,结合字节跳动内部的需求,具有高易用性、高性能、高扩展性等特点。


2.Gorm

什么是ORM?

ORM(Object Relational Mapping)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。简单理解为一种框架的格式。

2.1 准备工作

image-20230125142805421

  • 开源地址
  • 官方文档

下载gorm

根据官方文档提供的方法,我们可以直接使用go get命令来获取gorm依赖。

go get -u gorm.io/gorm

image-20230125144018311


2.2 数据库连接

除了自定义开发驱动外,目前GORM官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server

确定你需要使用的数据库类型之后,需要使用下面的命令安装对应的驱动依赖,下面以安装MySQL驱动为例,如果使用其他驱动依赖,只需要替换命令中driver后面的内容即可。

go get -u gorm.io/driver/mysql
func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "username:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {fmt.Println("数据库连接异常", err)}fmt.Printf("db:%v", db)
}

更多相关内容参考


2.3 基本使用

2.3.1 创建数据

介绍GORM的增删改查等基本操作。

  • 连接数据库以及初始化数据模型

可以通过使用default标签为字段设定默认值。

// User Article Product 定义go model
type User struct {Id         int    `gorm:"primaryKey"`UserName   string `gorm:"default:八尺妖剑"`Email      string `gorm:"ilikexff@gmail.com"`CreateTime time.Time
}// 为model定义表名func (u User) TableName() string {return "t_user"
}
  • 创建数据Create()

直接构建插入对象。

func main() {db, err := gorm.Open(mysql.Open("root:123456@tcp(127.0.0.1:3306)/gotest?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{})if err != nil {panic("数据库连接错误!")}//创建数据db.Create(&User{Id: 1, UserName: "李四", Email: "2217021563@qq.com", CreateTime: time.Now()})fmt.Printf("数据创建成功:%v", db)fmt.Printf("返回插入数据的主键:%v\n", user.Id)fmt.Printf("返回Error:%v\n", res.Error)fmt.Printf("返回插入记录的条数:%v\n", res.RowsAffected)
}

使用 指定字段创建记录。

res := db.Select("Id", "UserName", "CreateTime").Create(&user)
res := db.Create(&user)
fmt.Printf("返回插入数据的主键:%v\n", user.Id)
fmt.Printf("返回Error:%v\n", res.Error)
fmt.Printf("返回插入记录的条数:%v\n", res.RowsAffected)

创建一个记录且一同忽略传递给略去的字段值:人话就是除了传递过去的字段不需要创建之外,其他字段都要创建。

res := db.Omit("Email", "UserName").Create(&user)
fmt.Printf("返回插入数据的主键:%v\n", user.Id)
fmt.Printf("返回Error:%v\n", res.Error)
fmt.Printf("返回插入记录的条数:%v\n", res.RowsAffected)

使用分片批量创建数据。

var users = []User{{UserName: "汪淼", Email: "213213232@qq.com", CreateTime: time.Now()}, {UserName: "杨冬", Email: "213213232@qq.com", CreateTime: time.Now()}, {UserName: "叶文洁", Email: "213213232@qq.com", CreateTime: time.Now()}}
db.Create(&users)
for _, user := range users {fmt.Printf("批量创建之后的ID:%v\n", user.Id)
}

使用Map结构创建数据,这种方式创建记录时,association不会被调用且主键也不会自动填充。

// 根据Map结构创建数据-1
db.Model(&User{}).Create(map[string]interface{}{"UserName": "史强","Email":    "32323442@qq.com",
})
//根据Map结构创建数据-2
db.Model(&User{}).Create([]map[string]interface{}{{"UserName": "梅艳芳", "Email": "323232@qq.com"},{"UserName": "张国荣", "Email": "43223235@qq.com"},
})

冲突处理,以遇到冲突时不处理冲突创建数据为例:

//冲突处理:不处理任何冲突创建数据
us := &User{UserName: "小二", Email: "3232322@qq.com"}
db.Clauses(clause.OnConflict{DoNothing: true}).Create(&us)

关于更多创建数据的内容可参考


2.3.2 查询数据

根据主键检索。First()方法

var user User
fmt.Println("-------------------------------下面开始查询-----------------------------------------")
res := db.First(&user, 10)
//上面的语句等同于下面的语句
//db.First(&user,"10")
fmt.Printf("返回插入数据的主键:%v\n", user.Id)
fmt.Printf("返回Error:%v\n", res.Error)
fmt.Printf("返回插入记录的条数:%v\n", res.RowsAffected)

根据主键检索,使用Find()方法。

res := db.Find(&users, []int{1, 2, 3})
fmt.Printf("返回插入数据的主键:%v\n", user.Id)
fmt.Printf("返回Error:%v\n", res.Error)
fmt.Printf("返回查询记录的条数:%v\n", res.RowsAffected)

检索单个对象,GORM 提供了 FirstTakeLast 方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1 条件,且没有找到记录时,它会返回 ErrRecordNotFound 错误。

//获取第一条记录,按主键升序
db.First(&user)
//获取第一条记录,没有指定排序字段
db.Take(&user)
//获取最后一条记录(按主键降序)
db.Last(&user)

查询全部对象。

result := db.Find(&users)

条件查询,String条件。

//条件查询-根据条件获取一条记录
//SELECT * FROM users HWERE name = '李四' ORDER BY id LIMIT 1;
res := db.Where("user_name=?", "李四").First(&user)
PrintfRes(res)//SELECT * FROM users HWERE name<> '王五'
res1 := db.Where("user_name<> ?", "王五").Find(&users)
PrintfRes(res1)//IN
//SELECT * FROM users WHERE user_name IN('李四','李四2')
res2 := db.Where("user_name IN ?", []string{"李四", "李四2"}).Find(&users)
PrintfRes(res2)//LIKE
//SELECT * FROM users WHERE user_name LIKE '%李%'
res3 := db.Where("user_name LIKE?", "%李%").Find(&users)
PrintfRes(res3)//AND
//SELECT * FROM t_user WHERE user_name = '李四' AND id >=1
res4 := db.Where("user_name=? AND id >= ?", "李四", 1).Find(&users)
PrintfRes(res4)
}

条件查询,Struct & Map 条件。

//Struct
//SELECT * FROM user WHERE user_name = ”李四“ AND email = "2217021563@qq.com" ORDER BY id LIMIT 1;
res6 := db.Where(&User{UserName: "李四", Email: "2217021563@qq.com"}).First(&user)
PrintfRes(res6)//Map
//SELECT * FROM user WHERE user_name = "李四" AND email = "2217021563@qq.com"
res7 := db.Where(map[string]interface{}{"user_name": "李四", "email": "2217021563@qq.com"}).Find(&users)
PrintfRes(res7)

更多关于查询的内容可参考


2.3.3 更新数据

Save()方法,保存所有的字段,即使字段是零值。

db.First(&user)
user.UserName = "字节"
user.Email = "11111111@qq.com"
res := db.Save(&user)
PrintfRes(res)

条件更新,使用条件更新单个列。

//2.条件更新
UPDATE user SET user_name = '跳动'
res1 := db.Model(&User{}).Where("active = ?", 1).Update("user_name", "跳动")
PrintfRes(res1)//使用默认主键ID更新
res3 := db.Model(&user).Update("user_name", "hello")
PrintfRes(res3)//根据条件和model的值进行更新
//UPDATE users SET user_name = "yes", WHERE id = 1 AND active = 1
res4 := db.Model(&user).Where("active", 1).Update("user_name", "yes")
PrintfRes(res4)

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

//根据 struct更新属性,只会更新非零字段
res := db.Model(&user).Updates(User{UserName: "张国荣", Email: "00000000@qq.com", Active: 1})
PrintfRes(res)//根据map更新数据
res2 := db.Model(&user).Updates(map[string]interface{}{"user_name": "哥哥", "email": "2222222@qq.com", "active": 0})
PrintfRes(res2)

更新和排除指定字段

//更新指定字段
db.Model(&user).Select("user_name").Updates(map[string] interface{}{"user_name":"利好","email:":"9999999999@qq.com"})//排除指定字段
db.Model(&user).Omit("user_name").Updates(map[string] interface{}{"user_name":"李彦宏","email":"4444444444@qq.com"})

更多关于数据更新的内容可参考


2.3.4 删除数据

根据主键删除。GORM 允许通过主键(可以是复合主键)和内联条件来删除对象,它可以使用数字(如以下例子。也可以使用字符串——译者注)。查看 查询-内联条件(Query Inline Conditions) 了解详情。

//根据主键删除,ID可以时strin 	db.Delete(&User{},"10")
db.Delete(&User{}, 14)
//根据多个ID删除数据
db.Delete(&user, []int{5, 6, 7})

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

user.Id = 4
//删除一条记录(ID==2)
db.Delete(&user)
//带额外条件的删除
db.Where("user_name = ?", "Tom").Delete(&user)

批量删除,如果指定不包括主属性,那么GORM会执行批量删除,它将删除所有匹配的记录。

//批量删除
db.Where("email LIKE ?", "%213213%").Delete(&user)
//db.Delete(&User{},"email LIKE ?" ,"%213213%")

这篇关于Go框架三件套:Gorm的基本操作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/989090

相关文章

Go信号处理如何优雅地关闭你的应用

《Go信号处理如何优雅地关闭你的应用》Go中的优雅关闭机制使得在应用程序接收到终止信号时,能够进行平滑的资源清理,通过使用context来管理goroutine的生命周期,结合signal... 目录1. 什么是信号处理?2. 如何优雅地关闭 Go 应用?3. 代码实现3.1 基本的信号捕获和优雅关闭3.2

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

数据治理框架-ISO数据治理标准

引言 "数据治理"并不是一个新的概念,国内外有很多组织专注于数据治理理论和实践的研究。目前国际上,主要的数据治理框架有ISO数据治理标准、GDI数据治理框架、DAMA数据治理管理框架等。 ISO数据治理标准 改标准阐述了数据治理的标准、基本原则和数据治理模型,是一套完整的数据治理方法论。 ISO/IEC 38505标准的数据治理方法论的核心内容如下: 数据治理的目标:促进组织高效、合理地

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别? 在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。 无缓冲的 channel 行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel

如何确定 Go 语言中 HTTP 连接池的最佳参数?

确定 Go 语言中 HTTP 连接池的最佳参数可以通过以下几种方式: 一、分析应用场景和需求 并发请求量: 确定应用程序在特定时间段内可能同时发起的 HTTP 请求数量。如果并发请求量很高,需要设置较大的连接池参数以满足需求。例如,对于一个高并发的 Web 服务,可能同时有数百个请求在处理,此时需要较大的连接池大小。可以通过压力测试工具模拟高并发场景,观察系统在不同并发请求下的性能表现,从而

ZooKeeper 中的 Curator 框架解析

Apache ZooKeeper 是一个为分布式应用提供一致性服务的软件。它提供了诸如配置管理、分布式同步、组服务等功能。在使用 ZooKeeper 时,Curator 是一个非常流行的客户端库,它简化了 ZooKeeper 的使用,提供了高级的抽象和丰富的工具。本文将详细介绍 Curator 框架,包括它的设计哲学、核心组件以及如何使用 Curator 来简化 ZooKeeper 的操作。 1

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟