GORM 简单介绍

GORM 是 Golang 的一个 orm 框架。简单说,ORM 就是通过实例对象的语法,完成关系型数据库的操作的技术,是”对象-关系映射”(Object/Relational Mapping) 的缩写。使用 ORM框架可以让我们更方便的操作数据库。

GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server

特性

• 全功能 ORM

• 关联 (Has OneHas ManyBelongs ToMany To Many,多态,单表继承)

• Create,SaveUpdateDeleteFind 中钩子方法

• 支持 PreloadJoins 的预加载

• 事务,嵌套事务,Save PointRollback To Saved Point

• Context、预编译模式、DryRun 模式

• 批量插入,FindInBatchesFind/Create with Map,使用 SQL 表达式、Context Valuer

CRUD

• SQL 构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询

• 复合主键,索引,约束

• Auto Migration

• 自定义 Logger

• 灵活的可扩展插件 APIDatabase Resolver(多数据库,读写分离)、Prometheus…

• 每个特性都经过了测试的重重考验

• 开发者友好

GORM 指南 | GORM – The fantastic ORM library for Golang, aims to be developer friendly.https://gorm.io/zh_CN/docs/index.html

1、安装

go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite

使用go.mod管理的话,可以import后在编辑器加载(上述安装步骤可略)

2、Gin 中使用 Gorm 连接数据库

models 下面新建 core.go ,建立数据库链接

这段代码是在使用 Golang 中的 GORM 库连接到 MySQL 数据库,让我来解释一下:

