Go项目实战—开发完善分页插件(易扩展方式)【goshop开源项目 | 20220424更新】

goshop开源项目的更新

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

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

今天在考虑怎么实现数据分页和检索功能:
  1. 通过传入页数(page),分页条数(pageSize) ,实现数据的 limit 分页功能
  2. 动态支持检索条件和排序的功能
接下来咱们就来实现以上功能
  1. 首先需要先封装一个 Paginate 的扩展用于对gorm操作时引用OffsetLimit的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)跟我一起完成并推动项目的发展!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码一行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值