Go Gorm 示例详解

2025-01-16 16:50
文章标签 go 详解 示例 gorm

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

《GoGorm示例详解》Gorm是一款高性能的GolangORM库,便于开发人员提高效率,本文介绍了Gorm的基本概念、数据库连接、基本操作(创建表、新增记录、查询记录、修改记录、删除记录)等,本...

1. 概念

Gorm 官网:https://gorm.io/zh_CN/docs/

GormThe fantastic ORM library for golang aims to be developer friendly,这是官网的介绍,简单来说 Gorm 就是一款高性能的 Golang ORM 库,便于开发人员提高效率

那么 ORM(Object Relation Mapping) 又是什么呢?在 Golang 语言中,Object指的就是 struct 结构体对象,Relation 就是数据库当中的关系,Mapping则表示两者具有映射关系,具体表现如下:

  • Go当中的结构体声明 <-> 数据库层面的表结构
  • Go当中的结构体实例 <-> 数据库层面的一条表记录

2. 数据库连接

2.1 安装依赖

想要在 Go 代码中使用 gorm 我们需要先引入对应的依赖:

  • gorm 库依赖:gorm.io/gorm
  • 特定数据库驱动依赖:gorm.io/driver/mysql

然后使用 go mod 包管理工具加载对应的依赖:

go mod init first_gorm:初始化

Go Gorm 示例详解

go mod tidy:加载依赖

Go Gorm 示例详解

然后就可以开始编写代码了!

2.2 连接数据库

在操作数据库之前,我们还需要与指定的数据库建立连接,此处以 MySQL数据库为例:

基本语法:db, err := gorm.Open(mysql.Open(dsn语句), &gorm.Config{})

其中 dsn 语句为特定的连接格式,形式如下:user:pwd@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local

package main
import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
func main() {
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println("数据库连接失败!", err)
	}
	fmt.Println(db)
}

程序运行结果:

Go Gorm 示例详解

控制台打印出 db 对象,说明我们已经成功与数据库建立连接(必须保证数据库中存在指定的数据库)

3. 数据库基本操作

3.1 创建表(表关系映射)

3.1.1 基本使用

我们可以使用 gorm 提供的 API 来创建指定的表,需要关注的是 结构体声明 <=> 数据库表结构,因此我们想要创建一个表结构实则只需要定义一个结构体类型

-- 创建user表 --
create table t_user (
  user_id bigint primary key auto_increment,
  user_name varchar(32) not null,
  user_pwd varchar(128) not null,
  user_phone varchar(32) unique
) 

使用上述 SQL 语句创建表的行为等价于在 Go 语言当中定义下列结构体对象:

// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}

创建表基本语法:err := db.AutoMigrate(&特定结构体{})

package main
import (
    "fmt"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)
// User 结构体声明
type User struct {
    UserId    int64  `gorm:"primaryKey;autoIncrement"`
    UserName  string `gorm:"not null;type:varchar(32)"`
    UserPwd   string `gorm:"not null;type:varchar(128)"`
    UserPhone string `gorm:"unique;type:varchar(32)"`
}
func main() {
    // 连接数据库
    var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        fmt.Println("数据库连接失败!", err)
    }
    err = db.AutoMigrhttp://www.chinasem.cnate(&User{})
    if err != nil {
        fmt.Println("数据库表迁移失败!", err)
    }
}

程序运行结果:

Go Gorm 示例详解

3.1.2 自定义表名

我们发现定义结构体名称为 “User” 时会创建 “users” 的表名,但是如果我就希望叫做 “t_user” 应该怎么办呢?我们可以定义一个名为 TableName的方法接收器,格式如下:

func (*User) TableName() string {
	return "t_user"
}

删除原先的表后再次运行,可以发现此时表名称已经指定为t_user

3.2 新增记录

我们还可以使用 gorm 提供的 API 进行表记录的插入,这里我们需要关注** 结构体实例 <=> 表记录** 之间的映射关系,也就意味着我们可以通过创建一个结构体实例,实现插入一条记录的效果

3.2.1 单条数据插入

基本语法:db.Create(&结构体实例)

package main
import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"python
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println("数据库连接失败!", err)
	}
	// 插入单条数据
	var user = User{UserName: "wjj", UserPwd: "123", UserPhone: "111"}
	db.Create(&user)
	// 再次打印user
	fmt.Println(user)
}

数据库表结果:

Go Gorm 示例详解

程序运行结果:

Go Gorm 示例详解

提示:从中我们还可以发现,插入数据之后,还会将数据库表中记录回显到结构体实例当中!这也是为什么需要传递地址的原因!

3.2.2 批量插入数据

当我们需要批量插入多条数据的时候,循环调用 db.Create(&结构体实例)这个方法效率就太低了!因为数据库连接会话频繁创建销毁耗时比较高,更合适的方法就是进行批量插入

基本语法:db.Create(&结构体实例切片),仍旧是 Create 函数,但是参数我们可以传递结构体实例切片

