gin框架入门实战教程13_15

**Gin **框架入门实战系列教程

主讲教师:(大地)
在线文档:https://www.itying.com/gin
我的专栏:https://www.itying.com/category-79-b0.html

十三、**Gin **中的 Session

13.1 、Session 简单介绍

session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 session 保存在服务器上。

13.2 、Session 的工作流程

:::info
当客户端浏览器第一次访问服务器并发送请求时,服务器端会创建一个 session 对象,生成 一个类似于 key,value 的键值对,然后将 value 保存到服务器 将 key(cookie)返回到浏览器(客 户)端。浏览器下次访问时会携带 key(cookie) ,找到对应的 session(value)。
:::

13.3 、Gin 中使用 Session

:::info
Gin 官方没有给我们提供 Session 相关的文档,这个时候我们可以使用第三方的 Session 中间 件来实现
:::

https://github.com/gin-contrib/sessions

:::info
gin-contrib/sessions 中间件支持的存储引擎:
• cookie
• memstore
• redis
• memcached
• mongodb
:::

13.4 、基于 Cookie 存储 Session

1 、安装 session 包

go  get  github.com/gin-contrib/sessions

2 、基本的 session 用法

package  main

import  (
    "github.com/gin-contrib/sessions"
    "github.com/gin-contrib/sessions/cookie"
    "github.com/gin-gonic/gin"
)

func  main()  {
    r  :=  gin.Default()
    //  创建基于 cookie 的存储引擎,secret11111  参数是用于加密的密钥 store  :=  cookie.NewStore([]byte("secret11111"))
    //  设置 session  中间件,参数 mysession ,指的是 session  的名字,也是 cookie 的名字
    //  store 是前面创建的存储引擎,我们可以替换成其他存储引擎
    r.Use(sessions.Sessions("mysession",  store))
    r.GET("/",  func(c   *gin.Context)  {
        //初始化 session 对象
        session  :=  sessions.Default(c)
        //设置过期时间
        session.Options(sessions.Options{
            MaxAge:  3600  *  6,  //  6hrs
        })
        //设置 Session
        session.Set("username",  "张三")
        session.Save()

        c.JSON(200,  gin.H{"msg" :  session.Get("username")})

    })
    r.GET("/user",  func(c   *gin.Context)  {
        //  初始化 session 对象
        session  :=  sessions.Default(c)
        //  通过 session.Get 读取 session 值
        username  :=  session.Get("username")
        c.JSON(200,  gin.H{"username" :   username})
    })

    r.Run(" :8000")
}

13.5 、基于 Redis 存储 Session

:::info
如果我们想将 session 数据保存到 redis 中,只要将 session 的存储引擎改成 redis 即可。
使用 redis 作为存储引擎的例子:
首先安装 redis 存储引擎的包
:::

go  get  github.com/gin-contrib/sessions/redis

例子:

package  main

import  (
    "github.com/gin-contrib/sessions"
    "github.com/gin-contrib/sessions/redis"
    "github.com/gin-gonic/gin"
)

func  main()  {
    r  :=  gin.Default()
    //  初始化基于 redis  的存储引擎
    //  参数说明:
    //         第 1 个参数 -   redis 最大的空闲连接数
    //         第 2 个参数 -  数通信协议tcp 或者 udp
    //         第 3 个参数 -   redis 地址,  格式,host:port
    //         第 4 个参数 -  redis 密码
    //         第 5 个参数 -  session 加密密钥
    store,  _  :=  redis.NewStore(10,  "tcp",  "localhost:6379",  "",  []byte("secret"))

    r.Use(sessions.Sessions("mysession",  store))

    r.GET("/",  func(c   *gin.Context)  {
        session  :=  sessions.Default(c)
        session.Set("username",  "李四")
        session.Save()
        c.JSON(200,  gin.H{"username" :  session.Get("username")})
    })

    r.GET("/user",  func(c   *gin.Context)  {
        //  初始化 session 对象
        session  :=  sessions.Default(c)
        //  通过 session.Get 读取 session 值
        username  :=  session.Get("username")
        c.JSON(200,  gin.H{"username" :   username})
    })
    r.Run(" :8000")
}

