【GORM框架】一文学会用gorm实现对单表的增删改查操作

勤奋不是嘴上说说而已,而是实际的行动,在勤奋的苦度中持之以恒,永不退却。业精于勤,荒于嬉;行成于思,毁于随。在人生的仕途上,我们毫不迟疑地选择勤奋,她是几乎于世界上一切成就的催产婆。只要我们拥着勤奋去思考,拥着勤奋的手去耕耘,用抱勤奋的心去对待工作,浪迹红尘而坚韧不拔,那么,我们的生命就会绽放火花,让人生的时光更加的闪亮而精彩。

导读:本篇文章讲解 【GORM框架】一文学会用gorm实现对单表的增删改查操作,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

在这里插入图片描述

  • 博主简介:努力学习的大一在校计算机专业学生,热爱学习和创作。目前在学习和分享:数据结构、Go,Java等相关知识。
  • 博主主页: @是瑶瑶子啦
  • 所属专栏: GORM框架学习
  • 近期目标:写好专栏的每一篇文章

在这里插入图片描述

一、准备工作

在上一篇Gorm文章中,我们学习了如何使用gorm进行数据库的连接和一些高级配置、简单操作。👉【GORM框架】模型定义超详解,确定不来看看?

今天,我们要学习,如何使用gorm,进行单表的CRUD操作

在学习CRUD之前,这是一些准备工作:

有一个golang项目,其中连接是只负责和数据库进行连接
在这里插入图片描述

package main

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB

func init() {
	username := "root"     //账号
	password := "55667788" //密码
	host := "127.0.0.1"    //数据库地址,可以是Ip或者域名(这里用的就是localhost,是一个回送地址,值本地机
	port := 3306           //数据库端口
	Dbname := "testdb"     //数据库名
	timeout := "10s"       //连接超时,10秒

	// root:root@tcp(127.0.0.1:3306)/gorm?
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local&timeout=%s", username, password, host, port, Dbname, timeout)
	//连接MYSQL, 获得DB类型实例,用于后面的数据库读写操作。
	db, err := gorm.Open(mysql.Open(dsn))
	if err != nil {
		panic("连接数据库失败, error=" + err.Error())
	}
	// 连接成功
	fmt.Println(db)
	//把其DB类型实例赋给定义好的全局变量
	DB = db
}

再新建文件.go文件,进行CRUD练习

按住ctrl,点击多个.go文件,再右键go run,即可一次性运行多个go文件,但是注意,只能有一个main函数

这是模型定义:


// 1)模型定义:(表结构)
type Student struct {
	ID     uint   `gorm:"size:3"`
	Name   string `gorm:"size:8"`
	Age    int    `gorm:"size:3"`
	Gender byte
	Email  *string `gorm:"size:32"`
}

注意!!!

  • 为什么要把Email定义成指针类型呢?是为了更好的存储null类型。
  • 因为string在Go中是值类型,当string没有被赋值时,默认是空串""。它是长度为0,同样占存储空间的字符串。而不是明显的告诉我们:这是一个空!!这样会引起混淆
  • 相比之下,用指针类型,如果没有给出email,那就直接是空:null,既不会引起混淆,也可以节省空间(因为不会开辟内存)

二、增(Create)

1.1:添加一条记录

记录对应到代码里,其实就是结构体实体,所以我们只需实例化结构体,再使用gorm函数,进行create,即可建立联系,在数据库中增加记录

func main() {
	//2)建表
	DB.AutoMigrate(&Student{})

	//3)添加记录(实例化结构体)
	email := "3051337060@qq.com"
	s1 := Student{
		Name:   "瑶瑶子",
		Age:    19,
		Gender: 'F',
		Email:  &email,
	}
	//把该实体映射到表中的记录:
	err := DB.Create(&s1).Error
	fmt.Println(err)
}

注意!!!

  • Create函数接收的是指针

1.2:批量插入

批量插入也是用到Create方法,需要使用到Go中的切片

//批量插入记录
	//1)首先定义一个切片,用于存储多条记录
	var studentList []Student

	//2)向切片输入
	for i := 0; i < 100; i++ {
		studentList = append(studentList, Student{
			Name:   fmt.Sprintf("瑶瑶子%d号", i+1),
			Age:    19,
			Gender: 'F',
			Email:  &email,
		})
	}

	//3)直接将整个切片传入
	DB.Create(&studentList)

三、查询

3.1:查询单条记录

我们先来看一种比较简单的,使用Take()函数,查询一条记录:

  • 使用Take()函数,查询单条记录:

Take()函数将从数据库表中获取任何一条符合条件的记录。是根据数据库表中的主键或者默认排序规则来获取的。

	//定义一个结构体实体,用于存储数据库查询的返回的记录
	var student Student
	//使用gorm库中的方法,从数据库获取一条记录,映射到student变量中
	DB.Take(&student)
	fmt.Println(student)

注意:若上面已经执行了添加记录的语句,在执行查询语句时,需要把上面的增加语句注释掉,否则又会重复添加

  • First()Last()函数,返回查询结果集合的第一条、最后一条记录
