Go框架三件套:Gorm的基本操作

news2024/9/21 14:52:26

1.概述

这里的Go框架三件套是指 WebRPCORM框架,具体如下:

Gorm框架

gorm框架是一个已经迭代了10+年的功能强大的ORM框架,在字节内部被广泛使用并且拥有非常丰富的开源扩展。

Kitex框架

Kitex是字节内部的Golang微服务RPC框架,具有高性能、强可扩展的主要特点,支持多协议且拥有丰富的开源扩展。

Hertz框架

Hertz是字节内部的HTTP框架,参考了其他开源框架的优势,结合字节跳动内部的需求,具有高易用性、高性能、高扩展性等特点。


2.Gorm

什么是ORM?

ORM(Object Relational Mapping)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。简单理解为一种框架的格式。

2.1 准备工作

image-20230125142805421

  • 开源地址
  • 官方文档

下载gorm

根据官方文档提供的方法,我们可以直接使用go get命令来获取gorm依赖。

go get -u gorm.io/gorm

image-20230125144018311


2.2 数据库连接

除了自定义开发驱动外,目前GORM官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server

确定你需要使用的数据库类型之后,需要使用下面的命令安装对应的驱动依赖,下面以安装MySQL驱动为例,如果使用其他驱动依赖,只需要替换命令中driver后面的内容即可。

go get -u gorm.io/driver/mysql
func main() {
	// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
	dsn := "username:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println("数据库连接异常", err)
	}
	fmt.Printf("db:%v", db)
}

更多相关内容参考


2.3 基本使用

2.3.1 创建数据

介绍GORM的增删改查等基本操作。

  • 连接数据库以及初始化数据模型

可以通过使用default标签为字段设定默认值。

// User Article Product 定义go model
type User struct {
	Id         int    `gorm:"primaryKey"`
	UserName   string `gorm:"default:八尺妖剑"`
	Email      string `gorm:"ilikexff@gmail.com"`
	CreateTime time.Time
}

// 为model定义表名

func (u User) TableName() string {
	return "t_user"
}
  • 创建数据Create()

直接构建插入对象。

