Gin\Grom实战 | 青训营笔记

98 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天

package main

import (
	"io"
	"log"
	"net/http"
	"os"

	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type Video struct {
	gorm.Model
	Name string
	URL  string
}

func main() {
	// 连接数据库
	dsn := "root:password@tcp(127.0.0.1:3306)/video_stream?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal(err)
	}
	// 自动迁移数据库结构
	db.AutoMigrate(&Video{})

	// 创建 gin 实例
	r := gin.Default()

	// 定义视频流的接口
	r.GET("/stream/:name", func(c *gin.Context) {
		name := c.Param("name")
		var video Video
		if err := db.Where("name = ?", name).First(&video).Error; err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "视频不存在"})
			return
		}

		// 打开视频文件
		file, err := os.Open(video.URL)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "打开视频文件失败"})
			return
		}
		defer file.Close()

		// 设置响应头
		c.Header("Content-Type", "video/mp4")
		c.Header("Content-Disposition", "attachment;filename="+name+".mp4")

		// 将视频流复制到响应体中
		if _, err := io.Copy(c.Writer, file); err != nil {
			log.Println(err)
		}
	})

	// 启动 Web 服务
	r.Run(":8080")
}

定义了一个 Video 结构体,用于表示数据库中的视频。然后连接数据库,并自动迁移数据库结构。

创建一个 gin 实例,并定义了一个 /stream/:name 的接口,用于返回指定名称的视频流。在这个接口中,从数据库中查询到指定名称的视频,并打开对应的视频文件。然后,我们设置响应头,将视频流复制到响应体中,并发送给客户端。

db.AutoMigrate(&Video{})

db.AutoMigrate(&Video{}) 是 GORM 的一个函数调用,用于自动迁移数据库结构,即在数据库中创建表格和字段。 在这个调用中,我们将 &Video{} 作为参数传递给 AutoMigrate 函数。这表示我们希望自动创建与 Video 结构体对应的数据表。如果该表已经存在,AutoMigrate 函数也会检查表格结构是否需要更新,例如添加新的字段。 具体来说,当我们使用 db.AutoMigrate(&Video{}) 时,GORM 会执行以下操作:

  • 检查数据库中是否存在名为 videos 的表格。如果不存在,则创建该表格;
  • 检查 videos 表格中是否存在 id, created_at, updated_atdeleted_at 这些字段。如果.不存在,则创建这些字段;
  • 检查 videos 表格中是否存在 nameurl 字段。如果不存在,则创建这些字段。