【golang-web-gin】
Gin框架
1.Gin网络请求和路由处理
1.1 创建Engine
gin.Default()- 默认使用
logger和recovery中间件- logger 日志
- recovery 如果错误会报错并且返回错误
- 默认使用
gin.New()
// 创建engine的方式1 推荐使用
r1 := gin.Default()
// 创建engine的方式2
r2 := gin.New()
1.2 Engine对象的方法
context.FullPath():获取请求的路径context.DefaultQuery(key, defaultValue string):获取GET请求的参数- key:query的key
- defaultValue :如果获取不到默认值
context.PostForm(key string):获取POST请求的参数- key:form的key
context.Param(key string):获取DELETE请求的参数(/user/:id)- key:url中的参数key
context.Writer.Write([]byte("data")):返回给页面的内容
1.3 request请求处理方式
1.3.1 handle通用处理
-
handle处理
func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...HandlerFunc) IRoutes {- httpMethod:请求方式
- relativePath:请求地址
- HandlerFunc:处理函数
/*
handle处理http请求
*/
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main(){
// 创建一个引擎对象
engine := gin.Default()
// 1.handle处理
// handle处理get请求
// http://127.0.0.1:8000/hello?name=huhao
engine.Handle("GET","/hello", func(context *gin.Context) {
// context.FullPath() 请求接口
fmt.Println(context.FullPath())
// context.DefaultQuery() 获取get请求参数
name := context.DefaultQuery("name","default alex")
fmt.Println(name)
// context.Writer.Write() 返回给页面的内容
context.Writer.Write([]byte("hello"+name))
})
// handle处理post请求
// http://127.0.0.1:8000/hello?name=huhao
engine.Handle("POST","/login", func(context *gin.Context) {
// context.FullPath() 请求接口
fmt.Println(context.FullPath())
// context.DefaultQuery() 获取get请求参数
username := context.PostForm("username")
password := context.PostForm("password")
fmt.Println(username)
fmt.Println(password)
// context.Writer.Write() 返回给页面的内容
if username=="huhao"&&password=="123" {
context.Writer.Write([]byte(username+"登录"))
}else{
context.Writer.Write([]byte(username+"用户名或者密码错误"))
}
})
//运行
engine.Run("127.0.0.1:8000")
}
1.3.2 分类处理请求
-
分类处理
- engine.GET
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {- engine.POST
func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) IRoutes {- engine.DELETE
func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) IRoutes {- engine.PUT
func (group *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc) IRoutes {- relativePath:请求地址
- HandlerFunc:处理函数
/*
分类处理http请求
*/
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main(){
// 创建一个引擎对象
engine := gin.Default()
engine.GET("/hello", func(context *gin.Context) {
// context.FullPath() 请求接口
fmt.Println(context.FullPath())
// context.DefaultQuery() 获取get请求参数
name := context.DefaultQuery("name","default alex")
fmt.Println(name)
// context.Writer.Write() 返回给页面的内容
context.Writer.Write([]byte("hello"+name))
})
engine.POST("/login", func(context *gin.Context) {
// context.FullPath() 请求接口
fmt.Println(context.FullPath())
// context.DefaultQuery() 获取get请求参数
username := context.PostForm("username")
password := context.PostForm("password")
fmt.Println(username)
fmt.Println(password)
// context.Writer.Write() 返回给页面的内容
if username=="huhao"&&password=="123" {
context.Writer.Write([]byte(username+"登录"))
}else{
context.Writer.Write([]byte(username+"用户名或者密码错误"))
}
})
engine.DELETE("/user/:id", func(context *gin.Context) {
// context.FullPath() 请求接口
fmt.Println(context.FullPath())
// context.DefaultQuery() 获取get请求参数
id := context.Param("id")
fmt.Println(id)
// 返回
context.Writer.Write([]byte("id为"+id+"的户名已删除"))
})
//运行
engine.Run("127.0.0.1:8001")
}
1.4 表单实体绑定
1.4.1 GET请求
-
context.ShouldBindQuery(&stu)package main import ( "fmt" "github.com/gin-gonic/gin" "log" ) // 1.创建一个学生的结构体 type Student struct { Name string `form:"name"` Classes string `form:"classes"` } func main(){ r := gin.Default() //http://127.0.0.1:8000/hello?name=alex&classes=软件工程 r.GET("/hello", func(context *gin.Context) { fmt.Println(context.FullPath()) // 2.创建一个结构体的实例 通过 context.ShouldBindQuery(&stu) 的方式去绑定 var stu Student err := context.ShouldBindQuery(&stu) if err!=nil{ log.Fatal(err.Error()) return } fmt.Println(stu.Name) fmt.Println(stu.Classes) context.Writer.Write([]byte("hello,"+stu.Name)) }) r.Run("127.0.0.1:8002") }
1.4.2 POST请求表单
-
context.ShouldBind(®ister)package main import ( "fmt" "github.com/gin-gonic/gin" "log" ) func main(){ // 1.创建一个学生的结构体 type Register struct { UserName string `form:"name"` Phone string `form:"phone"` Password string `form:"password"` } r := gin.Default() //http://127.0.0.1:8000/hello r.POST("/hello", func(context *gin.Context) { fmt.Println(context.FullPath()) // 2.创建一个结构体的实例 通过 context.ShouldBind(&stu) 的方式去绑定 var register Register err := context.ShouldBind(®ister) if err!=nil{ log.Fatal(err.Error()) return } fmt.Println(register.UserName) fmt.Println(register.Phone) fmt.Println(register.Password) context.Writer.Write([]byte("Register,"+register.UserName)) }) r.Run("127.0.0.1:8002") }
1.4.3 POST请求json
-
context.BindJSON(&person)package main import ( "fmt" "github.com/gin-gonic/gin" "log" ) func main(){ // 1.创建一个学生的结构体 type Person struct { //约束了数据类型 Name string `form:"name"` Sex string `form:"sex"` Age string `form:"age"` } r := gin.Default() //http://127.0.0.1:8000/addstudent r.POST("/addstudent", func(context *gin.Context) { fmt.Println(context.FullPath()) // 2.创建一个结构体的实例 通过 context.ShouldBind(&stu) 的方式去绑定 var person Person err := context.BindJSON(&person) if err!=nil{ log.Fatal(err.Error()) return } fmt.Println(person.Name) fmt.Println(person.Sex) fmt.Println(person.Age) context.Writer.Write([]byte("addstudent,"+person.Name)) }) r.Run("127.0.0.1:8003") }
1.5 response应答
1.5.1 切片数组
-
byte[]()func main() { r := gin.Default() // 返回byte数组 r.GET("/byte", func(context *gin.Context) { path := context.FullPath() fmt.Println(path) context.Writer.Write([]byte(path)) }) r.Run("127.0.0.1:8004") }
1.5.2 字符串
-
stringfunc main() { r := gin.Default() // 返回string r.GET("/string", func(context *gin.Context) { path := context.FullPath() fmt.Println(path) context.Writer.WriteString(path) }) r.Run("127.0.0.1:8004") }
1.5.3 json
-
json-mapfunc main() { r := gin.Default() // 返回Json r.GET("/json", func(context *gin.Context) { path := context.FullPath() fmt.Println(path) context.JSON(200, map[string]interface{}{ "code":200, "msg":"ok", "data":"json", }) }) r.Run("127.0.0.1:8004") } -
json-structpackage main import ( "fmt" "github.com/gin-gonic/gin" ) //1.定义一个response结构体 type Response struct { Code int Msg string Data interface{} } func main() { r := gin.Default() // 返回Json--结构体 r.GET("/json_struct", func(context *gin.Context) { path := context.FullPath() fmt.Println(path) //map类型转换为json //2.实例化一个结构体 resp := Response{ Code: 200, Msg: "OK", Data:path, } context.JSON(200,&resp) }) r.Run("127.0.0.1:8005") }1.5.3 HTML
package main import ( "fmt" "github.com/gin-gonic/gin" "net/http" ) func main() { r := gin.Default() //1.指名加载html的目录 //r.LoadHTMLGlob("/gin_webframework/03Response/html/*") r.LoadHTMLGlob(".\\html\\*") r.GET("/html", func(context *gin.Context) { path := context.FullPath() fmt.Println(path) //2.加载html页面 //第一个参数:请求的状态码 //第二个参数:模板路径 //第三个参数:传递的参数 context.HTML(http.StatusOK,"index.html",gin.H{ "fullpath":path, }) }) r.Run("127.0.0.1:8007") }
2.使用路由组分类处理请求
2.1 Group
- 在项目开发中,模块化开发会使用相同的prefix接口前缀要用到group
2.2 封装
- main函数中只写接口
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
//第一个参数:分组的path
user := r.Group("/user")
user.POST("/register", registerHandle)
user.GET("/login", loginHandle)
user.DELETE("/:id", deleteHandle)
r.Run(":8010")
}
func registerHandle(context *gin.Context) {
path := "用户注册" + context.FullPath()
fmt.Println(path)
context.Writer.WriteString(path)
}
func loginHandle(context *gin.Context) {
path := "用户登录" + context.FullPath()
fmt.Println(path)
context.Writer.WriteString(path)
}
func deleteHandle(context *gin.Context) {
path := "删除登录" + context.FullPath()
UserID := context.Param("id")
fmt.Println(path)
context.Writer.WriteString(path + UserID)
}
3.middleware中间件
- 中间件可以处理一些公共的功能
- 权限验证
- 登录认证
- 数据分页
- 耗时统计
- 可以进行
beforerequest和afterrequest - 类似于django-
process_request - beforerequest中间件
- token验证
- 权限
- 节流
- 数据过滤
- 白名单
- afterrequest
- 数据过滤
- 统一相应头
在web应用中一些统一处理的可以用中间件来实现。比如权限管理、登录状态验证、日志的等
3.1 自定义中间件
- 自定义中间件
- func函数
- 返回值HandleFunc
//1.自定义请求方式的中间件
func RequestInfos() gin.HandlerFunc{
return func(context *gin.Context) {
path := context.FullPath()
method := context.Request.Method
fmt.Println("请求路径:"+path)
fmt.Println("请求方式:"+method)
}
}
3.2 使用中间件
- 通过
engine.use()全局使用中间件r.Use(RequestInfos())
func main() {
r := gin.Default()
//2.使用中间件
r.Use(RequestInfos())
r.GET("/login", loginHandle)
r.Run(":8011")
}
func loginHandle(context *gin.Context) {
context.Writer.WriteString("login")
}
- 在具体请求中添加中间件可以局部使用
r.GET("/login",RequestInfos(),loginHandle)
func main() {
r := gin.Default()
//2.使用中间件
// 全局使用
//r.Use(RequestInfos())
// 局部使用
r.GET("/login",RequestInfos(),loginHandle)
r.Run(":8011")
}
func loginHandle(context *gin.Context) {
context.Writer.WriteString("login")
}
3.3 context.Next()
- 相当于beforerequest和afterrequest
//1.自定义请求方式的中间件
func RequestInfos() gin.HandlerFunc{
return func(context *gin.Context) {
path := context.FullPath()
method := context.Request.Method
code := context.Writer.Status()
fmt.Println("请求路径:"+path)
fmt.Println("请求方式:"+method)
context.Next()//程序会往下走 不走下面的
fmt.Println("状态码:",code)
}
}
>>>
请求路径:/login
请求方式:GET
middleware使用
状态码: 200
[GIN] 2021/05/07 - 12:22:13 | 200 | 0s | 127.0.0.1 | GET "/login"
3.4 代码示例
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
/*
自定义中间件
1.func函数
2.返回值HandleFunc
*/
//1.自定义请求方式的中间件
func RequestInfos() gin.HandlerFunc{
return func(context *gin.Context) {
path := context.FullPath()
method := context.Request.Method
code := context.Writer.Status()
fmt.Println("请求路径:"+path)
fmt.Println("请求方式:"+method)
context.Next()//程序会往下走 不走下面的
fmt.Println("状态码:",code)
}
}
func main() {
r := gin.Default()
//2.使用中间件
// 全局使用
//r.Use(RequestInfos())
// 局部使用
r.GET("/login",RequestInfos(),loginHandle)
r.Run(":8011")
}
func loginHandle(context *gin.Context) {
fmt.Println("middleware使用")
context.Writer.WriteString("login")
}
3.4 Gin内置中间件
- BasicAuth 权限管理
- BasicAuthForRealm 认证分组
- Bind 拦截参数绑定
- ......
4.Golang连接mysql
- 创建驱动
- 执行sql
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
// 1.设置驱动
// "root:密码@tcp(ip:port)/数据库名称"
connStr := "root:root@tcp(127.0.0.1:3306)/db01"
db, err := sql.Open("mysql", connStr)
if err != nil {
log.Fatal(err.Error())
return
}
//// 2.创建数据表
//_, err = db.Exec("create table person(id int auto_increment primary key,name varchar(12) not null,age int default 1);")
//if err != nil {
// log.Fatal(err.Error())
// return
//} else {
// fmt.Println("数据表创建成功")
//}
// 3.插入数据
_, err = db.Exec("insert into person(name,age) values(?,?)", "tom", 15)
if err != nil {
log.Fatal(err.Error())
return
} else {
fmt.Println("插入数据成功")
}
// 4.查询数据
rows, err := db.Query("select * from person;")
if err != nil {
log.Fatal(err.Error())
return
} else {
fmt.Println("查询数据")
}
//rows.Next()==true表示有数据
//数据的遍历输出
scan:
if rows.Next(){
person := new(Person)
//从这一行中读
err := rows.Scan(&person.Id,&person.Name,&person.Age)
if err!=nil{
log.Fatal(err.Error())
return
}
fmt.Println(person.Id,person.Name,person.Age)
}
goto scan
}
type Person struct {
Id int
Name string
Age int
}
5.数据绑定
5.1 ShouldBind
- Form
- QueryString
- Json
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
router.GET("/query_bind", QueryBind) //postman:param:
router.POST("/form_bind", FormBind) //postman:body:x-www-form-urlencoded
router.POST("/json_bind", JsonBind) //postman:body:row:json
router.Run()
}
//绑定form和query和json可以使用form
type UserForm struct {
Name string `form:"name"`
Age int `form:"age"`
Addr string `form:"addr"`
}
//绑定json可以使用json
type UserJson struct {
Name string `json:"name"`
Age int `json:"age"`
Addr string `json:"addr"`
}
func FormBind(ctx *gin.Context) {
var user UserForm
err := ctx.ShouldBind(&user)
fmt.Println(err, user.Age, user.Name, user.Addr)
if err != nil {
ctx.String(http.StatusNotFound, "Form绑定失败")
return
}
ctx.String(http.StatusOK, "Form绑定成功")
return
}
func QueryBind(ctx *gin.Context) {
var user UserForm
err := ctx.ShouldBind(&user)
fmt.Println(err, user.Age, user.Name, user.Addr)
if err != nil {
ctx.String(http.StatusNotFound, "Query绑定失败")
return
}
ctx.String(http.StatusOK, "Query绑定成功")
return
}
//使用UserForm或者UserJson这个结构体
func JsonBind(ctx *gin.Context) {
var user UserForm
err := ctx.ShouldBind(&user)
fmt.Println(err, user.Age, user.Name, user.Addr)
if err != nil {
ctx.String(http.StatusNotFound, "json绑定失败")
return
}
ctx.String(http.StatusOK, "json绑定成功")
return
}
5.2 ShouldBindUri
- Uri
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
router.GET("/uri_bind/:name/:age/:addr", UriBind) //url: /query_bind/:name/:age/:addr
router.Run()
}
//绑定uri可以使用uri
type UserUri struct {
Name string `uri:"name"`
Age int `uri:"age"`
Addr string `uri:"addr"`
}
//使用UserUri这个结构体
func UriBind(ctx *gin.Context) {
var user UserUri
err := ctx.ShouldBindUri(&user)
fmt.Println(err, user.Age, user.Name, user.Addr)
if err != nil {
ctx.String(http.StatusNotFound, "uri绑定失败")
return
}
ctx.String(http.StatusOK, "uri绑定成功")
return
}
6.数据验证
binding
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
router.POST("/valid", PostValidData)
router.Run()
}
//绑定form和query和json可以使用form
/*
binding:"required" 不能为空
*/
type Article struct {
Id int `form:"-"`//表示不做验证
Title string `form:"title" binding:"required"`//不能为空
Content string `form:"content" binding:"required"`
Desc string `form:"desc" binding:"required"`
}
func PostValidData(ctx *gin.Context) {
var article Article
ctx.ShouldBind(&article)
fmt.Println(article)
ctx.String(http.StatusOK,"数据验证成功")
return
}
7.路由分发
7.1 简单使用
- 通过
router.Group设置路由组
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
v1 := router.Group("/api/v1")
{
User := v1.Group("/user")
{
User.GET("", UserGet)
User.POST("", UserPost)
User.PUT("", UserPut)
User.DELETE("", UserDelete)
}
}
}
func UserGet(ctx *gin.Context) {
path := ctx.FullPath()
ctx.String(http.StatusOK, path+":UserGet")
}
func UserPost(ctx *gin.Context) {
path := ctx.FullPath()
ctx.String(http.StatusOK, path+":UserPost")
}
func UserPut(ctx *gin.Context) {
path := ctx.FullPath()
ctx.String(http.StatusOK, path+":UserPut")
}
func UserDelete(ctx *gin.Context) {
path := ctx.FullPath()
ctx.String(http.StatusOK, path+":UserDelete")
}
7.2 路由分组
# 目录结构
--root # 根目录
--controller
--user # user模块
--api.go
--router.go
--order # order模块
--api.go
--router.go
--admin # admin模块
--api.go
--router.go
--router # 总路由
--router.go
--static
--template
--utils
--middleware
--main.go # 项目入口
//main.go
package main
import (
router2 "gin_webframework/09urlgroup/router"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router2.Router(router)
router.Run()
}
//router/router.go
package router
import (
Admin "gin_webframework/09urlgroup/admin"
Order "gin_webframework/09urlgroup/order"
User "gin_webframework/09urlgroup/user"
"github.com/gin-gonic/gin"
)
func Router(router *gin.Engine) {
v1 := router.Group("/api/v1")
v2 := router.Group("/api/v2")
{
user := v1.Group("/user")
admin := v1.Group("/admin")
order := v1.Group("/order")
Admin.Router(admin)
User.Router(user)
Order.Router(order)
}
{
user := v2.Group("/user")
admin := v2.Group("/admin")
order := v2.Group("/order")
Admin.Router(admin)
User.Router(user)
Order.Router(order)
}
}
// admin/router.go
package admin
import "github.com/gin-gonic/gin"
func Router(router *gin.RouterGroup){
router.GET("", UserGet)
router.POST("", UserPost)
router.PUT("", UserPut)
router.DELETE("", UserDelete)
}
// admin/api.go
package admin
import (
"github.com/gin-gonic/gin"
"net/http"
)
func UserGet(ctx *gin.Context) {
path := ctx.FullPath()
ctx.String(http.StatusOK, path+":UserGet")
}
func UserPost(ctx *gin.Context) {
path := ctx.FullPath()
ctx.String(http.StatusOK, path+":UserPost")
}
func UserPut(ctx *gin.Context) {
path := ctx.FullPath()
ctx.String(http.StatusOK, path+":UserPut")
}
func UserDelete(ctx *gin.Context) {
path := ctx.FullPath()
ctx.String(http.StatusOK, path+":UserDelete")
}
# console:
[GIN-debug] GET /api/v1/admin --> gin_webframework/09urlgroup/admin.UserGet (3 handlers)
[GIN-debug] POST /api/v1/admin --> gin_webframework/09urlgroup/admin.UserPost (3 handlers)
[GIN-debug] PUT /api/v1/admin --> gin_webframework/09urlgroup/admin.UserPut (3 handlers)
[GIN-debug] DELETE /api/v1/admin --> gin_webframework/09urlgroup/admin.UserDelete (3 handlers)
[GIN-debug] GET /api/v1/user --> gin_webframework/09urlgroup/user.UserGet (3 handlers)
[GIN-debug] POST /api/v1/user --> gin_webframework/09urlgroup/user.UserPost (3 handlers)
[GIN-debug] PUT /api/v1/user --> gin_webframework/09urlgroup/user.UserPut (3 handlers)
[GIN-debug] DELETE /api/v1/user --> gin_webframework/09urlgroup/user.UserDelete (3 handlers)
[GIN-debug] GET /api/v1/order --> gin_webframework/09urlgroup/order.UserGet (3 handlers)
[GIN-debug] POST /api/v1/order --> gin_webframework/09urlgroup/order.UserPost (3 handlers)
[GIN-debug] PUT /api/v1/order --> gin_webframework/09urlgroup/order.UserPut (3 handlers)
[GIN-debug] DELETE /api/v1/order --> gin_webframework/09urlgroup/order.UserDelete (3 handlers)
[GIN-debug] GET /api/v2/admin --> gin_webframework/09urlgroup/admin.UserGet (3 handlers)
[GIN-debug] POST /api/v2/admin --> gin_webframework/09urlgroup/admin.UserPost (3 handlers)
[GIN-debug] PUT /api/v2/admin --> gin_webframework/09urlgroup/admin.UserPut (3 handlers)
[GIN-debug] DELETE /api/v2/admin --> gin_webframework/09urlgroup/admin.UserDelete (3 handlers)
[GIN-debug] GET /api/v2/user --> gin_webframework/09urlgroup/user.UserGet (3 handlers)
[GIN-debug] POST /api/v2/user --> gin_webframework/09urlgroup/user.UserPost (3 handlers)
[GIN-debug] PUT /api/v2/user --> gin_webframework/09urlgroup/user.UserPut (3 handlers)
[GIN-debug] DELETE /api/v2/user --> gin_webframework/09urlgroup/user.UserDelete (3 handlers)
[GIN-debug] GET /api/v2/order --> gin_webframework/09urlgroup/order.UserGet (3 handlers)
[GIN-debug] POST /api/v2/order --> gin_webframework/09urlgroup/order.UserPost (3 handlers)
[GIN-debug] PUT /api/v2/order --> gin_webframework/09urlgroup/order.UserPut (3 handlers)
[GIN-debug] DELETE /api/v2/order --> gin_webframework/09urlgroup/order.UserDelete (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
8.Gorm
8.1 增删改查
- 连接
- 用户名:密码@tcp(ip:port)/数据库名称?charset=utf8&parseTime=True&loc=Local
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
//2.创建一个模型
//字段名称首字母大写
type User struct {
gorm.Model //自动加上id ctime utime dtime
Id int
Name string
Age int
Addr string
}
//使用TableName重写表名称
func (User)TableName()string{
return "test_gorm_table_name"
}
func main() {
//1.创建数据库连接
//连接数据库 用户名:密码@tcp(ip:port)/数据库名称?charset=utf8&parseTime=True&loc=Local
db, err := gorm.Open("mysql", "root:root@tcp(127.0.0.1:3306)/db01?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
//3.创建表 不指定表明模型后面会+s
db.CreateTable(&User{}) //users
//4.指定表名创建表
db.Table("user").CreateTable(&User{}) //user
//5.删除表
db.DropTable("user") //删掉表名称为users的表 删除了user
db.DropTable(&User{}) //按结构体老删除表 删除了users
//6.检查表是否存在
HasUser:=db.HasTable("user")
fmt.Println(HasUser) //true false
HasUsers:=db.HasTable(&User{})
fmt.Println(HasUsers) //true false
//统一给所有表加前缀后缀
gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
return "sys_"+defaultTableName+"_sys"
}
//7.自动迁移数据表
//自动迁移表仅仅是创建表,添加且少列和索引,并且不会改变现有列的类型,保护现有的数据
db.AutoMigrate(&User{}) //可以传多个模型
//8.增加
db.Create(&User{Name: "张三",Age:18,Addr: "北京市朝阳区"})
db.Create(&User{Name: "李四",Age:18,Addr: "北京市海淀区"})
db.Create(&User{Name: "王五",Age:18,Addr: "北京市顺义区"})
//9.查询
//9.1查询第一条
var user User
//db.First(&user,1) //默认根据id
db.First(&user,"name=?","李四")//指定根据name去查询
fmt.Println(user)
////10.修改
//var user User
//db.First(&user,1)
//db.Model(&user).Update("age",100)
//fmt.Println(user)
//
////11.删除
//var user User
//db.First(&user,2) //删除第二条数据
//db.Delete(&user)
defer db.Close() //关闭空闲的连接
}
8.2 对应关系
- 一对一
- 在任意表中加外键
//属于:关系和外键在一起
type UserInfo struct {
Id int
Name string
Age int
Addr string
}
type UserProfile struct {
Id int
Pic string
CPic string
Phone string
UserInfo UserInfo `gorm:"ForeignKey:UId;AssociationForeignKey:Id"` //关联关系
UId int //默认关联字段UserID
}
//包含:关系和外键不在同一方
type UserInfo struct {
Id int
Name string
Age int
Addr string
PId int //关联
}
type UserProfile struct {
Id int
Pic string
CPic string
Phone string
UserInfo UserInfo `gorm:"ForeignKey:PId;AssociationForeignKey:Id"` //关联关系
}
-
一对多
- 在多的里面加外键
-
多对多
- 建立一张关系表
id a_id b_id 1 1 1 2 1 2 3 2 1
9.日志
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"io"
"log"
"net/http"
"os"
)
func main(){
router := gin.Default()
//创建日志文件
file,_ := os.Create("gin.log")
gin.DefaultWriter = io.MultiWriter(file)
router.GET("/hello", func(ctx *gin.Context) {
path := ctx.FullPath()
log.Fatal(path)
fmt.Println(path)
ctx.String(http.StatusOK,path)
return
})
router.Run()
}

浙公网安备 33010602011771号