编写基于 Go 语言的 Web 应用程序,使用 Gin 框架和 GORM 库来创建一个简单的待办事项管理应用,让用户能够方便地添加、查看、编辑和删除待办事项。以下是这个项目的扩展描述:
待办事项管理应用
待办事项管理应用是一个基于 Web 的应用程序,旨在帮助用户有效地管理和组织日常任务和活动。该应用程序使用了 Go 语言的 Gin 框架和 GORM 库,结合 MySQL 数据库,为用户提供了一个直观的界面来管理待办事项,使用户能够更好地规划和跟踪自己的任务。
主要功能
- 添加待办事项: 用户可以通过在应用程序界面中输入任务标题,然后点击提交按钮来添加新的待办事项。这些任务将被持久化到数据库中,以便用户在之后访问时进行查看和编辑。
- 查看待办事项列表: 用户可以浏览已添加的所有待办事项。每个待办事项都会显示其标题和状态,以便用户清晰地了解哪些任务已经完成,哪些任务还未完成。
- 查看单个待办事项: 用户可以通过点击列表中的待办事项,进一步查看特定任务的详细信息。这包括任务的标题和状态,以及任何其他相关信息。
- 编辑待办事项: 用户可以编辑已存在的待办事项,修改任务标题或更新任务的完成状态。编辑后的信息会自动保存到数据库中,以确保用户的修改得以保留。
- 删除待办事项: 用户可以选择删除不再需要的待办事项。通过点击删除按钮,用户可以将任务从列表中移除,并且该任务的信息会从数据库中删除。
技术架构
该应用程序使用了以下技术组件:
- Gin 框架: Gin 是一个轻量级的 Web 框架,基于 Go 语言构建。它提供了快速的路由和中间件功能,使开发 Web 应用变得更加简单和高效。
- GORM 库: GORM 是一个优秀的对象关系映射(ORM)库,用于在 Go 语言中管理数据库。它允许开发人员通过代码操作数据库,而无需直接编写 SQL 查询。
- MySQL 数据库: 本项目使用 MySQL 作为数据库引擎。MySQL 是一个广泛使用的开源关系型数据库管理系统,适用于存储和管理各种数据。
打包前端项目
去github上打包前端项目并放置在如下/static目录下
后端编写
导入必要使用的包
import (
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"net/http"
)
数据库连接
- 定义全局变量DB,用于保存数据库连接
var (
DB *gorm.DB
)
- 定义TODO结构体
// Todo Model
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
Status bool `json:"status"`
}
- 定义初始化数据库连接函数initMySQL
// 第一个括号是参数,第二个括号是返回值
func initMySQL() (err error) {
dsn := "root:123456789@(localhost:3306)/db1_ts?charset=utf8mb4&parseTime=True&loc=Local"
DB, err = gorm.Open("mysql", dsn) //注意这里DB是全局变量不用:=
if err != nil {
return
}
return DB.DB().Ping()
}
4.在main函数中调用数据库连接函数,并进行模型的绑定
//连接数据库
err := initMySQL()
if err != nil {
panic(err)
}
//程序退出关闭数据库连接
defer DB.Close()
//模型绑定
DB.AutoMigrate(&Todo{})
导入静态文件和模板文件
r := gin.Default()
//告诉gin框架模板文件引用的静态文件哪里找
r.Static("/static", "static")
//告诉gin框架去哪里找模板文件
r.LoadHTMLGlob("template/*")
r.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", nil)
})
定义路由组并实现后端增删改查的逻辑
//定义路由组
v1Group := r.Group("v1")
{
//待办事项
//增加
v1Group.POST("/todo", func(c *gin.Context) {
//前端页面填写待办事项 点击提交 发送请求给后端
var todo Todo
c.BindJSON(&todo)
//从请求中把数据拿出来,放到数据库中
err = DB.Create(&todo).Error
if err != nil {
//遇到错误返回错误信息
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
//返回成功添加按钮
c.JSON(http.StatusOK, todo)
//c.JSON(http.StatusOK, gin.H{
// "code": 20000,
// "msg": "success",
// "data": todo,
//})
}
})
//查看所有代办事项
v1Group.GET("/todo", func(c *gin.Context) {
//查询todo这个表中所有的数据
var todoList []Todo
err = DB.Find(&todoList).Error
if err != nil {
//遇到错误返回错误信息
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
//返回成功添加按钮
c.JSON(http.StatusOK, todoList)
}
})
//查看某个代办事项
v1Group.GET("/todo/:id", func(c *gin.Context) {
})
//修改某个代办事项
v1Group.PUT("/todo/:id", func(c *gin.Context) {
//查找到该id的数据
id, ok := c.Params.Get("id")
if !ok {
c.JSON(http.StatusOK, gin.H{"error:": "无效的id"})
return
}
var todo Todo
err = DB.Where("id=?", id).First(&todo).Error
if err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
return
}
//编辑该数据
c.BindJSON(&todo)
err = DB.Save(&todo).Error
if err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, todo)
}
})
//删除某个代办事项
v1Group.DELETE("/todo/:id", func(c *gin.Context) {
//查找到该id的数据
id, ok := c.Params.Get("id")
if !ok {
c.JSON(http.StatusOK, gin.H{"error:": "无效的id"})
return
}
//删除该数据
err = DB.Where("id=?", id).Delete(Todo{}).Error
if err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, gin.H{id: "deleted"})
}
})
}