1. 程式人生 > 實用技巧 >Go語言輕量級框架-Gin與入門小案例MySQL增刪查改

Go語言輕量級框架-Gin與入門小案例MySQL增刪查改

Go語言輕量級框架-Gin與入門小案例MySQL增刪查改

簡單的使用一下gin框架,然後使用它完成資料庫的增刪查改

一、安裝和開始

要想使用gin必須要下載和安裝它,切換到自己的工作空間,執行go命令

go get -u github.com/gin-gonic/gin

但是因為網路問題可能會失敗,實在不行就直接通過github下載也可以。
安裝好之後就可以直接使用了,開啟ide建立一個新的專案helloGin,建立main.go

package main

import (
	"github.com/gin-gonic/gin"
	"log"
)

func main() {
	// Engin
	router := gin.Default()
	//router := gin.New()
	
	router.GET("/hello", func(context *gin.Context) {
		log.Println(">>>> hello gin start <<<<")
		context.JSON(200, gin.H{
			"code":    200,
			"success": true,
			"data" : "Hello LXR!",
		})
	})
	// 指定地址和埠號
	router.Run("127.0.0.1:8082")
}

在main函式裡面首先通過呼叫gin.Default()函式返回的是一個Engin指標,Engin代表的是整個框架的一個例項,它包含了多路複用、中介軟體和配置的設定,其實就是封裝了我們需要的內容。一般建立Engin都是使用Default()或者New(),當然Default()本身內部也是呼叫的New()函式。
接著呼叫Engin的GET方法,這個方法兩個引數,一個是相對路徑,一個是多個handler,即針對使用者一個請求地址,我可以指定多個handler來處理使用者請求。但是一般情況下我們都是一個handler處理一個請求。上面的程式碼裡使用了一個匿名函式處理"/hello"請求。然後以JSON格式的資料響應使用者請求,這個方法有兩個引數,第一個是狀態,第二個是結果。我這裡直接指定200,表示成功,或者也可以用http包的常量值http.StatusOK;gin.H其實是一個map的資料結構,然後將其轉成json格式輸出。
最後是router.Run("localhost:8082"),這個方法是指定服務的主機和埠號,不過一般直接指定埠號就行了。
下面啟動專案,並訪問"localhost:8082/hello",訪問結果如下圖所示:

二、一個簡單的gin與MySQL資料庫互動

也是基於MVC的程式設計思想,所以將程式碼分成了controller和model還有dao主要程式碼,目錄結構如下

首先需要去mysql裡面建立一個數據庫,SQL檔案如下

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID ',
  `username` varchar(64) NOT NULL COMMENT '使用者名稱稱 ',
  `age` int(11) NOT NULL COMMENT 'ID ',
  `mobile` varchar(64) NOT NULL COMMENT '手機號碼 ',
  `sex` varchar(32) DEFAULT NULL COMMENT '性別 ',
  `address` varchar(64) DEFAULT NULL COMMENT '地址 ',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者表';

model裡面其實資料庫表的一個類,go語言就是一個結構體

User.go

package model

type User struct {
	Username 	string	`json:"name" form:"name"`
	Age  		uint8	`json:"age" form:"age"`
	Mobile 		string	`json:"mobile" form:"mobile"`
	Sex			string	`json:"sex" form:"sex"`
	Address 	string	`json:"address" form:"address"`
	Id          uint16  `json:"id" form:"id"`
}


main函式其實相當於Java裡面的controller 處理路由的,程式碼如下

main.go

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/helloGin/controller"
	"net/http"
)

func main()  {

	// Engin
	router := gin.Default()

	//router := gin.New()
	router.LoadHTMLGlob("template/*")
	router.GET("/hello", hello)

	// 路由組
	user := router.Group("/user")
	{	// 請求引數在請求路徑上
		user.GET("/get/:id/:username",controller.QueryById)
		user.GET("/query",controller.QueryParam)
		user.POST("/insert",controller.InsertNewUser)
		user.GET("/form",controller.RenderForm)
		user.POST("/form/post",controller.PostForm)
		//可以自己新增其他,一個請求的路徑對應一個函式

		// ...
	}

	file := router.Group("/file")
	{
		// 跳轉上傳檔案頁面
		file.GET("/view",controller.RenderView)
		// 根據表單上傳
		file.POST("/insert",controller.FormUpload)
		file.POST("/multiUpload",controller.MultiUpload)
		// base64上傳
		file.POST("/upload",controller.Base64Upload)
	}

	// 指定地址和埠號
	router.Run(":9090")
}

func hello(context *gin.Context) {
	println(">>>> hello function start <<<<")

	context.JSON(http.StatusOK,gin.H{
		"code":200,
		"success":true,
	})
}

UserController.go

package controller

import (
	"database/sql"
	"github.com/gin-gonic/gin"
	"github.com/helloGin/database"
	"github.com/helloGin/model"
	"log"
	"net/http"

)

