go gorm的基础使用

133 min read

创建 mysql 连接

package main

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

var DB *gorm.DB

func main() {
   // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
   dsn := "root:root@tcp(192.168.194.74:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
   db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{
      SkipDefaultTransaction: false,
      NamingStrategy: schema.NamingStrategy{
         //TablePrefix: "t_",
         SingularTable: true,
      },
      DisableForeignKeyConstraintWhenMigrating: true,
   })

   DB = db


   type User struct {
      gorm.Model
      Name string
      Age uint
   }
   //_ = db.AutoMigrate(&User{})

}

开启调试模式, Select 用于指定操作字段

tx := db.Debug().Select("Name").Create(&User{
   Name: "pan",
   Age:  10,
})
INSERT INTO `user` (`created_at`,`upd
ated_at`,`name`) VALUES ('2021-10-11 20:36:58.16','2021-10-11 20:36:58.16','pa
n')

批量插入 ,传入切片指针

tx := db.Debug().Create(&[]User{
   {
      Name: "pan",
      Age: 10,
   },
   {
      Name: "test",
      Age:  11,
   },
})
INSERT INTO `user` (`created_at`,`up
dated_at`,`deleted_at`,`name`,`age`) VALUES ('2021-10-11 20:41:48.194','2021-1
0-11 20:41:48.194',NULL,'pan',10),('2021-10-11 20:41:48.194','2021-10-11 20:41
:48.194',NULL,'test',11)

First 按主键进行排序

var u User
db.Debug().Model(&User{}).First(&u)
fmt.Println(u)
SELECT * FROM `user` WHERE `user`.`del
eted_at` IS NULL ORDER BY `user`.`id` LIMIT 1

Last 按主键进行排序

var u User
db.Debug().Model(&User{}).Last(&u)
fmt.Println(u)
SELECT * FROM `user` WHERE `user`.`del
eted_at` IS NULL ORDER BY `user`.`id` DESC LIMIT 1

Take 不按主键进行排序

var u User
db.Debug().Model(&User{}).Take(&u)
fmt.Println(u)
SELECT * FROM `user` WHERE `user`.`del
eted_at` IS NULL LIMIT 1

查询错误判断

var u User
res := db.Debug().Model(&User{}).Take(&u,19)
fmt.Println(errors.Is(res.Error,gorm.ErrRecordNotFound))

Where 条件查询

var u User
res := db.Debug().Model(&User{}).Where("id =? ",1).First(&u)


res := db.Debug().Model(&User{}).Where(map[string]interface{}{
    "id":1,
}).First(&u)

res := db.Debug().Model(&User{}).Where(map[string]interface{}{
    "id":1,
}).Or("name = ?","pan").First(&u)

// 多条 find
var u []User
res := db.Debug().Model(&User{}).Where(map[string]interface{}{
		"id":1,
}).Or("name = ?","pan").Find(&u)



创建接受结构体

type UserInfo struct {
    NameString string `gorm:"column:name"`
    Age  uint
}
var u []UserInfo

res := db.Debug().Model(&User{}).Select("name").Where(map[string]interface{}{
    "id":1,
}).Or("name = ?","pan").Find(&u)
fmt.Println(res.Error)
fmt.Println(u)

update 只更新指定字段

	db.Model(&User{}).Debug().Where("id = ?",1).Update("name","song")

updates 使用map更新 零值

db.First(&User{}).Updates(&User{
		Name:  "",
		Age:   0,
	})

	db.First(&User{}).Updates(map[string]interface{}{
		"Name":"test1",
		"Age":1,
	})

软删除 / 硬删除

db.Model(&User{}).Debug().Where("id = ?",1).Update("name","song")
db.Debug().Unscoped().Where("id = ?",1).Delete(&User{})
type Student struct {
		gorm.Model
		Name string
		TeacherID uint
		//Teacher Teacher
	}

	type Teacher struct {
		gorm.Model
		Name string
		Student Student
	}



	//db.AutoMigrate(&Teacher{},&Student{})  // 自动创建关联表?

	//t1 := Teacher{Name: "t1",Model:gorm.Model{ID: 1}}
	//s1 := Student{Name: "s1",Teacher: t1}
	//db.Create(&s1)

	s2 := Student{
		Model:     gorm.Model{},
		Name:      "s2",
		TeacherID: 2,
	}

	t2 := Teacher{
		Model:   gorm.Model{},
		Name:    "t3",
		Student: s2,
	}

	db.Debug().Create(&t2)
INSERT INTO `teacher` (`created_at`,`updated_
at`,`deleted_at`,`name`) VALUES ('2021-10-11 22:08:51.199','2021-10-11 22:08:51.199',N
ULL,'t3')

INSERT INTO `student` (`created_at`,`updated_a
t`,`deleted_at`,`name`,`teacher_id`) VALUES ('2021-10-11 22:08:51.24','2021-10-11 22:0
8:51.24',NULL,'s2',15) ON DUPLICATE KEY UPDATE `teacher_id`=VALUES(`teacher_id`)

先创建Teacher对象然后创建与之关联的Student 关联方式为 TeacherID

Preload preload associations with given conditions
   db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
type Student struct {
		gorm.Model
		Name string
		TeacherID uint

	}

	type Teacher struct {
		gorm.Model
		Name string
		Student Student
	}



var t1 Teacher
	//var s1 Student
	db.Debug().Preload("Student").First(&t1,2)
	fmt.Println(t1)

预加载条件为 关联对象的关联键 id=2

神坑

在 Gorm v2 Save(..) 将所有字段写入数据库。由于 CreatedAt 字段为零值,因此将其写入数据库。

为了让您的代码正常工作,您可以使用地图:

err := r.writeDB.Model(&Record{Model:Model{ID:1}}).Update("name","AB").Error

另一种选择是不填写 Record 结构,而只是指向表并使用 Where 子句:

err := r.writeDB.Model(&Record{}).Where("id = ?", 1).Update("name","AB").Error

如果您有多个更新,您可以将 Updates(...) 与地图一起使用,请参见此处:https://gorm.io/docs/update.html