欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Gin+Gorm實(shí)現(xiàn)CRUD的實(shí)戰(zhàn)

 更新時(shí)間:2023年02月03日 08:33:44   作者:Conqueror712?lv-3  
本文主要介紹了Gin+Gorm實(shí)現(xiàn)CRUD的實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

簡介:

Q:Gin和Gorm都是干什么的?有什么區(qū)別?

A:Gin 和 Gorm 是 Go 編程語言中流行的開源庫。但是,它們服務(wù)于不同的目的,通常在 web 開發(fā)項(xiàng)目中一起使用。

Gin 是一個(gè)用于構(gòu)建 HTTP 服務(wù)器的 web 框架。它提供了一個(gè)簡單易用的 API,用于處理 HTTP 請求和響應(yīng)、路由、中間件和其他常見的 web 應(yīng)用程序所需的功能。它以其高性能和簡約為特點(diǎn),提供了輕量級和靈活的解決方案來構(gòu)建 web 服務(wù)器。

Gorm 是 Go 的一個(gè) ORM(對象關(guān)系映射)庫。它提供了一個(gè)簡單易用的 API,用于與數(shù)據(jù)庫交互、處理數(shù)據(jù)庫遷移和執(zhí)行常見的數(shù)據(jù)庫操作,如查詢、插入、更新和刪除記錄。它支持多種數(shù)據(jù)庫后端,包括 MySQL、PostgreSQL、SQLite 等。

總而言之, Gin 是用于處理 HTTP 請求和響應(yīng)、路由、中間件和其他與網(wǎng)絡(luò)相關(guān)的東西的 web 框架,而 Gorm 則是用于與數(shù)據(jù)庫交互并執(zhí)行常見數(shù)據(jù)庫操作的 ORM 庫。它們通常一起使用,來處理 HTTP 請求/響應(yīng)并在 web 開發(fā)項(xiàng)目中存儲或獲取數(shù)據(jù)。

開發(fā)環(huán)境:

  • Windows 10
  • VSCode

一、Gin

0. 快速入門:

package main

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

	"github.com/gin-gonic/gin"
	"github.com/thinkerou/favicon"
)

// 中間件(攔截器),功能:預(yù)處理,登錄授權(quán)、驗(yàn)證、分頁、耗時(shí)統(tǒng)計(jì)...
// func myHandler() gin.HandlerFunc {
// 	return func(ctx *gin.Context) {
// 		// 通過自定義中間件,設(shè)置的值,在后續(xù)處理只要調(diào)用了這個(gè)中間件的都可以拿到這里的參數(shù)
// 		ctx.Set("usersesion", "userid-1")
// 		ctx.Next()  // 放行
// 		ctx.Abort() // 阻止
// 	}
// }

