GORM 单表 增删查改 DML

JetBrains Goland:解决同个package不同文件不能互相调用-CSDN博客

官方文档地址:GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

此时操作的表的结构为:

GORM 单表 增删查改 DML_第1张图片

注意:使用的结构体的名字与表名对应 

单表插入

单个记录插入

main包下 连接.go文件,初始化数据库连接

package main

import (
	"fmt"
	"gorm.io/gorm/logger"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB

func init() {
	username := "root"   //账号
	password := "123456" //密码
	host := "127.0.0.1"  //数据库地址,可以是Ip或者域名
	port := 3306         //数据库端口
	Dbname := "gorm"     //数据库名
	timeout := "10s"     //连接超时,10秒

	// root:root@tcp(127.0.0.1:3306)/gorm?
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local&timeout=%s", username, password, host, port, Dbname, timeout)
	//连接MYSQL, 获得DB类型实例,用于后面的数据库读写操作。
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info),
	})
	if err != nil {
		panic("连接数据库失败, error=" + err.Error())
	}
	DB = db
	// 连接成功
	fmt.Println(db)
}

//type Student struct {
//	ID    uint    `gorm:"size:10"`
//	Name  string  `gorm:"size:16"`
//	Age   int     `gorm:"size:3"`
//	Email *string `gorm:"size:128"`
//}
//
//func main() {
//	DB.AutoMigrate(&Student{})
//}

 同一main包下,新建 单表插入.go

package main

type Student struct {
	ID    uint    `gorm:"size:10"`
	Name  string  `gorm:"size:16"`
	Age   int     `gorm:"size:3"`
	Email *string `gorm:"size:128"`
}

func main() {
	//DB.AutoMigrate(&Student{})

	email := "[email protected]"
	//添加记录 结构实例化
	s1 := Student{ //id自动创建
		Name:  "wang",
		Age:   21,
		Email: &email,
	}
	err := DB.Create(&s1).Error
	if err != nil {
		println(err)
	}
}

 运行后 可见studens表插入如下 记录

有两个地方需要注意

  1. 指针类型是为了更好的存null类型,但是传值的时候,也记得传指针
  2. Create接收的是一个指针,而不是值

多条记录插入

多表通过建立切片来进行多个记录的插入

多表          

├─ 多记录插入.go  

└─ 连接.go    

多表插入.go

package main

type Student struct {
	ID    uint    `gorm:"size:10"`
	Name  string  `gorm:"size:16"`
	Age   int     `gorm:"size:3"`
	Email *string `gorm:"size:128"`
}

func main() {
	//DB.AutoMigrate(&Student{})

	email := "[email protected]"
	//添加记录 结构实例化
	s1 := Student{ //id自动创建
		Name:  "wang",
		Age:   21,
		Email: &email, //指针类型可以传null值,别的不传默认为空值
	}
	s2 := Student{ //id自动创建
		Name:  "wang2",
		Age:   22,
		Email: nil, //指针类型可以传null值,别的不传默认为空值
	}

	s := []*Student{ //通过切片形式来生成多条记录
		&s1, &s2,
	}
	//s := []Student{
	//	s1, s2,
	//}
	err := DB.Create(s).Error
	if err != nil {
		println(err)
	}
}

 studens表

单表查询 

获取单条记录

我们一般使用Take方法进行查询

// 获取第一条记录(主键升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;

// 获取一条记录,没有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;

// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;

根据主键进行检索

db.First(&user, 10)
// SELECT * FROM users WHERE id = 10;

db.First(&user, "10")
// SELECT * FROM users WHERE id = 10;

db.Find(&users, []int{1,2,3})
// SELECT * FROM users WHERE id IN (1,2,3);

 Take的第二个参数,默认根据主键查询

DB.Take(&student, 2)
fmt.Println(student)

student = Student{} // 重新赋值
DB.Take(&student, "4")
fmt.Println(student)

         根据struct进行主键查询

	//主键查询
	var student Student
	student.ID = 1
	DB.Take(&student)
	fmt.Println(student)

 其他条件查询

同样使用Take方法,根据其他条件查询,使用?作为占位符,将查询内容放入,这里为查询age=22的记录

	DB.Take(&student, "age=?", 22)

获取查询结果

	var student2 Student
	affected := DB.Take(&student2, "age=?", 22).RowsAffected//获取查询的记录数
	fmt.Println(student2, affected)

查询多条记录

查询多条记录一般使用find方法,take只能获取一条记录,这里不再适用

查询全部记录

	//查询多条记录
	var students []Student //首先创建切片
	rowsAffected := DB.Find(&students).RowsAffected
	fmt.Println(students, rowsAffected)

	for _, s := range students {
		fmt.Println(s)

		marshal, _ := json.Marshal(s) //通过序列化可以读出指针所指的内容
		fmt.Println(string(marshal))
	}

根据主键列表查询

	//根据主键查询多条记录
	DB.Find(&students, []int{1, 2})
	//DB.Take(&students, []int{1, 3}) //take只能获取单条记录

