go开源宝藏gorm专场(含思维导图)|持续更新(代码片段)

小生凡一 小生凡一     2023-01-15     127

关键词:

写在前面

本人只是一个Go语言的初学者,这篇文只是把我平常经常用到的都总结起来而已。
具体详细的内容建议到去GORM的中文文档查看。
当然这篇文章也会持续更新,记录我的CURD打磨过程
这篇文章也会持续更新哒

思维导图

1. 简介

  • 介绍:一个Go语言开发的ORM库,是字节的一位大牛写哒!!国产框架!
  • 下载:go get -u github.com/jinzhu/gorm

流程:

  1. 导入Gorm
  2. 导入数据库驱动
  3. 定义数据库模型
  4. 与数据库连接
  5. 字段迁移映射
  6. 增、删、改、查
  7. 关闭数据库连接

2. 数据库驱动

数据库驱动导入
mysqlgithub.com/go-sql-driver/mysqlgithub.com/jinzhu/gorm/dialects/mysql
postgresqlgithub.com/lib/pqgithub.com/jinzhu/gorm/dialects/postgres
sqlitegithub.com/mattn/go-sqlite3github.com/jinzhu/gorm/dialects/sqlite
sqlservergithub.com/jinzhu/gorm/dialects/mssql

3. 连接(MySQL为例子)

配置ini文件

[mysql]
Db = mysql
DbHost = 127.0.0.1
DbPort = 3306
DbUser = root
DbPassWord = root
DbName = carsys

读取配置文件

	file, err := ini.Load("./conf/config.ini")
	if err != nil 
		fmt.Println("配置文件读取错误,请检查文件路径:", err)
	
	LoadMysqlData(file)

数据库路径拼接

path := strings.Join([]stringDbUser, ":", DbPassWord, "@tcp(", DbHost, ":", DbPort, ")/", DbName, "?charset=utf8&parseTime=true", "")  // 路径拼接
model.Database(path)  	// 连接数据库

连接数据库,这个是放在了model包,所以后面的操作都是model.DB

var DB *gorm.DB  //全局的数据库入口

func Database(connString string) 
	db, err := gorm.Open("mysql", connString)
	db.LogMode(true)
	if err != nil 
		panic(err)
	
	if gin.Mode() == "release" 
		db.LogMode(false)
	
	db.SingularTable(true)         //默认不加复数s,不然他的每个数据后面都会加上和s比如user变成users
	db.DB().SetMaxIdleConns(20)  	//设置连接池,空闲
	db.DB().SetMaxOpenConns(100) 	//设置打开最大连接
	db.DB().SetConnMaxLifetime(time.Second * 30)
	DB = db
	migration() //模型迁移映射到数据库

4. 迁移(MySQL为例子)

自动迁移数据库到最新版本,最会添加列和索引,不会修改类型删除列

4.1 构建数据库表

这个gorm.Model是自动加上create_timeupdate_timedelete_time

查看源码里面得gorm中得model

然后我们可以像这样直接去定义一个struct模型,准备映射到数据库中,就不用写sql语句了。
后面可以加上tag就像是gorm:"unique"这样的,表示这个是唯一的。

import "github.com/jinzhu/gorm"

type User struct 
	gorm.Model
	UserName       string `gorm:"unique"` 
	Email          string 
	PasswordDigest string
	Nickname       string `gorm:"unique"`
	Status         string
	Limit          int   // 0 非管理员  1 管理员
	Type           int    // 0表示用户  1表示商家
	Avatar         string `gorm:"size:1000"`
	Monery 		    int

4.2 数据库模型迁移

gorm提供了一个AutoMigrate的方法,很方便地进行映射迁移的工作。

func migration() 
	//自动迁移模式
	DB.Set("gorm:table_options", "charset=utf8mb4").
		AutoMigrate(&User)

4.3 tags束缚

4.3.1 一对多

语义场景:评论和帖子的关系。一个帖子有很多的评论,但是这个评论只能在这个帖子下面。

所以可以通过foreignkey进行外键的束缚。外键到Social这个模型。关系标识为social_id

type Comment struct 
	gorm.Model
	Content    string
	ParentId   uint   	// 父评论ID
	UserID     uint   	// 用户ID
	ReplyName  string 	// 回复者名字
	UserName   string
	UserAvatar string
	SocialId   uint  `gorm:"foreignkey:Social;association_jointable_foreignkey:social_id"` //社区帖子ID
	Children   []Comment `gorm:"foreignkey:ParentId"`

4.3.2 多对多

语义环境:一个用户可以有多个好友,反过来也可以。所以就是user表自己的多对多。

使用tags是many2many