func main() {
	// 創(chuàng)建一個(gè)服務(wù)
	ginServer := gin.Default()
	ginServer.Use(favicon.New("./Arctime.ico")) // 這里如果添加了東西然后再運(yùn)行沒有變化,請重啟瀏覽器,瀏覽器有緩存

	// 加載靜態(tài)頁面
	ginServer.LoadHTMLGlob("templates/*") // 一種是全局加載,一種是加載指定的文件

	// 加載資源文件
	ginServer.Static("/static", "./static")

	// 相應(yīng)一個(gè)頁面給前端

	ginServer.GET("/index", func(ctx *gin.Context) {
		ctx.HTML(http.StatusOK, "index.html", gin.H{
			"msg": "This data is come from Go background.",
		})
	})

	// 能加載靜態(tài)頁面也可以加載測試文件

	// 獲取請求中的參數(shù)

	// 傳統(tǒng)方式:usl?userid=xxx&username=conqueror712
	// Rustful方式:/user/info/1/conqueror712

	// 下面是傳統(tǒng)方式的例子
	ginServer.GET("/user/info", func(context *gin.Context) { // 這個(gè)格式是固定的
		userid := context.Query("userid")
		username := context.Query("username")
		// 拿到之后返回給前端
		context.JSON(http.StatusOK, gin.H{
			"userid":   userid,
			"username": username,
		})
	})
	// 此時(shí)執(zhí)行代碼之后,在瀏覽器中可以輸入http://localhost:8081/user/info?userid=111&username=666
	// 就可以看到返回了JSON格式的數(shù)據(jù)

	// 下面是Rustful方式的例子
	ginServer.GET("/user/info/:userid/:username", func(context *gin.Context) {
		userid := context.Param("userid")
		username := context.Param("username")
		// 還是一樣,返回給前端
		context.JSON(http.StatusOK, gin.H{
			"userid":   userid,
			"username": username,
		})
	})
	// 指定代碼后,只需要在瀏覽器中http://localhost:8081/user/info/111/555
	// 就可以看到返回了JSON數(shù)據(jù)了,非常方便簡潔

	// 序列化
	// 前端給后端傳遞JSON
	ginServer.POST("/json", func(ctx *gin.Context) {
		// request.body
		data, _ := ctx.GetRawData()
		var m map[string]interface{} // Go語言中object一般用空接口來表示,可以接收anything
		// 順帶一提,1.18以上,interface可以直接改成any
		_ = json.Unmarshal(data, &m)
		ctx.JSON(http.StatusOK, m)
	})
	// 用apipost或者postman寫一段json傳到localhost:8081/json里就可以了
	/*
		json示例:
		{
			"name": "Conqueror712",
			"age": 666,
			"address": "Mars"
		}
	*/
	// 看到后端的實(shí)時(shí)響應(yīng)里面接收到數(shù)據(jù)就可以了

	// 處理表單請求 這些都是支持函數(shù)式編程,Go語言特性,可以把函數(shù)作為參數(shù)傳進(jìn)來
	ginServer.POST("/user/add", func(ctx *gin.Context) {
		username := ctx.PostForm("username")
		password := ctx.PostForm("password")
		ctx.JSON(http.StatusOK, gin.H{
			"msg":      "ok",
			"username": username,
			"password": password,
		})
	})

	// 路由
	ginServer.GET("/test", func(ctx *gin.Context) {
		// 重定向 -> 301
		ctx.Redirect(301, "https://conqueror712.gitee.io/conqueror712.gitee.io/")
	})
	// http://localhost:8081/test

	// 404
	ginServer.NoRoute(func(ctx *gin.Context) {
		ctx.HTML(404, "404.html", nil)
	})

	// 路由組暫略

	// 服務(wù)器端口,用服務(wù)器端口來訪問地址
	ginServer.Run(":8081") // 不寫的話默認(rèn)是8080,也可以更改
}

API用法示例https://gin-gonic.com/zh-cn/docs/examples/

1. 基準(zhǔn)測試

Q:基準(zhǔn)測試是什么?

A:基準(zhǔn)測試,也稱為性能測試或壓力測試,是一種用于測量系統(tǒng)或組件性能的測試?;鶞?zhǔn)測試的目的是了解系統(tǒng)或組件在特定條件下的性能,并將結(jié)果與其他類似系統(tǒng)或組件進(jìn)行比較?;鶞?zhǔn)測試可用于評估各種類型的系統(tǒng)和組件,包括硬件、軟件、網(wǎng)絡(luò)和整個(gè)系統(tǒng)。

Q:什么時(shí)候需要基準(zhǔn)測試呀?

A:基準(zhǔn)測試通常涉及在被測系統(tǒng)或組件上運(yùn)行特定工作負(fù)載或任務(wù),并測量吞吐量、延遲時(shí)間、CPU使用率、內(nèi)存使用率等各種性能指標(biāo)?;鶞?zhǔn)測試的結(jié)果可用于識別瓶頸和性能問題,并做出有關(guān)如何優(yōu)化系統(tǒng)或組件以提高性能的明智決策。

有許多不同類型的基準(zhǔn)測試,每種類型都有自己的指標(biāo)和工作負(fù)載。常見的基準(zhǔn)測試類型包括:

  • 人工基準(zhǔn)測試:使用人工工作負(fù)載來測量系統(tǒng)或組件的性能。
  • 真實(shí)世界基準(zhǔn)測試:使用真實(shí)世界的工作負(fù)載或場景來測量系統(tǒng)或組件的性能。
  • 壓力測試:旨在將系統(tǒng)或組件推到極限,以確定在正常使用條件下可能不明顯的性能問題

重要的是要知道基準(zhǔn)測試不是一次性的活動,而是應(yīng)該定期進(jìn)行的活動,以評估系統(tǒng)的性能并檢測隨時(shí)間的消耗。

