今天我主要想向大家介绍一下自己在学习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...