Go实战项目之分页加载【开源十年出品】

kaiyuan10nian · 2022-10-09 20:59:42 · 2566 次点击 · 预计阅读时间 3 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2022-10-09 20:59:42 的文章,其中的信息可能已经有所发展或是发生改变。

一个深漂近10年的程序员立志用未来10年时间去维护一个项目,这个项目的功能未定,用到什么就做什么,遇到什么就写什么。其主要目的有二,一为加深自己的技术深度,二为其他学习者提供参考。

感兴趣的可以跟着我一起做这个项目,不收费、不套路、人间自有真情在。

备注:前面项目中用到的代码已经分享到GitHub中去了,并且以后所有项目中会出现的代码都会提交上去,欢迎查阅。

地址:https://github.com/kaiyuan10nian/kaiyuan10nian 感兴趣的可以点个star哦~开源十年项目的更新首发于公众号:计算机自学平台,有兴趣的小伙伴可以持续关注,并欢迎各位加我的微信(kaiyuan10nian)跟我一起完成并推动项目的发展。

Go实战项目之分页加载

这个功能是前几天就实现了的,忘记提交上去,在开始下一步之前先把这个功能简单介绍一下。

分页加载在日常开发中非常常见,如:

XXX记录明细

XXX文章列表

XXX好友列表

分页加载好处多多,我们经常会遇到在数据较多的情况下前端一次性加载会比较吃力,处理不好甚至会导致前端的OOM(前几年某知名大型blogAPP就出现过这个BUG)。总之,分页加载肯定是针对这种大量数据报表式的展示最友好的处理方式了。

其实对于后端开发人员来说实现起来也非常简单,核心思想就是:根据偏移量分多次查询数据即可

下面我们分析下对原项目的改动是如何一步一步实现的:

第一步 添加了两个字段分别是page和size

page是页码数,是我们计算偏移量的一个重要元素,之所以设置这个字段是为了方面前端分页使用;

size是每页的数据条目数,也是我们计算偏移量的重要元素,这个字段控制每页返回的数据条目数;

首先在接口中获取这两个字段:

page,_ := strconv.Atoi(ctx.DefaultQuery("page","1"))
size,_ := strconv.Atoi(ctx.DefaultQuery("size","10"))

其中设置了默认值,如果前端不给传这两个字段,我们默认为第一页且条目数为10条。

然后先去查一下一共有多少条数据:

    var total int
    c.DB.Model(&model.Article{}).Count(&total)
    if total == 0 {
        response.Fail(ctx,"文章不存在,请创建",nil)
        return
    }

查询总条目数的目的就是确定我们库中是否有足够的数据去给前端提供,这里我仅仅判断了0条目状态下的处理,你也可以在这里去添加于页码等不相符的逻辑,比如我们一共只有9条数据,你前端穿了一个page=2并且size=10的值给我,那么可以在这里判断后告诉你:请求数据不足等信息。

第二步 计算偏移量

每次去查数据库的时候,我们先看下前端用户给的是什么值,根据用户需求去查对应的数据:

offset := (page-1)*size

比如,用户传入page=1&size=5,那么这里的offset=(1-1)*5=0,偏移量就是0就意味着我们不需要在查数据库是跳过偏移量,直接从第一条开始查够5条后返回给前端即可。

if err := c.DB.Order("id DESC").Offset(offset).Limit(size).Find(&articles).Error;err != nil{
        response.Fail(ctx,"查询失败",nil)
        return
    }

上面这段代码实现了偏移量为offset,一共要size条数,并按照id排序的数据给了articles对象。

最后 返回结果给前端

response.Success(ctx,gin.H{"articles":articles, "page": page,"total": total},"请求成功")

直接把数据送回前端,over~

完整代码如下:

//文章列表
func (c ArticleController) List(ctx *gin.Context) {
    page,_ := strconv.Atoi(ctx.DefaultQuery("page","1"))
    size,_ := strconv.Atoi(ctx.DefaultQuery("size","10"))

    var total int
    c.DB.Model(&model.Article{}).Count(&total)
    if total == 0 {
        response.Fail(ctx,"文章不存在,请创建",nil)
        return
    }
    var articles []model.Article
    offset := (page-1)*size
    if err := c.DB.Order("id DESC").Offset(offset).Limit(size).Find(&articles).Error;err != nil{
        response.Fail(ctx,"查询失败",nil)
        return
    }
    //返回结果
    response.Success(ctx,gin.H{"articles":articles, "page": page,"total": total},"请求成功")
    return
}

完事!


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2566 次点击  ∙  1 赞  
加入收藏 微博
2 回复  |  直到 2022-10-13 14:51:13
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传