Q:什么樣的基準(zhǔn)測試結(jié)果是我們想要的呀?

A:

  • 在一定的時(shí)間內(nèi)實(shí)現(xiàn)的總調(diào)用數(shù),越高越好
  • 單次操作耗時(shí)(ns/op),越低越好
  • 堆內(nèi)存分配 (B/op), 越低越好
  • 每次操作的平均內(nèi)存分配次數(shù)(allocs/op),越低越好

2. Gin的特性與Jsoniter:

Gin v1 穩(wěn)定的特性:

  • 零分配路由。
  • 仍然是最快的 http 路由器和框架。
  • 完整的單元測試支持。
  • 實(shí)戰(zhàn)考驗(yàn)。
  • API 凍結(jié),新版本的發(fā)布不會破壞你的代碼。
  • Gin 項(xiàng)目可以輕松部署在任何云提供商上。

Gin 使用 encoding/json 作為默認(rèn)的 json 包,但是你可以在編譯中使用標(biāo)簽將其修改為 jsoniter。

$ go build -tags=jsoniter .

Jsoniter是什么?

  • json-iterator是一款快且靈活的JSON解析器,同時(shí)提供JavaGo兩個(gè)版本。
  • json-iterator是最快的JSON解析器。它最多能比普通的解析器快10倍之多
  • 獨(dú)特的iterator api能夠直接遍歷JSON ,極致性能、零內(nèi)存分配
  • 從dsljson和jsonparser借鑒了大量代碼。

下載依賴:go get github.com/json-iterator/go

二、GORM

0. 特性與安裝:

  • 全功能 ORM
  • 關(guān)聯(lián) (Has One,Has Many,Belongs To,Many To Many,多態(tài),單表繼承)
  • Create,Save,Update,Delete,F(xiàn)ind 中鉤子方法
  • 支持 Preload、Joins 的預(yù)加載
  • 事務(wù),嵌套事務(wù),Save Point,Rollback To Saved Point
  • Context、預(yù)編譯模式、DryRun 模式
  • 批量插入,F(xiàn)indInBatches,F(xiàn)ind/Create with Map,使用 SQL 表達(dá)式、Context Valuer 進(jìn)行 CRUD
  • SQL 構(gòu)建器,Upsert,數(shù)據(jù)庫鎖,Optimizer/Index/Comment Hint,命名參數(shù),子查詢
  • 復(fù)合主鍵,索引,約束
  • Auto Migration
  • 自定義 Logger
  • 靈活的可擴(kuò)展插件 API:Database Resolver(多數(shù)據(jù)庫,讀寫分離)、Prometheus…
  • 每個(gè)特性都經(jīng)過了測試的重重考驗(yàn)
  • 開發(fā)者友好
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite

其他的補(bǔ)充內(nèi)容:

  • Gorm是軟刪除,為了保證數(shù)據(jù)庫的完整性

三、Navicat

新建連接 -> MySQL -> 連接名隨便 -> 密碼隨便 -> 雙擊左側(cè)打開 -> 右鍵information_schema -> 新建數(shù)據(jù)庫 -> 名稱crud-list -> 字符集utf8mb4

這里如果打開的時(shí)候報(bào)錯(cuò)navicat 1045 - access denied for user 'root'@'localhost' (using password: 'YES'),則需要查看自己的數(shù)據(jù)庫本身的問題

四、Gin+Gorm的CRUD

連接數(shù)據(jù)庫

編寫測試代碼,成功運(yùn)行即可,但是這個(gè)時(shí)候還不能查看數(shù)據(jù)庫是否被創(chuàng)建,

如果要看我們需要定義結(jié)構(gòu)體,然后定義表遷移,具體代碼如下:

package main

