Gin框架笔记

Gin框架笔记

文章目录

  • Gin框架笔记
    • 1. GO标准库之http/template
    • 2. Gin框架介绍及基础使用
    • 3. GORM
    • 4.前后端分离小项目
      • 4.1 项目展示
      • 4.2 项目架构
      • 4.3 code


1. GO标准库之http/template

在一些前后端不分离的Web架构中,我们通常需要在后端将一些数据渲染到HTML文档中,从而实现动态的网页(网页的布局和样式大致一样,但展示的内容并不一样)效果。

我们这里说的模板可以理解为事先定义好的HTML文档文件,模板渲染的作用机制可以简单理解为文本替换操作–使用相应的数据去替换HTML文档中事先准备好的标记。

个人觉得类似于jsp技术,可能功能上没有jsp那么强大。


GO标准库之http/template


2. Gin框架介绍及基础使用


Gin是一个用Go语言编写的web框架。它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍。


Gin框架介绍及使用


3. GORM


gorm是一个使用Go语言编写的ORM框架。它文档齐全,对开发者友好,支持主流数据库。


GORM入门指南

GORM的CRUD指南


4.前后端分离小项目


4.1 项目展示


该项目将实现一个Bubble小清单,通过界面上的按钮,可以实现对待办事项的增删改查。


Gin框架笔记_第1张图片

Gin框架笔记_第2张图片

4.2 项目架构


前端采用的是vue框架,由于还没有学习到,所以不详细分析。后端数据库采用mysql,使用grom框架来间接操作数据库。
其中关于路由的操作使用了REST风格,关于REST风格可以看这个:阮一峰 理解RESTful架构

Gin框架笔记_第3张图片

应该能勉强称之为小型的MVC架构。

  • 首先来看控制器controller层,该层负责所有的业务逻辑,包括:加载首页、完成对数据的增删改查业务,但是该层并不直接对页面进行展示,或者对数据进行修改。每一个业务都对应着与其它层的一次交互。
  • 然后来看models模型层,该层直接对接数据库,负责对数据进行增删改查。models层下面还有一个dao包,负责初始化数据库然后向models层发送一个gorm.DB对象,models层通过该对象就能间接操作数据库。
  • 最后是前端部分,应该对应着view层。在前端和控制器之间还有一个routers包,负责对gin路由的控制,由此来实现前端和controller层的交互。前端和后端以json文件来进行数据交互。

以上分析纯属扯淡,重点看下面的代码。


4.3 code


mysql.go

先来初始化连接数据库。

package dao

import (
	"github.com/jinzhu/gorm"
)

// DB 为了方便初始化一个全局变量
var (
	DB *gorm.DB
)

func InitMysql() (err error)  {
	//连接数据库并返回一个数据库对象
	DB, err = gorm.Open("mysql", "root:123456@(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		return
	}
	return DB.DB().Ping()  //测试数据库的连通性
}

// Close 关闭数据库的连接,在main函数中可以以defer调用
func Close()  {
	_ = DB.Close()
}

todo.go

然后使用dao包中提供的dao.DB对象对数据进行具体的CRUD。

package models

import (
	"gin_littleProject/dao"
)

//Todo Model
type Todo struct {
	ID int `json:"id"`
	Title string `json:"title"`
	Status bool `json:"status"`
}

/*
	Todo 增删改查操作都放在这里
*/

//CreateATodo 创建todo
func CreateATodo(todo *Todo) (err error) {
	err = dao.DB.Create(&todo).Error
	return
}

// GetTodoList 返回数据表
func GetTodoList() (todoList []*Todo, err error) {
	if err = dao.DB.Find(&todoList).Error; err != nil {
		return nil, err
	}
	return
}

// GetTodoById 通过ID查找某条数据并返回
func GetTodoById(id string) (todo *Todo, err error) {
	todo = new(Todo)
	if err = dao.DB.Where("id=?", id).First(todo).Error; err != nil {
		return nil, err
	}
	return
}

