Gin+Gorm: 86行代码:数据库自动迁移,以及一个通用分页、全部、数据量查询API

短短几十行,同时实现:

  1. 数据库自动迁移/自动建表
  2. 启动一个HTTP接口服务
  3. 从URL地址接收分页参数
  4. 完整查询
  5. 分页查询
  6. 表数据量查询

并且极易拓展新的表进行复用,后期拓展新的表查询仅仅需要加个结构体和仓库定义即可。

直接上示例

package main

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

// 定义数据库user表结构体
type User struct {
	ID       uint   `gorm:"primarykey" json:"id"`
	Username string `gorm:"type:varchar(255)" json:"username"`
}

// 泛型仓库结构
type customRepo[T any] struct {
	DB *gorm.DB
}

// 用于存储不同表的数据库操作实例的全局变量
var (
	UserRepo *customRepo[User]
)

// 初始化数据库仓库,为每个表的连接不同的数据库操作实例
func InitRepo(db *gorm.DB) {
	UserRepo = NewRepo[UserRepo](db)
}

// 创建数据库操作实例
func NewRepo[T any](db *gorm.DB) *customRepo[T] {
	return &customRepo[T]{DB: db}
}

// 实现分页查询, 计算总数并查询分页数据
func (br *customRepo[T]) FindData(page, limit int) (int64, []T, error) {
	if page < 1 || limit < 1 {
		return 0, nil, errors.New("Page和limit必须是正整数")
	}
	var count int64
	if err := br.DB.Model(new(T)).Count(&count).Error; err != nil {
		return 0, nil, err
	}
	offset := (page - 1) * limit
	var dataSlice []T
	if err := br.DB.Limit(limit).Offset(offset).Find(&dataSlice).Error; err != nil {
		return 0, nil, err
	}
	return count, dataSlice, nil
}

// Gin处理函数,从url接收两个参数分别是limit和page, 可以不传自动默认值
func GetUserData(c *gin.Context) {
	pageStr, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limitStr, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
	count, entities, err := UserRepo.FindData(pageStr, limitStr)
	if err != nil {
		c.JSON(500, gin.H{"code": 500, "message": err.Error()})
		return
	}
	c.JSON(200, gin.H{
		"data_count": count,
		"data":       entities,
	})
}

func main() {
	// 初始化数据库连接
	db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
	if err != nil {
		return fmt.Errorf("数据库初始化失败: %w", err)
	}
	// 自动迁移
	db.AutoMigrate(&User{})
	// 初始化仓库
	InitRepo(db)
	// 设置Gin默认模式
	r := gin.Default()
	// 注册路由
	r.GET("/", GetUserData)
	// 运行服务器
	r.Run(":8080")
}
暂无评论

发送评论 编辑评论


				
上一篇
下一篇