go的orm框架-Gorm

2024-04-03 05:12
文章标签 go 框架 gorm orm

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

官网文档

特点

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

约定(重点)

主键

GORM 使用一个名为ID每个模型的默认主键的字段。

type User struct {ID   string // 默认情况下,名为 `ID` 的字段会作为表的主键Name string
}

可以通过标签 primaryKey 将其它字段设为主键 

// 将 `UUID` 设为主键
type Animal struct {ID     int64UUID   string `gorm:"primaryKey"`Name   stringAge    int64
}

表名称

默认情况下,GORM 将结构名称转换为snake_case表名称并将其复数化。例如,一个User结构体出现users在数据库中。

您可以实现 Tabler 接口来更改默认表名,例如:

type Tabler interface {TableName() string
}// TableName 会将 User 的表名重写为 `profiles`
func (User) TableName() string {return "profiles"
}

注意: TableName 不支持动态变化,它会被缓存下来以便后续使用。想要使用动态表名,你可以使用 Scopes,例如: 

func UserTable(user User) func (tx *gorm.DB) *gorm.DB {return func (tx *gorm.DB) *gorm.DB {if user.Admin {return tx.Table("admin_users")}return tx.Table("users")}
}db.Scopes(UserTable(user)).Create(&user)

临时指定表名

您可以使用 Table 方法临时指定表名,例如:

// 根据 User 的字段创建 `deleted_users` 表
db.Table("deleted_users").AutoMigrate(&User{})// 从另一张表查询数据
var deletedUsers []User
db.Table("deleted_users").Find(&deletedUsers)
// SELECT * FROM deleted_users;db.Table("deleted_users").Where("name = ?", "jinzhu").Delete(&User{})
// DELETE FROM deleted_users WHERE name = 'jinzhu';

列名

GORM 自动将结构体字段名转换为snake_case数据库中的列名。

type User struct {ID        uint      // 列名是 `id`Name      string    // 列名是 `name`Birthday  time.Time // 列名是 `birthday`CreatedAt time.Time // 列名是 `created_at`
}

您可以使用 column 标签或 命名策略 来覆盖列名 

type Animal struct {AnimalID int64     `gorm:"column:beast_id"`         // 将列名设为 `beast_id`Birthday time.Time `gorm:"column:day_of_the_beast"` // 将列名设为 `day_of_the_beast`Age      int64     `gorm:"column:age_of_the_beast"` // 将列名设为 `age_of_the_beast`
}

 你可以通过将 autoCreateTime 标签置为 false 来禁用时间戳追踪,例如:

type User struct {CreatedAt time.Time `gorm:"autoCreateTime:false"`
}

 

时间戳字段

GORM 使用名为CreatedAt和的字段UpdatedAt来自动跟踪记录的创建和更新时间。

对于有 CreatedAt 字段的模型,创建记录时,如果该字段值为零值,则将该字段的值设为当前时间

db.Create(&user) // 将 `CreatedAt` 设为当前时间user2 := User{Name: "jinzhu", CreatedAt: time.Now()}
db.Create(&user2) // user2 的 `CreatedAt` 不会被修改// 想要修改该值,您可以使用 `Update`
db.Model(&user).Update("CreatedAt", time.Now())

 对于有 UpdatedAt 字段的模型,更新记录时,将该字段的值设为当前时间。创建记录时,如果该字段值为零值,则将该字段的值设为当前时间

db.Save(&user) // 将 `UpdatedAt` 设为当前时间db.Model(&user).Update("name", "jinzhu") // 会将 `UpdatedAt` 设为当前时间db.Model(&user).UpdateColumn("name", "jinzhu") // `UpdatedAt` 不会被修改user2 := User{Name: "jinzhu", UpdatedAt: time.Now()}
db.Create(&user2) // 创建记录时,user2 的 `UpdatedAt` 不会被修改user3 := User{Name: "jinzhu", UpdatedAt: time.Now()}
db.Save(&user3) // 更新时,user3 的 `UpdatedAt` 会修改为当前时间

 你可以通过将 autoUpdateTime 标签置为 false 来禁用时间戳追踪,例如:

type User struct {UpdatedAt time.Time `gorm:"autoUpdateTime:false"`
}

安装

要在有mod文件的文件夹下面执行下面的命令

go get -u gorm.io/gorm

连接到数据库(mysql)

安装mysql驱动

go get -u gorm.io/driver/mysql

 

编写测试连接 

基础版

package main
import ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)
func main() {// 参考 root:123456@tcp(192.168.31.131:3306)/gotestdsn := "root:123456@tcp(192.168.31.131:3306)/gotest?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {fmt.Println("连接失败")return}fmt.Println("连接成功", db)
}

高级版

 