根据其他条件查询

	//根据其他条件查询多条记录,  可以与其他条件查询 单条记录进行对比
	DB.Find(&students, "age in ?", []int{21, 23}) //查询年龄为21和23岁的

model查询方法

// 获取第一个匹配的记录
db.Where("name = ?", "jinzhu").First(&user)
// SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1;

// 获取所有匹配的记录
db.Where("name = ?", "jinzhu").Find(&users)
// SELECT * FROM users WHERE name <> 'jinzhu';

// IN
db.Where("name IN ?", []string{"jinzhu", "jinzhu 2"}).Find(&users)
// SELECT * FROM users WHERE name IN ('jinzhu','jinzhu 2');

// LIKE
db.Where("name LIKE ?", "%jin%").Find(&users)
// SELECT * FROM users WHERE name LIKE '%jin%';

// AND
db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)
// SELECT * FROM users WHERE name = 'jinzhu' AND age >= 22;

// 时间
db.Where("updated_at > ?", lastWeek).Find(&users)
// SELECT * FROM users WHERE updated_at > '2000-01-01 00:00:00';

// BETWEEN
db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)
// SELECT * FROM users WHERE created_at BETWEEN '上周时间' AND '今天时间';

单表修改

Save保存所有字段.

        用于单个记录的全字段更新

        它会保存所有字段,即使零值也会保存

更新内容

	DB.Take(&stu, 3) //查询id为3的记录,将其转化为结构体实例
	//fmt.Println(stu)
	stu.Age = 18 //修改结构体内容
	stu.Name = "sb"

	DB.Save(&stu) //将结构体内容传回sql

        Save是一个组合功能。如果save value不包含主键,它将执行Create,否则将执行Update(包含所有字段)。

创建记录

	//save的create模式
	stu = Student{
		12,//原本students表中没有id为12的数据
		"wang",
		26,
		nil,
	}
	DB.Save(&stu)

INSERT INTO `students` (`name`,`age`,`email`,`id`) VALUES ('wang',26,NULL,12) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`),`age`=VALUES(`age`),`email`=VALUES(`email`)
db.Save(&User{Name: "jinzhu", Age: 100})
// INSERT INTO `users` (`name`,`age`,`birthday`,`update_at`) VALUES ("jinzhu",100,"0000-00-00 00:00:00","0000-00-00 00:00:00")

db.Save(&User{ID: 1, Name: "jinzhu", Age: 100})
// UPDATE `users` SET `name`="jinzhu",`age`=100,`birthday`="0000-00-00 00:00:00",`update_at`="0000-00-00 00:00:

更新指定字段, 跟直接save效果一致,但执行的sql语句不一致

var student Student
DB.Take(&student)
student.Age = 21
// 全字段更新
DB.Select("age").Save(&student)
// UPDATE `students` SET `age`=21 WHERE `id` = 1

批量更新 

更新单列

update方法

	//批量更新多条记录,单列
	var students []Student
	newEmail := "[email protected]"
	//这里查询如果使用其他条件可以参考前面的查询部分
	DB.Find(&students, []int{3, 4, 5}).Update("email", newEmail)
	//使用model方法进行单列的数据更新
	DB.Model(&students).Where("name=?", "sb").Update("name", "大聪明")
	//DB.Model(&Student{}).Where("name=?", "sb").Update("name", "小聪明")//这种也可以

	students = []Student{} //清空students

	//使用model方法根据主键进行单列数据更新
	DB.Model(&Student{ID: 12}).Update("age", 100)

 更新多列

updates方法,内需要用结构体

        如果是结构体,它默认不会更新零值

email := "[email protected]"
DB.Model(&Student{}).Where("age = ?", 21).Updates(Student{
  Email:  &email,
  Gender: false,  // 这个不会更新
})

// UPDATE `students` SET `email`='[email protected]' WHERE age = 21
	//使用model方法进行多列数据更新
	DB.Model(&Student{}).Where("name=?", "wang3").Updates(Student{Name: "帅哥", Age: 18})

UPDATE `students` SET `name`='帅哥',`age`=18 WHERE name='wang3'

如果要传零值,可以使用select或map,这里使用map来进行展示 

DB.Model(&Student{}).Where("age = ?", 21).Updates(map[string]any{
  "email":  &email,
  "gender": false,
})

删除记录

删除单条记录

	//根据主键删除
	DB.Delete(&Student{}, 1)           //删除主键为1的记录

	//删除id为1的记录
	DB.Delete(&Student{ID: 1})

	//删除id为5的记录
	DB.Where("id=?", 5).Delete(&Student{})

删除多条记录

	//根据主键删除
	DB.Delete(&Student{}, []int{1, 2}) //删除主键为1、2的记录

删除记录

	//使用其它条件进行删除,这里也是可以用于多条记录的删除
	email := "[email protected]"
	DB.Where("email=?", &email).Delete(&Student{})

	//使用其他条件进行删除
	DB.Where("email=?", "[email protected]").Delete(&Student{})

 更加详细的使用内容见官方文档

 官方文档地址:GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

你可能感兴趣的:(golang,数据仓库,学习)