当前位置: 首页 > article >正文

【Golang学习之旅】Go + MySQL 数据库操作详解

文章目录

    • 前言
    • 1. GORM简介
    • 2. 安装GORM并连接MySQL
      • 2.1 安装GORM和MySQL驱动
      • 2.2 连接MySQL
    • 3. GORM数据模型(Model)
      • 3.1 定义User结构体
      • 3.2 自动迁移(AutoMigrate)
    • 4. GORM CRUD 操作
      • 4.1 插入数据(Create)
      • 4.2 查询数据(Read)
      • 4.3 更新数据(Update)
      • 4.4 删除数据(Delete)
    • 5. 进阶功能:事务 & 关联关系
      • 5.1 事务操作
    • 6. GORM 性能优化
      • 6.1 添加索引
      • 6.2 批量插入
    • 🎯 总结

前言

✅ 适合人群:Go 后端开发者 | 数据库开发者 | 想掌握 GORM 的工程师
✅ 文章亮点:从 安装、基础操作、CRUD、事务、索引优化 到 进阶技巧,全面解析 GORM
✅ 目标:掌握 Go 语言 + MySQL(GORM),开发高效数据库应用!

1. GORM简介

GORM是Go语言最流行的ORM框架,它提供了一套强大且简介的数据库操作API,相比database/sql,它具备以下优势:
✅ 代码简洁:无需手写 SQL,使用链式调用
✅ 支持自动迁移:可自动创建和更新数据库表结构
✅ 支持事务、预加载、钩子函数
✅ 支持多种数据库(MySQL、PostgreSQL、SQLite、SQL Server)
✅ 支持软删除、乐观锁、索引管理

2. 安装GORM并连接MySQL

2.1 安装GORM和MySQL驱动

执行以下命令安装 GORM 和 MySQL 依赖:

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

2.2 连接MySQL

main.go中编写数据库连接代码:

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)
var DB *gorm.DB  // 全局数据库实例func InitDB() {dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"var err errorDB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {panic("数据库连接失败:" + err.Error())}fmt.Println("数据库连接成功!")
}func main() {InitDB()
}

📌 替换 root:password 为你的 MySQL 账号密码,testdb 为数据库名称
📌 确保 MySQL 服务已开启,并且testdb数据库已存在

3. GORM数据模型(Model)

GORM的模型(Model)类似于数据库中的表,每个字段对应表的列。

3.1 定义User结构体

type User struct {ID uint `gorm:"primaryKey"`  // 主键Name string `gorm:"size:100"`  // 名字,最大100字符Age int  // 年龄Email string `gorm:"unique"`  // 邮箱,唯一约束CreateAt time.Time
}

3.2 自动迁移(AutoMigrate)

GORM支持自动迁移,可以自动创建表结构。

package mainimport ("fmt""time""gorm.io/driver/mysql""gorm.io/gorm"
)type User struct {ID       uint   `gorm:"primaryKey"` // 主键Name     string `gorm:"size:100"`   // 名字,最大100字符Age      int    // 年龄Email    string `gorm:"unique"` // 邮箱,唯一约束CreateAt time.Time
}var DB *gorm.DBfunc InitDB() {dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"var err errorDB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {panic("❌ 数据库连接失败:" + err.Error())}fmt.Println("✅ 数据库连接成功!")
}func Migrate() {err := DB.AutoMigrate(&User{}) // 自动迁移User表if err != nil {fmt.Println("数据库迁移失败:", err)}else {fmt.Println("数据库迁移成功!")}
}func main() {InitDB()Migrate()
}

📌 运行 go run main.go,会自动创建 users 表! 🚀

4. GORM CRUD 操作

4.1 插入数据(Create)

