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
复制代码
然后下载这三个包:
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")
}
复制代码