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

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

1 Gin的安装

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

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

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

image.png

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

image.png

1.2创建服务

	ginServer := gin.Default()  

1.3创建端口

	ginServer.Run(":8082")

1.4通过Server创建get/post请求


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

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

代码:

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页面前端,可以看到:

image.png
该格式为JSON格式。

终端的显示命令为:

image.png

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

2.1 添加logo图像

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

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

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

加入命令:

    import "github.com/thinkerou/favicon"

主函数中加入:

    ginServer.Use(favicon.New("./favicon.ico"))

最终代码及效果:

image.pngimage.png

3 RESTful API

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

    get /user               //查

    post /create_user       //增
    post /update_user       //改
    post /dalete_user       //删

RESTful API

    get /user               //查

    post /user              //增
    put /user               //改
    dalate /user            //删

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

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

image.png

image.png

4 响应一个页面给前端

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

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

内容如下:

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


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

    ginServer.LoadHTMLGlob("templates/*")

响应页面

    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}},即可。

image.png

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

image.png

main.go代码

    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文件:

内容为:

    body{
        background: aqua;
    }

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

    alert(1)

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

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

来调取写好的js和css。

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

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

最终效果为:
image.png

image.png

总结:

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

5 获取请求中的参数

传统的?传参:

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

Go语言的传参:

	//接收前端传过来的参数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
结果为:

image.png

	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,
		})
	})

image.png

5 前端给后端传递信息

    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)

image.pngimage.png

6 传递表单数据

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

<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(后端)中写入:

	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

最终效果:

image.png

image.png

7 响应路由、重定向

	//路由
	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

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

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

<!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

结果为:

image.png

9 路由组

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

	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 中间件(拦截器)

首先自定义一个中间件:

image.png

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

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的值等。

例如:

	//接收前端传过来的参数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,
		})
	})

最终效果:

image.png

image.png

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

11 GORM

G:go语言

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

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

M:Mapping,映射

例子:

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表示了三个映射关系:

数据表<–>结构体

数据行<–>结构体实例

字段 <–>结构体字段

image.png

image.png

ORM的优缺点:

优点:

提高开发效率

缺点:

牺牲执行能力

牺牲灵活性

弱化SQL能力

12 GORM安装

终端输入:

go get -u github.com/jinzhu/gorm

12.1 导入数据库mysql

import _ "github.com/jinzhu/gorm/dialects/mysql"

12.2 数据库安装和连接

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

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

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

    mysql> create database db1;   

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

进入db1:

    mysql> use db1;

在main.go中写入:

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中:

浏览数据库:

    mysql> show databases;

image.png

进入数据库:

    mysql> use db1;

image.png

查看表:

    mysql> show tables;

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

image.png

查看表中的内容:

    mysql> select * from user_infos;

image.png

查看表结构:

    mysql> desc user_infos;

image.png查询:

在main.go主函数中写入:

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

运行后:

image.png

更新:

    db.Model(&u).Update("hobby", "双色球")

运行后:

image.png

删除:

    db.Delete(&u)

结果为:

image.png

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

参考学习视频网站:

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

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

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

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYvvcBXa' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片