日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

go语言mysql框架_超级详细:Go语言框架Gin和Gorm实现一个完整的待办事项微服务...

發布時間:2024/8/23 数据库 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 go语言mysql框架_超级详细:Go语言框架Gin和Gorm实现一个完整的待办事项微服务... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

本文通過一步一步的設計,最終實現一個完善的todo應用。

我們使用GO框架Gin用戶路由控制和返回數據。使用Gorm用于操作數據庫。

讀者可根據本教程操作,最終實現列出的各項功能。

技術清單

本文中所涉及的技術內容主要有以下幾種:Gin:輕量高效性能爆棚的WEB框架

Gorm:一個關系型數據庫的ORM工具包,避免直接SQL語句操作

MySQL:數據庫

curl工具,用于API接口數據測試

另外,使用的GO版本是go version go1.13.5 windows/amd64

對于第2,3條內容,可使用以下指令安裝

對于工具curl,我們使用的是 git bash內自帶的指令。如果是linux下用戶,開箱即用。

創建數據庫

本文使用MySQL數據庫裝載數據。本節我們僅需創建一個空的數據庫,就可以了。表結構在下一節使用gorm遷移功能創建。

使用Navicat工具新建界面如下圖。

需要特別留意數據庫字符集編碼使用 utf8mb4,這個是MySQL真正的utf8,用于中文字符支持。

創建表模型

gorm中的Automigrate()操作,用于刷新數據庫中的表,使其保持最新。即讓數據庫之前存儲的記錄的表字段和程序中最新使用的表字段保持一致(只增不減)。

我們先建一個todos表模型。

type (

todoModel struct {

gorm.Model

Title string `json:"title"`

Completed int `json:"completed`

}

fmtTodo struct {

ID uint `json:"id"`

Title string `json:"title"`

Completed bool `json:"completed"`

}

)

其中 todoModel用于數據庫todos表。我們默認繼承使用了gorm.Model的字段,主要包括以下幾個:

// gorm.Model 定義

type Model struct {

ID uint `gorm:"primary_key"`

CreatedAt time.Time

UpdatedAt time.Time

DeletedAt *time.Time

}

數據庫表會自動生成上述4個字段,并追加 title,completed兩個字段。模型名與表名不一致,我們手動指定表名:

// 指定表名

func (todoModel) TableName() string {

return "todos"

}

然后在代碼初始化過程中執行遷移。

var db *gorm.DB

// 初始化

func init() {

var err error

var constr string

constr = fmt.Sprintf("%s:%s@(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", "root", "111213", "localhost", 3306, "05-gin-gorm-todo")

db, err = gorm.Open("mysql", constr)

if err != nil {

panic("數據庫連接失敗")

}

db.AutoMigrate(&todoModel{})

}

首先聲明一個 gorm.DB,用于數據庫操作。

在使用gorm包之前,需要導入。

import (

"github.com/jinzhu/gorm"

_ "github.com/jinzhu/gorm/dialects/mysql"

)

第二項我們僅導入而不使用。這個導入操作,gorm執行了下述操作

import _ "github.com/go-sql-driver/mysql"

這樣我們無需重新手動處理包依賴關系。

MySQL的連接字符串是有特定格式的,這也是由底層 go-sql-driver/mysql 決定的參數配置項。其含義如下:

user:password@(hostname:port)/database_name?charset=utf8mb4&parseTime=True&loc=Local

此處我們使用的本地數據庫3306端口,root用戶,和 05-gin-gorm-todo 數據庫。

在執行完整的程序之后,todos表會被自動遷移創建,其詳細參數如下圖。

這張表也是我們本文所操作的數據基礎。

規劃路由

依照restful風格的API設計標準,我們規劃了5個路由,涵蓋了一個todo列表清單的增刪改查功能。

func main() {

r := gin.Default()

v1 := r.Group("/api/v1/todo")

{

v1.POST("/", add) // 添加新條目

v1.GET("/", all) // 查詢所有條目

v1.GET("/:id", take) // 獲取單個條目

v1.PUT("/:id", update) // 更新單個條目

v1.DELETE("/:id", del) // 刪除單個條目

}

r.Run(":9089")

}

這個是最終會使用到的main函數,使用了gin提供的路由功能。為了擴展方便,我們使用了gin路由的Group功能,將版本v1的所有路由集中處理。