type User struct 
	gorm.Model
	Relations 	   []User `gorm:"many2many:relation; association_jointable_foreignkey:relation_id"`
	UserName       string
	Email          string 	//`gorm:"unique"`
	Avatar         string 	`gorm:"size:1000"`
	Phone 		   string
	BanTime 	   int
	OpenID 		   string 	`gorm:"unique"`

这样的多对多的关联,就会多创建一个表来存两者的关系。


5. 增

5.1 一对一

create函数进行创建。

category := model.Category
		CategoryName: service.CategoryName,
		EnglishName:service.EnglishName,

err := model.DB.Create(&category).Error

5.2 一对多

语义环境:这里就是一评论表,socialId就是帖子, 一个帖子对应多个评论,和一对一是 一样的创建方式

	var comment model.Comment
	comment = model.Comment
		UserID:    user.ID,
		Content:   service.Content,
		ParentId:  service.ParentId,
		UserName:  user.UserName,
		UserAvatar:  user.Avatar,
		SocialId: service.SocialID,
	
	err := model.DB.Create(&comment).Error

5.3 多对多

语义环境:用户表,用户和用户之间建立多对多联系

type User struct 
	gorm.Model
	Relations 	   []User `gorm:"many2many:relation; association_jointable_foreignkey:relation_id"`
	UserName       string
	Email          string 	//`gorm:"unique"`
	Avatar         string 	`gorm:"size:1000"`
	Phone 		   string
	BanTime 	   int
	OpenID 		   string 	`gorm:"unique"`

选出user表中的两个元素。然后进行关联绑定。

	var user model.User
	var friend model.User
	model.DB.Model(&friend).Where(`id = ? `,id).First(&friend)  			//被关注者
	model.DB.Model(&user).Where(`id = ?`,userId).First(&user)			//关注者
	err := model.DB.Model(&user).Association(`Relations`).Append([]model.Userfriend).Error

这条语句就是把这个user和这个friend建立联系,存放在Relations表里面。


6. 删

6.1 一对一

GORM中的delete删除是软删除,就是虽然是删除了,但是并没有完全删除,而是保留在数据中但是查询并不查询这条已经删除的语句。

  • 单记录删除

先找到这条数据

	var social model.Society
	code := e.Success
	err := model.DB.First(&social, id).Error // 根据id找到这个social,记得传地址。

然后进行删除即可

	err = model.DB.Delete(&social).Error
  • 批量删除
 db.Where("user_name like ? ","%Fan%").Delete(User)
  • 永久删除:在数据库直接清空了,不是软删除了
db.Unscoped().Where("name Like ?","%6%").Delete(User)

6.2 一对多

其实一对一就是特殊的一对多

删除和一对一其实是一样的操作。

	var social model.Society
	model.DB.First(&social, id)  // 找到这个帖子
	model.DB.Delete(&social)   // 将其进行删除

6.3 多对多

找到这两者的关系,然后进行关联删除即可。就会从Relations表中把这两者的关系进行删除。

	var user model.User
	var friend []model.User
	model.DB.Model(&friend).Where(`id = ?`,id).First(&friend)  			//被关注者
	model.DB.Model(&user).Where(`id = ?`,userId).First(&user)	//关注者
	err := model.DB.Model(&user).Association(`Relations`).Delete(friend).Error

7. 改

7.1 一对一

  • Save
    会保存所有的字段,即使字段是零值
social := model.Society
		CategoryID:    service.CategoryID,
		Title:         service.Title,
		Content:       service.Content,
		Picture:       service.Picture,
		CategoryName:  service.CategoryName,
	
err := model.DB.Save(&social).Error
  • Update
    当使用Update更新单个列时,需要指定条件,否则会返回ErrMissingWhereClause错误。
model.DB.Model(model.User).Where("open_id=?", openid).Update("phone", phone)
  • Updates

批量更新,只会更新指定字段,但是如果是空值的情况下是不更新的成空值的。

只更新指定字段

model.DB.Table("user").Where("user_name = ?","FanOne").
Updates(map[string]interface"phone":"10001","email":"fanone@qq.com")

只更新更改的非零值的字段

model.DB.Model(&User).Where("user_name = ?","FanOne").
Updates(UserPhone:"10001",Email:"fanone@666.com")

7.2 一对多

直接更新字段,同上。

7.3 多对多

由于多对多的是根据关系来关联的,所以更新字段关系是无关的,同上。


8. 查

  • First 是找到第一个
  • Last 是找到最后一个
  • Find 是找到全部

8.1 一对一

语义环境:用户表

type User struct 
	gorm.Model
	Relations 	   []User `gorm:"many2many:relation; association_jointable_foreignkey:relation_id"`
	UserName       string
	Email          string 	//`gorm:"unique"`
	Avatar         string 	`gorm:"size:1000"`
	Phone 		      string
	BanTime 	      int
	OpenID 		   string 	`gorm:"unique"`

