实现一个Gin 的ORM增删改查自动迁移的例子(16)|Go主题月

ORM

很多后端MVC框架重要的其中一层,M层(model),官方说明是对象关系映射,每个数据库表都有一个对应的模型文件用来与该表交互,使用ORM方法简化了原生sql语句,更加方便使用数据缓存和数据库事务,数据表结构迁移等等,可以节约开发时间,让项目结构条理清晰。

Gin

Gin是一个基于go 的 web 框架,灵活,高性能,轻量简洁等优点,主要是简单就可以更快速的上手。
可以参考下面几个文档:

Gin框架相关文档:Gin的Git地址Gin中文文档
Go相关:地鼠文档

gorm和mysql

Gin使用ORM,需要使用专用的第三方包gorm包,如果用mysql来做对象映射还需要mysql包。首先在随意的文件创建一个名为GinORM的文件夹作为项目文件夹。再执行go mod init GinORM初始化项目(生成go.mod):

go mod init GinORM
复制代码

image.png
然后下载这三个包:

go get  github.com/gin-gonic/gin
复制代码
go get  github.com/jinzhu/gorm
复制代码
go get  github.com/go-sql-driver/mysql
复制代码

在GinORM下新建一个main.go文件复制一个Gin官方例子吧,然后导入这三个包:

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"github.com/go-sql-driver/mysql"
)


func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

复制代码

现在我们直接运行会报错,因为编译器会发现我们导入的包还没有使用。接下来准备连接数据库,首先要准备一个可以使用的mysql数据库,然后写一个结构体(struct)映射表的各个字段,字段数据类型。暂时在main.go里面加一个结构体,在大型项目中可以使用单独文件夹单个文件,测试就这样吧。

type User struct {
	ID   int    `gorm:"primary_key;AUTO_INCREMENT"` //主键自增ID。gorm:里面可以有多种类的标签,type声明列的类型
	Name string `gorm:"size:215"`                   //Size标签代表列大小
	Age  int    `gorm:"type:smallint"`              //int类型,type可以指定
	Mail string `gorm:"type:varchar(256);"`
}

复制代码

写四个路由来实现对这个数据表的增删改查:

	//增
	r.GET("/add", func(c *gin.Context) {
		for i := 0; i < 10; i++ {
			user := &User{Name: "robot_" + strconv.Itoa(i), Age: i, Mail: "qwe_" + strconv.Itoa(i) + "@qq.com"} //注意变量类型
			db.Create(&user)  //指针对象方式插入数据,id为自增主键,不用设置值
		}
		c.JSON(200, gin.H{
			"message": "添加10条数据完成",
		})
	})

	//删
	r.GET("/del", func(c *gin.Context) {
		id, _ := strconv.Atoi(c.Query("id"))  //接受url参数id,转整数,
		delUser := &User{
			ID: id,     //等价于where id = id
		}
		db.Delete(delUser)
		c.JSON(200, gin.H{
			"message": "删除完成",
		})
	})

	//改
	r.GET("/update", func(c *gin.Context) {
		id, _ := strconv.Atoi(c.Query("id"))
		name := c.Query("name")
		test := &User{
			ID: id,
		}
		db.Model(&test).Update("name", name)
		c.JSON(200, gin.H{
			"message": "更新成功",
		})
	})

	//查
	r.GET("/find", func(c *gin.Context) {
		var Result User
		name := c.Query("name")  //接受url参数name
		db.Debug().Where("name = ?", name).Find(&Result)  //在db后加Debug(),控制台会打印原生mysql,使用原因是字符大小写打错了,调了半天。
		c.JSON(200, gin.H{
			"message": Result,
		})
	})

复制代码

使用AutoMigrate()方法来实现数据库表迁移,可以自动增加表中没有的字段和索引,在Gin main.go函数中使用非常方便,不用手动运行迁移了(简陋,哈哈)。

db.AutoMigrate(&User{})
复制代码

总结

Gin 框架的ORM的功能是使用gorm实现,感觉两个相关性并不大,gorm文档也很简单,遇到问题需要自己研究,互联网的资料都很少,Gin使用的感觉跟Python的Flask的感觉差不多,是一个轻量级的框架,框架本身实现的东西并不多,多数功能依赖第三方包,最后献上完整代码,代码已经过测试,功能正常:

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	_ "github.com/go-sql-driver/mysql"
	"strconv"
)

type User struct {
	ID   int    `gorm:"primary_key;AUTO_INCREMENT"` //主键自增ID。gorm:里面可以有多种类的标签。Type声明列的类型
	Name string `gorm:"size:215"`                   //Size标签代表列大小
	Age  int    `gorm:"type:smallint"`              //int类型,type可以指定
	Mail string `gorm:"type:varchar(256);"`
}

func main() {
	r := gin.Default()
	db, err := gorm.Open("mysql", "root:123456@(127.0.0.1:33069)/test?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		panic("连接数据库失败")
	}

	db.AutoMigrate(&User{})
	defer db.Close()

	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "土味挖掘机",
		})
	})

	//增
	r.GET("/add", func(c *gin.Context) {
		for i := 0; i < 10; i++ {
			user := &User{Name: "robot_" + strconv.Itoa(i), Age: i, Mail: "qwe_" + strconv.Itoa(i) + "@qq.com"} //注意变量类型
			db.Create(&user)  //指针对象方式插入数据,id为自增主键,不用设置值
		}
		c.JSON(200, gin.H{
			"message": "添加10条数据完成",
		})
	})

	//删
	r.GET("/del", func(c *gin.Context) {
		id, _ := strconv.Atoi(c.Query("id"))  //接受url参数id,转整数,
		delUser := &User{
			ID: id,     //等价于where id = id
		}
		db.Delete(delUser)
		c.JSON(200, gin.H{
			"message": "删除完成",
		})
	})

	//改
	r.GET("/update", func(c *gin.Context) {
		id, _ := strconv.Atoi(c.Query("id"))
		name := c.Query("name")
		test := &User{
			ID: id,
		}
		db.Model(&test).Update("name", name)
		c.JSON(200, gin.H{
			"message": "更新成功",
		})
	})

	//查
	r.GET("/find", func(c *gin.Context) {
		var Result User
		name := c.Query("name")  //接受url参数name
		db.Debug().Where("name = ?", name).Find(&Result)  //在db后加Debug(),控制台会打印原生mysql,使用原因是字符大小写打错了,调了半天。
		c.JSON(200, gin.H{
			"message": Result,
		})
	})

	r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享