// UpdateATodo 更新某一条数据
func UpdateATodo(todo *Todo)(err error)  {
	err = dao.DB.Save(todo).Error
	return
}

// DeleteATodo 根据ID删除某一条数据
func DeleteATodo(id string) (err error)  {
	err = dao.DB.Where("id=?", id).Delete(&Todo{}).Error
	return
}

controller.go

接着使用控制器实现主要的逻辑。

package controller

import (
	"gin_littleProject/models"
	"github.com/gin-gonic/gin"
	"net/http"
)

// IndexHander 回调函数,向客户端返回一个HTML页面
func IndexHander(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", nil)
}

// CreateATodo 回调函数,在服务端数据库创建一个todo
func CreateATodo(c *gin.Context) {
	//1.从请求中把数据拿出来
	var todo models.Todo
	c.BindJSON(&todo)  //把json中的数据拷贝到todo结构体
	//2.存入数据库
	err := models.CreateATodo(&todo)
	//3.向客户端返回响应
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	} else {
		c.JSON(http.StatusOK, todo)
	}
}

// GetToList 回调函数,向客户端发送数据表
func GetToList(c *gin.Context) {
	//查询todo这个表里面的所有数据
	todoList, err := models.GetTodoList()
	//向客户端返回响应
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	} else {
		c.JSON(http.StatusOK, todoList)
	}
}

// UpdateATodo 回调函数,更新服务端数据库的一条数据
func UpdateATodo(c *gin.Context) {
	//根据id获得参数
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error" : "无效的id"})
		return
	}
	todo, err := models.GetTodoById(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}
	//将json中的数据拷贝到todo结构体
	c.BindJSON(&todo)
	//更新
	if err = models.UpdateATodo(todo); err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	} else {
		c.JSON(http.StatusOK, todo)
	}
}

// DeleteATodo 回调函数,删除服务端数据库的一条数据
func DeleteATodo(c *gin.Context) {
	//根据id获得参数
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error" : "无效的id"})
		return
	}
	if err := models.DeleteATodo(id); err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	} else {
		c.JSON(http.StatusOK, gin.H{id:"deleted"})
	}
}

routers.go

接下来实现一些路由操作。

package routers

import (
	"gin_littleProject/controller"
	"github.com/gin-gonic/gin"
)

func SetupRouter() *gin.Engine {
	r := gin.Default()
	//加载静态文件
	r.Static("/static", "static")
	//加载HTML页面
	r.LoadHTMLFiles("templates/index.html")
	r.GET("/index", controller.IndexHander)

	//创建路由组
	v1Group := r.Group("v1")
	{
		//使用REST风格,用HTTP协议中的4个请求方法代表不同的动作。
		//待办事项
		//添加
		v1Group.POST("/todo", controller.CreateATodo)
		//查看所有的待办事项
		v1Group.GET("/todo", controller.GetToList)
		//修改某一个待办事项
		v1Group.PUT("/todo/:id", controller.UpdateATodo)
		//删除某一个待办事项
		v1Group.DELETE("/todo/:id",controller.DeleteATodo)
	}
	//向主函数返回一个*gin.Engine指针
	return r
}

main.go

最后是main函数

package main

import (
	"gin_littleProject/dao"
	"gin_littleProject/models"
	"gin_littleProject/routers"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

func main() {
	//创建数据库
	//CREATE DATABASE BUBBLE
	err := dao.InitMysql()
	if err != nil {
		panic(err)
	}
	//程序退出就关闭数据库连接
	defer dao.Close()
	//模型绑定
	dao.DB.AutoMigrate(&models.Todo{})
	//注册路由
	r := routers.SetupRouter()
	r.Run(":9090")
}

最后不要忘记go mod tidy


所有源码都在七米老师的github上:
https://github.com/Q1mi/bubble

你可能感兴趣的:(go,golang)