func main() {
    db, err := gorm.Open(
        mysql.Open("root:123456@tcp(127.0.0.1:3306)/gotest?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{})
    if err != nil {
        panic("数据库连接错误!")
    }
    //创建数据
    db.Create(&User{Id: 1, UserName: "李四", Email: "2217021563@qq.com", CreateTime: time.Now()})
    fmt.Printf("数据创建成功:%v", db)
	fmt.Printf("返回插入数据的主键:%v\n", user.Id)
	fmt.Printf("返回Error:%v\n", res.Error)
	fmt.Printf("返回插入记录的条数:%v\n", res.RowsAffected)
}

使用 指定字段创建记录。

res := db.Select("Id", "UserName", "CreateTime").Create(&user)
res := db.Create(&user)
fmt.Printf("返回插入数据的主键:%v\n", user.Id)
fmt.Printf("返回Error:%v\n", res.Error)
fmt.Printf("返回插入记录的条数:%v\n", res.RowsAffected)

创建一个记录且一同忽略传递给略去的字段值:人话就是除了传递过去的字段不需要创建之外,其他字段都要创建。

res := db.Omit("Email", "UserName").Create(&user)
fmt.Printf("返回插入数据的主键:%v\n", user.Id)
fmt.Printf("返回Error:%v\n", res.Error)
fmt.Printf("返回插入记录的条数:%v\n", res.RowsAffected)

使用分片批量创建数据。

var users = []User{
    {UserName: "汪淼", Email: "213213232@qq.com", CreateTime: time.Now()}, {UserName: "杨冬", Email: "213213232@qq.com", CreateTime: time.Now()}, {UserName: "叶文洁", Email: "213213232@qq.com", CreateTime: time.Now()}}
db.Create(&users)
for _, user := range users {
    fmt.Printf("批量创建之后的ID:%v\n", user.Id)
}

使用Map结构创建数据,这种方式创建记录时,association不会被调用且主键也不会自动填充。

// 根据Map结构创建数据-1
db.Model(&User{}).Create(map[string]interface{}{
    "UserName": "史强",
    "Email":    "32323442@qq.com",
})
//根据Map结构创建数据-2
db.Model(&User{}).Create([]map[string]interface{}{
    {"UserName": "梅艳芳", "Email": "323232@qq.com"},
    {"UserName": "张国荣", "Email": "43223235@qq.com"},
})

冲突处理,以遇到冲突时不处理冲突创建数据为例:

//冲突处理:不处理任何冲突创建数据
us := &User{UserName: "小二", Email: "3232322@qq.com"}
db.Clauses(clause.OnConflict{DoNothing: true}).Create(&us)

关于更多创建数据的内容可参考


2.3.2 查询数据

根据主键检索。First()方法

var user User
fmt.Println("-------------------------------下面开始查询-----------------------------------------")
res := db.First(&user, 10)
//上面的语句等同于下面的语句
//db.First(&user,"10")
fmt.Printf("返回插入数据的主键:%v\n", user.Id)
fmt.Printf("返回Error:%v\n", res.Error)
fmt.Printf("返回插入记录的条数:%v\n", res.RowsAffected)

根据主键检索,使用Find()方法。

res := db.Find(&users, []int{1, 2, 3})
fmt.Printf("返回插入数据的主键:%v\n", user.Id)
fmt.Printf("返回Error:%v\n", res.Error)
fmt.Printf("返回查询记录的条数:%v\n", res.RowsAffected)

检索单个对象,GORM 提供了 FirstTakeLast 方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1 条件,且没有找到记录时,它会返回 ErrRecordNotFound 错误。

//获取第一条记录,按主键升序
db.First(&user)
//获取第一条记录,没有指定排序字段
db.Take(&user)
//获取最后一条记录(按主键降序)
db.Last(&user)

查询全部对象。

result := db.Find(&users)

条件查询,String条件。

//条件查询-根据条件获取一条记录
//SELECT * FROM users HWERE name = '李四' ORDER BY id LIMIT 1;
res := db.Where("user_name=?", "李四").First(&user)
PrintfRes(res)

//SELECT * FROM users HWERE name<> '王五'
res1 := db.Where("user_name<> ?", "王五").Find(&users)
PrintfRes(res1)

//IN
//SELECT * FROM users WHERE user_name IN('李四','李四2')
res2 := db.Where("user_name IN ?", []string{"李四", "李四2"}).Find(&users)
PrintfRes(res2)

//LIKE
//SELECT * FROM users WHERE user_name LIKE '%李%'
res3 := db.Where("user_name LIKE?", "%李%").Find(&users)
PrintfRes(res3)

//AND
//SELECT * FROM t_user WHERE user_name = '李四' AND id >=1
res4 := db.Where("user_name=? AND id >= ?", "李四", 1).Find(&users)
PrintfRes(res4)
}

条件查询,Struct & Map 条件。

//Struct
//SELECT * FROM user WHERE user_name = ”李四“ AND email = "2217021563@qq.com" ORDER BY id LIMIT 1;
res6 := db.Where(&User{UserName: "李四", Email: "2217021563@qq.com"}).First(&user)
PrintfRes(res6)

//Map
//SELECT * FROM user WHERE user_name = "李四" AND email = "2217021563@qq.com"
res7 := db.Where(map[string]interface{}{"user_name": "李四", "email": "2217021563@qq.com"}).Find(&users)
PrintfRes(res7)

更多关于查询的内容可参考


2.3.3 更新数据

Save()方法,保存所有的字段,即使字段是零值。

db.First(&user)
user.UserName = "字节"
user.Email = "11111111@qq.com"
res := db.Save(&user)
PrintfRes(res)

条件更新,使用条件更新单个列。

//2.条件更新
UPDATE user SET user_name = '跳动'
res1 := db.Model(&User{}).Where("active = ?", 1).Update("user_name", "跳动")
PrintfRes(res1)

//使用默认主键ID更新
res3 := db.Model(&user).Update("user_name", "hello")
PrintfRes(res3)

//根据条件和model的值进行更新
//UPDATE users SET user_name = "yes", WHERE id = 1 AND active = 1
res4 := db.Model(&user).Where("active", 1).Update("user_name", "yes")
PrintfRes(res4)

多列更新,Updates 方法支持 structmap[string]interface{} 参数。当使用 struct 更新时,默认情况下,GORM 只会更新非零值的字段。

//根据 struct更新属性,只会更新非零字段
res := db.Model(&user).Updates(User{UserName: "张国荣", Email: "00000000@qq.com", Active: 1})
PrintfRes(res)

//根据map更新数据
res2 := db.Model(&user).Updates(map[string]interface{}{"user_name": "哥哥", "email": "2222222@qq.com", "active": 0})
PrintfRes(res2)

更新和排除指定字段

//更新指定字段
db.Model(&user).Select("user_name").Updates(map[string] interface{}{"user_name":"利好","email:":"9999999999@qq.com"})

//排除指定字段
db.Model(&user).Omit("user_name").Updates(map[string] interface{}{"user_name":"李彦宏","email":"4444444444@qq.com"})

更多关于数据更新的内容可参考


2.3.4 删除数据

根据主键删除。GORM 允许通过主键(可以是复合主键)和内联条件来删除对象,它可以使用数字(如以下例子。也可以使用字符串——译者注)。查看 查询-内联条件(Query Inline Conditions) 了解详情。

//根据主键删除,ID可以时strin 	db.Delete(&User{},"10")
db.Delete(&User{}, 14)
//根据多个ID删除数据
db.Delete(&user, []int{5, 6, 7})

删除一条记录,删除一条记录时,删除对象需要指定主键,否则会触发 批量 Delete

user.Id = 4
//删除一条记录(ID==2)
db.Delete(&user)
//带额外条件的删除
db.Where("user_name = ?", "Tom").Delete(&user)

批量删除,如果指定不包括主属性,那么GORM会执行批量删除,它将删除所有匹配的记录。

//批量删除
db.Where("email LIKE ?", "%213213%").Delete(&user)
//db.Delete(&User{},"email LIKE ?" ,"%213213%")

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDEA不能创建新项目和新模块

问题&#xff1a; IDEA不管是创建新项目还是新模块都创建不成功&#xff0c;会报如下图错误 解决方案&#xff1a; 在电脑设置里搜索 “防火墙和网络保护” &#xff0c;打开如下图所示 找到你所安装的IDEA&#xff0c;更改设置&#xff0c;选中IDEA 最后&#xff0c;确定&am…

行为驱动开源免费接口测试框架:karate

什么是行为驱动测试&#xff1a; 行为驱动测试&#xff08;Behavior-Driven Testing&#xff0c;简称 BDT&#xff09;是一种测试方法&#xff0c;旨在通过描述系统行为和功能来编写测试用例。BDT的重点是从用户的角度出发&#xff0c;描述系统应该如何行为&#xff0c;而不是专…

机器学习笔记 KAN网络架构简述(Kolmogorov-Arnold Networks)

一、简述 在最近的研究中,出现了号称传统多层感知器 (MLP) 的突破性替代方案,重塑了人工神经网络 (ANN) 的格局。这种创新架构被称为柯尔莫哥洛夫-阿诺德网络 (KAN),它提出了一种受柯尔莫哥洛夫-阿诺德表示定理启发的函数逼近的方法。 与 MLP 不同,MLP 依赖于各个节…

嗨动PDF编辑器怎么对pdf修改?分享修改步骤

嗨动PDF编辑器怎么对pdf修改&#xff1f;PDF&#xff08;Portable Document Format&#xff09;格式因其跨平台、不易修改的特性&#xff0c;在日常工作和学习中得到了广泛的应用。然而&#xff0c;当需要对PDF文件进行修改时&#xff0c;许多人可能会感到困扰。此时&#xff0…

付费解锁隐藏动力和续航,订阅制又被特斯拉玩出花了

我们知道&#xff0c;「订阅制」早已成互联网领域各路大厂玩烂的操作。 上到程序订阅付费使用&#xff08;例如 Offics、Adobe&#xff09;&#xff0c;下到各类功能服务订阅&#xff08;如影视会员、网盘会员等&#xff09;。 甚至于某东、某宝等网购平台也整出了 VIP 订阅服…

2024五月母亲节嘉年华活动方案

2024以花之名 致谢母亲簪花趣味亲子五月母亲节嘉年华活动方案-43P 活动策划信息&#xff1a; 方案页码&#xff1a;43页 文件格式&#xff1a;PPT 方案简介&#xff1a; 岁月温柔治愈 母爱闪闪发光 一年一度的PY圈孝子孝女大赛即将到来 本次母亲节&#xff0c;“以花之名…

三分钟快速上手SpringSecurity框架

导入依赖框架 web 框架(spring-boot-starter-web) <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> springSecurity 框架(spring-boot-starter-security) <de…

MySQL基础使用指南

难度就是价值所在。大家好&#xff0c;今天给大家分享一下关于MySQL的基础使用&#xff0c;MySQL 是一个流行的关系型数据库管理系统&#xff0c;被广泛应用于各种类型的应用程序开发中。本文中将介绍 MySQL 的基础使用方法&#xff0c;包括创建数据库、创建表格以及进行增删改…

景源畅信数字:做抖音切片的方法分享?

一提起抖音切片&#xff0c;很多人可能会想到那些让人眼前一亮的短视频。它们通常短小精悍&#xff0c;内容丰富多彩&#xff0c;能够迅速吸引观众的注意力。但是&#xff0c;如何制作出这样的切片视频呢?这就是我们今天要探讨的问题。 一、选材与剪辑 制作抖音切片&#xff0…

判断上三角矩阵 分数 15

题目展示&#xff1a; 代码展示&#xff1a; 点这里&#xff0c;输入题目名称即可检索更多题目答案 ​#include<stdio.h>int main() {//T-tint t 0;scanf("%d",&t);while(t--)//循环t次&#xff0c;处理t个矩阵{int n 0;scanf("%d",&n);…

自学VBA 设置单元格文字格式 笔记

一.设定对应单元格对应需要显示的格式 Cells(1, 1).Font.Size 18 字体大小 Cells(1, 2).Font.Color RGB(255, 0, 0) 字体颜色 Cells(1, 3).Font.Name "黑体" 字体类型 Cells(1, 4).Font.Italic True 字体斜体 Cells(1, 5).Font.FontStyle "BOLD"…

创新指南 | 企业AI战略 实施方案探讨(上):如何构建基于AI的新商业模型和业务场景

2023年以ChatGPT为代表的生成式AI推出以来&#xff0c;从投资界到企业界都掀起了一股热潮。那么从企业角度来看&#xff0c;生成式AI到底能为业务带来哪些增量呢&#xff1f;企业如何构建基于AI的商业模式并进行落地实施呢&#xff1f; 企业AI战略 实施方案探讨分为上下两篇&am…

开发常用的实体属性转化API,copyProperties方法的用途,需要注意的点。

目录 1. 摘要 2. 传统 set 方法转化属性 3. cn.hutool.core.bean.BeanUtil 包下 copyProperties 方法 3.1 转化对象属性多于原始对象属性 3.2 转化对象属性少于原始对象属性 3.3 转化对象属性与原始对象属性存在差 4. org.springframework.beans.BeanUtils 包下 copyPro…

几个排序器的verilog及其资源占用、延时分析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 因为课题需要&#xff0c;调研了几个快速排序方法&#xff0c;并手写或者改进了若干待测试对象&#xff0c;包括记分板型冒泡排序&#xff08;这个是别人的&#xff09…

不相交集合的数据结构

一、不相交集合的操作 不相交集合的数据结构维护了一组不相交动态集的集合 &#xff0c;用集合中的某个成员作为代表标识集合。 集合在没有修改的情况下每次访问代表得到的答案是相同的&#xff0c;此外在其它一些应用中&#xff0c;可能按照规定选择集合的代表&#xff0c;例如…

Java:使用BigDecimal、NumberFormat和DecimalFormat保留小数

一、代码和调试结果 1.1 BigDecimal ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/fa36749de8124266a730817710fdf737.png) 1.2 DecimalFormat 1.3 NumberFormat 二、原代码 BigDecimalUtil.java 代码 package utils;import java.math.BigDecimal; import jav…