package mainimport ("fmt""time""gorm.io/driver/mysql""gorm.io/gorm"
)type User struct {ID       uint   `gorm:"primaryKey"` // 主键Name     string `gorm:"size:100"`   // 名字,最大100字符Age      int    // 年龄Email    string `gorm:"unique"` // 邮箱,唯一约束CreateAt time.Time
}var DB *gorm.DBfunc InitDB() {dsn := "root:123456@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"var err errorDB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {panic("❌ 数据库连接失败:" + err.Error())}fmt.Println("✅ 数据库连接成功!")
}func Migrate() {err := DB.AutoMigrate(&User{}) // 自动迁移User表if err != nil {fmt.Println("数据库迁移失败:", err)} else {fmt.Println("数据库迁移成功!")}
}func CreateUser() {user := User{Name: "Zhangsan", Age: 18, Email: "ponyma@tencent.com",CreateAt: time.Now()}result := DB.Create(&user)if result.Error != nil {fmt.Println("数据插入失败", result.Error)} else {fmt.Println("数据插入成功:", user)}
}func main() {InitDB()// Migrate()CreateUser()}

在这里插入图片描述

4.2 查询数据(Read)

func GetUserByID(id int) {var user Userresult := DB.First(&user, id)if result.Error != nil {fmt.Println("查询失败:",result.Error)}else {fmt.Println("查询成功:",user)}
}

在这里插入图片描述

4.3 更新数据(Update)

func UpdateUser(id int,newAge int) {result :=DB.Model(&User{}).Where("id = ?",id).Update("age",newAge)if result.Error != nil {fmt.Println("数据更新失败:", result.Error)}else {fmt.Println("数据更新成功:", result.RowsAffected,"行")}
}

在这里插入图片描述

4.4 删除数据(Delete)

func DeleteUser(id uint) {result := DB.Delete(&User{}, id)if result.Error != nil {fmt.Println("❌ 删除失败:", result.Error)} else {fmt.Println("✅ 删除成功:", result.RowsAffected, "行")}
}

在这里插入图片描述

5. 进阶功能:事务 & 关联关系

5.1 事务操作

func TransferFunds(senderID, receiverID uint, amount int) {tx := DB.Begin()  // 开启事务defer func() {if r := recover(); r != nil {tx.Rollback()  // 事务回滚}}()sender := User{}receiver := User{}if err := tx.First(&sender, senderID).Error; err != nil {tx.Rollback()return}if err := tx.First(&receiver, receiverID).Error; err != nil {tx.Rollback()return}// 模拟扣款sender.Age -= amountreceiver.Age += amountif err := tx.Save(&sender).Error; err != nil {tx.Rollback()return}if err := tx.Save(&receiver).Error; err != nil {tx.Rollback()return}tx.Commit()  // 提交事务
}

6. GORM 性能优化

6.1 添加索引

type Product struct {ID       uint   `gorm:"primaryKey"`Name     string `gorm:"index"`  // 索引Price    float64
}

6.2 批量插入

func BatchInsertUsers(users []User) {DB.Create(&users)
}

🎯 总结

✅ 学习了 GORM 基础:安装、连接 MySQL、定义 Model
✅ 掌握了 CRUD 操作:插入、查询、更新、删除
✅ 实现了事务操作,防止数据不一致
✅ 了解了索引优化 & 性能优化

🔥 现在,你已经掌握了 Go + MySQL(GORM)的完整开发流程! 🚀

相关文章:

【Golang学习之旅】Go + MySQL 数据库操作详解

文章目录 前言1. GORM简介2. 安装GORM并连接MySQL2.1 安装GORM和MySQL驱动2.2 连接MySQL 3. GORM数据模型(Model)3.1 定义User结构体3.2 自动迁移(AutoMigrate) 4. GORM CRUD 操作4.1 插入数据(Create)4.2 …...

33.日常算法

1.螺旋矩阵 题目来源 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5] class Solution { public:vec…...

ArgoCD实战指南:GitOps驱动下的Kubernetes自动化部署与Helm/Kustomize集成

摘要 ArgoCD 是一种 GitOps 持续交付工具,专为 Kubernetes 设计。它能够自动同步 Git 仓库中的声明性配置,并将其应用到 Kubernetes 集群中。本文将介绍 ArgoCD 的架构、安装步骤,以及如何结合 Helm 和 Kustomize 进行 Kubernetes 自动化部署。 引言 为什么选择 ArgoCD?…...

每日Attention学习22——Inverted Residual RWKV

模块出处 [arXiv 25] [link] [code] RWKV-UNet: Improving UNet with Long-Range Cooperation for Effective Medical Image Segmentation 模块名称 Inverted Residual RWKV (IR-RWKV) 模块作用 用于vision的RWKV结构 模块结构 模块代码 注:cpp扩展请参考作者原…...

机器学习之数学基础:线性代数、微积分、概率论 | PyTorch 深度学习实战

前一篇文章,使用线性回归模型逼近目标模型 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于 强化学习必修课:引领人工智能新时代【梗直哥瞿炜】 线性代数、微积分、概率论 …...

UNI-MOL: A UNIVERSAL 3D MOLECULAR REPRESENTATION LEARNING FRAMEWORK

UNI-MOL: A UNIVERSAL 3D MOLECULAR REPRESENTATION LEARNING FRAMEWORK Neurips23 推荐指数:#paper/⭐⭐⭐#​(工作量不小) 动机 在大多数分子表征学习方法中,分子被视为 1D 顺序标记或2D 拓扑图,这限制了它们为下游任务整合…...

SQL Server查询计划操作符(7.3)——查询计划相关操作符(6)

7.3. 查询计划相关操作符 48)Key Lookup:该操作符对一个有簇索引的表进行书签查找。参数列包含簇索引的名字和用于查找簇索引中数据行的簇键。该操作符总是伴随一个Nested Loops操作符。如果其参数列中出现WITH PREFETCH子句,则查询处理器已决定使用异步预取(预读,read-ah…...

C语言【基础篇】之数组——解锁多维与动态数组的编程奥秘

数组 🚀前言🦜数组的由来与用途🌟一维数组详解🖊️二维数组进阶💯动态数组原理🤔常见误区扫盲💻学习路径建议✍️总结 🚀前言 大家好!我是 EnigmaCoder。本文收录于我的专…...

C++ 字符串编码转换

UTF8 的string 转 UTF16 的 wstring std::wstring Utf8ToUtf16(const std::string& utf8Str) { // 获取 UTF-16 字符串所需的缓冲区大小 int wstrLength = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0); if (wstrLength == 0) { // …...

通讯录管理小程序

通讯录管理系统 是对c基础语法的巩固,比较简单的一个小程序,重点在于养成良好的c代码习惯。 通讯录是一个可以记录亲人、好友信息的工具。 本教程主要利用C来实现一个通讯录管理系统 下面是一些需要实现的功能: 1. 添加联系人 功能描述&…...

掌握API和控制点(从Java到JNI接口)_38 JNI从C调用Java函数 01

1. Why? 将控制点下移到下C/C层 对古典视角的反思 App接近User,所以App在整体架构里,是主导者,拥有控制权。所以, App是架构的控制点所在。Java函数调用C/C层函数,是合理的。 但是EIT造形告诉我们: App…...

理解UML中的四种关系:依赖、关联、泛化和实现

在软件工程中,统一建模语言(UML)是一种广泛使用的工具,用于可视化、设计、构造和文档化软件系统。UML提供了多种图表类型,如类图、用例图、序列图等,帮助开发者和设计师更好地理解系统的结构和行为。在UML中…...

windows蓝牙驱动开发-蓝牙 LE 邻近感应配置文件

邻近感应检测是蓝牙低功耗 (LE) 的常见用途。 本部分提供了创建可用于开发 UWP 设备应用的邻近感应配置文件的设备实现的指南。 在开发此应用之前,应熟悉蓝牙 LE 函数和蓝牙 LE 邻近感应配置文件规范。 示例服务声明 蓝牙低功耗引入了一个新的物理层,…...

【截图】selenium自动通过浏览器截取指定元素div的图片

【截图】selenium自动通过浏览器截取指定元素div的图片 思路 截取完整网页截图 通过元素的坐标 截图到指定位置的图片 前提是已经获取到 driver 了 # 定位目标divtarget_div driver.find_element(By.CLASS_NAME, headlines-right)# 获取div的位置和大小location target_div…...

【算法】动态规划专题⑨ —— 二维费用背包问题 python

目录 前置知识进入正题实战演练 前置知识 【算法】动态规划专题⑤ —— 0-1背包问题 滚动数组优化 python 进入正题 二维费用背包问题 方法思路 二维费用背包问题在传统背包问题的基础上增加了第二个维度的限制(如重量)。 每个物品具有两种费用&#x…...

免费windows pdf编辑工具Epdf

Epdf(完全免费) 作者:不染心 时间:2025/2/6 Github: https://github.com/dog-tired/Epdf Epdf Epdf 是一款使用 Rust 编写的 PDF 编辑器,目前仍在开发中。它提供了一系列实用的命令行选项,方便用户对 PDF …...

MVCC机制深度解析

在数据库管理系统中,多版本并发控制(MVCC,Multi-Version Concurrency Control)是一种用于提高数据库并发性能的技术。它通过在同一数据项上存储多个版本,允许事务在读取数据时不必等待其他事务的完成,从而提…...

C++:类和对象初识

C:类和对象初识 前言类的引入与定义引入定义类的两种定义方法1. 声明和定义全部放在类体中2. 声明和定义分离式 类的成员变量命名规则 类的访问限定符及封装访问限定符封装 类的作用域与实例化类的作用域类实例化实例化方式: 类对象模型类对象的大小存储…...

伪分布式Spark3.4.4安装

参考:Spark2.1.0入门:Spark的安装和使用_厦大数据库实验室博客 我的版本: hadoop 3.1.3 hbase 2.2.2 java openjdk version "1.8.0_432" 问了chatgpt,建议下载Spark3.4.4,不适合下载Spark 2.1.0: step1 Spark下载…...

kafka服务端之控制器

文章目录 概述控制器的选举与故障恢复控制器的选举故障恢复 优雅关闭分区leader的选举 概述 在Kafka集群中会有一个或多个broker,其中有一个broker会被选举为控制器(Kafka Controler),它负责管理整个集群中所有分区和副本的状态。…...

element-plus el-tree-select 修改 value 字段

element-plus el-tree-select 修改 value 字段 &#xff0c;不显示label 需要注意两个地方&#xff1a; <el-tree-select v-model"value" :data"data" multiple :render-after-expand"false" show-checkbox style"width: 240px" …...

SQL最佳实践(笔记)

写在前面&#xff1a; 之前baeldung的Java Weekly &#xfeff;Reviews里面推荐了一篇关于SQL优化的文章&#xff0c;正好最近在学习数据库相关知识&#xff0c;记一些学习笔记 原文地址&#xff1a;SQL Best Practices Every Java Engineer Must Know 1. 使用索引 使用索引…...

在 Java 中执行一个复杂的 SQL 查询(包含多表连接、子查询和聚合函数),如何确保查询的性能?请列举至少三条措施。请简要描述其工作原理?

在Java中执行复杂的SQL查询时&#xff0c;确保查询性能是非常重要的。 以下是三条关键措施&#xff0c;以及它们的详细解释、代码示例和实际开发中的注意事项。 1. 使用索引 索引是提高数据库查询性能的最基本手段之一。通过在查询条件中使用的列上创建索引&#xff0c;可以…...

java将list转成树结构

首先是实体类 public class DwdCusPtlSelectDto {//idprivate String key;//值private String value;//中文名private String title;private List<DwdCusPtlSelectDto> children;private String parentId;public void addChild(DwdCusPtlSelectDto child) {if(this.chil…...

【R语言】数据分析

一、描述性统计量 借助R语言内置的airquality数据集进行简单地演示&#xff1a; 1、集中趋势&#xff1a;均值和中位数 head(airquality) # 求集中趋势 mean(airquality$Ozone, na.rmT) # 求均值 median(airquality$Ozone, na.rmT) # 求中位数 2、众数 众数&#xff08;mod…...

传输层协议 UDP 与 TCP

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 前置复盘&#x1f98b; 传输层&#x1f98b; 再谈端口号&#x1f98b; 端口号范围划分&#x1f98b; 认识知名端口号 (Well-Know Port Number) 二&#xf…...

Linux 调用可执行程序

Linux 调用可执行程序 1. system() 函数1.1 system() 函数的声明1.2 system() 函数的不同场景返回值1.3 system() 函数的代码示例 2. exec() 函数族2.1 exec() 函数族的声明2.2 exec() 函数族执行失败的情况2.3 exec() 函数族的代码示例 3. exec() 与 system() 的区别以及使用注…...

Java/Kotlin双语革命性ORM框架Jimmer(一)——介绍与简单使用

概览 Jimmer是一个Java/Kotlin双语框架 包含一个革命性的ORM 以此ORM为基础打造了一套综合性方案解决方案&#xff0c;包括 DTO语言 更全面更强大的缓存机制&#xff0c;以及高度自动化的缓存一致性 更强大客户端文档和代码生成能力&#xff0c;包括Jimmer独创的远程异常 …...

剪辑学习整理

文章目录 1. 剪辑介绍 1. 剪辑介绍 剪辑可以干什么&#xff1f;剪辑分为哪些种类&#xff1f; https://www.bilibili.com/video/BV15r421p7aF/?spm_id_from333.337.search-card.all.click&vd_source5534adbd427e3b01c725714cd93961af 学完剪辑之后如何找工作or兼职&#…...

IDEA查看项目依赖包及其版本

一.IDEA将现有项目转换为Maven项目 在IntelliJ IDEA中,将现有项目转换为Maven项目是一个常见的需求,可以通过几种不同的方法来实现。Maven是一个强大的构建工具,它可以帮助自动化项目的构建过程,管理依赖关系,以及其他许多方面。 添加Maven支持 如果你的项目还没有pom.xm…...