8.1.1 基本查询

  • 查询第一个
var u1 User
db.First(&u1)
fmt.Println(u1)
  • 查询最后一个
var u2 User
db.Last(&u2)
fmt.Println(u2)
  • 按主键获取
var u3 User
db.First(&u3,2) //不指定的话,默认主键是id
fmt.Println(u3)
  • 按条件查询一条
var u4 User
db.First(&u4,"user_name=?","FanOne") //不指定的话,默认主键是id
fmt.Println(u4)
  • 获取所有数据
var u5 []User
db.Find(&u5) //查询所有的数据信息
fmt.Println(u5)

8.1.2 Where条件

  • 单一条件
var u1 User
db.Where("user_name = ?","FanOne").First(&u1)
  • 嵌套查询
var u1s []User
db.Where("user_name=?","fanone").Where("phone=?","10086").Find(&u1s)
  • 多条件
var u2 User
db.Where("user_name = ? AND phone = ?","FanOne","10086").First(&u2)
  • 模糊查询 记得加上%
var u3 User
db.Where("user_name LIKE ?","%Fan%").First(&u3)  //返回第一个user_name与Fan相近的数据
var u3s []User
db.Where("user_name LIKE ?","%Fan%").Find(&u3)   //返回多个user_name与Fan相近的数据
  • 范围查询
var u4 []User
db.Where("id > ?","FanOne","10").Find(&u2) // 找到id>10那部分的数据
  • 数组形式
var u5 []User
db.Where("user_name in (?)",[]string"Fan","One").Find(&u5)
  • 结构体形式
var u6 User
db.Where(&UserUserName:"FanOne").First(&u6)
  • map形式
var u7 User
db.Where(map[string]interface"user_name":"fan","phone":"10086").First(&u7)

8.1.3 Not条件

  • 查询UserName != FanOne的数据,返回列表
var u1 []User
db.Not(&UserUserName:"FanOne").Find(&u1)
  • 查询UserName != FanOne的数据,返回第一条数据
var u2 User
db.Not("user_name","FanOne").First(&u2)
  • 查询UserName != fan的数据,返回第一条数据
var u3 User
db.Not("user_name = ?","fan").First(&u2)
  • 查询 UserName 不在这个字符串列表当中的数据,返回第一条数据
var u4 User
db.Not("user_name",[]string"fan","one").First(&u4)
  • 查询 UserName 不在这个字符串列表当中的数据,返回列表
var u5 []User
db.Not("user_name in (?)",[]string"fan","one").Find(&u5)

8.1.4 选择查询

  • 只查询user_name这一列的数据
var u1 []User
db.Select("user_name").Find(&u1)
  • 只查询user_name和phone这两列的数据,字符串数组形式
var u1 []User
db.Select([]string"user_name","phone").Find(&u1)
  • 只查询user_name和phone这两列的数据,字符串数组形式
var u1 []User
db.Select("user_name , phone").Find(&u1)

8.1.5 排序

默认排序是升序的

var u1s,u2s []User
db.Order("name desc").Find(&u1s)  //按照名字降序
db.Order("name asc",true).Find(&u1s)  //按照名字升序

8.1.6 分页

Limit 页面大小
Offset 页数

var us []User
db.Order("id asc").Offset(5).Limit(3).Find(&us)

8.1.7 数量

var count int
db.Model(&User).Count(&count)
var count int
db.Model(&User).Where("user_name Like ?","%6%").Count(&count)
var count int
db.Table("users").Where("user_name Like ?","%6%").Count(&count)

8.1.8 原生SQL

当我们要进行比较复杂的查询的时候,可以通过这个原生sql进行查询。进行并查询操作

	query := "SELECT * FROM `work_time` WHERE `work_time`.`deleted_at` IS NULL AND month = "+ `"`+ data.Month +`"`

	if data.Search!="" 
		query += ` AND (( mask LIKE "`+"%"+data.Search +"%"+ `" ) OR ( number LIKE "`+"%"+data.Search+"%"+ `" ))`
	
	if data.DepartmentName!="" 
		query += " AND department_name LIKE " + `"`+"%" +data.DepartmentName+"%" + `"`
	
	if data.WorkType!="" 
		query += " AND work_type LIKE " + `"`+"%" +data.WorkType+"%" + `"`
	
	if data.EmployeeStatus!="" 
		query += " AND employee_status LIKE " + go开源宝藏golang爬虫|整点新花样(代码片段)

写在前面Python爬虫可能大家都玩腻了,那就玩一下Golang的爬虫吧!这篇文章会持续更新哒!思维导图想获取原图或是.xmind格式可在文末扫描并回复Go爬虫目录写在前面思维导图1.发送请求2.解析网页2.1CSS选择器2.2Xpath语... 查看详情