其中,訪問的方法跟別使用 POST表示添加,GET表示查詢,PUT表是更新,DELETE表示刪除,這是restful API設計的一般性方法。

API功能

上一節規劃的路由中,我們聲明了5個函數,本節逐一實現這5個函數。注意API返回數據都是JSON格式。

為了統一返回狀態碼,對于正確響應的,返回HTTP CODE = 200。JSON數據的正常與否,使用兩個常量表示,如下:

const (

JSON_SUCCESS int = 1

JSON_ERROR int = 0

)

成功返回1,失敗返回0。

1 - 添加條目 add

主要的功能,是拿到POST表單提交的數據,并寫入數據庫,成功則返回信息通知,失敗則給出相應提示。

// 創建TODO條目func add(c *gin.Context) {

completed, _ := strconv.Atoi(c.PostForm("completed"))

todo := todoModel{Title: c.PostForm("title"), Completed: completed}

db.Save(&todo)

c.JSON(http.StatusOK, gin.H{

"status": JSON_SUCCESS,

"message": "創建成功",

"resourceId": todo.ID,

})

}

注意我們對于POST提供的字段 completed 進行了轉換,因為表單數據默認都是字符串類型,而todoModel內Completed是int類型,所以需要進行轉換。

2 - 獲取所有條目

不接受任何參數,默認給出所有的條目內容。

// 獲取所有條目func all(c *gin.Context) {

var todos []todoModel

var _todos []fmtTodo

db.Find(&todos)

// 沒有數據if len(todos) <= 0 {

c.JSON(http.StatusOK, gin.H{

"status": JSON_ERROR,

"message": "沒有數據",

})

return

}

// 格式化for _, item := range todos {

completed := false

if item.Completed == 1 {

completed = true

} else {

completed = false

}

_todos = append(_todos, fmtTodo{

ID: item.ID,

Title: item.Title,

Completed: completed,

})

}

c.JSON(http.StatusOK, gin.H{

"status": JSON_SUCCESS,

"message": "ok",

"data": _todos,

})

}

為了API返回數據的便于使用,我們使用了一個結構體 fmtTodo 用于將結構體 todoModel 的數據進行格式化。如果沒有查詢到任何數據,返回狀態碼 status = 0。

3 - 獲取單個條目

在路由中附加的id,可以調用此路由,用于返回單條數據。

// 根據id獲取一個條目func take(c *gin.Context) {

var todo todoModel

todoID := c.Param("id")

db.First(&todo, todoID)

if todo.ID == 0 {

c.JSON(http.StatusNotFound, gin.H{

"status": JSON_ERROR,

"message": "條目不存在",

})

return

}

completed := false

if todo.Completed == 1 {

completed = true

} else {

completed = false

}

_todo := fmtTodo{

ID: todo.ID,

Title: todo.Title,

Completed: completed,

}

c.JSON(http.StatusOK, gin.H{

"status": JSON_SUCCESS,

"message": "ok",

"data": _todo,

})

}

根據ID查詢數據,如果存在就返回,并使用fmtTodo進行格式化;如果不存在,狀態碼等于0。

4 - 更新單個條目

已經存在的數據,根據ID對其內容進行修改。如果ID不存在,返回錯誤信息。

// 更新一個條目func update(c *gin.Context) {

var todo todoModel

todoID := c.Param("id")

db.First(&todo, todoID)

if todo.ID == 0 {

c.JSON(http.StatusNotFound, gin.H{

"status": JSON_ERROR,

"message": "條目不存在",

})

return

}

db.Model(&todo).Update("title", c.PostForm("title"))

completed, _ := strconv.Atoi(c.PostForm("completed"))

db.Model(&todo).Update("completed", completed)

c.JSON(http.StatusOK, gin.H{

"status": JSON_SUCCESS,

"message": "更新成功",

})

}

5 - 刪除單個條目

根據ID查詢是否存在,如果存在就進行刪除。

// 刪除條目func del(c *gin.Context) {

var todo todoModel

todoID := c.Param("id")

db.First(&todo, todoID)

if todo.ID == 0 {

c.JSON(http.StatusOK, gin.H{

"status": JSON_ERROR,

"message": "條目不存在",

})

return

}

db.Delete(&todo)

c.JSON(http.StatusOK, gin.H{

"status": JSON_SUCCESS,

"message": "刪除成功!",

})

}

