小白学习Gin框架以及GORM增删查改 | 青训营

今天我主要想向大家介绍一下自己在学习gin框架以及GORM中的整个详细过程,作为一个Go小白,刚学习时就感觉到东西很多,所以,我把自己学习的过程非常详细的写了出来,希望也能帮助到那些和我一样不知道如何入手的小白,给你们提供一些我学习时的经验和流程。

1 Gin的安装

1.新建一个gin_demo项目文件夹:

2.建一个go.mod文件:终端输入:go mod init go.mod

3.新建一个main.go主函数文件

4.Gin安装

Gin的官方文档地址:gin-gonic.com/zh-cn/docs

安装命令: go get -u github.com/gin-gonic/gin (如果访问该网站过慢或出错,golang 配置代理。_go 代理_lyfGeek的博客-CSDN博客可以解决问题)

2 开发流程

1.访问地址、服务器端口,通过服务器端口去访问地址,而地址可以处理请求(Request、Response)

1.1.导入gin

1.2创建服务

js 复制代码
	ginServer := gin.Default()  

1.3创建端口

js 复制代码
	ginServer.Run(":8082")

1.4通过Server创建get/post请求

js 复制代码
        //创建请求,寻求hello,向浏览器打一声招呼,func返回值(命名函数),它会返回context对象(上下文可以接收的数据)
        ginServer.GET("/hello",func(context *gin.Context){
        	context.JSON(200,gin.H{"msg":"hello,world"})			//JSON(code int,obj any)
        })

总结:创建一个服务------>给它一个端口------>写一段代码来接收请求,这个请求会给后端响应一些数据

代码:

js 复制代码
package main

//导入gin
import(
	"github.com/gin-gonic/gin"
)
func main() {
	//创建一个服务
	ginServer := gin.Default()
	//访问地址
	ginServer.GET("/hello",func(context *gin.Context){
    //创建请求,寻求hello,向浏览器打一声招呼,func返回值(命名函数),它会返回context对象(上下文可以接收的数据)
		context.JSON(200,gin.H{"msg":"hello,world"})			//JSON(code int,obj any)
	})
	//服务器端口
	ginServer.Run(":8082")
}

可以通过打开一个浏览器,然后访问localhost:8082/hello页面前端,可以看到:

该格式为JSON格式。

终端的显示命令为:

我们可以在前方加一些连接的数据库等等。

2.1 添加logo图像

在创建服务时,先导入github.com/thinkerou/favicon 的包,用go get "github.com/thinkerou/favicon"

导入后用ginServer添加一个favicon.ico图像;

从github网上下载一个favicon.ico放在gin_demo文件夹下

加入命令:

js 复制代码
    import "github.com/thinkerou/favicon"

主函数中加入:

js 复制代码
    ginServer.Use(favicon.New("./favicon.ico"))

最终代码及效果:

3 RESTful API

以前的写网站是通过以下命令来实现增删改查:

js 复制代码
    get /user               //查
    post /create_user       //增
    post /update_user       //改
    post /dalete_user       //删

RESTful API

js 复制代码
    get /user               //查
    post /user              //增
    put /user               //改
    dalate /user            //删

Gin框架也是支持RESTful API的开发。

上一步我们做的是GET请求,也可以使用POST、PUT以及DELTE,然后用postman软件进行测试验证。

4 响应一个页面给前端

首先需要写一个前端页面:

在当前新建一个templates文件夹,并在templates下新建一个index.html

内容如下:

js 复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>我的第一个Go Web 页面</title>
    </head>
    <body>
    
        <h1>感谢大家支持</h1>
        
    </body>
    </html>

然后在main.go中先加载该静态页面:

js 复制代码
    ginServer.LoadHTMLGlob("templates/*")

响应页面

js 复制代码
    ginServer.GET("/index",func(context *gin.Context){
        //返回一个页面
        context.HTML(http.StatusOK,"index.html",gin.H{         //HTML(code int,name string,obj any)(状态码,文件名,文件参数)
            "msg":"这是Go后台传递来的数据",
        })            
        //http.StatusOK是html自带的状态码,其实200是一样的
        //gin.H{}是Gin框架里的数据传送方法,是一个map集合,可以传任何key/value
    })

