gorm的使用(持续更新)

gorm的使用

1. 地址

官网

功能

截屏2022-11-05 下午8.28.39

2. 下载方式

go get -u gorm.io/gorm // gorm框架
go get -u github.com/go-sql-driver/mysql  // mysql驱动

3. 连接数据库

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
	"net/url"
	"time"
)

var DB *gorm.DB

func InitDatabase() *gorm.DB {
  // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name
	args := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=true&loc=%s",
		"root", //数据库的账号
		"123456", // 数据库的密码
		"localhost", // 数据的IP地址
		"3306", // 数据的端口
		"test", // 使用的数据库
		"utf8", // 编码格式
		url.QueryEscape(""))
	fmt.Println("args", args)
	db, err := gorm.Open("mysql", args)
	if err != nil {
		panic("failed to connect database, err: " + err.Error())
	}

	DB = db
	return db
}

func main() {
	InitDatabase()
}

4. 开始建立模型类

模型是标准的 struct,由 Go 的基本数据类型、实现了 ScannerValuer 接口的自定义类型及其指针或别名组成(从官网抄的)

4.1 字段类型

type User struct {
  ID           uint
  Name         string
  Email        *string
  Age          uint8
  Birthday     *time.Time
  MemberNumber sql.NullString
  ActivatedAt  sql.NullTime
  CreatedAt    time.Time
  UpdatedAt    time.Time
}

// 转成的sql语句
/* CREATE TABLE `users` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `age` tinyint unsigned DEFAULT NULL,
  `birthday` datetime DEFAULT NULL,
  `member_number` varchar(255) DEFAULT NULL,
  `activated_at` datetime DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
*/

4.2 字段的约束

4.2.1 说明

