03 . Go框架之Gin框架从入门到熟悉(Cookie和Session,数据库操作)
2020-10-31 17:22
1026 查看
Cookie
Cookie是什么
HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否由同一个客户端发出
Cookie就是解决HTTP协议无状态的方案之一,中文是小甜饼的意思
Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该信息处理请求
Cookie由服务器创建,并发送给浏览器,最终由浏览器保存
Cookie的用途
保持用户登录状态
Cookie的缺点
/*不安全,明文增加带宽消耗可以被禁用Cookie有上限*/
Cookie的使用
测试服务器发送cookie给客户端,客户端请求时携带cookie
package mainimport ("fmt""github.com/gin-gonic/gin")func main() {// 1.创建路由// 默认使用了2个中间件Logger(), Recovery()r := gin.Default()// 服务端要给客户端r.GET("cookie", func(c *gin.Context) {// 获取客户端是否携带cookiecookie,err := c.Cookie("key_cookie")if err != nil {cookie = "NotSet"// 给客户端设置cookie// maxAge int, 单位 s// path cookie 所在目录// domain string 域名// secure 是否只能通过https访问// httponly bool 是否允许别人通过js获取自己的cookiec.SetCookie("key_cookie","value_cookie",60,"/","localhost",false,true)}fmt.Printf("cookie的值是: %s\n",cookie)})r.Run()}
模拟实现权限验证中间件
package mainimport ("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() 创建一个新的sessionGetSession() 通过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存到内存中的mapGet(): 取数据,实现延迟加载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 dbimport ("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 modeltype 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 mainimport ("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,})}
相关文章推荐
- Yii框架学习笔记之session与cookie简单操作示例
- 解析PHP的Yii框架中cookie和session功能的相关操作
- golang实战使用gin+xorm搭建go语言web框架restgo详解9 session、日志、鉴权、验证码等
- Android数据库LitePal框架学习笔记(1)---数据库的adb操作以及LitePal使用入门
- 简单的三层框架以及使用dbutils进行数据库操作(入门)
- 简单的三层框架以及使用dbutils进行数据库操作(入门)
- laravel框架入门使用(DB类操作数据库)
- Hibernate入门BLOG [二、封装拿到数据库配置session对象、并且执行操作]
- 简单的三层框架以及使用dbutils进行数据库操作(入门)
- nodejs系列(3)Express框架GET、POST、COOKIE、上传、数据库操作
- Hibernate入门BLOG [二、封装拿到数据库配置session对象、并且执行操作]
- OrmLite框架 ——OrmLite 入门(android数据库操作框架)
- Go Web框架gin的入门教程
- django上课笔记4-复习数据库操作-复习模板-Seccion-详细cookie和session的区别
- python之Django的入门03------form表单和cookie、session
- 【Go语言】Faygo框架下的数据库操作
- 03创建数据库和表以及测试数据库的操作(单元测试框架)
- 解析PHP的Yii框架中cookie和session功能的相关操作
- Yii框架操作cookie与session的方法实例详解
- 简单的三层框架以及使用dbutils进行数据库操作(入门)