十四、**Gin **中使用 **GORM **操作 **mysql **数据库

14.1 、GORM 简单介绍

:::info
GORM 是 Golang 的一个 orm 框架。简单说,ORM 就是通过实例对象的语法,完成关系型 数据库的操作的技术,是"对象-关系映射"(Object/ Relational Mapping) 的缩写。使用 ORM 框架可以让我们更方便的操作数据库。
**GORM **官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server
:::

:::info
Gorm 特性
• 全功能 ORM
• 关联 (Has One ,Has Many ,Belongs To ,Many To Many ,多态,单表继承)
• Create ,Save ,Update ,Delete ,Find 中钩子方法
• 支持 Preload 、Joins 的预加载
• 事务,嵌套事务,Save Point ,Rollback To Saved Point
• Context 、预编译模式、DryRun 模式
• 批量插入,FindInBatches ,Find/Create with Map ,使用 SQL 表达式、Context Valuer 进 行 CRUD
• SQL 构建器,Upsert ,数据库锁,Optimizer/ Index/Comment Hint ,命名参数,子查询
• 复合主键,索引,约束
• Auto Migration
• 自定义 Logger
• 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus …
• 每个特性都经过了测试的重重考验
• 开发者友好
:::

官方文档:https://gorm.io/zh_CN/docs/index.html

14.2 、Gin 中使用 GORM

1 、安装

如果使用 go mod 管理项目的话可以忽略此步骤

go  get  -u  gorm.io/gorm
go  get  -u  gorm.io/driver/mysql

2 、Gin 中使用 Gorm 连接数据库

在 models 下面新建 core.go ,建立数据库链接

package  models

import  (
    "fmt"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)
var  DB  *gorm.DB
var  err  error

func  init()  {
    dsn  :=  "root:123456@tcp(192.168.0.6:3306)/gin?charset=utf8mb4&parseTime=True&loc= L ocal"
    DB,  err  =  gorm.Open(mysql.Open(dsn),  &gorm.Config{})
    if  err   !=  nil  {
        fmt.Println(err)
    }
}

3 、定义操作数据库的模型

:::info
Gorm 官方给我们提供了详细的:
https://gorm.io/zh_CN/docs/models.html

虽然在 gorm 中可以指定字段的类型以及自动生成数据表,但是在实际的项目开发中,我们 是先设计数据库表,然后去实现编码的。
在实际项目中定义数据库模型注意以下几点:
1 、结构体的名称必须首字母大写 ,并和数据库表名称对应。例如:表名称为 user 结构体 名称定义成 User ,表名称为 article_cate 结构体名称定义成 ArticleCate
2 、结构体中的字段名称首字母必须大写,并和数据库表中的字段一一对应。例如:下面结 构体中的 Id 和数据库中的 id 对应, Username 和数据库中的 username 对应,Age 和数据库中 的 age 对应,Email 和数据库中的 email 对应,AddTime 和数据库中的 add_time 字段对应
3 、默认情况表名是结构体名称的复数形式。如果我们的结构体名称定义成 User ,表示这个 模型默认操作的是 users 表。
4 、我们可以使用结构体中的自定义方法 TableName 改变结构体的默认表名称,如下:
:::

func  (User)  TableName()  string  {
    return  "user"
}

表示把 User 结构体默认操作的表改为 user 表

定义 **user **模型:

package  models

type  User  struct  {  //   默认表名是 `users`
    Id                 int
    Username  string
    Age              int
    Email         string
    AddTime    int
}

func  (User)  TableName()  string  {
    return  "user"
}

关于更多模型定义的方法参考:https://gorm.io/zh_CN/docs/conventions.html

gorm.Model
GORM 定义一个 gorm.Model 结构体,其包括字段 ID 、CreatedAt 、UpdatedAt 、DeletedAt
// gorm.Model 的定义