的思维导图目录简介(持续更新中)

博主为所有文章整理了思维导图形式的目录简介,如下图所示:右边为与学习相关的内容(考研相关/计算机相关/力扣算法整理/python系列),左边为生活相关内容(各种实用技巧/动漫相关/科技相关).并且对每个专栏做了简要的介绍,如果... 查看详情

力扣算法思维导图目前所有内容预览图(持续更新中)

本文提供了力扣算法思维导图至今为止的所有内容, 主要是为了让读者知道里面的内容.这个系列刚开始, 很多内容还没有重新整理标准重点, 之后会逐步整理导图中的所有内容, 并且也会不断地添加新的内容, 导图对应的资源... 查看详情

网络空间安全导论|基本思维导图持续更新中~

文章目录五大服务八大机制网络的安全问题网络的安全威胁数字证书  最近期末周了,一边复习一边做了点简单的导图帮助理解,也分享出来帮助大家更好地理清他们的关系  其他的基本在12.8号考试前都会补全,... 查看详情

it-游戏学习资源思维导图(持续更新,欢迎关注点赞加评论)

...了😄。品尝建议多喝点水🚰哈哈😂指导思想开源githubLinux博客分享& 查看详情

渗透测试入门到入狱(附思维导图)|寻找c站宝藏

一、渗透流程#信息收集漏洞验证/漏洞攻击提权,权限维持日志清理信息收集一般先运行端口扫描和漏洞扫描获取可以利用的漏洞。多利用搜索引擎端口扫描有授权的情况下直接使用nmap、masscan、自己写py脚本等端口扫描工具... 查看详情

go实战gin+gorm基于restfulapi的简单备忘录|含接口文档(代码片段)

...常重要的,此项目非常适合小白入门学习web开发Github开源链接接口文档TodoList接口文档密码:0000项目主要功能介绍 查看详情

开源协议思维导图

  查看详情

全文搜索知识点概要(思维导图)

...条理,为了更好的理解,我专门根据文章内容整理了一个思维导图,期望能对学习全文搜索和elasticsearch的同学提供一个指导。思维导图系列文章列表Elasticsearch系列文章汇总(持续更新...) 查看详情

go语言学习之旅--gorm(代码片段)

...个对象用主键检索检索全部对象String条件Struct&Map条件更新更新单个列更新多列更新选定字段批量更新删删除一条记录根据主键删除批量删除gorm概述ORM简介对象关系映射࿰ 查看详情

go开源宝藏go-cron定时任务(代码片段)

GO-CRON1.cron是什么1.1cron简介1.2cron详细语法2.下载3.使用1.cron是什么1.1cron简介cron:计划任务,其实就是定时任务。和系统约个时间,在几点几分几秒或者每隔一段时间跑一个任务(job),就那么简单。1.2cron详细语法结... 查看详情

操作系统思维导图|文件管理篇

计算机相关知识思维导图开源地址(源文件可修改扩展):https://github.com/FISHers6/CS-Mind适合408考研、计算机理论知识学习更新OS之文件管理:文件系统概念、文件系统实现、磁盘组织与管理文件系统基础文件系统实现磁盘组织与管理 查看详情

操作系统思维导图|文件管理篇

计算机相关知识思维导图开源地址(源文件可修改扩展):https://github.com/FISHers6/CS-Mind适合408考研、计算机理论知识学习更新OS之文件管理:文件系统概念、文件系统实现、磁盘组织与管理文件系统基础文件系统实现磁盘组织与管理 查看详情

设计模式:实际场景的落地应用(含开源项目和生产环境实践)--持续更新中

...码避免过多if-else的新姿势:策略模式、工厂+策略开源项目中应用核心J2EE设计模式Spring中用了哪些设计模式Mybatis源码解读-设计模式总结前言 单纯将设计模式,即使使用了漫画形式,也很难让人印象深刻,常常造成知道 查看详情

kafka知识点和面试题(持续更新ing)

思维导图Process思维导图地址面试题Kafka都有哪些特点?高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个topic可以分多个partition,consumergroup对partition进行consume操作。可扩展性࿱... 查看详情

信号与系统思维导图框图(更新)

信号与系统 查看详情

信号与系统思维导图框图(更新)

信号与系统 查看详情

go开源宝藏go-swagger自动生成api接口文档(代码片段)

Go-Swagger写在前面1.使用2.API注释介绍3.请求部分4.响应部分写在前面安装goget-ugithub.com/swaggo/swag/cmd/swagGo-Swagger可以用来自动生成接口文档,减少大家编写接口文档的时间。1.使用先下载驱动goget-ugithub.com/swaggo/swag/cmd/swag头部导入... 查看详情