GORM_note

这篇博客介绍了GORM在Go语言中进行MySQL数据库操作的基础使用,包括创建与查询、更新与删除的基本操作,以及Model模型的定义。博主分享了在使用过程中遇到的问题和解决方法,特别是关于模型定义的部分,提到了GORM中模型通常是结构体、基本Go类型或其指针,并展示了内置Model的结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


学习资料:https://gorm.io/zh_CN/docs/ 中文文档
hexo链接:https://woaixiaoyuyu.github.io/2020/03/20/GORM-note/#more

创建与查询的基本操作

基本的范畴我自己定的233,有一些地方为了避免多次运行注释掉了,我自己是看得懂的,如果你迷茫了,对不起,我只记录一些自己看文档的时候踩得坑

package main

import (
	"fmt"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
)

// UserInfo create对应用户表的结构体
type UserInfo struct {
	ID     int // 一定要大写字母开头,不然无法创建处这个字段
	Age    int
	Name   *string `gorm:"default:'galeone'"` //给一个默认值,但可以传入空串
	Gender string
}

func main() {
	// 打开mysql中名为go_test的数据库
	db, err := gorm.Open("mysql", "root:xiaoyuyu@/go_test?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()
	// create table
	db.AutoMigrate(&UserInfo{})
	// create data
	str := new(string)
	*str = "xiaoyuyu"
	u1 := UserInfo{1, 18, str, "male"}
	//u2 := UserInfo{Age: 22, Name: new(string), Gender: "male"}
	//u3 := UserInfo{Age: 25, Gender: "female"}
	//fmt.Println(u3.Name)
	db.Create(&u1)
	// ok := db.NewRecord(u2) // 检查创建的当前字段的PRI key 是否存在
	// if !ok {
	// 	fmt.Println("PRI key has been used")
	// } else {
	// 	db.Create(&u2)
	// }
	// //fmt.Println(ok)
	// ok = db.NewRecord(u3)
	// if !ok {
	// 	fmt.Println("PRI key has been used")
	// } else {
	// 	db.Create(&u3)
	// }
	//fmt.Println(ok)

	// 查询
	user := UserInfo{}
	// 根据主键查询第一条记录,查询出来的保存到对象user中
	db.First(&user)
	//// SELECT * FROM users ORDER BY id LIMIT 1;
	fmt.Println(user.ID, *user.Name, user.Age, user.Gender)

	// 如果不重新定义一个空结构体,之前的查询条件会累加到现存的查询上
	user = UserInfo{}
	// 随机获取一条记录
	db.Take(&user)
	//// SELECT * FROM users LIMIT 1;
	fmt.Println(user.ID, *user.Name, user.Age, user.Gender)

	user = UserInfo{}
	// 根据主键查询最后一条记录
	db.Last(&user)
	//// SELECT * FROM users ORDER BY id DESC LIMIT 1;
	fmt.Println(user.ID, *user.Name, user.Age, user.Gender)

	user2 := []UserInfo{}
	// 查询所有的记录
	db.Find(&user2)
	//// SELECT * FROM users;
	for _, value := range user2 {
		fmt.Println(value.ID, *value.Name, value.Age, value.Gender)
	}

	user = UserInfo{}
	// 查询指定的某条记录(仅当主键为整型时可用)
	db.First(&user, 3)
	//// SELECT * FROM users WHERE id = 1;
	fmt.Println(user.ID, *user.Name, user.Age, user.Gender)

	//Where 查询

	user = UserInfo{}
	// Struct,map也行但是作用我觉得和struct差不多
	*str = "xiaoyuyu"
	db.Where(&UserInfo{Name: str, Age: 18}).First(&user)
	//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1;
	fmt.Println(user.ID, *user.Name, user.Age, user.Gender)

	// 主键的切片
	user2 = []UserInfo{}
	db.Where([]int64{1, 3}).Find(&user2)
	//// SELECT * FROM users WHERE id IN (20, 21, 22);
	for _, value := range user2 {
		fmt.Println(value.ID, *value.Name, value.Age, value.Gender)
	}

	// AND
	user = UserInfo{}
	db.Where("name = ? AND age >= ?", "xiaoyuyu", "10").Find(&user)
	//// SELECT * FROM users WHERE name = 'jinzhu' AND age >= 22;
	fmt.Println(user.ID, *user.Name, user.Age, user.Gender)
}

更新与删除的基本操作

package main

import (
	"fmt"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
)

// UserInfo create对应用户表的结构体
type UserInfo struct {
	ID     int // 一定要大写字母开头,不然无法创建处这个字段
	Age    int
	Name   *string `gorm:"default:'galeone'"` //给一个默认值,但可以传入空串
	Gender string
}

func main() {
	// 打开mysql中名为go_test的数据库
	db, err := gorm.Open("mysql", "root:xiaoyuyu@/go_test?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()

	// create table 要是表已经存在,不会新创建,二十直接调用
	db.AutoMigrate(&UserInfo{})
	str := new(string)
	*str = "dawa"
	user := UserInfo{ID: 7, Age: 30, Name: str, Gender: "unknown"}
	db.Create(&user)

	// Save 更新,Save会更新所有字段,即使你没有赋值
	user = UserInfo{}
	db.First(&user, 7)
	user.Gender = "male"
	db.Save(&user)

	// 更新单个属性,如果它有变化
	db.Model(&user).Update("Name", "zhuzhu")

	// 用struct或者map更新多个值,只会更新其中有变化且为非零值的字段
	*str = "xiaokeai"
	db.Model(&user).Updates(UserInfo{Name: str, Age: 50})

	// 批量更新
	db.Table("user_infos").Where("name IN (?)", []string{"", "galeone"}).Updates(map[string]interface{}{"name": "xxx", "age": 18})
	//// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11);

	// 使用 `RowsAffected` 获取更新记录总数
	num := db.Table("user_infos").Where("name IN (?)", []string{"luck"}).Updates(map[string]interface{}{"name": "lucky", "age": 23}).RowsAffected
	fmt.Println(num)

	// 删除
	db.Where("name = ?", "lucky").Delete(UserInfo{})
}

Model 模型的定义

在GORM中模型(Models)通常是正常定义的结构体、基本的go类型或它们的指针

先看一下本身自带的Model

package gorm

import "time"

// Model base model definition, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embedded in your models
//    type User struct {
//      gorm.Model
//    }
type Model struct {
	ID        uint `gorm:"primary_key"`
	CreatedAt time.Time
	UpdatedAt time.Time
	DeletedAt *time.Time `sql:"index"`
}

其实就是个ID,和时间的内嵌,挺好用的

package main

import (
	"database/sql"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
)

// User struct
type User struct {
	gorm.Model
	Name         string
	Age          sql.NullInt64
	Birthday     *time.Time
	Email        string  `gorm:"type:varchar(100);unique_index"`
	Role         string  `gorm:"size:255;column:job"` // 设置字段大小为255,修改列名
	MemberNumber *string `gorm:"unique;not null"`     // 设置会员号(member number)唯一并且不为空
	Num          int     `gorm:"AUTO_INCREMENT"`      // 设置 num 为自增类型
	Address      string  `gorm:"index:addr"`          // 给address字段创建名为addr的索引
	IgnoreMe     int     `gorm:"-"`                   // 忽略本字段
}

func main() {
	// 打开mysql中名为go_test的数据库
	db, err := gorm.Open("mysql", "root:xiaoyuyu@/go_test?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()

	// 自己用花里胡哨的办法生成一个杂七杂八的Model
	// 这次不用AutoMigrate,我的表名我做主
	db.Table("workers").CreateTable(&User{})
}

基础的用得上的,基本就这些了吧,以后遇到了再记录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值