import (
	"fmt"
	"time"

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

func main() {
	// 如何連接數(shù)據(jù)庫 ? MySQL + Navicat
	// 需要更改的內(nèi)容:用戶名,密碼,數(shù)據(jù)庫名稱
	dsn := "root:BqV?eGcc_1o+@tcp(127.0.0.1:3306)/crud-list?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	fmt.Println("db = ", db)
	fmt.Println("err = ", err)

	// 連接池
	sqlDB, err := db.DB()
	// SetMaxIdleConns 設(shè)置空閑連接池中連接的最大數(shù)量
	sqlDB.SetMaxIdleConns(10)
	// SetMaxOpenConns 設(shè)置打開數(shù)據(jù)庫連接的最大數(shù)量。
	sqlDB.SetMaxOpenConns(100)
	// SetConnMaxLifetime 設(shè)置了連接可復(fù)用的最大時(shí)間。
	sqlDB.SetConnMaxLifetime(10 * time.Second) // 10秒鐘

	// 結(jié)構(gòu)體
	type List struct {
		Name    string
		State   string
		Phone   string
		Email   string
		Address string
	}

	// 遷移
	db.AutoMigrate(&List{})

	// 接口
	r := gin.Default()

	// 端口號
	PORT := "3001"
	r.Run(":" + PORT)
}

定義好之后我們運(yùn)行,沒有報(bào)錯(cuò)并且在終端顯示出來3001就是正確的,這個(gè)時(shí)候我們可以去Navicat里面查看crud-list下面的"表",刷新后發(fā)現(xiàn)有一個(gè)lists產(chǎn)生,那就是對的了。

但是這個(gè)時(shí)候我們存在兩個(gè)問題:

  • 沒有主鍵:在struct里添加gorm.Model來解決,Ctrl+左鍵可以查看model
  • 表里面的名稱變成了復(fù)數(shù):詳見文檔的高級主題-GORM配置里,在*db*, *err* *:=* gorm.Open(mysql.Open(dsn), *&*gorm.Config{})里面添加一段話即可

更改完成之后我們要先在Navicat里面把原來的表lists刪掉才能重新創(chuàng)建,這個(gè)時(shí)候我們重新運(yùn)行,就會發(fā)現(xiàn)表單里面多了很多東西

結(jié)構(gòu)體定義與優(yōu)化

例如:

`gorm:"type:varchar(20); not null" json:"name" binding:"required"`

需要注意的是:

  • 結(jié)構(gòu)體里面的變量(Name)必須首字母大寫,否則創(chuàng)建不出列,會被自動忽略
  • gorm指定類型
  • json表示json接收的時(shí)候的名稱
  • binding required表示必須傳入

CRUD接口

// 測試
r.GET("/", func(c *gin.Context) {
	c.JSON(200, gin.H{
		"message": "請求成功",
	})
})

編寫完這一段之后運(yùn)行代碼,然后去postman里面新建一個(gè)GET接口127.0.0.1:3001然后send一下,出現(xiàn)請求成功就請求成功了。

增也是一樣,寫好之后直接用如下JSON來測試就可以:

{
	"name" : "張三",
    "state" : "在職",
    "phone" : "13900000000",
    "email" : "6666@qq.com",
    "address" : "二仙橋成華大道"
}

返回:

{
    "code": "200",
    "data": {
        "ID": 1,
        "CreatedAt": "2023-01-24T09:27:36.73+08:00",
        "UpdatedAt": "2023-01-24T09:27:36.73+08:00",
        "DeletedAt": null,
        "name": "張三",
        "state": "在職",
        "phone": "13900000000",
        "email": "6666@qq.com",
        "address": "二仙橋成華大道"
    },
    "msg": "添加成功"
}

這時(shí)候也可以在數(shù)據(jù)庫里看到這條數(shù)據(jù)

刪除也是一樣,編寫完運(yùn)行之后添加一個(gè)DELETE接口,然后輸入127.0.0.1:3001/user/delete/2之后send就可以看到返回了(前提是有數(shù)據(jù))

{
    "code": 200,
    "msg": "刪除成功"
}

如果是刪除了不存在的id,就會返回

{
    "code": 400,
    "msg": "id沒有找到,刪除失敗"
}

順帶一提,事實(shí)上這個(gè)代碼還可以優(yōu)化,這里的if else太多了,后面優(yōu)化的時(shí)候有錯(cuò)誤直接return

修改也是一樣,示例:

{
	"name" : "張三",
    "state" : "離職",
    "phone" : "13900000000",
    "email" : "6666@qq.com",
    "address" : "二仙橋成華大道"
}

返回:

{
    "code": 200,
    "msg": "修改成功"
}

查詢分為兩種:

  • 條件查詢
  • 分頁查詢

條件查詢的話,直接寫好了請求127.0.0.1:3001/user/list/王五

返回:

{
    "code": "200",
    "data": [
        {
            "ID": 3,
            "CreatedAt": "2023-01-24T10:06:25.305+08:00",
            "UpdatedAt": "2023-01-24T10:06:25.305+08:00",
            "DeletedAt": null,
            "name": "王五",
            "state": "在職",
            "phone": "13100000000",
            "email": "8888@qq.com",
            "address": "八仙橋成華大道"
        }
    ],
    "msg": "查詢成功"
}

全部 / 分頁查詢的話

譬如說請求是:127.0.0.1:3001/user/list?pageNum=1&pageSize=2

意思就是查詢第一頁的兩個(gè)

返回:

{
    "code": 200,
    "data": {
        "list": [
            {
                "ID": 3,
                "CreatedAt": "2023-01-24T10:06:25.305+08:00",
                "UpdatedAt": "2023-01-24T10:06:25.305+08:00",
                "DeletedAt": null,
                "name": "王五",
                "state": "在職",
                "phone": "13100000000",
                "email": "8888@qq.com",
                "address": "八仙橋成華大道"
            }
        ],
        "pageNum": 1,
        "pageSize": 2,
        "total": 2
    },
    "msg": "查詢成功"
}

如果請求是:127.0.0.1:3001/user/list

返回:

{
    "code": 200,
    "data": {
        "list": [
            {
                "ID": 1,
                "CreatedAt": "2023-01-24T09:27:36.73+08:00",
                "UpdatedAt": "2023-01-24T09:55:20.351+08:00",
                "DeletedAt": null,
                "name": "張三",
                "state": "離職",
                "phone": "13900000000",
                "email": "6666@qq.com",
                "address": "二仙橋成華大道"
            },
            {
                "ID": 3,
                "CreatedAt": "2023-01-24T10:06:25.305+08:00",
                "UpdatedAt": "2023-01-24T10:06:25.305+08:00",
                "DeletedAt": null,
                "name": "王五",
                "state": "在職",
                "phone": "13100000000",
                "email": "8888@qq.com",
                "address": "八仙橋成華大道"
            }
        ],
        "pageNum": 0,
        "pageSize": 0,
        "total": 2
    },
    "msg": "查詢成功"
}

完整代碼如下:

package main

import (
	"fmt"
	"strconv"
	"time"

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

func main() {
	// 如何連接數(shù)據(jù)庫 ? MySQL + Navicat
	// 需要更改的內(nèi)容:用戶名,密碼,數(shù)據(jù)庫名稱
	dsn := "root:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true,
		},
	})

	fmt.Println("db = ", db)
	fmt.Println("err = ", err)

	// 連接池
	sqlDB, err := db.DB()
	// SetMaxIdleConns 設(shè)置空閑連接池中連接的最大數(shù)量
	sqlDB.SetMaxIdleConns(10)
	// SetMaxOpenConns 設(shè)置打開數(shù)據(jù)庫連接的最大數(shù)量。
	sqlDB.SetMaxOpenConns(100)
	// SetConnMaxLifetime 設(shè)置了連接可復(fù)用的最大時(shí)間。
	sqlDB.SetConnMaxLifetime(10 * time.Second) // 10秒鐘

	// 結(jié)構(gòu)體
	type List struct {
		gorm.Model        // 主鍵
		Name       string `gorm:"type:varchar(20); not null" json:"name" binding:"required"`
		State      string `gorm:"type:varchar(20); not null" json:"state" binding:"required"`
		Phone      string `gorm:"type:varchar(20); not null" json:"phone" binding:"required"`
		Email      string `gorm:"type:varchar(40); not null" json:"email" binding:"required"`
		Address    string `gorm:"type:varchar(200); not null" json:"address" binding:"required"`
	}

	// 遷移
	db.AutoMigrate(&List{})

	// 接口
	r := gin.Default()

	// 測試
	// r.GET("/", func(c *gin.Context) {
	// 	c.JSON(200, gin.H{
	// 		"message": "請求成功",
	// 	})
	// })

	// 業(yè)務(wù)碼約定:正確200,錯(cuò)誤400

	// 增
	r.POST("/user/add", func(ctx *gin.Context) {
		// 定義一個(gè)變量指向結(jié)構(gòu)體
		var data List
		// 綁定方法
		err := ctx.ShouldBindJSON(&data)
		// 判斷綁定是否有錯(cuò)誤
		if err != nil {
			ctx.JSON(200, gin.H{
				"msg":  "添加失敗",
				"data": gin.H{},
				"code": "400",
			})
		} else {
			// 數(shù)據(jù)庫的操作
			db.Create(&data) // 創(chuàng)建一條數(shù)據(jù)
			ctx.JSON(200, gin.H{
				"msg":  "添加成功",
				"data": data,
				"code": "200",
			})
		}
	})

	// 刪
	// 1. 找到對應(yīng)的id對應(yīng)的條目
	// 2. 判斷id是否存在
	// 3. 從數(shù)據(jù)庫中刪除 or 返回id沒有找到

	// Restful編碼規(guī)范
	r.DELETE("/user/delete/:id", func(ctx *gin.Context) {
		var data []List
		// 接收id
		id := ctx.Param("id") // 如果有鍵值對形式的話用Query()
		// 判斷id是否存在
		db.Where("id = ? ", id).Find(&data)
		if len(data) == 0 {
			ctx.JSON(200, gin.H{
				"msg":  "id沒有找到,刪除失敗",
				"code": 400,
			})
		} else {
			// 操作數(shù)據(jù)庫刪除(刪除id所對應(yīng)的那一條)
			// db.Where("id = ? ", id).Delete(&data) <- 其實(shí)不需要這樣寫,因?yàn)椴榈降膁ata里面就是要刪除的數(shù)據(jù)
			db.Delete(&data)

			ctx.JSON(200, gin.H{
				"msg":  "刪除成功",
				"code": 200,
			})
		}

	})

	// 改
	r.PUT("/user/update/:id", func(ctx *gin.Context) {
		// 1. 找到對應(yīng)的id所對應(yīng)的條目
		// 2. 判斷id是否存在
		// 3. 修改對應(yīng)條目 or 返回id沒有找到
		var data List
		id := ctx.Param("id")
		// db.Where("id = ?", id).Find(&data) 可以這樣寫,也可以寫成下面那樣
		// 還可以再Where后面加上Count函數(shù),可以查出來這個(gè)條件對應(yīng)的條數(shù)
		db.Select("id").Where("id = ? ", id).Find(&data)
		if data.ID == 0 {
			ctx.JSON(200, gin.H{
				"msg":  "用戶id沒有找到",
				"code": 400,
			})
		} else {
			// 綁定一下
			err := ctx.ShouldBindJSON(&data)
			if err != nil {
				ctx.JSON(200, gin.H{
					"msg":  "修改失敗",
					"code": 400,
				})
			} else {
				// db修改數(shù)據(jù)庫內(nèi)容
				db.Where("id = ?", id).Updates(&data)
				ctx.JSON(200, gin.H{
					"msg":  "修改成功",
					"code": 200,
				})
			}
		}
	})

	// 查
	// 第一種:條件查詢,
	r.GET("/user/list/:name", func(ctx *gin.Context) {
		// 獲取路徑參數(shù)
		name := ctx.Param("name")
		var dataList []List
		// 查詢數(shù)據(jù)庫
		db.Where("name = ? ", name).Find(&dataList)
		// 判斷是否查詢到數(shù)據(jù)
		if len(dataList) == 0 {
			ctx.JSON(200, gin.H{
				"msg":  "沒有查詢到數(shù)據(jù)",
				"code": "400",
				"data": gin.H{},
			})
		} else {
			ctx.JSON(200, gin.H{
				"msg":  "查詢成功",
				"code": "200",
				"data": dataList,
			})
		}
	})

	// 第二種:全部查詢 / 分頁查詢
	r.GET("/user/list", func(ctx *gin.Context) {
		var dataList []List
		// 查詢?nèi)繑?shù)據(jù) or 查詢分頁數(shù)據(jù)
		pageSize, _ := strconv.Atoi(ctx.Query("pageSize"))
		pageNum, _ := strconv.Atoi(ctx.Query("pageNum"))

		// 判斷是否需要分頁
		if pageSize == 0 {
			pageSize = -1
		}
		if pageNum == 0 {
			pageNum = -1
		}

		offsetVal := (pageNum - 1) * pageSize // 固定寫法 記住就行
		if pageNum == -1 && pageSize == -1 {
			offsetVal = -1
		}

		// 返回一個(gè)總數(shù)
		var total int64

		// 查詢數(shù)據(jù)庫
		db.Model(dataList).Count(&total).Limit(pageSize).Offset(offsetVal).Find(&dataList)

		if len(dataList) == 0 {
			ctx.JSON(200, gin.H{
				"msg":  "沒有查詢到數(shù)據(jù)",
				"code": 400,
				"data": gin.H{},
			})
		} else {
			ctx.JSON(200, gin.H{
				"msg":  "查詢成功",
				"code": 200,
				"data": gin.H{
					"list":     dataList,
					"total":    total,
					"pageNum":  pageNum,
					"pageSize": pageSize,
				},
			})
		}

	})

	// 端口號
	PORT := "3001"
	r.Run(":" + PORT)
}

