学习资料: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{})
}
注
基础的用得上的,基本就这些了吧,以后遇到了再记录