清晰前端的json数据,理清需要是实现的功能点。对于我们这种前端不熟悉的人,可以借助Postman进行后端测试。
下载地址:https://github.com/Q1mi/go_web
查看前端界面:
首先是资源文件来源配置与页面请求
//静态文件资源加载
r.Static("/static", "./static")
//加载资源文件
r.LoadHTMLGlob("templates/*")
r.GET("/index", func(c *gin.Context) {
c.HTML(200, "index.html", nil)
})
需要实现的功能:遇事不决,先写注释,对初学者来说十分重要。
bubble清单:待办事项
1.添加事项
2.更新修改 某个事项
3.查看 显示所有事项
4.删除 某个事项
//添加 事项
v1Group.POST("/todo", func(c *gin.Context) {
//前端页面填写待办事项 点击提交 会发送请求到这里
//1.从请求中把数据拿出来
var todo Todo //声明一个Todo类型的结构体 todo
c.BindJSON(&todo) //将数据从请求中取出BindJSON 数据json格式,存入变量todo
//2.存入数据库 DB.Create()
//err := DB.Create(&todo).Error
//if err != nil {
//
//}
//3.反应具体响应
if err = DB.Create(&todo).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, todo) //数据插入数据库成功 直接返回todo变量
//c.JSON(http.StatusOK, gin.H{
// "code": 2000,
// "msg": "success",
// "data": todo,
//}) //数据插入数据库成功 直接返回todo变量,前端要求返回的格式
}
})
//修改,更新 肯定是某一个ID事项
v1Group.PUT("/todo/:id", func(c *gin.Context) {
id, _ := c.Params.Get("id") //拿到请求路径的id
var todo Todo
//通过id 从数据库 查询到对应的数据
if err = DB.Where("id=?", id).First(&todo).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
}
c.BindJSON(&todo) //BindJSON 将数据从请求中取出 数据json格式,存入变量todo
if err = DB.Save(&todo).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
}
})
//查看所有待办事项,页面显示菜单
v1Group.GET("/todo", func(c *gin.Context) {
//查询todo这个表里面所有数据
var todolist []Todo //声明一个Todo结构体类型的切片 todolost
if err = DB.Find(&todolist).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, todolist)
//c.JSON(http.StatusOK, gin.H{
// "code": 2000,
// "msg": "success",
// "data": todolost,
//})
}
})
//查看某一个代办事项
v1Group.GET("/todo/:id", func(c *gin.Context) {
// 该项目未使用
})
v1Group.DELETE("/todo/:id", func(c *gin.Context) {
//从库里面删除
id, _ := c.Params.Get("id") //拿到请求路径的id
//var todo Todo
//通过id 从数据库 删除对应的数据
if err = DB.Where("id=?", id).Delete(&Todo{}).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, gin.H{
id: "delteted",
})
}
})
1.定义模块
// Model Todo 1、定义模块
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
Status bool `json:"status"`
}
2.创建数据库
bubble:sql CREAT DATABASE bubble
3.连接数据库
// 包装成一个函数 //下载依赖 _ "github.com/jinzhu/gorm/dialects/mysql"
func initMYSQL() (err error) {
dsn := "root:123456@(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
DB, err = gorm.Open("mysql", dsn) //初始化全局变量DB,不能用DB, err := gorm.Open("mysql", dsn)
if err != nil {
return
}
return DB.DB().Ping() //是否ping得通
}
//3.连接数据库
err := initMYSQL()
if err != nil {
panic(err) //连接数据库失败
}
4. 模型绑定,自动创建表 表名字Todos表结构
DB.AutoMigrate(&Todo{})
5.整体全部后端逻辑与请求
package main
import (
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"net/http"
)
// Model Todo 1、定义模块
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
Status bool `json:"status"`
}
// 初始化全局变量DB
var (
DB *gorm.DB
)
// 包装成一个函数 //下载依赖 _ "github.com/jinzhu/gorm/dialects/mysql"
func initMYSQL() (err error) {
dsn := "root:123456@(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
DB, err = gorm.Open("mysql", dsn) //初始化全局变量DB,不能用DB, err := gorm.Open("mysql", dsn)
if err != nil {
return
}
return DB.DB().Ping() //是否ping得通
}
func main() {
r := gin.Default()
//2.创建数据库 bubble:sql CREAT DATABASE bubble
//3.连接数据库
err := initMYSQL()
if err != nil {
panic(err) //连接数据库失败
}
defer DB.Close() //程序退出关闭数据库连
// 模型绑定,自动创建表 表名字Todos表结构
DB.AutoMigrate(&Todo{})
//静态文件资源加载
r.Static("/static", "./static")
//加载资源文件
r.LoadHTMLGlob("templates/*")
r.GET("/index", func(c *gin.Context) {
c.HTML(200, "index.html", nil)
})
//v1
v1Group := r.Group("v1")
{
//待办事项
//添加 事项
v1Group.POST("/todo", func(c *gin.Context) {
//前端页面填写待办事项 点击提交 会发送请求到这里
//1.从请求中把数据拿出来
var todo Todo //声明一个Todo类型的结构体 todo
c.BindJSON(&todo) //将数据从请求中取出BindJSON 数据json格式,存入变量todo
//2.存入数据库 DB.Create()
//err := DB.Create(&todo).Error
//if err != nil {
//
//}
//3.反应具体响应
if err = DB.Create(&todo).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, todo) //数据插入数据库成功 直接返回todo变量
//c.JSON(http.StatusOK, gin.H{
// "code": 2000,
// "msg": "success",
// "data": todo,
//}) //数据插入数据库成功 直接返回todo变量,前端要求返回的格式
}
})
//查看所有待办事项,页面显示菜单
v1Group.GET("/todo", func(c *gin.Context) {
//查询todo这个表里面所有数据
var todolist []Todo //声明一个Todo结构体类型的切片 todolost
if err = DB.Find(&todolist).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, todolist)
//c.JSON(http.StatusOK, gin.H{
// "code": 2000,
// "msg": "success",
// "data": todolost,
//})
}
})
//查看某一个代办事项
v1Group.GET("/todo/:id", func(c *gin.Context) {
// 该项目未使用
})
//修改,更新 肯定是某一个ID事项
v1Group.PUT("/todo/:id", func(c *gin.Context) {
id, _ := c.Params.Get("id") //拿到请求路径的id
var todo Todo
//通过id 从数据库 查询到对应的数据
if err = DB.Where("id=?", id).First(&todo).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
}
c.BindJSON(&todo) //BindJSON 将数据从请求中取出 数据json格式,存入变量todo
if err = DB.Save(&todo).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
}
})
//删除 肯定是某一个ID事项
v1Group.DELETE("/todo/:id", func(c *gin.Context) {
//从库里面删除
id, _ := c.Params.Get("id") //拿到请求路径的id
//var todo Todo
//通过id 从数据库 删除对应的数据
if err = DB.Where("id=?", id).Delete(&Todo{}).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, gin.H{
id: "delteted",
})
}
})
}
r.Run(":8080")
}
1.controller层面里面 不写具体逻辑 只调用具体的逻辑 像logic层
url --> controller --> logic --> model
请求来了 --> 控制器 -->业务逻辑层 复杂 --> 模型层的具体的增删改查**
main 里面的路由请求全部放到controller层。
controller层的函数结构:如下
由于这个清单项目比较简单,可以直接从controller操作dao层的函数处理
1、定义模块
// Model Todo 1、定义模块
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
Status bool `json:"status"`
}
2.具体的数据库操作放置
Todo 的增删改查操作都会放在这里
// CreatATodo 创建todo
func CreatATodo(todo *Todo) (err error) {
if err = dao.DB.Create(&todo).Error; err != nil {
return err
}
return
}
// 查询 全部数据 函数
func Getlisttodo() (todolist []*Todo, err error) {
if err = dao.DB.Find(&todolist).Error; err != nil {
return nil, err
}
return
}
// 通过id 查询到某个数据
func GetAtodo(id string) (todo *Todo, err error) {
//通过id 从数据库 查询到对应的数据
todo = new(Todo)
err = dao.DB.Where("id=?", id).First(&todo).Error
if err != nil {
return nil, err
}
return
}
// 通过id 查询到某个数据后,再更新改数据的
func UpdataAtodo(todo *Todo) (err error) {
err = dao.DB.Save(&todo).Error
return
}
func DeltetAtodo(id string) (err error) {
if err = dao.DB.Where("id=?", id).Delete(&Todo{}).Error; err != nil {
return
}
return
}
数据库连接包装
package dao
import "github.com/jinzhu/gorm"
// 数据库连接
// 初始化全局变量DB
var (
DB *gorm.DB
)
// 包装成一个函数 //下载依赖 _ "github.com/jinzhu/gorm/dialects/mysql"
func InitMYSQL() (err error) {
dsn := "root:123456@(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
DB, err = gorm.Open("mysql", dsn) //初始化全局变量DB,不能用DB, err := gorm.Open("mysql", dsn)
if err != nil {
return
}
return DB.DB().Ping() //是否ping得通
}
func Close() {
DB.Close()
}
bubble小清单项目 前端Vue不是很熟悉,要加强对前端代码的理解。后端框架的操作,遇事不决,先写注释。继续学习进阶Go web 。