Go/GORM中如何使用between条件查询int64类型字段
GORM 针对int64类型字段实现Between范围查询方案
你的created_at字段用bigint存时间戳,做between查询不需要额外类型转换,GORM支持直接拼接条件,具体实现步骤如下:
1. 先调整查询参数结构体
你原来的Project结构体只有单值CreatedAt字段,无法接收前端传的起止时间/时间数组,需要单独定义列表查询的请求参数结构,兼容两种前端传参格式:
import "strconv" // 项目列表查询请求参数 type ProjectListReq struct { Page int `json:"page"` PageSize int `json:"page_size"` Email string `json:"email"` CreatedAtSt int64 `json:"create_at_st"` // 起始时间戳 对应第一种传参格式 CreatedAtEnd int64 `json:"create_at_end"` // 结束时间戳 对应第一种传参格式 CreatedAtRange []string `json:"create_at"` // 时间范围数组 对应第二种传参格式 }
2. Between条件的两种GORM写法
两种写法最终生成的SQL执行效果完全一致,选你觉得好维护的用就行:
- 直接写原生Between语法,和你预期的SQL完全匹配:
db = db.Where("created_at BETWEEN ? AND ?", 起始时间戳, 结束时间戳)
- 用大于等于+小于等于条件拼接,逻辑和Between等价:
db = db.Where("created_at >= ?", 起始时间戳).Where("created_at <= ?", 结束时间戳)
3. 完整改造后的查询方法
你原来的代码存在几个问题:未定义db/List/total变量、Count查询带了分页参数会导致总数统计错误、原有created_at <> ?是不等于逻辑和范围查询无关需要删除,改造后代码如下:
func (p *Project) ProjectList(req ProjectListReq) ([]Project, int64, error) { var list []Project var total int64 // 初始化DB实例 替换成你项目里的gorm DB对象 db := gorm.Model(&Project{}) // 拼接邮箱模糊查询条件 if req.Email != "" { db = db.Where("email LIKE ?", "%"+req.Email+"%") } // 拼接时间范围条件 优先处理起止时间参数 if req.CreatedAtSt != 0 && req.CreatedAtEnd != 0 && req.CreatedAtEnd > req.CreatedAtSt { db = db.Where("created_at BETWEEN ? AND ?", req.CreatedAtSt, req.CreatedAtEnd) } else if len(req.CreatedAtRange) == 2 { // 兼容数组格式传参 先把字符串时间戳转成int64 st, errSt := strconv.ParseInt(req.CreatedAtRange[0], 10, 64) ed, errEd := strconv.ParseInt(req.CreatedAtRange[1], 10, 64) if errSt == nil && errEd == nil && ed > st { db = db.Where("created_at BETWEEN ? AND ?", st, ed) } } // 先查总数 克隆DB对象避免分页参数影响count结果 countTx := db.Session(&gorm.Session{}) if err := countTx.Count(&total).Error; err != nil { return nil, 0, err } // 拼接分页、排序参数查列表 err := db.Offset((req.Page - 1) * req.PageSize). Limit(req.PageSize). Order("id DESC"). Find(&list).Error return list, total, err }
注意事项
- 时间参数要做合法性校验:结束时间必须大于起始时间,避免生成无效条件查不到数据
- Count查询必须在拼接分页参数之前执行,或者克隆新的DB对象执行,否则
Offset/Limit会被带到count SQL里导致总数统计错误 - 因为字段本身是int64类型,直接传int64值给GORM即可,不需要做时间格式转换,不会出现类型不匹配问题
内容的提问来源于stack exchange,提问作者Elsa
相关产品推荐
相关产品推荐