NAT技术总结与双向NAT配置案例

NAT的转换方式&#xff1a; 1.静态转换&#xff1a;固定的一对一IP地址映射。 interface GigabitEthernet0/0/1 ip address 122.1.2.24 nat static global 122.1.2.1 inside 192.168.1.1 #在路由器出接口 公网地址 私网地址。 2.动态转换&#xff1a;Basic NAT nat address-gr…

[ROS 系列学习教程] 建模与仿真 - URDF 建模实践

ROS 系列学习教程(总目录) 本文目录 一、机器人结构组成二、新建功能包三、编写launch文件四、创建底盘五、添加轮子六、添加其他部件七、解决部分实体位于地面以下的问题 前文介绍了URDF建模与URDF语法&#xff0c;接下来介绍怎么使用URDF从零构建一个机器人模型并在rviz中显示…

智能防疫电梯模拟控制系统设计-设计说明书

设计摘要&#xff1a; 本设计是基于单片机的智能防疫电梯模拟控制系统&#xff0c;主要实现了多项功能。首先&#xff0c;系统进行无接触测温&#xff0c;如果温度正常则可以启动电梯运行&#xff0c;如果温度异常则电梯会报警提示有乘客体温异常&#xff0c;电梯不会运行。其…

Java——CLASSPATH配置

什么是CLASSPATH&#xff1f; 答&#xff1a; classpath类似于windows中的系统环境变量path。 在windows中&#xff0c;如果要想在DOS命令窗口中执行一个程序。系统会先去当前文件路径下找对应命令的执行程序。如果找不到&#xff0c;就会到系统环境变量path中挨个遍历每一个路…