〇、前言
本文将会写一个前后端分离的的小项目,本文将会只实现后端。
 
一、定义全局变量与模型
本文需要一个数据库,因此将这个数据库定义为全局变量将会非常轻松。
var (
	DB *gorm.DB
)
type Todo struct {
	ID     int    `json:"id"`
	Title  string `json:"title"`
	Status bool   `json:"status"`
}
二、建立数据库
database create bubble;
use bubble;
可以看到,已经创建了 一个名为bubble的mysql数据库:
 
三、连接数据库
在 gorm 框架下,对于 mysql 等多种数据库的使用极其方便:
func initMySQL() (err error) {
	// 连接数据库
	dsn := "root:pwd@tcp(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
	DB, err = gorm.Open("mysql", dsn)
	if err != nil {
		return err
	}
	// 判断是否连通
	return DB.DB().Ping()
}
四、载入前端静态文件
部署一个项目,假设前端可靠,那么就可以放心得写后端了:
// 连接数据库
	err := initMySQL()
	if err != nil {
		panic(err)
	}
	// 模型绑定
	DB.AutoMigrate(&Todo{}) // todos
	defer func(DB *gorm.DB) {
		err := DB.Close()
		if err != nil {
			panic(err)
		}
	}(DB)
	r := gin.Default()
	r.Static("/static", "/Users/***/GoLand/gin_practice/chap18/static")
	r.LoadHTMLGlob("/Users/***/GoLand/gin_practice/chap18/templates/*")
	r.GET("/bubble", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})
五、路由组的实现
我们可以根据前端的各种请求,写一个路由组:
v1Group := r.Group("v1")
	{
		// 待办事项
		v1Group.POST("/todo", func(c *gin.Context) {
			
		})
		// 查看所有的待办事项
		v1Group.GET("/todo", func(c *gin.Context) {
			
		})
		// 查看某一个待办事项
		v1Group.GET("/todo/:id", func(c *gin.Context) {
		})
		// 修改(更新) 某一个事项
		v1Group.PUT("/todo/:id", func(c *gin.Context) {
			
		})
		// 删除
		v1Group.DELETE("/todo/:id", func(c *gin.Context) {
			
		})
	}
六、功能的实现
添加事项:
	v1Group.POST("/todo", func(c *gin.Context) {
			// 前端页面提交待办事项,接受请求
			// 返回响应
			var todo Todo
			c.BindJSON(&todo)
			// 从请求中把数据捞出来,存储到数据库
			if err := DB.Create(&todo).Error; err != nil {
				// 失败时的响应
				c.JSON(http.StatusOK, gin.H{
					"err": err.Error(),
				})
				return
			} else {
				// 成功的响应
				c.JSON(http.StatusOK, todo)
				//c.JSON(http.StatusOK, gin.H{
				//	"code": 2000,
				//	"msg":  "Ok",
				//	"data": todo,
				//})
			}
		})
查询事项:
	v1Group.GET("/todo", func(c *gin.Context) {
			// 查询todo数据库中的数据所有的数据
			var todoList []Todo
			if err = DB.Find(&todoList).Error; err != nil {
				// 如果出错
				c.JSON(http.StatusOK, gin.H{
					"err": err.Error(),
				})
				return
			} else {
				// 如果成功
				c.JSON(http.StatusOK, todoList)
			}
		})
修改事项:
	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
			if err = DB.Where("id=?", id).First(&todo).Error; err != nil {
				// 如果出错
				c.JSON(http.StatusOK, gin.H{
					"err": err.Error(),
				})
				return
			} // 更新
			c.BindJSON(&todo)
			if err = DB.Save(&todo).Error; err != nil {
				c.JSON(http.StatusOK, gin.H{
					"error": err.Error(),
				})
				return
			}
			// 成功
			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
			}
			var todo Todo
			if err = DB.Where("id=?", id).Delete(&todo).Error; err != nil {
				// 如果出错
				c.JSON(http.StatusOK, gin.H{
					"err": err.Error(),
				})
				return
			}
			// 成功
			c.JSON(http.StatusOK, todo)
		})
这样,就完成了整个项目的后端处理。
七、运行起来的样子
点击运行,可以看到一个还算清爽的界面(前端写得好,与我无瓜):

 添加几个事项:
 
 查看一下数据库:

 可以看到,数据库成功地将前端提交的表达做了持久化存储。再标记几个已完成:

 再看看数据库:

 可以看到成功地将 status 标记成了 1。撤销看看:

数据库:
 
 删除看看:

数据库:

 可以看到,后端的功能都正常。
全文完,感谢阅读。











![[MAUI程序设计] 用Handler实现自定义跨平台控件](https://img-blog.csdnimg.cn/0436623e1b9d4b6f817f0045c69a6668.png)