package main
import ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)
func main() {// 参考 root:123456@tcp(192.168.31.131:3306)/gotestdsn := "root:123456@tcp(192.168.31.131:3306)/gotest?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.New(mysql.Config{DSN:                       dsn,   // DSN data source nameDefaultStringSize:         256,   // string 类型字段的默认长度DisableDatetimePrecision:  true,  // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持DontSupportRenameIndex:    true,  // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引DontSupportRenameColumn:   true,  // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置}), &gorm.Config{})if err != nil {fmt.Println("连接失败")return}fmt.Println("连接成功", db)
}

 crud

准备数据库和结构体

package main
import ("errors""fmt""gorm.io/driver/mysql""gorm.io/gorm"
)
type Stu struct {Id      int `gorm:"primaryKey"`Name    stringAge     intAddress string
}func getDb() *gorm.DB {dsn := "root:123456@tcp(192.168.31.131:3306)/gotest?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {fmt.Println("连接失败")panic(errors.New("连接失败"))}fmt.Println("连接成功", db)return db
}

注意结构体中的属性首字母要大写,否则就不可见,还要指定主键 

查询

需要带条件的可以自己查看api

查询一个

first
 获取第一条记录(主键升序)
func main() {db := getDb()testFirst(db)
}
func testFirst(db *gorm.DB) {var stu Stures := db.Table("stu").First(&stu)if res.Error != nil {fmt.Println("查询数据失败")return}fmt.Println(stu)
}

Take
获取一条记录,没有指定排序字段
func testTake(db *gorm.DB) {var stu Stures := db.Table("stu").Take(&stu)if res.Error != nil {fmt.Println("查询数据失败")return}fmt.Println(stu)
}
Last
获取最后一条记录(主键降序)
func testLast(db *gorm.DB) {var stu Stures := db.Table("stu").Last(&stu)if res.Error != nil {fmt.Println("查询数据失败")return}fmt.Println(stu)
}

批量查询

func testMany(db *gorm.DB) {var stus = make([]Stu, 0)//相当于条件是id为10_ = db.Table("stu").Find(&stus)fmt.Println(stus)
}

新增

如果表不存在,会创建表

新增一个

func testAddOne(db *gorm.DB) {stu := Stu{Name: "新增名称", Age: 11, Address: "新增地址"}tx := db.Table("stu").Create(&stu)if tx.Error != nil {fmt.Println("新增失败")return}fmt.Println(stu.Id)
}

批量新增

func testAddMany(db *gorm.DB) {stus := []Stu{{Name: "批量新增名称1", Age: 11, Address: "批量新增地址1"}, {Name: "批量新增名称2", Age: 11, Address: "批量新增地址2"}}tx := db.Table("stu").Create(&stus)if tx.Error != nil {fmt.Println("新增失败")return}fmt.Println(stus)
}

更新

更新一个

func testUpdateOne(db *gorm.DB) {var stu Stu_ = db.Table("stu").First(&stu)stu.Name = "更新后名字"db.Table("stu").Save(&stu)
}
func testUpdateOne1(db *gorm.DB) {db.Table("stu").Where("id=?", 72).Update("name", "更新").Update("address", "跟新地址")
}

批量更新

func testUpdateMany(db *gorm.DB) {db.Table("stu").Where("id in (?)", []int{1,2,3,43}).Update("name", "更新").Update("address", "跟新地址")
}

删除

func testDeleteMany(db *gorm.DB) {db.Table("stu").Where("id in (?)", []int{1, 2, 3, 43}).Delete(&Stu{})
}

 

这篇关于go的orm框架-Gorm的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

Go语言中json操作的实现

《Go语言中json操作的实现》本文主要介绍了Go语言中的json操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 一、jsOChina编程N 与 Go 类型对应关系️ 二、基本操作:编码与解码 三、结构体标签(Struc

Java 缓存框架 Caffeine 应用场景解析

《Java缓存框架Caffeine应用场景解析》文章介绍Caffeine作为高性能Java本地缓存框架,基于W-TinyLFU算法,支持异步加载、灵活过期策略、内存安全机制及统计监控,重点解析其... 目录一、Caffeine 简介1. 框架概述1.1 Caffeine的核心优势二、Caffeine 基础2

使用Go调用第三方API的方法详解

《使用Go调用第三方API的方法详解》在现代应用开发中,调用第三方API是非常常见的场景,比如获取天气预报、翻译文本、发送短信等,Go作为一门高效并发的编程语言,拥有强大的标准库和丰富的第三方库,可以... 目录引言一、准备工作二、案例1:调用天气查询 API1. 注册并获取 API Key2. 代码实现3

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

Python ORM神器之SQLAlchemy基本使用完全指南

《PythonORM神器之SQLAlchemy基本使用完全指南》SQLAlchemy是Python主流ORM框架,通过对象化方式简化数据库操作,支持多数据库,提供引擎、会话、模型等核心组件,实现事务... 目录一、什么是SQLAlchemy?二、安装SQLAlchemy三、核心概念1. Engine(引擎)

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对