1. `dsn := “用户:密码@tcp(ip:数据库端口)/库名” />

2. `DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})`: 这一行代码使用 GORM 库中的 `Open` 函数来连接到 MySQL 数据库。它使用了之前定义的数据源名称 `dsn`,并且传递了一个空的 `gorm.Config{}`,表示使用默认配置。

在这段代码中,GORM 是一个用于数据库操作的 Go 语言库,而 `mysql.Open(dsn)` 用于指定使用 MySQL 数据库,并且传递了之前定义的数据源名称。

连接成功后,`DB` 将包含一个数据库连接对象,`err` 将包含可能出现的错误信息。

core.go

package models//这个操作是目的连接数据库,以及定义操作的是哪个库内的表import (// 我们使用了go.mod来管理包"fmt""gorm.io/driver/mysql""gorm.io/gorm")// ----如果要全局使用数据库,需要先定义var DB *gorm.DB var err errorfunc init(){// 连接数据库// gin是你要选择的操作的库dsn := "root:Hszp@123@tcp(127.0.0.1:3306)/gin?charset=utf8mb4&parseTime=True&loc=Local"DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})// 上面不用冒号,因为上面已经定义了,直接赋值了if err != nil {fmt.Println(err)}}

3、定义操作数据库的模型

约定 | GORM – The fantastic ORM library for Golang, aims to be developer friendly.https://gorm.io/zh_CN/docs/conventions.html

虽然在 gorm 中可以指定字段的类型以及自动生成数据表,但是在实际的项目开发中,我们是先设计数据库表,然后去实现编码的。

在实际项目中定义数据库模型注意以下几点:

1、结构体的名称必须首字母大写 ,并和数据库表名称对应。例如:表名称为 user 结构体名称定义成 User,表名称为 article_cate 结构体名称定义成 ArticleCate

2、结构体中的字段名称首字母必须大写,并和数据库表中的字段一一对应。例如:下面结构体中的 Id 和数据库中的 id 对应,Username 和数据库中的 username 对应,Age 和数据库中的 age 对应,Email 和数据库中的 email 对应,AddTime 和数据库中的 add_time 字段对应

3、默认情况表名是结构体名称的复数形式。如果我们的结构体名称定义成 User,表示这个模型默认操作的是 users 表。

4、我们可以使用结构体中的自定义方法 TableName 改变结构体的默认表名称,如下:

func (User) TableName() string {return "user"}

表示把 User 结构体默认操作的表改为 user 表

定义 user 模型:

package models// 定义的结构体要和数据库的表名字一致,且里面的字段要和数据库的字段一致,且大写type User struct { //默认情况表名是结构体名称的复数形式;比如这个就是操作的表为usersId intUsername stringAgeintEmailstringAddTimeint}// TableName 表示配置操作数据库的表名称func (user User) TableName() string {return "user"}

我们准备测试的数据库:

4、全部查找以及按照条件查找

我们依旧使用之前的模块隔离的形式,使用之前的useraddcontroller.go控制器,以及adminrouter.go路由

adminrouter.go:

package routersimport ("gindemo04/controllers/admin""gindemo04/middle""github.com/gin-gonic/gin")func AdminRoutersInit(r *gin.Engine) {//middlewares.InitMiddleware中间件adminRouters := r.Group("/admin", middle.InitMiddleware){adminRouters.GET("/", admin.IndexController{}.Index)adminRouters.GET("/user", admin.UserAddController{}.Index)adminRouters.GET("/user/add", admin.UserAddController{}.Add)adminRouters.GET("/user/edit", admin.UserAddController{}.Edit)adminRouters.GET("/user/delete", admin.UserAddController{}.Delete)}}

package adminimport ("fmt""gindemo04/models""net/http""os""path""strconv""github.com/gin-gonic/gin")type UserAddController struct {BaseController}func (con UserAddController) Index(c *gin.Context) {// 1、查询数据库userList := []models.User{}// FIND方法可以获取表内数据,然后赋值给userlist(切片)models.DB.Find(&userList) c.JSON(http.StatusOK, gin.H{"result" : userList,})}

这段代码是使用 Golang 中的 Gin 框架和 GORM 库从数据库中检索用户数据并将其作为 JSON 响应返回。

1. `userList := []models.User{}`: 在这一行中,定义了一个空的 `userList` 切片,用于存储从数据库中检索到的用户数据。

2. `models.DB.Find(&userList)`: 这一行代码使用 GORM 库中的 `Find` 方法从数据库中检索用户数据,并将结果存储到 `userList` 中。`models.DB` 表示之前连接到数据库的 GORM 对象,`.Find` 方法用于执行查询操作,`&userList` 传递了切片的指针,以便查询结果可以被存储到切片中。

3. `c.JSON(http.StatusOK, gin.H{“result” : userList})`: 最后一行代码使用 Gin 框架中的 `c.JSON` 方法将查询结果作为 JSON 格式的响应返回。`http.StatusOK` 表示 HTTP 状态码为 200,`gin.H{“result” : userList}` 创建了一个包含查询结果的 JSON 对象,其中键为 “result”,值为查询到的用户列表。

从数据库中检索用户数据,将其作为 JSON 格式的响应返回给客户端。

按照条件查找

查找年龄大于10的

package adminimport ("fmt""gindemo04/models""net/http""os""path""strconv""github.com/gin-gonic/gin")type UserAddController struct {BaseController}func (con UserAddController) Index(c *gin.Context) {// 2、按照条件进行查找(age>10)userList := []models.User{}models.DB.Where("age > " />

1. `userList := []models.User{}`: 在这一行中,定义了一个空的 `userList` 切片,用于存储从数据库中检索到的用户数据。

2. `models.DB.Where("age > ?",10).Find(&userList)`: 这一行代码使用 GORM 库中的 `Where` 方法指定了筛选条件,即年龄大于 10,然后使用 `Find` 方法从数据库中检索符合条件的用户数据,并将结果存储到 `userList` 中。`models.DB` 表示之前连接到数据库的 GORM 对象,`.Where("age > ?",10)` 指定了筛选条件,`Find` 方法用于执行查询操作,`&userList` 传递了切片的指针,以便查询结果可以被存储到切片中。

3. `c.JSON(http.StatusOK, gin.H{"result" : userList})`: 最后一行代码使用 Gin 框架中的 `c.JSON` 方法将查询结果作为 JSON 格式的响应返回。`http.StatusOK` 表示 HTTP 状态码为 200,`gin.H{"result" : userList}` 创建了一个包含查询结果的 JSON 对象,其中键为 "result",值为查询到的用户列表。

5、添加数据操作

实例化按照结构体内的数据

package adminimport ("fmt""gindemo04/models""net/http""os""path""strconv""github.com/gin-gonic/gin")type UserAddController struct {BaseController}func (con UserAddController) Add(c *gin.Context) {// c.HTML(http.StatusOK, "admin/useradd.html", gin.H{})// //3、增加数据user := models.User{Id: 7,Username: "芭乐",Age: 19,Email: "12213@qq.com",AddTime: int(models.GetUnix()),}// 将数据插入到数据库中models.DB.Create(&user)c.JSON(http.StatusOK, gin.H{"result" : "添加成功",})}

6、更新数据(save)

查询 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.https://gorm.io/zh_CN/docs/query.html

package adminimport ("fmt""gindemo04/models""net/http""os""path""strconv""github.com/gin-gonic/gin")type UserAddController struct {BaseController}}func (con UserAddController) Edit(c *gin.Context) {// //6、更新数据//6.1查询id=5的数据user := models.User{Id: 5}models.DB.Find(&user)fmt.Println(user)c.JSON(http.StatusOK, gin.H{"result" : user,})// //6.2更新数据(sava表示保存所有数据)user.Username = "莫比---1"models.DB.Save(&user)c.JSON(http.StatusOK, gin.H{"result" : "修改成功",})}

更新操作的单列形式

package adminimport ("fmt""gindemo04/models""net/http""os""path""strconv""github.com/gin-gonic/gin")type UserAddController struct {BaseController}func (con UserAddController) Edit(c *gin.Context) {user := models.User{}//id=? 这是占位符models.DB.Model(&user).Where("id = " />

7、删除操作

where后面跟的字段要和数据库内字段匹配,而上面的修改操作需要和定义的结构体自动匹配,两个不一样

package adminimport ("fmt""gindemo04/models""net/http""os""path""strconv""github.com/gin-gonic/gin")type UserAddController struct {BaseController}func (con UserAddController) Delete(c *gin.Context) {//8、进行删除操作(where后面跟的字段要和数据库内字段匹配,而上面的修改操作需要和定义的结构体自动匹配,两个不一样)user := models.User{}models.DB.Where("id = " />