引言:
本次主要实现分页查询功能,因昨天写这个功能时遇到了困难,因此放到今天好好研究一下。
首先,官方文档中的orm是有对分页查询操作的。只不过要用到链式操作,因此先学习一下链式操作。
模型创建
g.Model("article")
m:=g.Model("article")
这里涉及到一个概念,叫链式安全
文档中对链式安全的定义是这样的
链式安全只是模型操作的两种方式区别:一种会修改当前model对象(不安全,默认),一种不会(安全)但是模型属性修改/条件叠加需要使用赋值操作,仅此而已。
使用gf gen dao产生的dao对象默认是链式安全的,因此这里不多赘述,想了解的可以看这里。
接下来是查询操作
数据查询
先从简单的where学起:
where+string,条件参数使用字符串和预处理
// 查询多条记录并使用Limit分页
// SELECT * FROM user WHERE uid>1 LIMIT 0,10
g.Model("user").Where("uid > ?", 1).Limit(0, 10).All()
用ScanAndCount实现
// GetList 获取实例的用户列表.
func (s sUserInfo) GetList(ctx context.Context, in model.UserInfoGetListInput) (items []entity.UserInfo, total int, err error) {
items = make([]entity.UserInfo, 0)
err = dao.UserInfo.Ctx(ctx).OmitEmpty().
Where(do.UserInfo{
ResourceId: in.ResourceId,
Status: in.Statuses,
}).
Order(in.OrderBy, in.OrderDirection).
Limit(in.Offset, in.Limit).
ScanAndCount(&items, &total, true)
return
}
然而官方文档中貌似只有这个业务逻辑实现的代码
其中的Order和Limit都是现在不需要的,所以直接删了就行,将里面的部分内容换成自己项目的数据,修改后的代码如下
func (s sArticle) GetList(ctx context.Context, in model.ArticleGetListInput) (items []entity.Article, size int, err error) {
items = make([]entity.Article, 0)
size = in.Size
err = dao.Article.Ctx(ctx).OmitEmpty().
Where("delete_time is null").
ScanAndCount(&items, &size, true)
return
}
之后修改api中对应的文件
type ArticleGetListReq struct {
g.Meta `path:"/article/get-list" tags:"Article" method:"get" summary:"获取文章列表"`
Page int `p:"page" v:"min:0#请输入正确的页数" dc:"页数"`
Size int `p:"size" v:"min:1#请输入正确的页数" dc:"页数"`
}
type ArticleGetListRes struct {
List []entity.Article `json:"list"`
Size int
Page int
}
再去修改控制层对应的文件
func (c *ControllerV1) ArticleGetList(ctx context.Context, req *v1.ArticleGetListReq) (res *v1.ArticleGetListRes, err error) {
res = &v1.ArticleGetListRes{}
res.List, res.Size, err = service.Article().GetList(ctx, model.ArticleGetListInput{
Page: req.Page,
Size: req.Size
})
return
}
在修改调试该文件的内容时,遇到了空指针的问题,百度之后加上了
res = &v1.ArticleGetListRes{}
这句
语句的作用是显式初始化res为&v1.ArticleGetListRes{}。这样即使service.Article().GetList方法失败,也不会因为尝试解引用nil指针而引发运行时错误。
最后改一下model中的结构体
type ArticleGetListInput struct {
Page int
Size int
}
运行测试一下看看
虽然好像还有点小问题,但是能跑就行,之后的学习总能解决的
这样一来crud就大致上完成了一遍