进行完这些以后,让前台来接收这个数据:

在index.html中加入赋值表达式{{.msg}},即可。

然后访问localhost:8082/index页面:

main.go代码

js 复制代码
    package main

    //导入gin
    import(
            "github.com/gin-gonic/gin"
            "github.com/thinkerou/favicon"		//需要导包
            "net/http"
    )
    func main() {
            //创建一个服务
            ginServer := gin.Default()
            ginServer.Use(favicon.New("./favicon.ico"))		//加入logo

            //加载静态页面
            ginServer.LoadHTMLGlob("templates/*")			//页面全局加载,还有一个LoadHTMLFiles()
            //或者ginServer.LoadHTMLFiles("templates/index.html")	比较麻烦
            //响应一个页面给前端
            ginServer.GET("/index",func(context *gin.Context){
                    //context.JSON()			//JSON(code int,obj any)(状态码,文件参数)
                    context.HTML(http.StatusOK,"index.html",gin.H{			//HTML(code int,name string,obj any)(状态码,文件名,文件参数)
                            "msg":"这是Go后台传递来的数据",
                    })					
            })
            //服务器端口
            ginServer.Run(":8082")
    }

在页面中加入需求css和js

先在项目中创建一个static文件夹,再放一个css文件夹,一个js文件夹;css下创建一个css文件:

内容为:

js 复制代码
    body{
        background: aqua;
    }

js下新建一个js文件,内容为:

js 复制代码
    alert(1)

然后在index.html静态页面中< head >中加入:

js 复制代码
    <link rel="stylesheet" href="/static/css/style.css">
    <script src="/static/js/common.js"></script>

来调取写好的js和css。

在main.go主函数文件中加载资源页面,加入代码:

js 复制代码
            //加载资源页面
            ginServer.Static("/static","./static") 		//Static(relativePath,root)		相对路径和绝对路径

最终效果为:

总结:

GO语言可以发送RESTful API,也可以给前端响应页面。

5 获取请求中的参数

传统的?传参:

js 复制代码
    //url?userid=xxx&username=xxx   (传统的问号拼接参数)
    //  /user/info/1/kuangshen      (Request 分格的传参)

Go语言的传参:

js 复制代码
	//接收前端传过来的参数uesrid(在前端必须有写好的useid参数)
	ginServer.GET("/user/info",func(context *gin.Context){
		userid := context.Query("userid")			//在前端获取到的userid参数,赋值命令为userid
		username := context.Query("username")       //在前端获取到的username参数,赋值命名为username
		context.JSON(http.StatusOK,gin.H{				//将获取到的值,返回给前端
			"userid":userid,
			"username":username,
		})			
	})

运行main.go,再访问http://localhost:8082/user/info?userid=12&username=3 结果为:

js 复制代码
	ginServer.GET("/user/info/:userid/:username/", func(context *gin.Context) {
		userid := context.Param("userid")     //在前端获取到的userid参数,赋值命令为userid
		username := context.Param("username") //在前端获取到的username参数,赋值命名为username
		context.JSON(http.StatusOK, gin.H{    //将获取到的值,返回给前端
			"userid":   userid,
			"username": username,
		})
	})

5 前端给后端传递信息

js 复制代码
    ginServer.POST("/json",func(context *gin.Context){
    //request.body
        data,_ := context.GetRawData()         //GetRawData()表示要接受的数据,并且赋值给data (为[]byte数据)
        var m map[string]interface{}          //interface{}表示空接口
        //将[]byte包装为json数据  
        _ = json.Unmarshal(data,&m)           //将前端发送过来的数据丢掉
        context.JSON(http.StatusOK,m)         //后端响应200 OK
    })

最终效果:(记得go run main.go)

6 传递表单数据

在index.html(前端)中写入:

js 复制代码
<form action="/user/add" method="post">
    <p>username:<input type="text" name="username"></p>
    <p>password:<input type="text" name="password"></p>

    <button type="submit" 提交></button>
    
</form>

在main.go(后端)中写入:

