gorm的Scopes,DryRun 模式,子查询案例
如果以拼接sql字符串来做的话,可能相对容易些,以前用过laravel的orm,感觉写起来叶没有那么困难,而转化为gorm时,则感觉花了比较久,也可能是因为还不熟悉的原因。
此次用到Scopes,感觉有点类似闭包,用到了子查询,以及DryRun模式,应用的gorm的技巧较多,只是完成一个功能。具体看代码。
package main
import (
"fmt"
"gorm.io/gorm"
"time"
)
var GDB *gorm.DB
type Ae struct {
Id int32 `json:"id"`
AId int32 `json:"a_id"`
BeginAt time.Time `json:"begin_at"`
EndAt time.Time `json:"end_at"`
}
type A struct {
Id int32 `json:"id"`
BeginAt time.Time `json:"begin_at"`
EndAt time.Time `json:"end_at"`
Aes []Ae `json:"aes"`
}
func main() {
GDB = getDB()
GDB.AutoMigrate(A{}, Ae{})
A1 := A{
BeginAt: time.Date(2022, 7, 11, 0, 0, 0, 0, time.Local),
EndAt: time.Date(2022, 7, 18, 0, 0, 0, 0, time.Local),
Aes: []Ae{
{
BeginAt: time.Date(2022, 7, 22, 0, 0, 0, 0, time.Local),
EndAt: time.Date(2022, 7, 23, 0, 0, 0, 0, time.Local),
},
},
}
// 创建记录
GDB.Create(&A1)
// 简单测试
fmt.Println(count("2022-07-01", "2022-07-10"))
fmt.Println(count("2022-07-17", "2022-07-19"))
fmt.Println(count("2022-07-11", "2022-07-22"))
}
/**
count 作用是找出总数,条件是a的时间范围在该查询的时间范围内(dateBegin ~ dateEnd),或者关联的ae的时间范围在该时间范围内
sql:
select count(*) from a where
(
(date(end_at) >= ? and date(begin_at) <= ?)
or exists
(select id from ae where date(end_at) >= ? and date(begin_at) <= ? and ae.a_id=a.id)
)
*/
func count(dateBegin, dateEnd string) int64 {
db := GDB.Model(&A{})
if dateBegin != "" || dateEnd != "" {
sub := GDB.Model(&Ae{}).Select("Id").Where("a_id = a.id")
if dateBegin != "" {
sub.Where("date(end_at) >= ?", dateBegin)
}
if dateEnd != "" {
sub.Where("date(begin_at) <= ?", dateEnd)
}
dryRunDB := GDB.Session(&gorm.Session{DryRun: true})
db.Where(db.Where(dryRunDB.Scopes(func(tx *gorm.DB) *gorm.DB {
if dateBegin != "" || dateEnd != "" {
if dateBegin != "" {
tx.Where("date(end_at) >= ?", dateBegin)
}
if dateEnd != "" {
tx.Where("date(begin_at) <= ?", dateEnd)
}
return tx
}
return tx
})).Or(dryRunDB.Where("exists (?)", sub)))
}
var count int64
db.Count(&count)
return count
}
分类:
gorm
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?