DB.First(&student) 
// SELECT * FROM `students` ORDER BY `students`.`id` LIMIT 1
DB.Last(&student)  
// SELECT * FROM `students` ORDER BY `students`.`id` DESC LIMIT 1

如果没有指定排序顺序,默认是按主键顺序升序排序ordered by `students`.`id`.

  • 根据给定主键参数进行查询
	var stu Student
	DB.Take(&stu, 3)
	fmt.Println(stu)
	// SELECT * FROM `students` WHERE `students`.`id` = 3 LIMIT 1
  • 根据其他字段进行查询
	var stu Student
	DB.Take(&stu, "name = ?", "瑶瑶子")
	fmt.Println(stu)

注意,这里使用?作为占位符,原理是将用户输入进行转义后,再拼接。防止sql注入问题

3.2:查询多条记录

  • Find()查询数据库中所有与条件匹配的记录(以切片形式返回),如果没有,则返回空切片
var students []Student
	DB.Find(&students)
	for _, student := range students {
		fmt.Println(student)
	}
  • 根据主键进行查找
	var students []Student
	
	DB.Find(&students, []int{1, 3, 5, 6})
	DB.Find(&students, 1, 3, 5, 6) //和上面等价
	fmt.Println(students)
  • 根据其他条件查询
	var students []Student
	DB.Find(&students, "name in ?", []string{"瑶瑶子3号", "瑶瑶子6号"})

3.3:获取查询结果

  • 获取查询的记录数
	var students []Student
	DB.Find(&students)
	//核心代码如下行
	count := DB.Find(&students).RowsAffected
	fmt.Println(count)
  • 是否查询失败
	var students []Student

	err := DB.Find(&students).Error
	switch err {
	case gorm.ErrRecordNotFound:
		fmt.Println("没有找到")
	default:
		fmt.Println("sql错误")
	}

四、改

  • Save()进行单个记录的全字段更新
//1)先找到要修改的记录
	var student Student
	DB.Take(&student, 11)

	//2)对其字段进行修改
	student.Name = "是瑶瑶子啦"
	//3)使用sava,进行保存(数据库内相映射的记录更新)
	DB.Save(&student)
	// UPDATE `students` SET `name`='是瑶瑶子啦',`age`=19,`gender`email`='3051337060@qq.com' WHERE `id` = 11

注意:零值也会被更新(即将字段修改为零值,使用sava,其在数据库映射也会被修改)

  • Select()更新指定字段

可以看到,上面save()语句翻译成sql是进行全字段更新,即使只修改了一个。
使用select,则进行指定字段更新

	//1)先找到要修改的记录
	var student Student
	DB.Take(&student, 11)

	//2)对其字段进行修改
	student.Name = "是瑶瑶子啦"
	//3)使用sava,进行保存(数据库内相映射的记录更新)
	DB.Select("Name").Save(&student)
	// UPDATE `students` SET `name`='是瑶瑶子啦' WHERE `id` = 11
  • 批量更新
//1)让所有年龄为19的年龄全修改为20(使用了其他属性查询
	var students []Student
	DB.Find(&students, "age = ?", 19).Update("Age", 20)

	//2)将ID为1,2,3的年龄改为21(使用主键查询
	DB.Find(&students, 1, 2, 3).Update("Age", 21)
  • 使用结构体更新多字段(不会更新零值)
var students []Student

	DB.Find(&students, 1, 2, 3).Updates(Student{
		Name: "yyz",
		Age:  0, //结构体更新零值,不会进行修改
	})
	fmt.Println(students)
	//结果:[{1 yyz 21 70 0xc00022c940} {2 yyz 21 70 0xc00022c960} {3 yyz 21 70 0xc00022c980}]

  • 使用map更新多字段(会更新零值)
	DB.Model(&Student{}).Where("age = ?", 21).Updates(map[string]any{
		"age":  0,
		"name": "yyz2024",
	})
	//UPDATE `students` SET `age`=0,`name`='yyz2024' WHERE age = 21

五、删除

  • delete()根据主键进行删除
	DB.Delete(&student, 2)
	// DELETE FROM `students` WHERE `students`.`id` = 2
  • delete()根据主键批量删除
	DB.Delete(&student, 12, 13)
	// DELETE FROM `students` WHERE `students`.`id` IN (12,13)
  • delete()+其他条件,批量删除
DB.Delete(&Student{}, "name = ?", "是瑶瑶子啦")
//DELETE FROM `students` WHERE name = '是瑶瑶子啦'
  • delete()+where(其他条件)批量删除
//批量删除
	DB.Where("name = ?", "瑶瑶子").Delete(&Student{})
	// DELETE FROM `students` WHERE name = '瑶瑶子'

注意:

  • 警告 删除记录时,请确保主键字段有值,GORM 会通过主键去删除记录,如果主键为空,GORM 会删除该 model 的所有记录。
  • 如果一个 model 有 DeletedAt 字段,他将自动获得软删除的功能! 当调用 Delete 方法时, 记录不会真正的从数据库中被删除, 只会将DeletedAt 字段的值会被设置为当前时间

欢迎在评论区交流和留下你的想法和建议

如果对你有用,还请:💭评论+👍🏻点赞+⭐收藏+➕关注

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/142418.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!