Go项目实战—开发完善分页插件

591 阅读2分钟

goshop开源项目的更新

备注:前面项目中用到的代码已经分享到GitHub中去了,并且以后所有项目中会出现的代码都会提交上去,欢迎查阅。感兴趣的可以点个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