Go项目实战之开发完善分页插件(易扩展方式)-------【goshop开源项目】【第12次更新】

qiaoshuai951123 · 2022-04-26 13:46:12 · 2561 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2022-04-26 13:46:12 的主题,其中的信息可能已经有所发展或是发生改变。

goshop开源项目的更新

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

地址 goshop 感兴趣的可以点个star哦~ goshop开源项目的更新

今天在考虑怎么实现数据分页和检索功能:

  1. 通过传入页数(page),分页条数(pageSize) ,实现数据的limit 分页功能
  2. 动态支持检索条件和排序的功能

接下来咱们就来实现以上功能

  1. 首先需要先封装一个 Paginate 的扩展用于对gorm操作时引用Offset和Limit的sql拼合。实现代码过程如下:
package Paginate

import (
    "github.com/jinzhu/gorm"
    "strconv"
)

// 这里需要注意的是:page和pageSize 的数据类型需要指定
// 这里根据我之前封装的:获取全部请求参数的一个map指定的返回类型后,决定使用string类型进行定义
func Paginate(page, pageSize string) func(db *gorm.DB) *gorm.DB {
    return func(db *gorm.DB) *gorm.DB {
        pageUp, _ := strconv.Atoi(page)
        if pageUp == 0 {
            pageUp = 1
        }
        pageSizeInt, _ := strconv.Atoi(pageSize)
        switch {
        case pageSizeInt <= 0:
            pageSizeInt = 10
        }
        offset := (pageUp - 1) * pageSizeInt
        return db.Offset(offset).Limit(pageSizeInt)
    }
}
  1. 封装好后,接下来就是使用了,在代码中,分页类我使用在:model文件中。相应代码如下:
// 根据检索条件,获取记录行,并获取总记录条数
func (Goods) FindAll(DB *gorm.DB, params map[string]interface{}) ([]Goods, int64) {
    var GoodResult []Goods
    page := params["page"].(string)         // 对返回的interface类型进行转换成字符串
    pageSize := params["pageSize"].(string) // 对返回的interface类型进行转换成字符串
    // 这里使用了过滤,在下面使用Where条件时过滤掉page,pageSize
    ParamsFilter := utils.ParamsFilter(params, "page,pageSize")
    // 通过 Scopes 引用加载 分页类中返回的 DB指针
    DB.Scopes(Paginate.Paginate(page, pageSize)).Where(ParamsFilter).Order("created_at desc").Find(&GoodResult)
    // 这里时查询全部数据,用于返回总记录条数
    GoodCount := DB.Find(&Goods{})
    return GoodResult, GoodCount.RowsAffected
}

// 这是过滤的封装,一起贴出来了
func ParamsFilter(params map[string]interface{}, isFilterStr string) map[string]interface{} {
    var data = make(map[string]interface{})
    for key, value := range params {
        if find := strings.Contains(isFilterStr, key); !find {
            data[key] = value
        }
    }
    return data
}
  1. 接下来就是在控制器(controller)中使用封装好的FindAll 获取数据了。 代码如下:
// 获取商品列表信息
func GetGoodsList(ctx *gin.Context) {
    // 获取DB句柄
    DB := config.InitDB()
    // 使用获取全部请求参数方法进行:获取参数
    params, _ := utils.DataMapByRequest(ctx)
    // 查询数据
    var goods model.Goods
    // 使用封装好的FindAll
    GoodResult, count := goods.FindAll(DB, params)
    // struct 转 map  (反射 reflect包)
    //data := make(map[string]interface{})
    //elem := reflect.ValueOf(&goods).Elem()
    //var relType reflect.Type
    //for i := 0; i < relType.NumField(); i++ {
    //    data[relType.Field(i).Name] = elem.Field(i).Interface()
    //}
    // 返回值
    utils.Success(ctx, "获取成功", gin.H{
        "count": count,
        "data":  GoodResult,
    })
}
  1. 最后一步就是:配置路由。 话不多说,直接上代码:
func Routers(r *gin.Engine) {
    app := r.Group("/app")
    {
        // v1
        v1 := app.Group("/v1")
        {
            // ........ 更多
            // 管理平台
            adminGroup := v1.Group("/admin", middleware.CheckToken())
            {
                // ........ 更多
                // 商品
                goodsGroup := adminGroup.Group("/goods")
                {
                    goodsGroup.POST("/get-list", controller.GetGoodsList)
                    // ........ 更多
                }
                // ........ 更多
            }

        }
    }
}

走到这里就完成了一个分页的检索查询。

更多功能请持续关注!!!!!

欢迎各位加我的微信(jobhandsome)跟我一起完成并推动项目的发展!

加入我们.png


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

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

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