基於gin框架搭建的一個簡單的web服務


剛把go編程基礎知識學習完了,學習的時間很短,可能還有的沒有完全吸收。不過還是在項目中發現知識,然后在去回顧已學的知識,現在利用gin這個web框架做一個簡單的CRUD操作。

1.Go Web框架的技術選型

Top 6 web frameworks for Go as of 2017,可以看看這個go語言中Web框架的對比和老大的推薦,我選擇gin框架作為學習go語言的框架。

image.png

2.Gin介紹

gin框架的中文文檔,這個文檔相當好,清晰明了解釋gin框架的整個用法。下面是gin框架的全部特性:

image.png

3.建立一個web服務實現Hello Word

首先需要安裝ginweb框架和gorm作為ORM層,然后利用go-sql數據庫驅動,前提是要配置Gopath環境變量,使用go get安裝即可:gin安裝地址

//使用github上的gin托管地址 $ go get -u github.com/gin-gonic/gin $ go get -u github.com/jinzhu/gorm $ go get github.com/go-sql-driver/mysql 

使用Gin實現Hello world非常簡單,創建一個router(路由),然后執行Run方法即可:

package main import ( "github.com/gin-gonic/gin" "net/http" ) func main() { router:=gin.Default() router.GET("/", func(c *gin.Context) { c.String(http.StatusOK,"Hello World") }) router.Run(":8080") } 

結果如下:

image.png

image.png

是不是比Java方便多了!下面來仔細分析下上面的代碼結構:

  • 1、router:=gin.Default():這是默認的服務器。使用gin的Default方法創建一個路由Handler
  • 2、然后通過Http方法綁定路由規則和路由函數。不同於net/http庫的路由函數,gin進行了封裝,把request和response都封裝到了gin.Context的上下文環境中。
  • 3、最后啟動路由的Run方法監聽端口。還可以用http.ListenAndServe(":8080", router),或者自定義Http服務器配置。

4.基於database/sql的CURD操作

1.建立數據庫表

image.png

2.CURD操作,以查詢為例

參考人世間

package main import ( "database/sql" _ "github.com/go-sql-driver/mysql" "log" "net/http" "github.com/gin-gonic/gin" ) //利用的是原生的SQL的ORM層 var db *sql.DB //定義person類型結構 type Person struct { Id int `json:"id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` } //定義一個getALL函數用於回去全部的信息 func (p Person) getAll() (persons []Person,err error) { rows,err:=db.Query("SELECT id, first_name, last_name FROM person") if err!=nil { return } for rows.Next() { var person Person //遍歷表中所有行的信息 rows.Scan(&person.Id,&person.FirstName,&person.LastName) //將person添加到persons中 persons=append(persons,person) } //最后關閉連接 defer rows.Close() return } func main() { var err error db,err =sql.Open("mysql","root:123456@tcp(127.0.0.1:3306)/test?parseTime=true") //錯誤檢查 if err!=nil{ log.Fatal(err.Error()) } //推遲數據庫連接的關閉 defer db.Close() // err = db.Ping() if err != nil { log.Fatal(err.Error()) } //創建一個路由Handler router:=gin.Default() //get方法的查詢 router.GET("/person", func(c *gin.Context) { p:=Person{} persons,err:= p.getAll() if err !=nil { log.Fatal(err) } //H is a shortcut for map[string]interface{} c.JSON(http.StatusOK,gin.H{ "result":persons, "count":len(persons), }) }) router.Run(":8080") } 

3.測試結果如下

image.png
image.png

完整代碼如下:

package main import ( "database/sql" _ "github.com/go-sql-driver/mysql" "log" "net/http" "github.com/gin-gonic/gin" "strconv" "fmt" ) var db *sql.DB //定義person類型結構 type Person struct { Id int `json:"id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` } //定義一個getALL函數用於回去全部的信息 func (p Person) getAll() (persons []Person, err error) { rows, err := db.Query("SELECT id, first_name, last_name FROM person") if err != nil { return } for rows.Next() { var person Person //遍歷表中所有行的信息 rows.Scan(&person.Id, &person.FirstName, &person.LastName) //將person添加到persons中 persons = append(persons, person) } //最后關閉連接 defer rows.Close() return } //通過id查詢 func (p Person) get() (person Person, err error) { row := db.QueryRow("SELECT id, first_name, last_name FROM person WHERE id=?", p.Id) err = row.Scan(&person.Id, &person.FirstName, &person.LastName) if err != nil { return } return } func (p Person) add() (Id int, err error) { stmt, err := db.Prepare("INSERT INTO person(first_name, last_name) VALUES (?, ?)") if err != nil { return } //執行插入操作 rs, err := stmt.Exec(p.FirstName, p.LastName) if err != nil { return } //返回插入的id id, err := rs.LastInsertId() if err != nil { log.Fatalln(err) } //將id類型轉換 Id = int(id) defer stmt.Close() return } //通過id刪除 func (p Person) del() (rows int, err error) { stmt, err := db.Prepare("DELETE FROM person WHERE id=?") if err != nil { log.Fatalln(err) } rs, err := stmt.Exec(p.Id) if err != nil { log.Fatalln(err) } //刪除的行數 row, err := rs.RowsAffected() if err != nil { log.Fatalln(err) } defer stmt.Close() rows = int(row) return } func main() { var err error db, err = sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test?parseTime=true") //錯誤檢查 if err != nil { log.Fatal(err.Error()) } //推遲數據庫連接的關閉 defer db.Close() // err = db.Ping() if err != nil { log.Fatal(err.Error()) } //創建一個路由Handler router := gin.Default() //get方法的查詢 router.GET("/person", func(c *gin.Context) { p := Person{} persons, err := p.getAll() if err != nil { log.Fatal(err) } //H is a shortcut for map[string]interface{} c.JSON(http.StatusOK, gin.H{ "result": persons, "count": len(persons), }) }) //利用get方法通過id查詢 router.GET("/person/:id", func(c *gin.Context) { var result gin.H //c.Params方法可以獲取到/person/:id中的id值 id := c.Param("id") Id, err := strconv.Atoi(id) if err != nil { log.Fatal(err) } //定義person結構 p := Person{ Id: Id, } person, err := p.get() if err != nil { result = gin.H{ "result": nil, "count": 0, } } else { result = gin.H{ "result": person, "count": 1, } } c.JSON(http.StatusOK, result) }) //利用post方法新增數據 router.POST("/person", func(c *gin.Context) { var p Person err := c.Bind(&p) if err != nil { log.Fatal(err) } Id, err := p.add() fmt.Print("id=", Id) name := p.FirstName + " " + p.LastName c.JSON(http.StatusOK, gin.H{ "message": fmt.Sprintf("%s 插入成功", name), }) }) //利用DELETE請求方法通過id刪除 router.DELETE("/person/:id", func(c *gin.Context) { id := c.Param("id") Id, err := strconv.ParseInt(id, 10, 10) if err != nil { log.Fatalln(err) } p := Person{Id: int(Id)} rows, err := p.del() if err != nil { log.Fatalln(err) } fmt.Println("delete rows ", rows) c.JSON(http.StatusOK, gin.H{ "message": fmt.Sprintf("Successfully deleted user: %s", id), }) }) router.Run(":8080") } 

下一篇博客在學習下實際項目中的基於gorm的ORM層的SQL寫法,以及規范的項目結構分層!



作者:Michaelhbjian
鏈接:https://www.jianshu.com/p/3227289306e0
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM