探索Gorm - Golang流行的数据库ORM框架

news2025/1/21 8:43:49

🏷️个人主页:鼠鼠我捏,要死了捏的主页 

🏷️系列专栏:Golang全栈-专栏

🏷️个人学习笔记,若有缺误,欢迎评论区指正 

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。

前言

我们在之前的专栏中讲解了在Go中如何使用原生的database/sql库完成数据库编程,今天我们继续来了解一下一款在go中常用的数据库ORM框架-Gorm(GORM - The fantastic ORM library for Golang, aims to be developer friendly.)

ORM(Object-Relational Mapping)是一种编程技术,它将对象和关系数据库之间的映射抽象出来,使得开发者可以通过面向对象的方式操作数据库,而不用直接处理SQL语句,相当于在业务逻辑层和数据库层之间一座桥梁。

Gorm是一款用于Golang的ORM框架,它提供了丰富的功能,包括模型定义、数据验证、关联查询等。 Gorm的设计目标是简洁而强大,使得开发者能够更轻松地进行数据库操作


目录

前言

1.安装与配置

安装gorm库

安装mysql驱动

连接url的组成

2.建立连接

自定义mysql配置

自定义gorm配置

调用open对象建立连接,获取连接客户端

扩展:使用AutoMigrate进行表结构同步(根据定义的结构体创建/修改表结构,保证数据结构的一致性,省去手动建表的步骤)

3.基本使用

添加

Create()

Save()

CreateInBatches(records, batchSize)

删除

Delete()

.Unscoped().Delete()

Where().Delete()

修改

db.Save()

db.Model().Update()

db.Updates()

db.UpdateColumn()

db.Where().Update()

查询

db.First()

db.Where().Find()

db.Order()

db.Limit()

db.Offset()

db.Count()

事务

4.其他常用方法

Preload():预加载

目的:减少sql查询次数,避免N+1问题,减少内存开销,适用于复杂关系

基本使用:

Omit():查询中省略指定字段

5.格式化时间字段

总结


1.安装与配置

安装gorm库
go get -u gorm.io/gorm
安装mysql驱动
go get -u gorm.io/driver/mysql
连接url的组成
[DRIVER]://[USER]:[PASS]@[IP]:[PORT]/[DBNAME]?charset=utf8&parseTime=True&loc=Local
  • DRIVER: 数据库驱动名称,如mysql,postgres,sqlite3等

  • USER: 数据库用户名

  • PASS: 数据库密码

  • IP: 数据库主机IP地址,可以是localhost或127.0.0.1等

  • PORT: 数据库端口,默认为3306

  • DBNAME: 数据库名称

  • charset: 字符集,默认utf8

  • parseTime: 是否解析时间字段,默认True

  • loc: 时区,默认Local

示例(mysql连接url)

mysql://root:123123@tcp(127.0.0.1:3306)/testName?charset=utf8mb4&parseTime=True&loc=Local

2.建立连接

自定义mysql配置
mysqlConfig := mysql.Config{
    DSN:                       dsn,   // 连接url
    DefaultStringSize:         255,   // string 类型字段的默认长度
    DisableDatetimePrecision:  true,  // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
    DontSupportRenameIndex:    true,  // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
    DontSupportRenameColumn:   true,  // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
    SkipInitializeWithVersion: false, // 根据版本自动配置
}
自定义gorm配置
gormConfig := &gorm.Config{
    DisableForeignKeyConstraintWhenMigrating: true,
    // 使用自定义的logger,gorm默认是将日志输出控制台,使用自定义logger可保存日志到文件
    Logger:                                   getGormLogger(), 
}
调用open对象建立连接,获取连接客户端
if db, err := gorm.Open(mysql.New(mysqlConfig), gormConfig); err != nil {
		global.App.Log.Error("mysql connect failed, err:", zap.Any("err", err))
		return nil
	} else {
		global.App.Log.Info("mysql数据库连接成功~~~~~")
		sqlDB, _ := db.DB()
		sqlDB.SetMaxIdleConns(dbConfig.MaxIdleConns)
		sqlDB.SetMaxOpenConns(dbConfig.MaxOpenConns)
		//数据库表结构同步
		initMySqlTables(db)
		return db
	}

扩展:使用AutoMigrate进行表结构同步(根据定义的结构体创建/修改表结构,保证数据结构的一致性,省去手动建表的步骤)
/*
数据库表结构同步,该方法只会增加新的字段或修改字段,不会删除字段,
AutoMigrate 方法会尝试自动更改表结构,以使其与结构体定义保持一致
*/
func initMySqlTables(db *gorm.DB) {
    err := db.AutoMigrate(
       // 需要同步的表的结构体放里面
       model.User{},
       model.Media{},
    )
    if err != nil {
       global.App.Log.Error("migrate table failed", zap.Any("err", err))
       // 退出程序
       os.Exit(0)
    }
}

3.基本使用

添加

Create()

添加一条数据,不能重复添加

user := User{Name: "jinzhu"}
db.Create(&user) 
user := User{Name: "jinzhu"}
db.Model(&user).Create(&user)
Save()

添加一条数据,若已存在,则更新对应数据

user := User{Name: "jinzhu"}
db.Save(&user) 
CreateInBatches(records, batchSize)

批量添加数据

  • records:要插入的记录的切片或结构体
  • batchSize:每个批量添加的数量,避免一次性插入太多记录对数据库造成压力
users := []User{
  {Name: "jinzhu"},
  {Name: "hello"},
} 
db.CreateInBatches(users, 10)

删除

Delete()

根据结构体Id删除一条数据,若定义了DeletedAt字段,则会进行软删除

db.Delete(&user)
db.Model(&user).Delete(&User{})
.Unscoped().Delete()

忽略软删除直接删除一条数据

db.Unscoped().Delete(&user)
Where().Delete()

根据条件删除多条记录

db.Where("name = ?", "jinzhu").Delete(&User{})

修改

db.Save()

根据结构体主键更新数据

user.Name = "updated"
db.Save(&user) 
db.Model().Update()

通过模型对象更新指定字段

db.Model(&user).Update("name", "new_name")
db.Updates()

批量更新结构体中的字段

db.Model(&user).Updates(User{Name: "new"}) 
db.UpdateColumn()

更新单个字段

db.Model(&user).UpdateColumn("name", "new")
db.Where().Update()

根据条件更新多条记录

db.Where("id=?", 1).Update("name", "updated")

查询

db.First()

查询第一条记录

var user User
db.First(&user, 1) // id = 1 
db.Where().Find()

条件查询多条记录

db.Where("name = ?", "jinzhu").Find(&users)
db.Order()

排序查询

db.Order("age desc").Find(&users) 
db.Limit()

限制返回条数

db.Limit(10).Find(&users)
db.Offset()

分页查询

db.Offset(20).Limit(10).Find(&users)
db.Count()

统计记录数

var count int
db.Find(&users).Count(&count)

事务

tx := db.Begin() //开启事务
tx.Create(&user)
tx.Commit() //提交事务
tx.Rollback() //回滚事务

4.其他常用方法

Preload():预加载

目的:减少sql查询次数,避免N+1问题,减少内存开销,适用于复杂关系
基本使用:

结构体定义:gorm:"foreignKey:problem_id;references:id"指明关联关系,gorm会根据该关系进行预加载。如下面例子中把Struct111的problem_id与ProblemBasic的id关联起来。

// 要使用预加载函数的结构体
type ProblemBasic struct {
    ID                uint               `gorm:"primarykey;" json:"id"`
    
    //  需要预加载的数据
    Struct1 []*Struct111 `gorm:"foreignKey:problem_id;references:id" json:"problem_categories"` 
    Struct2 *Struct2222 `gorm:"foreignKey:problem_id;references:id;" json:"test_cases"`             
}

使用预加载函数:

err = tx.Preload("Struct1").Preload("Struct2").Find(&problemList).Error

预加载中省略某字段:

err = tx.Preload("Struct1", func(db *gorm.DB) *gorm.DB {
    return db.Omit("省略的字段名")
}).Preload("Struct2").Find(&problemList).Error

Omit():查询中省略指定字段

tx := DB.Model(&model.ProblemBasic{}).Omit("content")

5.格式化时间字段

当我们使用gorm时,往往需要格式化时间字段来满足使用需求

自定义时间类型,重写其方法

type LocalTime time.Time

// 定义 LocalTime 类型在 JSON 编码时的行为
func (t *LocalTime) MarshalJSON() ([]byte, error) {
	tTime := time.Time(*t)
	return []byte(fmt.Sprintf("\"%v\"", tTime.Format("2006-01-02 15:04:05"))), nil
}

// Value方法即在存储时调用,将该方法的返回值进行存储,该方法可以实现数据存储前对数据进行相关操作
func (t LocalTime) Value() (driver.Value, error) {
   	var zeroTime time.Time
   	tlt := time.Time(t)
   	//判断给定时间是否和默认零时间的时间戳相同
   	if tlt.UnixNano() == zeroTime.UnixNano() {
   		return nil, nil
   	}
   	return tlt, nil
}

// Scan方法可以实现在数据查询出来之前对数据进行相关操作
func (t *LocalTime) Scan(v interface{}) error {
   	if value, ok := v.(time.Time); ok {
   		*t = LocalTime(value)
   		return nil
   	}
   	return fmt.Errorf("can not convert %v to timestamp", v)
}


总结

Gorm是一款用于Golang的ORM框架,它提供了丰富的功能,包括模型定义、数据验证、关联查询等。Go提供的原生库已经能够很好的完成数据库编程,而Gorm对其进行了封装,使得数据库操作变得更加简单和灵活。

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

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

相关文章

备战蓝桥杯---组合数学2

本专题主要介绍容斥原理。 大家高中的时候肯定接触过韦恩图&#xff0c;容斥原理比较通俗的理解就是减去所有可能并加上重叠的部分。 我们直接看公式&#xff1a; 知道后&#xff0c;我们先看道模板题&#xff1a; 下面是AC代码&#xff1a; #include<bits/stdc.h> us…

C#,奥西里斯数(Osiris Number)的算法与源代码

1 奥西里斯数(Osiris Number) 奥西里斯数(Osiris Number)是一个数字&#xff0c; 其值等于通过将其自身数字的所有排列相加而形成的所有数字的值之和。 计算结果&#xff1a; 2 源程序 using System; namespace Legalsoft.Truffer.Algorithm { /// <summary> /…

【JavaScrpt 漫游】【015】JSON 对象简记

文章简介 本文为【JavaScript 漫游】专栏的第 015 篇文章&#xff0c;主要是对 JS 语言中的 JSON 对象的知识点进行了简要记录。 JSON 格式JSON 对象JSON.stringify()JSON.parse() JSON 格式 JSON 格式&#xff08;JavaScript Object Notation 的缩写&#xff09;是一种用于…

windows10|音视频剪辑|FFMPEG录屏和网络推流源初步的生成

前言&#xff1a; FFMPEG的功能强大是毋庸置疑的&#xff0c;那么录屏的需求大家在某些时候大家可能是非常需要的&#xff0c;例如&#xff0c;现有的项目需要演示&#xff0c;因此录制一段演示视频&#xff1b;亦或者做内容分发直播的&#xff0c;比如游戏主播&#xff0c;需…

Netty Review - NioServerSocketChannel源码分析

