yzbtdiy

yzbtdiy

github
bilibili

Golang後端數據分頁

前端對於請求數據條數過多時,可以考慮數據分頁顯示,可以通過兩個參數pageSize(每頁顯示的條數)和pageNumber(頁數)來進行控制。

前端請求數據傳參#

發送 ajax 請求時傳遞 psizepnum 兩個參數,psize 為 10 期望每頁返回 10 條數據,pnum 為 1 期望返回第一頁的數據。

http://localhost:8848/api/datalist?psize=10&pnum=1

後端獲取參數處理#

HandleFunc 如下#

從請求的 url 中讀取 psizepnum 的值,由於從 url 中獲取的值為字符串類型,所以要先轉化為整數類型,然後傳遞給數據庫處理。

func DataListApi(w http.ResponseWriter, r *http.Request) {
	params := r.URL.Query()
	pageSize, _ := strconv.Atoi(params.Get("psize"))
	pageNum, _ := strconv.Atoi(params.Get("pnum"))
	dataList := GetDataFromDbByPages(pageSize, pageNum)
	if dataList != nil {
		jsonData, _ := json.Marshal(dataList)
		_, err := w.Write(jsonData)
		if err != nil {
			log.Println(err)
		}
	}
}

Gorm 查詢操作如下#

從數據庫中查詢指定條件數據,查詢成功返回一個構造體數組,沒有查詢到數據返回 nil。

偏移量為 (pnum-1)*psize 的值,限制返回條數為 psize

func GetDataFromDbByPages(psize, pnum int) (dataList *[]UserDataModel) {
	result := db.Offset((pnum - 1) * psize).Limit(psize).Find(&dataList)
	if result.RowsAffected == 0 {
		log.Println("獲取數據失敗")
		return nil
	} else {
		return dataList
	}
}

完整後端代碼 (demo)#

package main

import (
	"encoding/json"
	"log"
	"net/http"
	"strconv"

	"github.com/glebarez/sqlite"
	"gorm.io/gorm"
)

// 監聽本地8848端口,處理來自 /api/datalist 的請求
func main() {
	server := http.Server{
		Addr: "127.0.0.1:8848",
	}
	http.HandleFunc("/api/datalist", DataListApi)
	log.Println("Server is running on http://127.0.0.1:8848")
	if err := server.ListenAndServe(); err != nil {
		log.Println(err)
	}
}

// 處理 /api/datalist 請求,請求需要攜帶psize和pnum參數
func DataListApi(w http.ResponseWriter, r *http.Request) {
	params := r.URL.Query()
	pageSize, _ := strconv.Atoi(params.Get("psize"))
	pageNum, _ := strconv.Atoi(params.Get("pnum"))
	dataList := GetDataFromDbByPages(pageSize, pageNum)
	if dataList != nil {
		jsonData, _ := json.Marshal(dataList)
		_, err := w.Write(jsonData)
		if err != nil {
			log.Println(err)
		}
	}
}

// 數據庫存儲數據的構造體
type UserDataModel struct {
	Id   int    `gorm:"column:id;type:INTEGER NOT NULL;primaryKey;autoIncrement;"`
	Name string `gorm:"column:name;type:TEXT NOT NULL UNIQUE;"`
	Desc string `gorm:"column:desc;type:TEXT NOT NULL;"`
}

// 自定義表名
func (UserDataModel) TableName() string {
	return "user_data"
}

var db *gorm.DB

// 在 main 函數執行前用 init 初始化 sqlite 數據庫
func init() {
	var err error
	db, err = gorm.Open(sqlite.Open("./data.db"), &gorm.Config{})
	if err != nil {
		log.Fatal(err)
	}

	sqlDB, _ := db.DB()
	sqlDB.SetMaxOpenConns(1)

	tableInit(&UserDataModel{})
}

// 檢查表是否存在,不存在則創建
func tableInit(table interface{}) {
	if db.Migrator().HasTable(table) {
		return
	} else {
		db.Migrator().CreateTable(table)
		genTestData()
	}
}

// 從數據庫根據 psize 和 pnum 讀取數據
func GetDataFromDbByPages(psize, pnum int) (dataList *[]UserDataModel) {
	result := db.Offset((pnum - 1) * psize).Limit(psize).Find(&dataList)
	if result.RowsAffected == 0 {
		log.Println("獲取數據失敗")
		return nil
	} else {
		return dataList
	}
}

// 生成測試數據 100 條
func genTestData() {
	for i := 1; i <= 100; i++ {
		testData := UserDataModel{
			Id:   i,
			Name: "user" + strconv.Itoa(i),
			Desc: "Hello, I'm user" + strconv.Itoa(i),
		}
		db.Create(&testData)
	}
}

測試#

demo 下載: https://yzbtdiy.lanzoul.com/iICXi0pung7c

初次運行會在當前目生成 sqlite 數據庫,文件名為 data.db

然後創建 user_data 表,插入 100 條測試數據,

監聽 8848 端口,可以訪問 /api/datalist 獲取數據,需要傳遞 psizepnum 兩個參數。

可以通過瀏覽器訪問測試,也可以用命令行測試。

~ $ curl "http://127.0.0.1:8848/api/datalist?psize=10&pnum=1"
[{"Id":1,"Name":"user1","Desc":"Hello, I'm user1"},{"Id":2,"Name":"user2","Desc":"Hello, I'm user2"},{"Id":3,"Name":"user3","Desc":"Hello, I'm user3"},{"Id":4,"Name":"user4","Desc":"Hello, I'm user4"},{"Id":5,"Name":"user5","Desc":"Hello, I'm user5"},{"Id":6,"Name":"user6","Desc":"Hello, I'm user6"},{"Id":7,"Name":"user7","Desc":"Hello, I'm user7"},{"Id":8,"Name":"user8","Desc":"Hello, I'm user8"},{"Id":9,"Name":"user9","Desc":"Hello, I'm user9"},{"Id":10,"Name":"user10","Desc":"Hello, I'm user10"}]

~ $ curl "http://127.0.0.1:8848/api/datalist?psize=5&pnum=3"
[{"Id":11,"Name":"user11","Desc":"Hello, I'm user11"},{"Id":12,"Name":"user12","Desc":"Hello, I'm user12"},{"Id":13,"Name":"user13","Desc":"Hello, I'm user13"},{"Id":14,"Name":"user14","Desc":"Hello, I'm user14"},{"Id":15,"Name":"user15","Desc":"Hello, I'm user15"}]
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。