到此這篇關(guān)于Gin+Gorm實(shí)戰(zhàn)CRUD的文章就介紹到這了,更多相關(guān)Gin Gorm CRUD內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • GoLang讀取文件的10種方法實(shí)例

    GoLang讀取文件的10種方法實(shí)例

    讀取文件是所有編程語言中最常見的操作之一,下面這篇文章主要給大家介紹了關(guān)于GoLang讀取文件的10種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • golang time包做時(shí)間轉(zhuǎn)換操作

    golang time包做時(shí)間轉(zhuǎn)換操作

    這篇文章主要介紹了golang time包做時(shí)間轉(zhuǎn)換操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 使用golang腳本基于kubeadm創(chuàng)建新的token(問題分析)

    使用golang腳本基于kubeadm創(chuàng)建新的token(問題分析)

    這篇文章主要介紹了使用golang腳本基于kubeadm創(chuàng)建新的token(問題分析),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-10-10
  • 一文解析 Golang sync.Once 用法及原理

    一文解析 Golang sync.Once 用法及原理

    這篇文章主要介紹了一文解析 Golang sync.Once 用法及原理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • 詳解Golang如何實(shí)現(xiàn)支持隨機(jī)刪除元素的堆

    詳解Golang如何實(shí)現(xiàn)支持隨機(jī)刪除元素的堆

    堆是一種非常常用的數(shù)據(jù)結(jié)構(gòu),它能夠支持在O(1)的時(shí)間復(fù)雜度獲取到最大值(或最小值)。本文主要介紹了如何實(shí)現(xiàn)支持O(log(n))隨機(jī)刪除元素的堆,需要的可以參考一下
    2022-09-09
  • Go中的新增對模糊測試的支持

    Go中的新增對模糊測試的支持

    這篇文章主要為大家介紹了Go中的新增對模糊測試的支持,文中還包含了一些功能實(shí)驗(yàn)性測試分析有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-03-03
  • Go的gin參數(shù)校驗(yàn)中的validator庫詳解

    Go的gin參數(shù)校驗(yàn)中的validator庫詳解

    這篇文章主要介紹了Go的gin參數(shù)校驗(yàn)之validator庫,使用 validator 以后,只需要在定義結(jié)構(gòu)體時(shí)使用 binding 或 validate tag標(biāo)識相關(guān)校驗(yàn)規(guī)則,就可以進(jìn)行參數(shù)校驗(yàn)了,而不用自己單獨(dú)去寫常見的校驗(yàn)規(guī)則,需要的朋友可以參考下
    2023-08-08
  • Go?為什么不支持可重入鎖原理解析

    Go?為什么不支持可重入鎖原理解析

    這篇文章主要為大家介紹了Go?為什么不支持可重入鎖原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • golang 切片的三種使用方式及區(qū)別的說明

    golang 切片的三種使用方式及區(qū)別的說明

    這篇文章主要介紹了golang 切片的三種使用方式及區(qū)別的說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 淺談Golang的GC垃圾回收機(jī)制

    淺談Golang的GC垃圾回收機(jī)制

    本文介紹了Go語言的垃圾回收機(jī)制,通過使用對象池、減少短生命周期對象的創(chuàng)建和優(yōu)化內(nèi)存布局等方法,可以有效地減少GC壓力,提高程序的性能,感興趣的可以了解一下
    2024-11-11

最新評論