type  Model  struct  {
    ID                  uint                         `gorm:"primaryKey"`
    CreatedAt  time.Time
    UpdatedAt  time.Time
    DeletedAt  gorm.DeletedAt  `gorm:"index"`
}

14.3 、Gin GORM CURD

找到要操作数据库表的控制器,然后引入 models 模块

1 、增加

增加成功后会返回刚才增加的记录

func  (con  UserController)  Add(c   *gin.Context)  {

    user  :=  models.User{
        Username:  "itying.com",
        Age:              18,
        Email:         "itying@qq.com",
        AddTime:    int(time.Now().Unix()),
    }

    result  :=  models.DB.Create(&user)  //  通过数据的指针来创建
    if  result.RowsAffected  >  1  {
        fmt.Print(user.Id)
    }
    fmt.Println(result.RowsAffected)
    fmt.Println(user.Id)
    c.String(http.StatusOK,  "add 成功")
}

更多增加语句:https://gorm.io/zh_CN/docs/create.html

2 、查找

查找全部

func  (con  UserController)  Index(c  *gin.Context)  {
    user  :=  []models.User{}
    models.DB.Find(&user)
    c.JSON(http.StatusOK,  gin.H{
        "success" :  true,
        "result" :     user,
    })
}

指定条件查找

func  (con  UserController)  Index(c  *gin.Context)  {
    user  :=  []models.User{}
    models.DB.Where("username=?",  "王五").Find(&user)
    c.JSON(http.StatusOK,  gin.H{
        "success" :  true,
        "result" :     user,
    })
}

更多查询语句:https://gorm.io/zh_CN/docs/query.html

3 、修改

func  (con  UserController)  Edit(c  *gin.Context)  {

    user  :=  models.User{Id:  7}
    models.DB.Find(&user)
    user.Username  =  "gin  gorm"
    user.Age  =  1
    models.DB.Save(&user)
    c.String(http.StatusOK,  "Edit")
    
}

更多修改的方法参考:https://gorm.io/zh_CN/docs/update.html

4 、删除

func  (con  UserController)  Delete(c  *gin.Context)  {
    user  :=  models.User{Id:  8}
    models.DB.Delete(&user)
    c.String(http.StatusOK,  "Delete")
}

更多删除的方法参考:https://gorm.io/zh_CN/docs/delete.html

5 、批量删除

db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
// DELETE from emails where email LIKE "%jinzhu%";
db.Delete(Email{}, "email LIKE ?", "%jinzhu%")
// DELETE from emails where email LIKE "%jinzhu%";


func  (con  UserController)  DeleteAll(c  *gin.Context)  {
    user  :=  models.User{}
    models.DB.Where("id>9").Delete(&user)
    c.String(http.StatusOK,  "DeleteAll")
}

更多删除的方法参考:https://gorm.io/zh_CN/docs/delete.html

14.4 、Gin GORM 查询语句详解

https://gorm.io/zh_CN/docs/query.html

1 、Where

:::tips

<

>
<=

>=

!=

IS NOT NULL

IS NULL

BETWEEN AND

NOT BETWEEN AND

IN

OR

AND

NOT

LIKE
:::

nav  :=  []models.Nav{}
models.DB.Where("id<3").Find(&nav)
c.JSON(http.StatusOK,  gin.H{
    "success" :  true,
    "result" :     nav,
})

var  n  =  5
nav  :=  []models.Nav{}
models.DB.Where("id>?",  n).Find(&nav)

c.JSON(http.StatusOK,  gin.H{
    "success" :  true,
    "result" :     nav,
})
var  n1  =  3
var  n2  =  9
nav  :=  []models.Nav{}
models.DB.Where("id  >  ?  AND  id  <   ?",   n1,  n2).Find(&nav)
c.JSON(http.StatusOK,  gin.H{
    "success" :  true,
    "result" :     nav,
})
nav  :=  []models.Nav{}
models.DB.Where("id  in  (?)",  []int{3,  5,  6}).Find(&nav)

c.JSON(http.StatusOK,  gin.H{
    "success" :  true,
    "result" :     nav,
})
nav  :=  []models.Nav{}
models.DB.Where("title  like  ?",   "%会%").Find(&nav)