文章目录 概述入口NioServerSocketChannel 类继承关系实例化过程中做的事情小结 概述 入口 ChannelFuture channelFuture serverBootstrap.bind(9000).sync();我们进入bind方法 /*** Create a new {link Channel} and bind it.*/ public ChannelFuture bind(int inetPort) {…

【学网攻】 第(26)节 -- 综合网络实验一

系列文章目录 目录 系列文章目录 文章目录 前言 一、综合实验 二、实验 1.引入 实验目标 实验设备 实验拓扑图 实验配置 文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口【学网攻】 第(4)节…

Ubuntu Desktop - Files Preferences

Ubuntu Desktop - Files Preferences 1. Behavior2. ViewsReferences 1. Behavior Go to file browser’s Menu -> Edit -> Preferences -> Behavior 2. Views Go to file browser’s Menu -> Edit -> Preferences -> Views ​​​ References [1] Yong…

猫头虎分享已解决Bug || AttributeError: ‘Sequential‘ object has no attribute ‘session‘

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

盘点数据可视化大屏焦点图十种样式

所谓焦点图就是大屏中居于中心位置的图&#xff0c;是视觉的中心&#xff0c;本位列举了十种焦点图样式供大家参考。 地球作为焦点图 图片来自网络 地图作为焦点图 图片来自网络 城市作为焦点图 图片来自网络 园区做焦点图 图片来自网络 建筑做焦点图 图片来自网络 生产线…

【lesson51】信号之信号处理

文章目录 信号处理可重入函数volatileSIGCHLD信号 信号处理 信号产生之后&#xff0c;信号可能无法被立即处理&#xff0c;一般在合适的时候处理。 1.在合适的时候处理&#xff08;是什么时候&#xff1f;&#xff09; 信号相关的数据字段都是在进程PCB内部。 而进程工作的状态…

Centos9部署LAMP

配置LAMP 参考文档 https://blog.csdn.net/weixin_51432789/article/details/112254685 首先安装 yum install -y libxml2-devel 安装apr-1.7.4 解压 tar xf apr-1.7.4.tar.gz 安装以来 yum -y install gcc cd apr-1.7.4/ 预编译 ./configure --prefix/usr/local/…

RK3588平台开发系列讲解(视频篇)RKMedia 数据流向

文章目录 一、 获取RKMedia模块通道中的数据二、RKMedia的数据源和接收者三、模块通道绑定API调用 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; &#x1f4e2;RKMedia是RK提供的一种多媒体处理方案&#xff0c;可实现音视频捕获、音视频输…

计算机网络——10FTP

FTP FTP&#xff1a;文件传输协议 向远程主机上传输文件或从远程主机接收文件客户/服务器模式 客户端&#xff1a;发起传输的一方服务器&#xff1a;远程主机 ftp:RFC 959ftp服务器&#xff1a;端口号为21 FTP&#xff1a;控制连接与数据连接分开 控制连接 FTP客户端与FTP服…

数据结构与算法:单链表

朋友们大家好&#xff0c;本节来到数据结构与算法的新内容&#xff1a;单链表 在上篇文章中&#xff0c;我们知道顺序表通常需要预分配一个固定大小的内存空间&#xff0c; 通常以二倍的大小进行增容&#xff0c;可能会造成空间的浪费&#xff0c;本篇文章我们介绍的链表可以解…

Day 43 | 动态规划 1049. 最后一块石头的重量 II 、494. 目标和 、 474.一和零

1049. 最后一块石头的重量 II 题目 文章讲解 视频讲解 思路&#xff1a;dp[j] 表示容量为 j 的背包&#xff0c;最多可以背最大重量为dp[j]。 class Solution {public int lastStoneWeightII(int[] stones) {int sum 0;for (int i 0; i < stones.length; i) {sum stone…

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核内存管理-静态内存

目录 一、内存管理二、静态内存2.1、静态内存运行机制2.2、静态内存开发流程2.3、静态内存接口2.4、实例2.5、代码分析&#xff08;待续...&#xff09;坚持就有收货 一、内存管理 内存管理模块管理系统的内存资源&#xff0c;它是操作系统的核心模块之一&#xff0c;主要包括…

微信小程序(四十一)wechat-http的使用

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.模块下载 2.模块的使用 在终端输入npm install wechat-http 没有安装成功vue的先看之前的一篇 微信小程序&#xff08;二十&#xff09;Vant组件库的配置- 如果按以上的成功配置出现如下报错先输入以下语句 …

【开源】JAVA+Vue+SpringBoot实现学生综合素质评价系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学生功能2.2 教师功能2.3 教务处功能 三、系统展示四、核心代码4.1 查询我的学科竞赛4.2 保存单个问卷4.3 根据类型查询学生问卷4.4 填写语数外评价4.5 填写品德自评问卷分 五、免责说明 一、摘要 1.1 项目介绍 基于J…

【Time Series】基于Transformer的时间序列预测代码实战

一、简介 在上篇《【Time Series】LSTM代码实战》中&#xff0c; 采用的是LSTM方法实现时序预测任务。自Transformer问世以来&#xff0c;在各个CV/NLP两个领域不断迭代不断屠榜&#xff0c;但在Time Series Predict(TSP)类型的任务中&#xff0c;从21年以后开始研究才慢慢红火…

五.实战软件部署 1-3实战章节-前言MYSQL 5.7版本在centos系统安装MYSQL 8.0版本在centos系统安装

目录 五.实战软件部署 1-实战章节-前言 五.实战软件部署 2-MYSQL 5.7版本在centos系统安装 1-配置yum仓库 2-使用yum安装mysql 3-安装完成后&#xff0c;启动mysql并配置开机自启动 4-检查mysql的运行状态 --配置 1-获取mysql的初识密码 2-登录mysql数据库系统 3-修改…