<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ## Gin安裝 配置代理:[https://goproxy.cn,direct](https://goproxy.cn,direct) > go get -u github.com/gin-gonic/gin ## 入門案例 ~~~ package main ? import ( "github.com/gin-gonic/gin" ) ? func main() { // 創建一個默認的路由引擎 r := gin.Default() // GET:請求方式;/hello:請求的路徑 // 當客戶端以GET方法請求/hello路徑時,會執行后面的匿名函數 r.GET("/hello", func(c *gin.Context) { // c.JSON:返回JSON格式的數據 c.JSON(200, gin.H{ "message": "Hello world!", }) }) // 默認8080,括號里的參數是端口號 r.Run() } ~~~ ## Gin渲染 ### HTML渲染 我們首先定義一個存放模板文件的`templates`文件夾,然后在其內部按照業務分別定義一個`posts`文件夾和一個`users`文件夾。 `posts/index.html`文件的內容如下: ~~~ {{define "posts/index.html"}} <!DOCTYPE html> <html lang="en"> ? <head> ? ?<meta charset="UTF-8"> ? ?<meta name="viewport" content="width=device-width, initial-scale=1.0"> ? ?<meta http-equiv="X-UA-Compatible" content="ie=edge"> ? ?<title>posts/index</title> </head> <body> ? {{.title}} </body> </html> {{end}} ~~~ `users/index.html`文件的內容如下: ~~~ {{define "users/index.html"}} <!DOCTYPE html> <html lang="en"> <head> ? ?<meta charset="UTF-8"> ? ?<meta name="viewport" content="width=device-width, initial-scale=1.0"> ? ?<meta http-equiv="X-UA-Compatible" content="ie=edge"> ? ?<title>users/index</title> </head> <body> ? {{.title}} </body> </html> {{end}} ~~~ Gin框架中使用`LoadHTMLGlob()`或者`LoadHTMLFiles()`方法進行HTML模板渲染。 ~~~ func main() { r := gin.Default() r.LoadHTMLGlob("templates/**/*") //r.LoadHTMLFiles("templates/posts/index.html", "templates/users/index.html") r.GET("/posts/index", func(c *gin.Context) { c.HTML(http.StatusOK, "posts/index.html", gin.H{ "title": "posts/index", }) }) ? r.GET("users/index", func(c *gin.Context) { c.HTML(http.StatusOK, "users/index.html", gin.H{ "title": "users/index", }) }) ? r.Run(":8080") } ~~~ ## 獲取參數 ### 獲取querystring參數 `querystring`指的是URL中`?`后面攜帶的參數,例如:`/user/search?username=小王子&address=沙河`。 獲取請求的querystring參數的方法如下: ~~~ func main() { //Default返回一個默認的路由引擎 r := gin.Default() r.GET("/user/search", func(c *gin.Context) { ? ? ? ?// 可以添加默認值 username := c.DefaultQuery("username", "小王子") //username := c.Query("username") address := c.Query("address") //輸出json結果給調用方 c.JSON(http.StatusOK, gin.H{ "message": ?"ok", "username": username, "address": ?address, }) }) r.Run() } ~~~ ~~~ http://localhost:8080/user/search?username=小王子&address=沙河 ~~~ ### 獲取path參數 請求的參數通過URL路徑傳遞,例如:`/user/search/小王子/沙河`。 獲取請求URL路徑中的參數的方式如下。 ~~~ func main() { //Default返回一個默認的路由引擎 r := gin.Default() r.GET("/user/search/:username/:address", func(c *gin.Context) { username := c.Param("username") address := c.Param("address") //輸出json結果給調用方 c.JSON(http.StatusOK, gin.H{ "message": ?"ok", "username": username, "address": ?address, }) }) ? r.Run(":8080") } ~~~ ## 文件上傳 ### 單文件上傳 寫個前端頁面,結構 ![](https://img.kancloud.cn/9c/f0/9cf09c185aa2ea0d07a753d11945c385_330x304.png) ~~~ {{define "uploads/upload.html"}} ? ?<!DOCTYPE html> ? ?<html lang="zh-CN"> ? ?<head> ? ? ? ?<title>上傳文件示例</title> ? ?</head> ? ?<body> ? ?<form action="/uploads/upload" method="post" enctype="multipart/form-data"> ? ? ? ?<input type="file" name="f1"> ? ? ? ?<input type="submit" value="上傳"> ? ?</form> ? ?</body> ? ?</html> {{end}} ~~~ 后臺: ~~~ func main() { router := gin.Default() ? ?//模板路徑 ? ?router.LoadHTMLGlob("templates/**/*") ? ? ? ?r.GET("/upload/index", func(c *gin.Context) { ? ? ? ?//頁面路徑 c.HTML(200,"uploads/upload.html",nil) }) // 處理multipart forms提交文件時默認的內存限制是32 MiB // 可以通過下面的方式修改 // router.MaxMultipartMemory = 8 << 20 // 8 MiB router.POST("/upload", func(c *gin.Context) { // 單個文件 file, err := c.FormFile("f1") if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": err.Error(), }) return } ? log.Println(file.Filename) dst := fmt.Sprintf("C:/tmp/%s", file.Filename) // 上傳文件到指定的目錄 c.SaveUploadedFile(file, dst) c.JSON(http.StatusOK, gin.H{ "message": fmt.Sprintf("'%s' uploaded!", file.Filename), }) }) router.Run() } ~~~ ### 多文件上傳 input選擇框里面加個`multiple`表示你可以多選 ~~~ {{define "uploads/uploads.html"}} ? ?<!DOCTYPE html> ? ?<html lang="zh-CN"> ? ?<head> ? ? ? ?<title>上傳文件示例</title> ? ?</head> ? ?<body> ? ?<form action="/uploads" method="post" enctype="multipart/form-data"> ? ? ? ?<input type="file" name="files" multiple> ? ? ? ?<input type="submit" value="上傳"> ? ?</form> ? ?</body> ? ?</html> {{end}} ~~~ 后臺: ~~~ r.POST("/uploads", func(c *gin.Context) { // Multipart form form, _ := c.MultipartForm() files := form.File["files"] ? for _, file := range files { log.Println(file.Filename) dst := fmt.Sprintf("D:/%s", file.Filename) // 上傳文件到指定的目錄 c.SaveUploadedFile(file, dst) } c.JSON(http.StatusOK, gin.H{ "message": fmt.Sprintf("%d files uploaded!", len(files)), }) }) ~~~ 這次只有核心代碼,可以結合前面單文件稍加修改,這并不難! ## 重定向 ### HTTP重定向 HTTP 重定向很容易。 內部、外部重定向均支持。 ~~~ r.GET("/test", func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com/") }) ~~~ ### 路由重定向 路由重定向,使用`HandleContext`: ~~~ r.GET("/test", func(c *gin.Context) { ? ?// 指定重定向的URL ? ?c.Request.URL.Path = "/test2" ? ?r.HandleContext(c) }) r.GET("/test2", func(c *gin.Context) { ? ?c.JSON(http.StatusOK, gin.H{"hello": "world"}) }) ~~~ ## 中間件 Gin框架允許開發者在處理請求的過程中,加入用戶自己的鉤子(Hook)函數。這個鉤子函數就叫中間件,中間件適合處理一些公共的業務邏輯,比如登錄認證、權限校驗、數據分頁、記錄日志、耗時統計等。 ### 定義中間件 Gin中的中間件必須是一個`gin.HandlerFunc`類型。例如我們像下面的代碼一樣定義一個統計請求耗時的中間件。 ~~~ // StatCost 是一個統計耗時請求耗時的中間件 func StatCost() gin.HandlerFunc { return func(c *gin.Context) { start := time.Now() c.Set("name", "小王子") // 可以通過c.Set在請求上下文中設置值,后續的處理函數能夠取到該值 // 調用該請求的剩余處理程序 c.Next() // 不調用該請求的剩余處理程序 // c.Abort() // 計算耗時 cost := time.Since(start) log.Println(cost) } } ~~~ ### 注冊中間件 ~~~ func main() { // 新建一個沒有任何默認中間件的路由 r := gin.New() // 注冊一個全局中間件 r.Use(StatCost()) r.GET("/test", func(c *gin.Context) { name := c.MustGet("name").(string) // 從上下文取值 log.Println(name) c.JSON(http.StatusOK, gin.H{ "message": "Hello world!", }) }) r.Run() } ~~~ ### 為某個路由單獨注冊 ~~~ // 給/test2路由單獨注冊中間件(可注冊多個) r.GET("/test2", StatCost(), func(c *gin.Context) { name := c.MustGet("name").(string) // 從上下文取值 log.Println(name) c.JSON(http.StatusOK, gin.H{ "message": "Hello world!", }) }) ~~~ ### 為路由組注冊中間件 寫法1: ~~~ shopGroup := r.Group("/shop", StatCost()) { ? ?shopGroup.GET("/index", func(c *gin.Context) {...}) ? ?... } ~~~ 寫法2: ~~~ shopGroup := r.Group("/shop") shopGroup.Use(StatCost()) { ? ?shopGroup.GET("/index", func(c *gin.Context) {...}) ? ?... } ~~~ # Gorm框架 ## 安裝 ~~~ go get -u github.com/jinzhu/gorm ~~~ ## 連接MySQL ~~~ import ( ?"github.com/jinzhu/gorm" ?_ "github.com/jinzhu/gorm/dialects/mysql" ) ? func main() { ?db, err := gorm.Open("mysql", "user:password@(localhost)/dbname?charset=utf8mb4&parseTime=True&loc=Local") ?defer db.Close() } ~~~ ## GORM操作MySQL ### 創建數據庫 ~~~ CREATE DATABASE db1; ? CREATE TABLE `user_info` ( `id` int(30) NOT NULL AUTO_INCREMENT COMMENT 'id', `name` varchar(255) DEFAULT NULL, `gender` varchar(255) DEFAULT NULL COMMENT 'Gender ', `hobby` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4; ~~~ ~~~ 表與實體映射的問題搞了我很久,我今天第一次建表的時候字段的首字母都是大寫,為了和實體名保持一致。結果反而讓自己查不到數據,一直以為是代碼的問題,直到把一個配置去了之后,go自動建表對比了下字段名才發現問題! ~~~ ### 基本操作 ~~~ package main ? import ( "fmt" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) ? // UserInfo 用戶信息 type UserInfo struct { ID int Name string Gender string Hobby string } ? ? func main() { db, err := gorm.Open("mysql", "root:123456@(127.0.0.1:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local") if err!= nil{ panic(err) } defer db.Close() ? // 自動遷移 db.AutoMigrate(&UserInfo{}) ? u1 := UserInfo{1, "七米", "男", "籃球"} u2 := UserInfo{2, "沙河娜扎", "女", "足球"} // 創建記錄 db.Create(&u1) db.Create(&u2) // 查詢 var u = new(UserInfo) db.First(u) fmt.Printf("%#v\n", u) ? var uu UserInfo db.Find(&uu, "hobby=?", "足球") fmt.Printf("%#v\n", uu) ? // 更新 db.Model(&u).Update("hobby", "雙色球") // 刪除 db.Delete(&u) } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看