フロントエンドでは、データのリクエストが多すぎる場合、データのページネーション表示を検討することができます。pageSize
(ページごとに表示するデータの数)とpageNumber
(ページ番号)の 2 つのパラメータを使用して制御することができます。
フロントエンドでのデータのリクエストパラメータ#
Ajax リクエストを送信する際に、psize
とpnum
の 2 つのパラメータを渡します。psize
は 10 で、1 ページあたり 10 件のデータを返すことを期待しています。pnum
は 1 で、1 ページ目のデータを返すことを期待しています。
http://localhost:8848/api/datalist?psize=10&pnum=1
バックエンドでのパラメータの取得と処理#
以下の HandleFunc#
リクエストの URL からpsize
とpnum
の値を読み取ります。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
}
}
完全なバックエンドのコード(デモ)#
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("サーバーは 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)
}
}
テスト#
デモのダウンロード:https://yzbtdiy.lanzoul.com/iICXi0pung7c
初回実行時には、現在のディレクトリにdata.db
という名前の SQLite データベースが生成されます。
その後、user_data
テーブルが作成され、100 件のテストデータが挿入されます。
8848 ポートをリッスンし、データを取得するために/api/datalist
にアクセスできます。psize
とpnum
の 2 つのパラメータを渡す必要があります。
ブラウザでテストするか、コマンドラインでテストすることができます。
~ $ 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"}]