Gin之GORM 操作数据库(MySQL)

发布时间:2023年12月17日

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.icon-default.png?t=N7T8https://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:数据库端口)/库名?charset=utf8mb4&parseTime=True&loc=Local"`: 这里定义了一个数据源名称(DSN),包括了数据库的连接信息,用户名、密码、协议(tcp)、地址、端口、数据库名(gin)以及一些连接选项(charset=utf8mb4、parseTime=True、loc=Local)。

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 error

func 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.icon-default.png?t=N7T8https://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 { //默认情况表名是结构体名称的复数形式;比如这个就是操作的表为users
	Id       int
	Username string
	Age      int
	Email    string
	AddTime  int
}

// TableName 表示配置操作数据库的表名称
func (user User) TableName() string {
	return "user"
}

我们准备测试的数据库:

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

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

adminrouter.go:

package routers

import (
	"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 admin

import (
	"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 admin

import (
	"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 > ?",10).Find(&userList)
	c.JSON(http.StatusOK, gin.H{
		"result" : userList,
	})

}

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 admin

import (
	"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.icon-default.png?t=N7T8https://gorm.io/zh_CN/docs/query.html

package admin

import (
	"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 admin

import (
	"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 = ?", 5).Update("username", "莫比")
 	c.JSON(http.StatusOK, gin.H{
			"result" : "修改成功",
	})
}

?

?7、删除操作

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

package admin

import (
	"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 = ?", 5).Delete(&user)
	c.JSON(http.StatusOK, gin.H{
		"result" : "删除成功",
	})

}

?

?

文章来源:https://blog.csdn.net/m0_72264240/article/details/134948202
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。