精华内容
下载资源
问答
  • Go语言Gin开发实战

    2019-11-21 23:30:38
    Go语言Gin开发实战

    Go语言Gin开发实战

    阅读全文: http://gitbook.cn/gitchat/activity/5dd61b284be9984a6f7fa444

    您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

    FtooAtPSkEJwnW-9xkCLqSTRpBKX

    展开全文
  • go语言gin框架教程 熟悉类Unix、Windows Server等操作系...

    扫码下载「CSDN程序员学院APP」,1000+技术好课免费看

    APP订阅课程,领取优惠,最少立减5元 ↓↓↓

    订阅后:请点击此处观看视频课程

     

    视频教程-go语言gin框架教程-Go语言

    学习有效期:永久观看

    学习时长:44分钟

    学习计划:1天

    难度:

     

    口碑讲师带队学习,让你的问题不过夜」

    讲师姓名:王雷

    技术总监

    讲师介绍:熟悉类Unix、Windows Server等操作系统、擅长Python、Golang、PHP语言及web全栈开发等技术。讲课方式风趣幽默,浅显易懂!

    ☛点击立即跟老师学习☚

     

    「你将学到什么?」

    Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。如果你需要极好的性能,使用 Gin 吧。

     

    「课程学习目录」

    1.gin框架hello world
    2.返回json、xml
    3.解析模板
    4.静态资源
    5.请求参数
    6.参数绑定,参数验证
    7.上传文件
    8.上传多文件
    9.路由组
    10.自定义中间件

     

    7项超值权益,保障学习质量」

    • 大咖讲解

    技术专家系统讲解传授编程思路与实战。

    • 答疑服务

    专属社群随时沟通与讲师答疑,扫清学习障碍,自学编程不再难。

    • 课程资料+课件

    超实用资料,覆盖核心知识,关键编程技能,方便练习巩固。(部分讲师考虑到版权问题,暂未上传附件,敬请谅解)

    • 常用开发实战

    企业常见开发实战案例,带你掌握Python在工作中的不同运用场景。

    • 大牛技术大会视频

    2019Python开发者大会视频免费观看,送你一个近距离感受互联网大佬的机会。

    • APP+PC随时随地学习

    满足不同场景,开发编程语言系统学习需求,不受空间、地域限制。

     

    「什么样的技术人适合学习?」

    • 想进入互联网技术行业,但是面对多门编程语言不知如何选择,0基础的你
    • 掌握开发、编程技术单一、冷门,迫切希望能够转型的你
    • 想进入大厂,但是编程经验不够丰富,没有竞争力,程序员找工作难。

     

    「悉心打造精品好课,1天学到大牛3年项目经验」

    【完善的技术体系】

    技术成长循序渐进,帮助用户轻松掌握

    掌握Go语言知识,扎实编码能力

    【清晰的课程脉络】

    浓缩大牛多年经验,全方位构建出系统化的技术知识脉络,同时注重实战操作。

    【仿佛在大厂实习般的课程设计】

    课程内容全面提升技术能力,系统学习大厂技术方法论,可复用在日后工作中。

     

    「你可以收获什么?」

    学习使用gin框架开发网站

    学习gin框架的特点

     

    展开全文
  • go语言gin框架教程

    2019-12-29 13:52:36
    Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。如果你需要极好的性能,使用 Gin 吧。
  • go语言 gin框架

    2020-12-31 11:24:31
    go gin

    Go 下载
    官方下载地址

    https://golang.google.cn/dl/
    或者
    https://golang.org/dl/

    以下内容以window为例

    下载解压安装之后,在系统变量中 添加模块代理 goproxy
    可以加快下载速度

    GO111MODULE=on
    GOPROXY=https://goproxy.cn,direct
    

    系统变量

    在cmd命令行运行

    go version
    

    成功查看go版本
    再安装gin框架

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

    运行结束后,选择一个合适的空文件夹下创建test.go

    package main
    import "github.com/gin-gonic/gin"
    func main() {
      r := gin.Default()
      r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
          "message": "pong",
        })
      })
      r.Run() // listen and serve on 0.0.0.0:8080
    }
    

    需要用到 go mod 的包依赖管理,才可以正常运行 test.go

    go mod init gin 
    

    命令运行结束后会在test.go的同级目录下生成一个新的文件 go.mod

    此后可以正常运行test.go
    在test.go的文件夹下打开 powershell 或者 cmd

    go run test.go
    

    浏览器打开 localhost:8080/ping

    展开全文
  • Go语言gin框架的安装

    2021-01-07 21:01:03
    问题来了,因为墙的问题,go get会很慢,所以命令行里面半天什么反应也没有,不要急,慢慢等着就会看到gin-gonic/gin这个目录出现 这个时候命令行还是没有结束,表示还在下一些东西。有的时候可能心急的人就停了...
  • 下载使用$ go get -u github.com/gin-gonic/ginimport "github.com/gin-gonic/gin"HTTP服务func main() {router := gin.Default()//路由router.GET("/", func(c *gin.Context) {c.JSON(200, gin.H{"message": "hello...

    下载使用

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

    import "github.com/gin-gonic/gin"

    HTTP服务

    func main() {

    router := gin.Default()

    //路由

    router.GET("/", func(c *gin.Context) {

    c.JSON(200, gin.H{

    "message": "hello gin",

    })

    })

    router.Run(":8080")

    }

    路由绑定

    router.GET("/", index)表示用GET方式接收路由,如果路由是根目录,那么直接执行index控制器方法,index控制器必须含有gin.Context参数,也可以向上面一样将index控制器的内容写成匿名函数。

    router.GET("/", index)

    func index(c *gin.Context) {

    c.JSON(200, gin.H{

    "msg": "hello gin",

    })

    }

    路由分离

    为了更好的管理路由,最好将路由和控制器分开不同的文件

    在根目录下新建router.go

    package gin

    import (

    "github.com/gin-gonic/gin"

    "os"

    "path/filepath"

    )

    func initRouter() *gin.Engine {

    //路由

    router := gin.Default()

    router.GET("/", index)

    return router

    }

    在main方法中进行初始化

    func main() {

    router := initRouter()

    router.Run(":8080")

    }

    此时目录结构如下

    --src

    --gin

    --gin.go #用于存放控制器

    --router.go #用于存放路由

    --main.go

    路由组

    一些情况下,我们会有统一前缀的 url 的需求,典型的如 Api 接口版本号 /v1/something。Gin 可以使用 Group 方法统一归类到路由组中

    func main() {

    router := gin.Default()

    // /v1/login 就会匹配到这个组

    v1 := router.Group("/v1")

    {

    v1.POST("/login", loginEndpoint)

    v1.POST("/submit", submitEndpoint)

    v1.POST("/read", readEndpoint)

    }

    // 不用花括号包起来也是可以的。上面那种只是看起来会统一一点。看你个人喜好

    v2 := router.Group("/v2")

    v2.POST("/login", loginEndpoint)

    v2.POST("/submit", submitEndpoint)

    v2.POST("/read", readEndpoint)

    router.Run(":8080")

    }

    异步处理

    goroutine 机制可以方便地实现异步处理

    func main() {

    r := gin.Default()

    //1. 异步

    r.GET("/long_async", func(c *gin.Context) {

    // goroutine 中只能使用只读的上下文 c.Copy()

    cCp := c.Copy()

    go func() {

    time.Sleep(5 * time.Second)

    // 注意使用只读上下文

    log.Println("Done! in path " + cCp.Request.URL.Path)

    }()

    })

    //2. 同步

    r.GET("/long_sync", func(c *gin.Context) {

    time.Sleep(5 * time.Second)

    // 注意可以使用原始上下文

    log.Println("Done! in path " + c.Request.URL.Path)

    })

    // Listen and serve on 0.0.0.0:8080

    r.Run(":8080")

    }

    接收参数

    接收GET参数

    路由

    router.GET("/user", hello)

    控制器 (这里用的接收方法是Query)

    func hello(c *gin.Context) {

    firstname := c.DefaultQuery("firstname", "Guest") //设置默认参数值

    lastname := c.Query("lastname") //获取参数值,c.Request.URL.Query().Get("lastname")的缩写

    c.String(http.StatusOK, "Hello %s %s", firstname, lastname)

    }

    或者

    路由 (参数名用:号标记)

    router.GET("/user/:name/:action", user)

    或者

    router.GET("/user/:name/*action", user)

    上面这个写法将会匹配/user/:name/开头的所有路由

    控制器 (这里的接收方法是Param)

    func user(c *gin.Context) {

    name := c.Param("name")

    action := c.Param("action")

    message := name + " is " + action

    c.String(http.StatusOK, message)

    }

    接收POST参数

    路由

    router.POST("/post", post)

    控制器

    func post(c *gin.Context) {

    name := c.PostForm("name")

    age := c.PostForm("age")

    fmt.Printf("name: %s, age: %s;", name, age)

    }

    文件上传

    单文件上传

    路由

    router.POST("/upload", upload)

    控制器

    func upload(c *gin.Context) {

    file, _ := c.FormFile("file") //表单的文件name="file"

    //文件上传路径和文件名

    c.SaveUploadedFile(file, "./upload/"+file.Filename)

    c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))

    }

    多文件上传

    注意多文件上传表单

    标签需要注明属性enctype="multipart/form-data" method="post",标签的name属性值必须相同,例如全部为name="file"

    路由

    router.POST("/multiupload", multiupload)

    控制器

    func multiupload(c *gin.Context) {

    // 文件上传大小限制 8 MB,在路由注册时设定

    //router.MaxMultipartMemory = 8 << 20

    formdata := c.Request.MultipartForm

    files := formdata.File["file"] //表单的文件name="file"

    for i, _ := range files {

    file, err := files[i].Open()

    defer file.Close()

    if err != nil {

    c.String(http.StatusBadRequest, fmt.Sprintf("get file err: %s", err.Error()))

    return

    }

    //文件上传路径和文件名

    out, err := os.Create("./upload/" + files[i].Filename)

    defer out.Close()

    if err != nil {

    c.String(http.StatusBadRequest, fmt.Sprintf("upload err: %s", err.Error()))

    return

    }

    _, err = io.Copy(out, file)

    if err != nil {

    c.String(http.StatusBadRequest, fmt.Sprintf("save file err: %s", err.Error()))

    return

    }

    c.String(http.StatusOK, "upload successful")

    }

    }

    视图模板

    目录结构

    在根目录下新建templates文件夹用于存放html页面,为了便于管理在templates目录下再创建一个index文件夹存放与index控制器相关的页面,在index目录下新建index.html文件

    Title

    {{.title}}

    此时目录结构如下

    - src

    --gin

    --main.go

    --router.go

    --templates

    --index

    --index.html

    加载视图

    在初始化路由的位置加载所有视图模板,其中**表示各个控制器或路由组对应的视图目录,*表示该目录下所有文件

    router := gin.Default()

    //加载模板

    router.LoadHTMLGlob(filepath.Join(os.Getenv("GOPATH"), "./src/gin/templates/**/*"))

    router.GET("/", index)

    控制器绑定视图

    func index(c *gin.Context) {

    c.HTML(http.StatusOK, "index.html", gin.H{

    "title": "Main website",

    })

    }

    静态文件

    网页开发离不开css和图片等静态资源文件,我们必须设置好路径才能正确访问,例如我的目录结构为(缩进表示二级目录)

    --src

    --gin

    --static

    --css

    --index.css

    --templates

    --index

    --index.html

    --router.go

    --main.go

    如果index.html文件需要引入index.css文件,则在路由申请的地方声明

    //加载模板

    router.LoadHTMLGlob(filepath.Join(os.Getenv("GOPATH"), "./src/gin/templates/**/*"))

    //加载静态文件

    router.Static("/static", filepath.Join(os.Getenv("GOPATH"), "./src/gin/static"))

    然后index.css文件中这样调用就可以了,其他静态资源用法类似

    参数传递

    在控制器传递参数

    c.HTML(http.StatusOK, "index.html", gin.H{

    "title": "Main website",

    })

    在视图渲染参数

    {{.title}}

    重定向

    r.GET("/redirect", func(c *gin.Context) {

    //支持内部和外部的重定向

    c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com/")

    })

    中间件

    使用中间件

    router := gin.Default()

    router.Use(middleware.IPLimit()) //使用自定义中间件:IP验证

    中间件实现

    package middleware

    import (

    "core"

    "github.com/gin-gonic/gin"

    "net/http"

    "strings"

    )

    //访问ip限制

    func IPLimit() gin.HandlerFunc {

    return func(c *gin.Context) {

    ip := c.ClientIP()

    ipList := strings.Split(core.Config["allow_ip"], "|")

    flag := false

    for i := 0; i < len(ipList); i++ {

    if ip == ipList[i] {

    flag = true

    break

    }

    }

    if !flag {

    c.Abort()

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

    "code": 0,

    "msg": "IP " + ip + " 没有访问权限",

    "data": nil})

    return // return也是可以省略的,执行了abort操作,会内置在中间件defer前,return,写出来也只是解答为什么Abort()之后,还能执行返回JSON数据

    }

    }

    }

    数据绑定和验证

    使用 c.ShouldBind方法,可以将参数自动绑定到 struct,该方法是会检查 Url 查询字符串和 POST 的数据,而且会根据 content-type类型,优先匹配JSON或者 XML,之后才是 Form。数据绑定可以用来做数据验证,例如

    路由

    router.POST("/binding", binding)

    控制器

    //数据结构体,username为表单字段,required表示必须参数,可选的话binding留空即可

    type Login struct {

    Username string `form:"username" binding:"required"`

    Password string `form:"password" binding:"required"`

    }

    //控制器

    func binding(c *gin.Context) {

    var form Login

    // 验证数据并绑定

    if err := c.ShouldBind(&form); err == nil {

    if form.Username == "manu" && form.Password == "123" {

    c.JSON(http.StatusOK, gin.H{"msg": "Login successfully"})

    } else {

    c.JSON(http.StatusUnauthorized, gin.H{"msg": "username or password error"})

    }

    } else {

    c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})

    }

    }

    当没有接收到参数时返回

    {

    "error": "Key: 'Login.Username' Error:Field validation for 'Username' failed on the 'required' tag"

    }

    当参数错误时返回

    {

    "msg": "username or password error"

    }

    当接收到参数且正确时放回

    {

    "msg": "Login successfully"

    }

    日志

    自带日志

    Gin日志默认只在控制台显示,如果要写入文件需要在main方法中声明

    gin.DisableConsoleColor() //关掉控制台颜色,可省略

    f, _ := os.Create("gin.log") //日志文件

    //gin.DefaultWriter = io.MultiWriter(f) //将日志写入文件

    gin.DefaultWriter = io.MultiWriter(f, os.Stdout) //将日志写入文件同时在控制台输出

    Logrus 日志库

    Gin自带的日志系统只支持简单的功能,需要更强大的功能还需要用到第三方日志库,这里选择github上面star最多的Logrus。

    下载

    go get github.com/sirupsen/logrus

    使用

    package main

    import (

    log "github.com/Sirupsen/logrus"

    )

    func main() {

    log.Trace("Something very low level.")

    log.Debug("Useful debugging information.")

    log.Info("Something noteworthy happened!")

    log.Warn("You should probably take a look at this.")

    log.Error("Something failed but I'm not quitting.")

    // Calls os.Exit(1) after logging

    log.Fatal("Bye.")

    // Calls panic() after logging

    log.Panic("I'm bailing.")

    }

    数据库

    Gin框架没有自带的数据库封装,导入的数据库驱动由开发使用的数据库类型决定,例如开发使用mysql就直接import _ "github.com/go-sql-driver/mysql";但是访问数据库都是直接用写 sql,取出结果然后自己拼成对象,使用上面不是很方便,可读性也不好。这里使用目前github上star数量最多的https://github.com/jinzhu/gorm

    gorm的详细教程参考http://gorm.book.jasperxu.com/models.html#md

    下载

    go get -u github.com/jinzhu/gorm

    连接mysql

    package gin

    import (

    "github.com/jinzhu/gorm"

    )

    func Index() {

    db, err := gorm.Open("mysql", "root:root@(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local")

    if err != nil {

    panic(err)

    }

    defer db.Close()

    }

    数据表

    import (

    "github.com/jinzhu/gorm"

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

    "time"

    )

    //定义数据表模型

    type User struct {

    Id uint `gorm:"primary_key;AUTO_INCREMENT"` // 自增主键

    Name string `gorm:"size:255"` // string默认长度为255, 使用这种tag重设。

    Address string `gorm:"not null;unique"` // 设置字段为非空并唯一

    Addtime time.Time `gorm:"default:'2019-03-11 13:19:40'"` //默认值

    }

    func Index() {

    //连接数据库

    db, err := gorm.Open("mysql", "root:root@(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local")

    if err != nil {

    panic(err)

    }

    //关闭数据库

    defer db.Close()

    //设置默认表名前缀

    gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {

    return "test_" + defaultTableName

    }

    //创建表

    if !db.HasTable(&User{}) { //检查表是否存在

    if err := db.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8").CreateTable(&User{}).Error; err != nil {

    panic(err)

    }

    }

    // 删除表users

    db.DropTable("test_users")

    // 修改模型`User`的"addtime"列类型

    db.Model(&User{}).ModifyColumn("addtime", "text")

    // 删除模型`User`的addtime列

    db.Model(&User{}).DropColumn("addtime")

    // 为`name`列添加索引`idx_user_name`

    db.Model(&User{}).AddIndex("idx_user_name", "name")

    // 删除索引

    db.Model(&User{}).RemoveIndex("idx_user_name")

    }

    添加记录

    //添加记录

    user := User{Name: "jian", Address: "1234", Addtime: time.Now()}

    if err := db.Create(&user).Error; err != nil {

    panic(err)

    }

    查询数据

    无条件查询

    // 获取第一条记录,按主键排序

    db.First(&user)

    // SELECT * FROM users ORDER BY id LIMIT 1;

    // 获取最后一条记录,按主键排序

    db.Last(&user)

    // SELECT * FROM users ORDER BY id DESC LIMIT 1;

    // 获取所有记录

    db.Find(&users)

    // SELECT * FROM users;

    // 使用主键获取记录

    db.First(&user, 10)

    // SELECT * FROM users WHERE id = 10;

    Where查询条件

    user := User{}

    // 获取第一个匹配记录

    db.Where("name = ?", "jinzhu").First(&user)

    fmt.Println(user.Name) //读取数据

    // SELECT * FROM users WHERE name = 'jinzhu' limit 1;

    // 获取最后一条记录,按主键排序

    db.Last(&user)

    // SELECT * FROM users ORDER BY id DESC LIMIT 1;

    // 获取所有匹配记录

    db.Where("name = ?", "jinzhu").Find(&users)

    // SELECT * FROM users WHERE name = 'jinzhu';

    db.Where("name <> ?", "jinzhu").Find(&users)

    // IN

    db.Where("name in (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users)

    // LIKE

    db.Where("name LIKE ?", "%jin%").Find(&users)

    // AND

    db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)

    // Time

    db.Where("updated_at > ?", lastWeek).Find(&users)

    db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)

    // Struct

    db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)

    SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1;

    // Map

    db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)

    // SELECT * FROM users WHERE name = "jinzhu" AND age = 20;

    // 主键的Slice

    db.Where([]int64{20, 21, 22}).Find(&users)

    // SELECT * FROM users WHERE id IN (20, 21, 22);

    Not条件查询

    db.Not("name", "jinzhu").First(&user)

    // SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1;

    // Not In

    db.Not("name", []string{"jinzhu", "jinzhu 2"}).Find(&users)

    // SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");

    // Not In slice of primary keys

    db.Not([]int64{1,2,3}).First(&user)

    // SELECT * FROM users WHERE id NOT IN (1,2,3);

    db.Not([]int64{}).First(&user)

    // SELECT * FROM users;

    // Plain SQL

    db.Not("name = ?", "jinzhu").First(&user)

    // SELECT * FROM users WHERE NOT(name = "jinzhu");

    // Struct

    db.Not(User{Name: "jinzhu"}).First(&user)

    // SELECT * FROM users WHERE name <> "jinzhu";

    Or条件查询

    db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users)

    // SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';

    // Struct

    db.Where("name = 'jinzhu'").Or(User{Name: "jinzhu 2"}).Find(&users)

    // SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';

    // Map

    db.Where("name = 'jinzhu'").Or(map[string]interface{}{"name": "jinzhu 2"}).Find(&users)

    指定字段和表

    db.Select("name, age").Find(&users)

    // SELECT name, age FROM users;

    db.Table("users").Select("COALESCE(age,?)", 42).Rows()

    // SELECT COALESCE(age,'42') FROM users;

    Order条件查询

    db.Order("age desc, name").Find(&users)

    // SELECT * FROM users ORDER BY age desc, name;

    Limit条件查询

    db.Limit(3).Find(&users)

    // SELECT * FROM users LIMIT 3;

    Offset条件查询

    指定在开始返回记录之前要跳过的记录数

    db.Offset(3).Find(&users)

    // SELECT * FROM users OFFSET 3;

    Count条件查询

    db.Where("name = ?", "jinzhu").Or("name = ?", "jinzhu 2").Find(&users).Count(&count)

    // SELECT * from USERS WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (users)

    多条件查询

    db.Where("role = ?", "admin").Or("role = ?", "super_admin").Not("name = ?", "jinzhu").Find(&users)

    db.Where("name <> ?","jinzhu").Where("age >= ? and role <> ?",20,"admin").Find(&users)

    更新数据

    // 使用组合条件更新单个属性

    db.Model(&user).Where("active = ?", true).Update("name", "hello")

    // UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;

    // 使用`map`更新多个属性,只会更新这些更改的字段

    db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})

    // 使用`struct`更新多个属性,只会更新这些更改的和非空白字段

    db.Model(&user).Updates(User{Name: "hello", Age: 18})

    删除数据

    db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})

    // DELETE from emails where email LIKE "%jinhu%";

    db.Delete(Email{}, "email LIKE ?", "%jinzhu%")

    // DELETE from emails where email LIKE "%jinhu%";

    执行原生SQL语句

    Scan()是将结果扫描到另一个结构中。

    db.Exec("DROP TABLE users;")

    db.Exec("UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, []int64{11,22,33})

    db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)

    row := db.Table("users").Where("name = ?", "jinzhu").Select("name, age").Row() // (*sql.Row)

    row.Scan(&name, &age)

    rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)

    defer rows.Close()

    for rows.Next() {

    ...

    rows.Scan(&name, &age, &email)

    ...

    }

    连接池

    db.DB().SetMaxIdleConns(10)

    db.DB().SetMaxOpenConns(100)

    锁行

    注意:加行锁的表必须是InnoDB并且要加索引,否则无效;语句必须在事务里面,必须提交或回滚

    // 为Select语句添加扩展SQL选项

    db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)

    // SELECT * FROM users WHERE id = 10 FOR UPDATE;

    锁表

    db.Exec("LOCK TABLES real_table WRITE, insert_table WRITE;") //锁定real_table和insert_table表

    UNLOCK TABLES; //解锁

    日志

    // 启用Logger,显示详细日志

    db.LogMode(true)

    // 禁用日志记录器,不显示任何日志

    db.LogMode(false)

    // 调试单个操作,显示此操作的详细日志

    db.Debug().Where("name = ?", "jinzhu").First(&User{})

    //自定义日志

    db.SetLogger(gorm.Logger{revel.TRACE})

    db.SetLogger(log.New(os.Stdout, "\r\n", 0))

    事务

    // 开始事务

    tx := db.Begin()

    // 注意,一旦你在一个事务中,使用tx作为数据库句柄,而不再是上面的db

    // 在事务中做一些数据库操作(从这一点使用'tx',而不是'db')

    tx.Create(...)

    // ...

    // 发生错误时回滚事务

    tx.Rollback()

    // 提交事务

    tx.Commit()

    展开全文
  • Gin是一个用Go语言编写的web框架。它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍。 如果你是性能和高效的追求者, 你会爱上GinGin框架介绍 Go世界里最流行的Web框架,...
  • go语言Gin框架教程

    2020-08-05 18:28:16
    本文作者:陈进坚 个人博客:https://jian1098.github.io CSDN博客:... 下载使用 $ go get -u github.com/gin-gonic/gin import "github.com/gin-gonic/gin" HTTP服务 func main() { router := gin..
  • go语言 gin框架学习01

    2020-12-31 23:05:51
    https://www.cnblogs.com/xinliangcoder/p/11200332.html go get -u -v github.com/gin-gonic/gin
  • go语言 gin框架学习02

    2021-01-02 22:51:12
    P184 gin数据解析和绑定 表单数据解析和绑定,代码如下 URI 数据解析和绑定 P185 gin各种渲染 P186 重定向 http://127.0.0.1:8080/redirect http://127.0.0.1:8080/longAsync ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 937
精华内容 374
关键字:

go语言gin