标签名说明
columndb的列名
type列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not nullsize, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INCREMENT
serializer指定将数据序列化或反序列化到数据库中的序列化器, 例如: serializer:json/gob/unixtime
primaryKey将列定义为主键
unique将列定义为唯一键
default定义列的默认值
precision指定列的精度
scale指定列大小
not null指定列为 not null
autoincrement指定列为自增长
autoIncrementIncrement自动步长,控制连续记录之间的间隔
embedded嵌套字段
embeddedPrefix嵌入字段的列名前缀 (发现没有效果
autoCreateTime创建时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoCreateTime:nano
autoUpdateTime创建/更新时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoUpdateTime:milli
index根据参数创建索引,多个字段使用相同的名称则创建复合索引,查看 索引 获取详情
uniqueIndexindex 相同,但创建的是唯一索引
check检查约束的类型,列入check:age>13,
<-设置字段写入的权限, <-:create 只创建、<-:update 只更新、<-:false 无写入权限、<- 创建和更新权限
->设置字段读的权限,->:false 无读权限
-忽略该字段,- 表示无读写,-:migration 表示无迁移权限,-:all 表示无读写迁移权限
comment迁移时为字段添加注释

4.2.2 具体实例

type User struct {
	ID           uint       `gorm:"primaryKey;comment:'id'"`
	Name         string     `gorm:"unique; comment:'用户的名字'; column:name"`
	Email        *string    `gorm:"varchar(200);"`
	Age          uint8      `gorm:"default:18"`
	Birthday     *time.Time `gorm:"not null;"`
	MemberNumber sql.NullString
	ActivatedAt  sql.NullTime
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

/*
生成的表
CREATE TABLE `users` (
  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(255) DEFAULT NULL COMMENT '用户的名字',
  `email` varchar(255) DEFAULT NULL,
  `age` tinyint unsigned DEFAULT '18',
  `birthday` datetime DEFAULT NULL,
  `member_number` varchar(255) DEFAULT NULL,
  `activated_at` datetime DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 
*/
type Base struct {
	Id         uint       `gorm:"primaryKey; comment:'id'; uniqueIndex; autoIncrement; autoIncrementIncrement:3; column:id"`
	CreateTime *time.Time `gorm:"autoCreateTime; comment:'创建时间'"`
	UpdateTime *time.Time `gorm:"autoUpdateTime; comment:'更新时间'"`
	Test       string
}
type Card struct {
	Base Base `gorm:"embedded;embeddedPrefix:'card_'"`
	Uid  uint `gorm:"not null; comment:'用户id'; check:uid>0; column:user_id"`
}

/*
embeddedPrefix 好像没有效果

 CREATE TABLE `cards` (
  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `test` varchar(255) DEFAULT NULL,
  `user_id` int unsigned NOT NULL COMMENT '用户id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3     
*/

5. 建立外键

5.1 一对一

5.1.1 创建结构体

type User struct {
	ID           uint       `gorm:"primaryKey;comment:'id'"`
	Name         string     `gorm:"unique; comment:'用户的名字'; column:name"`
	Email        *string    `gorm:"varchar(200);"`
	Age          uint8      `gorm:"default:18"`
	Birthday     *time.Time `gorm:"not null;"`
	MemberNumber sql.NullString
	ActivatedAt  sql.NullTime
	CreatedAt    time.Time
	UpdatedAt    time.Time
	CardId       Card
	Card Card
}

type Base struct {
	Id         uint       `gorm:"primaryKey; comment:'id'; uniqueIndex; autoIncrement; autoIncrementIncrement:3; column:id"`
	CreateTime *time.Time `gorm:"autoCreateTime; comment:'创建时间'"`
	UpdateTime *time.Time `gorm:"autoUpdateTime; comment:'更新时间'"`
	Test       string
}

type Card struct {
	Base Base `gorm:"embedded;embeddedPrefix:'card_'ti"`
	Uid  uint `gorm:"not null; comment:'用户id'; check:uid>0; column:user_id"`
}

5.1.2 保存数据

func inUser(db *gorm.DB) {
	/*
		@desc: 插入数据到user表里面
		@auth: alex
		@data: 11/6/22
		@params db *gorm.DB
	*/
	email := "alexxu@qq.com"
	layoutISO := "2006-01-02"
	date := "2000-08-24"
	birthDay, _ := time.Parse(layoutISO, date)
	user := User{
		Name:     "alex",
		Email:    &email,
		Age:      3,
		Birthday: &birthDay,
		MemberNumber: struct {
			String string
			Valid  bool
		}{String: "13096575416", Valid: true},
		ActivatedAt: struct {
			Time  time.Time
			Valid bool
		}{Time: time.Now(), Valid: true},
		Card: Card{Base: Base{Test: "hello world"}},
	}
	db.Debug().Omit("Card").Create(&user)
	db.Save(&user)

	user1 := User{
		Name:     "alex1",
		Email:    &email,
		Age:      3,
		Birthday: &birthDay,
		MemberNumber: struct {
			String string
			Valid  bool
		}{String: "13096575416", Valid: true},
		ActivatedAt: struct {
			Time  time.Time
			Valid bool
		}{Time: time.Now(), Valid: true},
		Card: Card{Base: Base{Test: "hello world"}},
	}
	db.Debug().Omit("Card").Create(&user1)
	db.Save(&user1)
}

截屏2022-11-06 下午9.52.39

5.1.3 查询数据

5.1.3.1 正向查询
func FindUser(db *gorm.DB) {
	/*
		@desc: /*
		@auth: alex
		@data: 11/6/22
		@params db gorm.DB
	*/
	var user User
	var card Card
	db.Model(&user).Where(map[string]interface{}{"ID": 1}).First(&user).Association("Card").Find(&card)
	fmt.Println("card", card.Base.Test)
}

截屏2022-11-06 下午10.10.54

5.1.3.2 反向查询
func FindUser(db *gorm.DB) {
	/*
		@desc: /*
		@auth: alex
		@data: 11/6/22
		@params db gorm.DB
	*/
	var user User
	var card Card
	db.Model(&card).Where(map[string]interface{}{"Id": 1}).Preloads("Card").Find(&user)
	fmt.Println("user", user)
}

Screenshot2022-11-07 PM9.42.36

5.2一对多

5.2.1 创建结构体
type User struct {
	ID           uint       `gorm:"primaryKey;comment:'id'"`
	Name         string     `gorm:"unique; comment:'用户的名字'; column:name"`
	Email        *string    `gorm:"varchar(200);"`
	Age          uint8      `gorm:"default:18"`
	Birthday     *time.Time `gorm:"not null;"`
	MemberNumber sql.NullString
	ActivatedAt  sql.NullTime
	CreatedAt    time.Time
	UpdatedAt    time.Time
	CardId       uint
	Card         Card
	ClassId      uint   `gorm:"comment:'班级id';"`
}

type Card struct {
	Base Base `gorm:"embedded;embeddedPrefix:'card_'"`
}

type Class struct {
	Base        // 班级
	User []User `gorm:"foreignKey:ClassId;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` // 将数据存在CLassId里面
}
5.2.2 保存数据
func inUser(db *gorm.DB) {
	/*
		@desc: /*
		@auth: alex
		@data: 11/8/22
		@params db *gorm.DB
	*/
	email := "alexxu@qq.com"
	layoutISO := "2006-01-02"
	date := "2000-08-24"
	birthDay, _ := time.Parse(layoutISO, date)

	class := Class{
		User: []User{User{
			Name:     "alex",
			Email:    &email,
			Age:      3,
			Birthday: &birthDay,
			MemberNumber: struct {
				String string
				Valid  bool
			}{String: "13096575416", Valid: true},
			ActivatedAt: struct {
				Time  time.Time
				Valid bool
			}{Time: time.Now(), Valid: true},
			Card: Card{Base: Base{Test: "hello world"}},
		}},
	}
	db.Debug().Create(&class)
}

Screenshot2022-11-10 PM7.50.26

5.2.3查询数据
5.2.3.1正向查询
func findUser(db *gorm.DB) {
	user := []User{}
	class := Class{}
	a := db.Where(map[string]interface{}{
		"Id": 1,
	}).Find(&class).Association("User").Find(&user)
	fmt.Println("a", a)
	fmt.Println("class", len(user))
}

Screenshot2022-11-10 PM8.15.08

5.2.3.2 反向查询

func findUser(db *gorm.DB) {
	// 反向查询
	user := User{}
	class := Class{}
	db.Model(&class).Where(map[string]interface{}{
		"Id": 1,
	}).Preloads("User").Find(&user)
	fmt.Println("user", user.ID)
}

Screenshot2022-11-10 PM8.16.38

5.3 多对多

5.3.1 创建结构体
type User struct {
	ID           uint       `gorm:"primaryKey;comment:'id'"`
	Name         string     `gorm:"unique; comment:'用户的名字'; column:name"`
	Email        *string    `gorm:"varchar(200);"`
	Age          uint8      `gorm:"default:18"`
	Birthday     *time.Time `gorm:"not null;"`
	MemberNumber sql.NullString
	ActivatedAt  sql.NullTime
	CreatedAt    time.Time
	UpdatedAt    time.Time
	CardId       uint
	Card         Card
	ClassId      uint    `gorm:"comment:'班级id';"`
	Happy        []Happy `gorm:"many2many:user_happy"` // 为了插入数据的时候方便
}

type Happy struct {
	// 兴趣
	Base
	Name string `gorm:"comment:'兴趣'; not null; unique;"`
	User []User `gorm:"many2many:user_happy"` //user_happy是表名
}

Screenshot2022-11-10 PM8.44.39

5.3.2 保存数据
5.3.2.1在happy里面插入数据
func inHappy(db *gorm.DB) {
	happySlice := make([]Happy, 0)
	happySlice = append(happySlice, Happy{Name: "唱歌"})
	happySlice = append(happySlice, Happy{Name: "旅游"})
	happySlice = append(happySlice, Happy{Name: "跳舞"})
	for index := 0; index < len(happySlice); index++ {
		db.Save(&happySlice[index])
	}
}

Screenshot2022-11-10 PM8.52.55

5.3.2.2将user和happy绑定在一起
func inUser(db *gorm.DB) {
	// 开始插入数据
	user := User{}                 // 用户
	happySlice := make([]Happy, 0) // 用户的兴趣
	db.Where(map[string]interface{}{
		"id": 1,
	}).Find(&user)

	db.Where([]uint{1, 2}).Find(&happySlice)
  // 不知道为什么,只更新Happy的话是不会更新的,所以我加了一个Name字段
	db.Debug().Model(&user).Updates(User{Happy: happySlice, Name: user.Name})

}

5.4 查询数据

func findUser(db *gorm.DB) {
	user := User{}
	happySlice := make([]Happy, 0)
	// 直接在后面用associationd,只有where条件在happy表也会存在
	db.Model(&user).Where(map[string]interface{}{
		"Id": 1,
	}).Find(&user)

	db.Model(&user).Association("Happy").Find(&happySlice)
	for index := 0; index < len(happySlice); index++ {
		fmt.Println("happy", happySlice[index].Name)

	}
}

Screenshot2022-11-10 PM9.46.05


结束了,谢谢大家可以看到现在。如果有哪里写的不好,大家可以指出来,然后我再去修改,希望大家可以提出宝贵的意见

这里是我的微信,如果有需要的话,大家可以扫码添加我好友

191668088110_.pic

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值