GORM框架增删改查

3、增删改查

3.1. 插入数据

user := User{
	Username:"zhangsan",
	Password:"123456",
	CreateTime:time.Now().Unix(),
}
db.Create(&user)

user.ID             // 返回插入数据的主键
result.Error        // 返回 error
result.RowsAffected // 返回插入记录的条数
3.1.1 用指定的字段创建:
db.Select("username","password").Create(&user)
3.1.2 忽略字段
db.Omit("username").Create(&user)
3.1.3 批量插入:
var users = []User{{Username: "jinzhu1"}, {Username: "jinzhu2"}, {Username: "jinzhu3"}}
db.Create(&users)

for _, user := range users {
  user.ID // 1,2,3
}

使用 CreateInBatches 分批创建时,你可以指定每批的数量,例如:

var users = []User{{Username: "jinzhu_1"}, ...., {Username: "jinzhu_10000"}}

// 数量为 100
db.CreateInBatches(users, 100)
3.1.4 使用map创建:
db.Model(&User{}).Create(map[string]interface{}{
  "Name": "jinzhu", "Age": 18,
})

// batch insert from `[]map[string]interface{}{}`
db.Model(&User{}).Create([]map[string]interface{}{
  {"Name": "jinzhu_1", "Age": 18},
  {"Name": "jinzhu_2", "Age": 20},
})

map创建注意,主键不会被填充。

3.1.5 sql表达式:
DB.Model(&User{}).Create(map[string]interface{}{
		"username": "jinzhu",
		"password": clause.Expr{SQL: "md5(?)", Vars: []interface{}{"123456"}},
	})
3.1.6 使用原生sql语句:
db.Exec("insert into users (username,password,createtime) values (?,?,?)", user.Username, user.Password, user.CreateTime)

3.2 更新数据

在创建一个表