c.JSON(http.StatusOK,  gin.H{
    "success" :  true,
    "result" :     nav,
})
nav  :=  []models.Nav{}
models.DB.Where("id  between  ?  and  ?",  3,  6).Find(&nav)
c.JSON(http.StatusOK,  gin.H{
    "success" :  true,
    "result" :     nav,
})

2 、Or 条件

nav  :=  []models.Nav{}
models.DB.Where("id=?  OR  id=?",  2,  3).Find(&nav)
nav  :=  []models.Nav{}
models.DB.Where("id=?",  2).Or("id=?",  3).Or("id=4").Find(&nav)

3 、选择字段查询

nav  :=  []models.Nav{}
models.DB.Select("id,  title,url").Find(&nav)

4 、排序 Limit 、Offset

nav  :=  []models.Nav{}
models.DB.Where("id>2").Order("id  Asc").Find(&nav)
nav  :=  []models.Nav{}
models.DB.Where("id>2").Order("sort  Desc").Order("id  Asc").Find(&nav)
nav  :=  []models.Nav{}
odels.DB.Where("id>1").Limit(2).Find(&nav)

跳过 2 条查询 2 条

nav  :=  []models.Nav{}
models.DB.Where("id>1").Offset(2).Limit(2).Find(&nav)

5 、获取总数

nav  :=  []models.Nav{}

var  num  int

models.DB.Where("id  >   ?",  2).Find(&nav).Count(&num)

6 、Distinct

从模型中选择不相同的值

nav  :=  []models.Nav{}
models.DB.Distinct("title").Order("id  desc").Find(&nav)
c.JSON(200,  gin.H{
    "       "
    nav  :  nav,
})
SELECT  DISTINCT  `title`   FROM  `nav`  ORDER   BY  id   desc

7 、Scan

type  Result  struct  {
    Name  string
    Age    int
}

var  result  Result
db.Table("users").Select("name",  "age").Where("name  =   ?",  "Antonio").Scan(&result)

//  原生 SQL
db.Raw("SELECT  name,  age  FROM  users  WHERE   name  =   ?",  "Antonio").Scan(&result)


var  result  []models.User
models.DB.Raw("SELECT  *  FROM  user").Scan(&result)
fmt.Println(result)

8 、Join (先了解 后面课程会讲关联查询)

type  result  struct  {
    Name    string
    Email  string
}
db. Model(&User{}).Select("users. name,  emails.email").Joins("left  join  emails   on  emails.user_i d  =   users.id").Scan(&result{})
SELECT  users.name,  emails.email  FROM  `users`   left  join  emails  on  emails.user_id  =  users.i d

14.5 、Gin GORM 查看执行的 sql

func init() {
    dsn :=
    "root:123456@tcp(192.168.0.6:3306)/gin?charset=utf8mb4&parseTime=True&loc=Local"
    DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
        QueryFields: true,
    })
    // DB.Debug()
    if err != nil {
        fmt.Println(err)
    }
}

十五、原生 **SQL **和 **SQL **生成器

更多使用方法参考:

https://gorm.io/zh_CN/docs/sql_builder.html

1 、使用原生 sql 删除 user 表中的一条数据

| result := models.DB.Exec(“delete from user where id=?”, 3)

fmt.Println(result.RowsAffected)

2 、使用原生 sql 修改 user 表中的一条数据

result := models.DB.Exec(“update user set username=? where id=2”, " 哈哈") fmt.Println(result.RowsAffected)

3 、查询 uid=2 的数据

| var result models.User
models.DB.Raw(“SELECT * FROM user WHERE id = ?”, 2).Scan(&result)

fmt.Println(result)

4 、查询 User表中所有的数据

| var result []models.User
models.DB.Raw(“SELECT * FROM user”).Scan(&result)

fmt.Println(result)

5 、统计 user 表的数量

| var count int
row := models.DB.Raw(“SELECT count(1) FROM user”).Row(&count )

row.Scan(&count)
  • 25
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值