var db *sql.DB

func init()  {
	log.Println(">>>> get database connection start <<<<")
	db = database.GetDataBase()
}

// localhost:9090/user/query?id=2&name=hello
func QueryParam(context *gin.Context) {
	println(">>>> query user by url params action start <<<<")
	id := context.Query("id")
	name := context.Request.URL.Query().Get("name")
	var u model.User
	context.Bind(&u)
	context.ShouldBind(&u)

	println(u.Username)
	rows := db.QueryRow("select username,address,age,mobile,sex from t_user where id = ? and username = ?",id,name)
	var user model.User
	err := rows.Scan(&user.Username,&user.Address,&user.Age,&user.Mobile,&user.Sex)
	checkError(err)

	checkError(err)
	context.JSON(200,gin.H{
		"result":user,
	})

}
// localhost:9090/user/get/2/hello
func QueryById (context *gin.Context) {
	println(">>>> get user by id and name action start <<<<")

	// 獲取請求引數
	id := context.Param("id")
	name := context.Param("username")

	// 查詢資料庫
	rows := db.QueryRow("select username,address,age,mobile,sex from t_user where id = ? and username = ?",id,name)

	var user model.User
	//var username string
	//var address string
	//var age uint8
	//var mobile string
	//var sex string
	err := rows.Scan(&user.Username,&user.Address,&user.Age,&user.Mobile,&user.Sex)
	checkError(err)

	checkError(err)
	context.JSON(200,gin.H{
		"result":user,
	})
}

// json格式資料
func InsertNewUser (context *gin.Context) {
	println(">>>> insert controller action start <<<<")
	var user model.User

	// 使用ioutile讀取二進位制資料
	//bytes,err := ioutil.ReadAll(context.Request.Body)
	//if err != nil {
	//	log.Fatal(err)
	//}
	//err = json.Unmarshal(bytes,&user)

	// 直接將結構體和提交的json引數作繫結
	err := context.ShouldBindJSON(&user)

	// 寫入資料庫
	res,err := db.Exec("insert into t_user (username,sex,address,mobile,age) values (?,?,?,?,?)",
		&user.Username,&user.Sex,&user.Address,&user.Mobile,&user.Age)
	var count int64
	count,err = res.RowsAffected()
	checkError(err)
	if count != 1 {
		context.JSON(200,gin.H{
			"success":false,
		})
	} else {
		context.JSON(200,gin.H{
			"success":true,
		})
	}

}

// form表單提交
func PostForm(context *gin.Context) {
	println(">>>> bind form post params action start <<<<")
	var u model.User

	// 繫結引數到結構體
	context.Bind(&u)
	context.ShouldBind(&u)
	res,err := db.Exec("insert into t_user (username,sex,address,mobile,age) values (?,?,?,?,?)",
		&u.Username,&u.Sex,&u.Address,&u.Mobile,&u.Age)
	var count int64
	count,err = res.RowsAffected()
	checkError(err)

	if count != 1 {
		context.JSON(200,gin.H{
			"success":false,
		})
	} else {
		//context.JSON(200,gin.H{
		//	"success":true,
		//})

		// 重定向
		context.Redirect(http.StatusMovedPermanently,"/file/view")
	}

}

// 跳轉html
func RenderForm(context *gin.Context) {
	println(">>>> render to html action start <<<<")

	context.Header("Content-Type", "text/html; charset=utf-8")
	context.HTML(200,"insertUser.html",gin.H{})
}

func checkError(e error) {
	if e != nil {
		log.Fatal(e)
	}
}

MySQL的配置檔案程式碼如下

connectDB.go

package database

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"log"
	"strings"
)

//資料庫的基礎資訊
const (
	userName = "root"
	password = "xxw2020"
	ip = "127.0.0.1"
	port = "3306"
	dbName = "student"
)

func GetDataBase() *sql.DB {

	//mysql 資料庫
	//構建連線:"使用者名稱:密碼@tcp(IP:埠)/資料庫?charset=utf8"
	path := strings.Join([]string{userName, ":", password, "@tcp(",ip, ":", port, ")/", dbName, "?charset=utf8"}, "")
	fmt.Println(path)
	//開啟資料庫,前者是驅動名,所以要匯入: _ "github.com/go-sql-driver/mysql"
	DB, _ := sql.Open("mysql", path)
	if DB == nil {
		log.Fatal("連線失敗!")
		return nil
	}
	//設定資料庫最大連線數
	DB.SetConnMaxLifetime(10)
	//設定上資料庫最大閒置連線數
	DB.SetMaxIdleConns(5)
	//驗證連線
	if err := DB.Ping(); err != nil{
		log.Fatal("opon database fail")
		return nil
	}
	return DB
}

主要的程式碼已經上傳到github

首先這個需要在gopath目錄下的src/github.com/目錄下clone該程式碼,然後執行資料庫建表,最後執行就ok了

參考部落格golang輕量級框架-Gin入門