03 . Go框架之Gin框架从入门到熟悉(Cookie和Session,数据库操作)
Cookie
Cookie是什么
HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否由同一个客户端发出
Cookie就是解决HTTP协议无状态的方案之一,中文是小甜饼的意思
Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该信息处理请求
Cookie由服务器创建,并发送给浏览器,最终由浏览器保存
Cookie的用途
保持用户登录状态
Cookie的缺点
/*
		不安全,明文
		增加带宽消耗
		可以被禁用
		Cookie有上限
*/
Cookie的使用
测试服务器发送cookie给客户端,客户端请求时携带cookie
package main
import (
	"fmt"
	"github.com/gin-gonic/gin"
)
func main() {
	// 1.创建路由
	// 默认使用了2个中间件Logger(), Recovery()
	r := gin.Default()
	// 服务端要给客户端
	r.GET("cookie", func(c *gin.Context) {
		// 获取客户端是否携带cookie
		cookie,err := c.Cookie("key_cookie")
		if err != nil {
			cookie = "NotSet"
			// 给客户端设置cookie
			// maxAge int, 单位 s
			// path cookie  所在目录
			// domain string  域名
			// secure  是否只能通过https访问
			// httponly bool  是否允许别人通过js获取自己的cookie
			c.SetCookie("key_cookie","value_cookie",60,"/","localhost",false,true)
		}
		fmt.Printf("cookie的值是: %s\n",cookie)
	})
	r.Run()
}
模拟实现权限验证中间件
package main
import (
	"github.com/gin-gonic/gin"
	"net/http"
)
func AuthMiddleWare() gin.HandlerFunc {
	return func(c *gin.Context) {
		if cookie, err := c.Cookie("abc"); err == nil {
			if cookie == "123" {
				c.Next()
				return
			}
		}
		// 返回错误
		c.JSON(http.StatusUnauthorized,gin.H{"error":"err"})
		c.Abort()
		return
	}
}
func main() {
	// 1.创建路由
	// 默认使用了2个中间件Logger(), Recovery()
	r := gin.Default()
	r.GET("/login", func(c *gin.Context) {
		c.SetCookie("abc","123",60,"/","localhost",false,true)
		c.String(200,"Login success!")
	})
	r.GET("/home",AuthMiddleWare(), func(c *gin.Context) {
		c.JSON(200,gin.H{"data":"home"})
	})
	r.Run()
}
Session
Session是什么
Session可以弥补Cookie的不足, Session必须依赖于Cookie才能使用, 生成一个SessionID放在Cookie里传到客户端就可以.
Session中间件开发
设计一个通用的Session服务, 支持内存存储和redis存储
Session模块设计
/*
		本质上k-v系统,通过key进行增删改查.
		Session可以存储在内存或者redis(2个版本)
*/
Session接口设计
/*
		Set()
		Get()
		Del()
		Save()  session存储, redis的实现延迟加载
*/
SessionMgr接口设计
/*
		Init()  初始化,加载redis地址
		CreateSession()  创建一个新的session
		GetSession()   通过SessionID获取对应的Session对象
*/
MemorySession设计
/*
		定义MemorySession对象 (字段:  SessionID, 存kv的map,读写锁)
		构造函数,为了获取对象
		Set()
		Get()
		Del()
		Save()
*/
MemorySessionMgr设计
/*
		定义MemorySessionMgr对象(字段: 存放所有session的map, 读写锁)
		构造函数
		Init()
		CreateSession()
		GetSession()
*/
RedisSession设计
/*
		定义RedisSession对象(字段: sessionID,存kv的map, 读写锁, redis连接池, 记录内存中map是否被修改的标记)
		构造函数
		Set(): 将session存到内存中的map
		Get(): 取数据,实现延迟加载
		Del()
		Save():  将session存到redis
*/
RedisSessionMgr设计
/*
		定义RedisSessionMgr对象(字段: redis地址,redis密码, 连接池,读写锁, 大map)
		构造函数
		Init()
		CreateeSession()
		GetSession()
*/
session.go
数据库操作
sql
CREATE TABLE `book` (
  `id` int(50) NOT NULL AUTO_INCREMENT,
  `title` varchar(50) DEFAULT NULL,
  `price` int(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
结构
 tree
.
├── book
├── db
│   └── db.go
├── go.mod
├── go.sum
├── main.go
├── model
│   └── book.go
└── templates
    ├── book_list.html
    └── new_book.html
db
db.go
// 查询单条数据示例
package db
import (
	"database_test1/model"
	"fmt"
	_ "github.com/go-sql-driver/mysql" // init()
	"github.com/jmoiron/sqlx"
)
// Go连接MySQL示例
var db *sqlx.DB // 是一个连接池对象
func InitDB() (err error) {
	// 数据库信息
	// 用户名:密码@tcp(ip:端口)/数据库的名字
	dsn := "test:ZHOUjian.22@tcp(121.36.43.223:3306)/book?charset=utf8"
	// 连接数据库
	db, err = sqlx.Connect("mysql", dsn)
	if err != nil {
		return
	}
	db.SetMaxOpenConns(10) // 设置数据库连接池的最大连接数
	db.SetMaxIdleConns(5)  // 设置最大空闲连接数
	return
}
func QueryAllBook() (bookList []*model.Book,err error)  {
	sqlStr := "select id,title,price from book"
	err = db.Select(&bookList,sqlStr)
	if err != nil {
		fmt.Println("查询失败")
		return
	}
	return
}
func InsertBook(title string,price int64) (err error)  {
	sqlStr := "insert into book(title,price) values(?,?)"
	_, err = db.Exec(sqlStr,title,price)
	if err != nil {
		fmt.Println("插入失败")
		return
	}
	return
}
func DeleteBook(id int64) (err error)  {
	sqlStr := "delete from book where id =?"
	_,err = db.Exec(sqlStr,id)
	if err != nil {
		fmt.Println("删除失败")
		return
	}
	return
}
model
book.go
package model
type Book struct {
	ID string `db:"id"`
	Title string  `db:"title"`
	Price int64 `db:"price"`
}
template
book_list.html
{{ define "book_list.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>书籍列表</title>
</head>
<body>
    <div><a href="/book/new">添加新书</a></div>
    <table border="1">
        <thead>
            <tr>
                <th>ID</th>
                <th>title</th>
                <th>price</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            {{ range .data}}
                <tr>
                    <td>{{ .ID }}</td>
                    <td>{{ .Title }}</td>
                    <td>{{ .Price }}</td>
                    <td><a href="/book/delete?id={{ .ID }}">删除</a></td>
                </tr>
            {{  end }}
        </tbody>
    </table>
</body>
</html>
{{ end }}
new_book.html
{{ define "new_book.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加图书信息</title>
</head>
<body>
    <form action="/book/new" method="POST">
        <div>
            <label>书名:
                <input type="text" name="title">
            </label>
        </div>
        <div>
            <label>价格:
                <input type="number" name="price">
            </label>
        </div>
        <div>
            <input type="submit" value="点我">
        </div>
    </form>
</body>
</html>
{{ end }}
Main.go
package main
import (
	"database_test1/db"
	"github.com/gin-gonic/gin"
	"net/http"
)
func main()  {
	// 初始化数据库
	err := db.InitDB()
	if err != nil {
		panic(err)
	}
	r := gin.Default()
	r.LoadHTMLGlob("./templates/*")
	// 查询所有图书
	r.GET("/book/list",bookListHandler)
	r.Run()
}
func bookListHandler(c *gin.Context)  {
	bookList ,err := db.QueryAllBook()
	if err != nil {
		c.JSON(http.StatusOK,gin.H{
			"code":1,
			"msg":err,
		})
		return
	}
	// 返回数据
	c.HTML(http.StatusOK,"book_list.html",gin.H{
		"code":200,
		"data":bookList,
	})
}
03 . Go框架之Gin框架从入门到熟悉(Cookie和Session,数据库操作)的更多相关文章
- 01 . Go框架之Gin框架从入门到熟悉(路由和上传文件)
		Gin框架简介 Gin是使用Go/Golang语言实现的HTTP Web框架, 接口简洁, 性能极高,截止1.4.0版本,包含测试代码,仅14K, 其中测试代码9K, 也就是说测试源码仅5k左右, 具 ... 
- Go语言基础之20--web编程框架之Gin框架
		一.Gin框架介绍 1.1 简介 A. 基于httprouter开发的web框架. http://github.com/julienschmidt/httprouter B. 提供Martini风格的 ... 
- 02 . Go框架之Gin框架从入门到熟悉(数据解析和绑定,渲染,重定向,同步异步,中间件)
		数据解析和绑定 json数据解析和绑定 package main import ( "github.com/gin-gonic/gin" "net/http" ... 
- Web框架之Gin
		Gin是一个用Go语言编写的web框架.它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍. 如果你是性能和高效的追求者, 你会爱上Gin. ... 
- Gin框架介绍及使用
		Gin是一个用Go语言编写的web框架.它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍. 如果你是性能和高效的追求者, 你会爱上Gin. ... 
- gin框架中间件
		1. Gin框架中间件Gin框架中间件A. Gin框架允许在请求处理过程中,加入用户自己的钩子函数.这个钩子函数就叫中间件B. 因此,可以使用中间件处理一些公共业务逻辑,比如耗时统计,日志打印,登陆校 ... 
- Web框架之Gin介绍及使用
		Gin是一个用Go语言编写的web框架.它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍. 如果你是性能和高效的追求者, 你会爱上Gin. ... 
- Gin框架介绍与使用
		Gin // 初识 Gin框架 //下载(可能会下载不全.缺什么get什么即可) //go get -u -v github.com/gin-gonic/gin package main import ... 
- 前端程序员学习 Golang gin 框架实战笔记之一开始玩 gin
		原文链接 我是一名五六年经验的前端程序员,现在准备学习一下 Golang 的后端框架 gin. 以下是我的学习实战经验,记录下来,供大家参考. https://github.com/gin-gonic ... 
随机推荐
- C++实现职工管理系统(中)
			C++实现职工管理系统(中) 大家好,今天是在博客园的第九天,博主今天给大家带来的是职工管理系统(C++)(中) 这次的随笔记录是实现(上)结语处说的几个功能 目录 C++实现职工管理系统(中) 1. ... 
- Centos-系统内存信息-free
			free 显示系统内存信息,包括物理内存.虚拟内存.共享内存和系统缓存 相关选项 -b 以字节byte为单位显示内存使用情况 -k 以k为单位显示内存使用情况 -m 以MB为单位显示内存使用情况 - ... 
- Java知识系统回顾整理01基础02面向对象02属性
			一.根据实例给出"属性"的定义 一个英雄有姓名,血量,护甲等等状态 这些状态就叫做一个类的属性 二.属性的类型 属性的类型可以是基本类型,比如int整数,float 浮点数 也可以 ... 
- c++中sprintf和sprintf_s的区别
			参考:https://blog.csdn.net/qq_37221466/article/details/81140901 sprintf_s是sprintf的安全版本,指定缓冲区长度来避免sprin ... 
- C语言中最常用的标准库函数
			标准头文件包括: <asset.h> <ctype.h> <errno.h> <float.h> <limits ... 
- vue拼图动画Demo
			这是一个基于vue的Demo,可以实现拼图动画,但是具体的没有写拼图成功的逻辑,鼠标悬停移动.周期刷新 我把它放到的我的博客园界面上了.刷新界面可以看到. 演示地址 :https://liruilon ... 
- CentOS 7 系统的安装
			1.进入安装界面 2.选择"Install CentOS 7" 3.进入欢迎界面,默认语言为"English",点击"Continue" 进 ... 
- 用C写一个简单的推箱子游戏(一)
			我现在在读大二,我们有一门课程叫<操作系统>,课程考查要求我们可以写一段程序或者写Windows.iOS.Mac的发展历程.后面我结合网上的资料参考,就想用自己之前简单学过的C写一关的推箱 ... 
- 基于raft共识搭建的Fabric1.4.4多机网络环境
			1准备工作介绍 1各个主机ip以及节点分配情况 各个主机的节点分配情况 ip地址 orderer0.example.com,peer0.org1.example.com 172.17.3.60 ord ... 
- Oracle体系结构概述与SQL解析剖析
			Oracle服务器 是一个数据库管理系统,它提供了一种全面.开放.集成的方法来管理信息. Oracle服务器由Oracle数据库和Oracle实例组成. oracle数据库软件和Oracle数据库软件 ... 