CREATE TABLE `goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id',
  `title` varchar(100) NOT NULL COMMENT '商品名',
  `price` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '商品价格',
  `stock` int(11) DEFAULT '0' COMMENT '商品库存',
  `type` int(11) DEFAULT '0' COMMENT '商品类型',
  `create_time` datetime NOT NULL COMMENT '商品创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
package dao

import "time"

type Goods struct {
	Id         int
	Title      string
	Price      float64
	Stock      int
	Type       int
	CreateTime time.Time
}

func (v Goods) TableName() string {
	return "goods"
}

func SaveGoods(goods Goods) {
	DB.Create(&goods)
}
package dao

import (
	"testing"
	"time"
)

func TestSaveGoods(t *testing.T) {
	goods := Goods{
		Title:      "毛巾",
		Price:      25,
		Stock:      100,
		Type:       0,
		CreateTime: time.Now(),
	}
	SaveGoods(goods)
}
3.2.1 保存数据
goods := Goods{}
DB.Where("id = ?", 1).Take(&goods)

goods.Price = 100
//UPDATE `goods` SET `title`='毛巾',`price`=100.000000,`stock`=100,`type`=0,`create_time  `='2022-11-25 13:03:48' WHERE `id` = 1
DB.Save(&goods)
3.2.2 更新单个列

goods := Goods{}
DB.Where(“id = ?”, 2).Take(&goods)
DB.Model(&goods).Update(“title”, “hello”)

3.2.3 更新多列
  goods := Goods{}
	DB.Where("id = ?", 2).Take(&goods)
    //更新非零值的字段  也可以使用map
	DB.Model(&goods).Updates(Goods{
		Title: "hello",
		Stock: 200,
	})
3.2.4 更新选定的字段
goods := Goods{}
	DB.Where("id = ?", 2).Take(&goods)
	DB.Model(&goods).Select("title").Updates(Goods{
		Title: "hello",
		Stock: 200,
	})

排除:

goods := Goods{}
	DB.Where("id = ?", 2).Take(&goods)
	DB.Model(&goods).Omit("title").Updates(Goods{
		Title: "hello",
		Stock: 200,
	})

也可以组合使用

Select("*").Omit("title")
gorm更新必须带条件进行更新,否则会返回错误gorm.ErrMissingWhereClause,或者启用 AllowGlobalUpdate 模式

db.Session(&gorm.Session{AllowGlobalUpdate: true}).Model(&User{}).Update("name", "jinzhu")
3.2.5 表达式
db.Model(&goods).Update("stock", gorm.Expr("stock + 1"))
db.Model(&goods).Update(map[string]interface{}{"stock": gorm.Expr("stock + 1")})
3.2.6 子查询更新
  goods := Goods{}
	DB.Where("id = ?", 2).Take(&goods)
	DB.Model(&goods).Update("title", DB.Model(&User{}).Select("username").Where("id=?", 2))

3.3 删除数据

goods := Goods{}
DB.Where(“id = ?”, 2).Take(&goods)
DB.Delete(&goods)

//根据主键删除
DB.Delete(&Goods{}, 1)

同样的道理,不带条件不能进行删除,必须加一些条件,或者使用原生 SQL,或者启用 AllowGlobalUpdate 模式

db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&User{})
// DELETE FROM users

3.4 查询数据

3.4.1 查询函数
  • Take:查询一条记录
db.Take(&goods)
  • First: 根据主键正序排序后,查询第一条数据
db.First(&goods)
  • Last:根据主键倒序排序后,查询最后一条记录
db.Last(&goods)
  • Find:查询多条记录
db.Find(&goods)
  • Pluck:查询一列值
var titles []string
db.Model(&Goods{}).Pluck("title", &titles)

当 First、Last、Take 方法找不到记录时,GORM 会返回 ErrRecordNotFound 错误,可以通过对比gorm.ErrRecordNotFound进行判断,或者使用Find和Limit的组合进行查询。

db.Limit(1).Find(&user)
3.4.2 where

通过db.Where函数设置条件

函数说明: db.Where(query interface{}, args …interface{})

参数说明:
在这里插入图片描述
比如:

db.Where("id in (?)", []int{1,2,5,6}).Take(&goods)
3.4.3 select

设置select子句, 指定返回的字段

var goods Goods
DB.Select("id", "title").Find(&goods)

也可以写聚合函数

var total int
DB.Model(&Goods{}).Select("count(*) as total").Pluck("total", &total)
fmt.Println(total)

3.4.4 order

排序

var goods []Goods
	DB.Order("id desc").Find(&goods)
3.4.5 分页

通过limit和Offset实现

var goods []Goods
DB.Order("create_time desc").Limit(10).Offset(10).Find(&goods)
3.4.6 count

返回查询匹配的行数

var total int64 = 0
DB.Model(Goods{}).Count(&total)
fmt.Println(total)
3.4.7 分组
//统计每个商品分类下面有多少个商品
//定一个Result结构体类型,用来保存查询结果
type Result struct {
    Type  int
    Total int
}
var results []Result
//等价于: SELECT type, count(*) as  total FROM `goods` GROUP BY type HAVING (total > 0)
db.Model(Goods{}).Select("type, count(*) as  total").Group("type").Having("total > 0").Scan(&results)

//scan类似Find都是用于执行查询语句,然后把查询结果赋值给结构体变量,区别在于scan不会从传递进来的结构体变量提取表名.
//这里因为我们重新定义了一个结构体用于保存结果,但是这个结构体并没有绑定goods表,所以这里只能使用scan查询函数。

Group函数必须搭配Select函数一起使用

3.4.8 直接执行sql语句
sql := "SELECT type, count(*) as  total FROM `goods` where create_time > ? GROUP BY type HAVING (total > 0)"
//因为sql语句使用了一个问号(?)作为绑定参数, 所以需要传递一个绑定参数(Raw第二个参数).
//Raw函数支持绑定多个参数
db.Raw(sql, "2022-11-06 00:00:00").Scan(&results)
fmt.Println(results)
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值