Gin之GORM 操作数据库(MySQL)

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" : "删除成功",
	})

}

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/239882.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin+Apache HttpClient+代理服务器=高效的eBay图片爬虫

引入 你是否想过用Kotlin来编写爬虫程序?你是否想过用Apache HttpClient来处理HTTP请求和响应?你是否想过用代理服务器来绕过反爬措施?如果你的答案是肯定的,那么本文将为你介绍一种高效的eBay图片爬虫的实现方式,让你…

深入理解 Kafka 集群管理与最佳实践

构建和管理一个稳定、高性能的Kafka集群对于实现可靠的消息传递至关重要。本文将深入研究Kafka集群的各个方面,包括集群搭建、节点配置、分区与副本管理、安全性与监控,为读者提供全面的指导和实例代码。 1. 搭建 Kafka 集群 1.1 Broker 节点 在Kafka…

C++11 【初识】

C11简介 1.在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1),使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。 2.不过由于C03(TC1)主要是对C98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合…

java版Spring Cloud+Spring Boot+Mybatis之隐私计算 FATE - 多分类神经网络算法测试

一、说明 本文分享基于 Fate 使用 横向联邦 神经网络算法 对 多分类 的数据进行 模型训练,并使用该模型对数据进行 多分类预测。 二分类算法:是指待预测的 label 标签的取值只有两种;直白来讲就是每个实例的可能类别只有两种 (0 或者 1)&…

【运维】Kafka高可用: KRaft(不依赖zookeeper)集群搭建

文章目录 一. kafka kraft 集群介绍1. KRaft架构2. Controller 服务器3. Process Roles4. Quorum Voters 二. 集群安装1. 安装1.1. 配置1.2. 格式化 2. 启动测试2.1. 启功节点服务2.2. 测试 本文主要介绍了 kafka raft集群架构: 与旧架构的不同点,有哪些…

ISP去噪(2)_np 噪声模型

#灵感# ISP 中的去噪,都需要依赖一个噪声模型。很多平台上使用采集的raw进行calibration,可以输出这个模型,通常称为 noise profile。 名词解释: Noise profile 似乎可以翻译成“噪声档案”,其含义是某个噪声源&…

昇腾910安装驱动出错,降低Centos7.6的内核版本

零、问题描述: 在安装Atlas800-9000服务器的驱动的时候,可能会出现错误:Dkms install failed, details in : /var/log/ascend_seclog/ascend_install.log 如下所示: [rootlocalhost ~]# ./Ascend-hdk-910-npu-driver_23.0.rc3_l…

数字孪生项目的开发框架

数字孪生的开发框架提供了一套工具和API,使开发者能够创建和管理数字孪生模型。这些框架通常包括虚拟建模、仿真、数据集成和分析等功能。以下是一些常见的数字孪生开发框架,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发…

python matplotlib set_aspect

说明: # 设置轴比例相等,以获得圆柱体视角 ax.set_aspect(equal) 代码案例: import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np# 创建数据 theta np.linspace(0, 2*np.pi, 100) z np.linspace(0, 1, 100) r z**2 …

k8s集群部署及可视化kuboard 部署

目录 一.准备环境 1.准备三台服务器 2.做域名解析[集群] 3.时间同步[集群] 4.关闭防火墙与selinux[集群] 5.配置静态ip[集群] 6.关闭swap分区[集群] 7.注意: 二.docker部署[集群] 2.安装最新版 3.查看Docker版本: 4.启动Docker服务&#xff1…

maui sqlite开发一个商城加购物车的演示(3)

购物车界面及代码 <?xml version"1.0" encoding"utf-8" ?> <ContentPage xmlns"http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x"http://schemas.microsoft.com/winfx/2009/xaml"xmlns:syncfusion"clr-namesp…

基于51单片机的语音识别控制系统

0-演示视频 1-功能说明 &#xff08;1&#xff09;使用DHT11检测温湿度&#xff0c;然后用LCD12864显示&#xff0c;语音播放&#xff0c;使用STC11l08xe控制LD3320做语音识别&#xff0c; &#xff08;2&#xff09;上电时语音提示&#xff1a;欢迎使用声音识别系统&#xf…

微信小程序改变checkbox大小

.weui-cell__hd {transform: scale(0.6,0.6);} <checkbox color"#447189" />

Qt12.12

头文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTime> #include <QTimer> #include <QTimerEvent> #include <QTextToSpeech> //文本转语言类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_…

Dockerfile创建镜像--LNMP+wordpress

实验准备&#xff1a; nginx&#xff1a;172.111.0.10 docker-nginx mysql&#xff1a;172.111.0.20 docker-mysql php&#xff1a;172.111.0.30 docker-php 自定义网段&#xff1a;172.111.0.0/16mkdir nginx mysql php mv nginx-1.22.0.tar.gz wordpress-6.4.2-zh_CN.ta…

Java实现选择排序及其动图演示

选择排序是一种简单直观的排序算法。它的基本思想是每次从未排序的元素中选出最小&#xff08;或最大&#xff09;的元素&#xff0c;然后将其放到已排序的序列的末尾。具体步骤如下&#xff1a; 首先&#xff0c;找到未排序序列中的最小&#xff08;或最大&#xff09;元素&a…

Linux实用操作(超级实用)

Linux实用操作篇-上篇&#xff1a;Linux实用操作-上篇-CSDN博客 Linux实用操作篇-下篇&#xff1a;Linux实用操作篇-下篇-CSDN博客 一、各类小技巧&#xff08;快捷键&#xff09; 1.1 ctrl c 强制停止 Linux某些程序的运行&#xff0c;如果想要强制停止它&#xff0c;可以…

BigDecimald简单使用

为什么要用BigDecimal运算 在计算浮点型数据时,往往会存在数据计算失真问题 例1 2.0 - 1.9 应该等于0.1,用float类型赋值运算得出的结果为0.100000024,有问题 例2 1.8 - 1.9 应该等于 -0.1,用double类型赋值得出的结果为-0.09999999999999987,明显有问题 BigDecimal使用 BigDec…

1.6 实战:Postman请求Get接口-获取用于登录的图形验证码

上一小节我们学习了Postman的布局,对Postman有了一个整体的认知,本小节我们就来实操一下Get接口。 我们打开Postman,点击我们之前创建的请求”获取登录页验证码“。我们在地址栏里填入获取登录页验证码的接口地址。怎么查看这个接口地址呢?我们打开校园二手交易系统,打开…

scala数据类型

scala安装使用教程_一篇搞定&#xff01;-CSDN博客 1.7 Scala数据类型 # Any是所有类型的父类它定义了一些通用的方法如equals、hashCode和toString。Any有两个直接子类&#xff1a;AnyVal和AnyRef。 # AnyVal是所有值类型的父类有9个预定义的非空的值类型分别是&#xff1a;D…