以上就是5個方法的具體實現,只能用作demo,而不能用于生產。因為表單數據的有效性檢測,我們在代碼中并沒有實現。這在線上是絕對不允許的。

還有一些數據的鑒權,用戶身份權限鑒定,本示例中都沒有。

使用curl測試

完成以上步驟,該todo清單功能基本完善,我們使用

go build main.go

進行編譯,如果不出錯,編譯通過后,會生成 main.exe 文件。我們在命令行直接運行該文件,結果如下圖。

下面我們對五個url分別進行測試。

首先是獲取所有的條目,

curl -s -X GET http://localhost:9089/api/v1/todo/

這會命中第二條路由規則,返回值如下:

{"message":"沒有數據","status":0}

暫時沒有數據。接著添加一個條目:

curl -s -X POST -d "title=Talk is cheap, show me the code." -d "completed=0" http://localhost:9089/api/v1/todo/

執行成功返回數據

{"message":"創建成功","resourceId":8,"status":1}

接著我們再查詢所有的條目,看看能否找到。返回結果如下:

{"data":[{"id":8,"title":"Talk is cheap, show me the code.","completed":false}],"message":"ok","status":1}

為了演示方便,我們再隨機寫入幾條數據,然后測試單條數據查詢,修改,和刪除。

curl -s -X POST -d "title=Life is short, I use python." -d "completed=0" http://localhost:9089/api/v1/todo/

curl -s -X POST -d "title=Zen of Golang." -d "completed=0" http://localhost:9089/api/v1/todo/

curl -s -X POST -d "title=Do not repeat yourself." -d "completed=0" http://localhost:9089/api/v1/todo/

然后獲取所有的條目

curl -s -X GET http://localhost:9089/api/v1/todo/

結果JSON數組格式化輸出如下:

測試獲取單條數據,這里使用id=10這一條,執行如下指令

curl -s -X GET http://localhost:9089/api/v1/todo/10

返回結果如下:

{"data":{"id":10,"title":"Zen of Golang.","completed":false},"message":"ok","status":1}

測試修改該條數據,設置completed=1,為已完成狀態。

curl -s -X PUT -d "title=Zen of Golang." -d "completed=1" http://localhost:9089/api/v1/todo/10

執行成功返回:

{"message":"更新成功!","status":1}

注意更新操作使用的method = PUT。會命中第4條路由規則。

下面刪除id=10的條目,使用以下指令:

curl -s -X DELETE http://localhost:9089/api/v1/todo/10

執行成功后返回結果:

{"message":"刪除成功!","status":1}

OK,上面所有的路由都已經測試完畢,看服務器端的訪問歷史,大致如下圖:

注意到有一條是數據庫連接的自動釋放,這是由MySQL設置的連接超時時間決定的,超期閑置則釋放。如果有新的連接請求,重新建立。這可以節約資源。

關鍵點總結

在測試上述功能的時候,列出一些初學者可能會犯的錯。

1 - 數據庫連接失敗

一定要確保連接字符串書寫正確,賬號密碼書寫正確,數據庫IP地址和端口號正確,還有數據庫名稱對應。如果始終不能連接成長,可以嘗試單獨拿出來數據庫連接進行測試,直到通過。

2 - 路由地址

根據設定的路由規則,正確地書寫路由地址,還有傳送參數方法,這樣才能在程序中獲取到提交的數據。

比如使用POST,傳送的表單數據使用 c.PostForm 可以獲取到。而 c.Param 則用于獲取路由中 “/:id” id 這個位置參數。

3 - curl測試工具使用

注意使用請求方式 -X 參數,還有POST中使用的 -d 參數選項。

結語

以上內容使用兩個成熟的包,快速地創建了一個待辦清單的微服務。可以看到Go語言生態日臻完善,優秀的框架頻出,給開發帶來了很高的效率。

另外,GO語言的易于書寫特性,接近與腳本語言的表達力,還有嚴格的數據類型檢測,將不少低級的錯誤排除在編譯階段。

Happy coding :-)

【本文由 @程序員小助手 發布,持續分享編程與程序員成長相關的內容,歡迎關注】

總結

以上是生活随笔為你收集整理的go语言mysql框架_超级详细:Go语言框架Gin和Gorm实现一个完整的待办事项微服务...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。