package main
import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连China编程接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 批量插入多条数据
	var users = []User{
		{UserName: "th", UserPwd: "123", UserPhone: "222"},
		{UserName: "lhf", UserPwd: "123", UserPhone: "333"},
		{UserName: "zcy", UserPwd: "123", UserPhone: "444"},
	}
	db.Create(&users)
	// 打印结果
	fmt.Println(users)
}

数据库表结果:

Go Gorm 示例详解

程序运行结果:

Go Gorm 示例详解

3.3 查询记录

3.3.1 查询所有记录

基本语法:db.Find(&结构体实例切片)

package main
import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 查询全部记录
	vjsar users []User
	db.Find(&users)
	// 打印结果
	fmt.Println(users)
}

程序运行结果:

Go Gorm 示例详解

3.3.2 按照条件查询

我们可以使用 Where 指定查询条件进行过滤

基本语法:db.Where("user_id > ?", 2).Find()表示想要查询 user_id > 2 的所有记录

package main
import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 按照条件查询
	var users []User
	db.Where("user_id > ?", 2).Find(&users)
	// 打印
	fmt.Println(users)
}

程序运行结果:

Go Gorm 示例详解

3.3.3 查询单条记录

查询单条记录有以下两种情况:

  • 查询第一条记录:db.First(&结构体实例)
  • ​​​​​​​查询最后一条记录:db.Last(&结构体实例)
package main
import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 查询第一条记录
	var firstUser User
	db.First(&firstUser)
	// 查询最后一条记录
	var lastUser User
	db.Last(&lastUser)
	fmt.Println(firstUser, lastUser)
}

程序运行结果:

Go Gorm 示例详解

3.3.4 查询记录总数

基本语法:db.Find(&结构体实例切片).Count(&整型变量)

package main
import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 查询总数
	var users []User
	var totalSize int64
	db.Find(&users).Count(&totalSize)
	fmt.Println("记录总数:", totalSize)
}

程序运行结果:

Go Gorm 示例详解

3.4 修改记录

3.4.1 按照默认主键修改

基本语法:db.Save(&结构体实例)会按照结构体实例当中的主键字段找到对应数据库记录进行修改

package main
import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 查询user_id为1的记录
	var stu User
	db.Where("user_id = ?", 1).DqxoLApFind(&stu)
	// 修改stu姓名为wjj1
	stu.UserName = "wjj1"
	// 修改(按照主键修改)
	db.Save(&stu)
}

程序运行结果:

Go Gorm 示例详解

3.4.2 修改指定字段

上述按照默认主键修改的方式修改了全部字段,如果我们只想修改特定单个字段可以使用以下方式:

基本语法:db.Model(&结构体实例).Where(条件).Update(字段, 修改值)

package main
import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 修改user_id为1的记录 user_name为wjj
	var stu User
	db.Model(&stu).Where("user_id = ?", 1).Update("user_name", "wjj")
}

程序运行结果:

Go Gorm 示例详解

3.4.3 修改多个字段

我们还可以指定多个字段进行修改

基本语法:db.Model(&结构体实例).Where(条件).updates(修改实例),其中修改实例可以是结构体也可以是map对象

package main
import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 修改user_id为1的记录 user_name为WJJ, user_pwd为"999"
	var stu User
	var fields = map[string]interface{}{"user_name": "WJJ", "user_pwd": "999"}
	db.Model(&stu).Where("user_id = ?", 1).Updates(fields)
}

程序运行结果:

Go Gorm 示例详解

3.5 删除记录

3.5.1 按照默认主键删除

基本语法:db.Delete(&结构体实例)会自动按照主键找到表中记录,然后删除

package main
import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 按照默认主键删除
	var user = User{UserId: 1}
	db.Delete(&user)
}

程序运行结果:

Go Gorm 示例详解

3.5.2 指定条件删除

我们想更加精细化的控制删除条件就需要借助 Where 函数:

基本语法:db.Where(条件).Delete(&结构体实例)

package main
import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)
// User 结构体声明
type User struct {
	UserId    int64  `gorm:"primaryKey;autoIncrement"`
	UserName  string `gorm:"not null;type:varchar(32)"`
	UserPwd   string `gorm:"not null;type:varchar(128)"`
	UserPhone string `gorm:"unique;type:varchar(32)"`
}
func (*User) TableName() string {
	return "t_user"
}
func main() {
	// 连接数据库
	var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 按照条件删除
	db.Where("user_id = ?", 10).Delete(&User{})
}

程序运行结果:

Go Gorm 示例详解

到此这篇关于Go Gorm 详解的文章就介绍到这了,更多相关Go Gorm 内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于Go Gorm 示例详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完

MySQL8 密码强度评估与配置详解

《MySQL8密码强度评估与配置详解》MySQL8默认启用密码强度插件,实施MEDIUM策略(长度8、含数字/字母/特殊字符),支持动态调整与配置文件设置,推荐使用STRONG策略并定期更新密码以提... 目录一、mysql 8 密码强度评估机制1.核心插件:validate_password2.密码策略级