js 复制代码
	ginServer.POST("/user/add", func(context *gin.Context) {
		username := context.PostForm("username") //PostForm()为专门处理表单的函数
		password := context.PostForm("password") //获取刚才前端写的password,username
        //可以在这里加入校验密码,名称是否符合规范的判断条件
		context.JSON(http.StatusOK, gin.H{       //后端响应数据
			"msg":      "ok",
			"username": username,
			"password": password,
		})
	})

go run main.go

访问localhost:8082/index

最终效果:

7 响应路由、重定向

js 复制代码
	//路由
	ginServer.GET("/test", func(context *gin.Context) {
		//重定向 状态码为301
		context.Redirect(http.StatusMovedPermanently, "https://www.baidu.com") //Redirect(int,string)表示重定向
		//http.StatusMovedPermanently为重定向的状态码301
	})

访问localhost:8082/test,会直接跳转到www.baidu.com 页面。

8 404页面

main.go

js 复制代码
	//404 NoRoute
	ginServer.NoRoute(func(ctx *gin.Context) {
		ctx.HTML(http.StatusNotFound, "404.html", nil) //转到404.html页面,再返回空
		//http.StatusNotFound为404状态码
	})

templates文件夹下。新建一个404.html

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>404</title>
</head>
<body>
    <h1>我的404页面</h1>
</body>
</html>

go run main.go

随便访问一个错误页面,例如localhost:8082/ladskfjksdjlskadg

结果为:

9 路由组

路由组用来统一管理路由的地方:

js 复制代码
	userGroup := ginServer.Group("/user")       //第一个路由组
	{
		userGroup.GET("/add")        //可以后加func()函数来处理请求
		userGroup.POST("/login")
		userGroup.POST("/logout")
	}
	orderGroup := ginServer.Group("/order")               //第二个路由组
	{
		orderGroup.GET("/add")
		orderGroup.DELETE("/delete")
	} 

10 中间件(拦截器)

首先自定义一个中间件:

必须在func main(){}外自定义func nyHendler()

js 复制代码
func myHandler()(gin.HandlerFunc){          //gin.HandlerFunc表示返回自己的Hendler中间件
	return func(context *gin.Context) {
		//通过自定义的中间件,设置的值,在后续处理只要调用了这个中间件的都可以拿到这里参数set的值
		context.Set("usersesion","userid-1")         //用于全局变量
		context.Next()            //放行可以加入判断,来放行还是阻止
		context.Abort()           //阻止
	}
}
func main(){
    。。。
}

之后可以调用这个中间件来,放行和阻止访问,还可以使用其中的usersesion的值等。

例如:

js 复制代码
	//接收前端传过来的参数uesrid(在前端必须有写好的useid参数)
	ginServer.GET("/user/info", myHandler(),func(context *gin.Context) {
		//取出中间件的值
		usersesion := context.MustGet("usersesion").(string)
		log.Println("===============>",usersesion)

		userid := context.Query("userid")     
		username := context.Query("username") 
		context.JSON(http.StatusOK, gin.H{    
			"userid":   userid,
			"username": username,
		})
	})

最终效果:

