golang 项目 gorm 列表 条件过滤查询 和 分页

2 篇文章 0 订阅
文章介绍了如何使用GORMORM在Go语言中编写通用的分页查询和条件过滤方法,包括基于`scopes`的分页函数`Paginate`、排序函数`Order`、字符串过滤`StringFilter`以及数组过滤`ArrayFilter`,允许进行`LIKE`、`IN`、`NOTIN`等操作,方便在项目中对数据库查询进行抽象和复用。
摘要由CSDN通过智能技术生成

         在我们编写的项目的时候,列表总是有各种条件进行查询,不过一般都是and 查询,这里编写了一个稍微通用些的方法利用scopes,返回列表查询数据;

        创建orm文件:这里目录结构我这边设计是存在名叫ormModels 文件夹中,新建base.go文件

package ormModels

import (
	"github.com/spf13/cast"
	"gorm.io/gorm"

	"reflect"
)
// 这里是分页也相关 传入参数 page和 size, 以及对应 默认分页配置 s eg:map[string]interface{}{"page" : 1, "size" : 20}, 如果传入为 map[string]interface{}{},默认设定 page 1, size 20
func Paginate(pageParam interface{}, sizeParam interface{}, s map[string]interface{}) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		page := cast.ToInt(pageParam)
		size := cast.ToInt(sizeParam)

		if page == 0 {
			if s["page"] != nil {
				page = s["page"].(int)
			} else {
				page = 1
			}
		}

		if size == 0 {
			if s["size"] != nil {
				size = s["size"].(int)
			} else {
				size = 20
			}
		}
		offset := (page - 1) * size
		return db.Offset(offset).Limit(size)
	}
}

func Order(sort string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		returnDb := db
		if len(sort) == 0 {
			sort = "id desc"
		}
		return returnDb.Order(sort)
	}
}

//进行快速条件过滤
func StringFilter(key string, value string, operator string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		returnDb := db
		if value != "" {
			switch operator {
			case "like":
				returnDb = returnDb.Where(key+" Like ? ", "%"+value+"%")
			case "=", ">=", ">", "<=", "<":
				returnDb = returnDb.Where(key+" "+operator+" "+"?", value)
			}

		}
		return returnDb
	}
}
// 进行wehre in 或者 where not in
func ArrayFilter(key string, value interface{}, operator string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		returnDb := db
		if reflect.ValueOf(value).Len() != 0 {
			whereMap := map[string]interface{}{
				key: value,
			}
			switch operator {
			case "in":
				returnDb = returnDb.Where(whereMap)
			case "not in":
				returnDb = returnDb.Not(whereMap)
			}
		}
		return returnDb
	}
}

之后创建的所有模型都可以进行使用分页 和 where 查询 使用方法:

builder.Scopes(ormModels.Paginate(params.Page, params.Size, map[string]interface{}{})).
		Find(&list)
	builder := ormModels.GetDb().Model(&ormModels.Test{}).
		Scopes(ormModels.StringFilter("state", params.State, "=")).
		Scopes(ormModels.StringFilter("tax_no", params.TaxNo, "like"))
	builder := ormModels.GetDb().Model(&ormModels.Test{}).
		Scopes(ormModels.ArrayFilter("serial_no", params.SerialNos, "in")).

以下是使用Golanggorm库进行递归查询单表的示例代码: ```go package main import ( "fmt" "gorm.io/driver/mysql" "gorm.io/gorm" ) type Category struct { ID uint Name string ParentID uint Children []Category `gorm:"foreignKey:ParentID"` } func main() { // 连接MySQL数据库 dsn := "user:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic(err) } // 自动迁移模式,创建categories表 db.AutoMigrate(&Category{}) // 创建分类数据 db.Create(&Category{Name: "电子产品"}) db.Create(&Category{Name: "手机", ParentID: 1}) db.Create(&Category{Name: "电脑", ParentID: 1}) db.Create(&Category{Name: "笔记本电脑", ParentID: 3}) db.Create(&Category{Name: "台式电脑", ParentID: 3}) db.Create(&Category{Name: "家具"}) db.Create(&Category{Name: "沙发", ParentID: 7}) db.Create(&Category{Name: "床", ParentID: 7}) // 递归查询分类数据 var categories []Category db.Preload("Children").Where("parent_id = ?", 0).Find(&categories) printCategories(categories, 0) } func printCategories(categories []Category, level int) { for _, category := range categories { fmt.Printf("%s%d. %s\n", getIndent(level), category.ID, category.Name) printCategories(category.Children, level+1) } } func getIndent(level int) string { var indent string for i := 0; i < level; i++ { indent += " " } return indent } ``` 上述代码中,我们定义了一个Category结构体,其中包含ID、Name、ParentID和Children四个字段。其中,ParentID表示当前分类的父分类ID,Children表示当前分类的子分类列表。在查询时,我们使用Preload方法预加载Children字段,以便在查询结果中包含子分类数据。然后,我们使用Where方法指定ParentID为0,即查询所有顶级分类数据。最后,我们使用printCategories函数递归打印分类数据,其中getIndent函数用于生成缩进字符串,以便在输出时区分不同层级的分类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值