ginServer.GET("/user/info", myHandler(),func(context * gin.Context) 中如果不加myHendler(),就会表示对全局使用这个中间件,若加了就表示只对这个调用使用。

11 GORM

G:go语言

O:Object,对象,程序中的对象/实例,例如Go中的结构体实例

R:Relational,关系数据库,例如MySQL

M:Mapping,映射

例子:

js 复制代码
package main

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

type UserInfo struct{
	ID uint
	Name string
	Gender string
	Hobby string
}
func main(){
	u1 := UserInfo{1,"七米","男","篮球"}
	//将u1数据导入数据库
	//SQL语句:insert into userinfo values(1,"七米","男","篮球");
	//ORM语句
	orm.Create(&u1)

}

ORM表示了三个映射关系:

数据表<-->结构体

数据行<-->结构体实例

字段 <-->结构体字段

ORM的优缺点:

优点:

提高开发效率

缺点:

牺牲执行能力

牺牲灵活性

弱化SQL能力

12 GORM安装

终端输入:

js 复制代码
go get -u github.com/jinzhu/gorm

12.1 导入数据库mysql

js 复制代码
import _ "github.com/jinzhu/gorm/dialects/mysql"

12.2 数据库安装和连接

除了在main.go中加以上代码外,还需与mysql数据库连接,MySQL的具体安装过程可以参考:GORM入门指南 | 李文周的博客 (liwenzhou.com) 或者自己在MySQL官网上下载安装。

12.3 数据的增删查改的具体过程

下载好后进入MySQL,首先创建一个数据库:

js 复制代码
    mysql> create database db1;   

MySQL命令不区分大小写,但通常固定不变的格式会采用大写.

进入db1:

js 复制代码
    mysql> use db1;

在main.go中写入:

js 复制代码
package main

import (
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

// UserInfo --> 数据表
type UserInfo struct {    //定义MySQL表中的结构、名称、大小及类型
	ID     uint
	Name   string
	Gender string
	Hobby  string
}

func main() {
	//连接MySQL数据库
	db, err := gorm.Open("mysql", "root:duibuqi.123@(localhost:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local") //打开数据库mysql
	//root(user):用户名,duibuqi.123(password):密码,@(localhost:3306):主机ip和端口号,db1(dbname):数据库名,charset=utf8mb4:编码UTF-8,parseTime:暂停时间,loc:本地时间
	if err != nil {      //如果错误,返回err
		panic(err)
	}
	defer db.Close()     //关闭数据库
        //添加数据行
	u1 := UserInfo{2, "qimi", "男", "蛙泳"}
	db.Create(&u1)
	u2 := UserInfo{3, "2米6", "女", "跳舞"}
	db.Create(&u2)
        
}

运行main.go,之后再进入MySQL中:

浏览数据库:

js 复制代码
    mysql> show databases;

进入数据库:

js 复制代码
    mysql> use db1;

查看表:

js 复制代码
    mysql> show tables;

便可以看到刚才自己新加入的表

查看表中的内容:

js 复制代码
    mysql> select * from user_infos;

查看表结构:

js 复制代码
    mysql> desc user_infos;

查询:

在main.go主函数中写入:

js 复制代码
	var u UserInfo    //新建一个表中变量u
	db.First(&u)       //查询表中的第一条数据保存到u中
  fmt.Printf("u:%#v\n", u)  //输出显示

运行后:

更新:

js 复制代码
    db.Model(&u).Update("hobby", "双色球")

运行后:

删除:

js 复制代码
    db.Delete(&u)

结果为:

好了,今天我就讲这么多,希望能够帮助到你,如果你觉得有帮助,也希望能够给我点点赞~~~

参考学习视频网站:

1. www.bilibili.com/video/BV1Rd...

2. www.bilibili.com/video/BV1gJ...

3. GORM入门指南 | 李文周的博客 (liwenzhou.com)

相关推荐
Find1 个月前
MaxKB 集成langchain + Vue + PostgreSQL 的 本地大模型+本地知识库 构建私有大模型 | MarsCode AI刷题
青训营笔记
理tan王子1 个月前
伴学笔记 AI刷题 14.数组元素之和最小化 | 豆包MarsCode AI刷题
青训营笔记
理tan王子1 个月前
伴学笔记 AI刷题 25.DNA序列编辑距离 | 豆包MarsCode AI刷题
青训营笔记
理tan王子1 个月前
伴学笔记 AI刷题 9.超市里的货物架调整 | 豆包MarsCode AI刷题
青训营笔记
夭要7夜宵1 个月前
分而治之,主题分片Partition | 豆包MarsCode AI刷题
青训营笔记
三六1 个月前
刷题漫漫路(二)| 豆包MarsCode AI刷题
青训营笔记
tabzzz1 个月前
突破Zustand的局限性:与React ContentAPI搭配使用
前端·青训营笔记
Serendipity5651 个月前
Go 语言入门指南——单元测试 | 豆包MarsCode AI刷题;
青训营笔记
wml1 个月前
前端实践-使用React实现简单代办事项列表 | 豆包MarsCode AI刷题
青训营笔记
用户44710308932421 个月前
详解前端框架中的设计模式 | 豆包MarsCode AI刷题
青训营笔记