【Go】Go Gorm 詳解

1. 概念

Gorm 官網:https://gorm.io/zh_CN/docs/

GormThe fantastic ORM library for Golang aims to be developer friendly,這是官網的介紹,簡單來說 Gorm 就是一款高性能的 Golang ORM 庫,便于開發人員提高效率

那么 ORM(Object Relation Mapping) 又是什么呢?在 Golang 語言中,Object指的就是 struct 結構體對象,Relation 就是數據庫當中的關系,Mapping則表示兩者具有映射關系,具體表現如下:

  • Go當中的結構體聲明 <-> 數據庫層面的表結構
  • Go當中的結構體實例 <-> 數據庫層面的一條表記錄

2. 數據庫連接

2.1 安裝依賴

想要在 Go 代碼中使用 gorm 我們需要先引入對應的依賴:

  • gorm 庫依賴:gorm.io/gorm
  • 特定數據庫驅動依賴:gorm.io/driver/mysql

然后使用 go mod 包管理工具加載對應的依賴:

  1. go mod init first_gorm:初始化
  2. go mod tidy:加載依賴

然后就可以開始編寫代碼了!

2.2 連接數據庫

在操作數據庫之前,我們還需要與指定的數據庫建立連接,此處以 MySQL數據庫為例:

基本語法:db, err := gorm.Open(mysql.Open(dsn語句), &gorm.Config{})

  • 其中 dsn 語句為特定的連接格式,形式如下:user:pwd@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)func main() {var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {fmt.Println("數據庫連接失敗!", err)}fmt.Println(db)
}

程序運行結果:

控制臺打印出 db 對象,說明我們已經成功與數據庫建立連接(必須保證數據庫中存在指定的數據庫)

3. 數據庫基本操作

3.1 創建表(表關系映射)

3.1.1 基本使用

我們可以使用 gorm 提供的 API 來創建指定的表,需要關注的是 結構體聲明 <=> 數據庫表結構,因此我們想要創建一個表結構實則只需要定義一個結構體類型

-- 創建user表 --
create table t_user (user_id bigint primary key auto_increment,user_name varchar(32) not null,user_pwd varchar(128) not null,user_phone varchar(32) unique
) 

使用上述 SQL 語句創建表的行為等價于在 Go 語言當中定義下列結構體對象:

// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}

創建表基本語法:err := db.AutoMigrate(&特定結構體{})

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {fmt.Println("數據庫連接失敗!", err)}err = db.AutoMigrate(&User{})if err != nil {fmt.Println("數據庫表遷移失敗!", err)}
}

程序運行結果:

3.1.2 自定義表名

我們發現定義結構體名稱為 “User” 時會創建 “users” 的表名,但是如果我就希望叫做 “t_user” 應該怎么辦呢?我們可以定義一個名為 TableName的方法接收器,格式如下:

func (*User) TableName() string {return "t_user"
}

刪除原先的表后再次運行,可以發現此時表名稱已經指定為t_user

3.2 新增記錄

我們還可以使用 gorm 提供的 API 進行表記錄的插入,這里我們需要關注** 結構體實例 <=> 表記錄** 之間的映射關系,也就意味著我們可以通過創建一個結構體實例,實現插入一條記錄的效果

3.2.1 單條數據插入

基本語法:db.Create(&結構體實例)

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {fmt.Println("數據庫連接失敗!", err)}// 插入單條數據var user = User{UserName: "wjj", UserPwd: "123", UserPhone: "111"}db.Create(&user)// 再次打印userfmt.Println(user)
}

數據庫表結果:

程序運行結果:

💡 提示:從中我們還可以發現,插入數據之后,還會將數據庫表中記錄回顯到結構體實例當中!這也是為什么需要傳遞地址的原因!

3.2.2 批量插入數據

當我們需要批量插入多條數據的時候,循環調用 db.Create(&結構體實例)這個方法效率就太低了!因為數據庫連接會話頻繁創建銷毀耗時比較高,更合適的方法就是進行批量插入

基本語法:db.Create(&結構體實例切片),仍舊是 Create 函數,但是參數我們可以傳遞結構體實例切片

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 批量插入多條數據var users = []User{{UserName: "th", UserPwd: "123", UserPhone: "222"},{UserName: "lhf", UserPwd: "123", UserPhone: "333"},{UserName: "zcy", UserPwd: "123", UserPhone: "444"},}db.Create(&users)// 打印結果fmt.Println(users)
}

數據庫表結果:

程序運行結果:

3.3 查詢記錄

3.3.1 查詢所有記錄

基本語法:db.Find(&結構體實例切片)

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 查詢全部記錄var users []Userdb.Find(&users)// 打印結果fmt.Println(users)
}

程序運行結果:

3.3.2 按照條件查詢

我們可以使用 Where 指定查詢條件進行過濾

基本語法:db.Where("user_id > ?", 2).Find()表示想要查詢 user_id > 2 的所有記錄

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 按照條件查詢var users []Userdb.Where("user_id > ?", 2).Find(&users)// 打印fmt.Println(users)
}

程序運行結果:

3.3.3 查詢單條記錄

查詢單條記錄有以下兩種情況:

  • 查詢第一條記錄:db.First(&結構體實例)
  • 查詢最后一條記錄:db.Last(&結構體實例)
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}
func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 查詢第一條記錄var firstUser Userdb.First(&firstUser)// 查詢最后一條記錄var lastUser Userdb.Last(&lastUser)fmt.Println(firstUser, lastUser)
}

程序運行結果:

3.3.4 查詢記錄總數

基本語法:db.Find(&結構體實例切片).Count(&整型變量)

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 查詢總數var users []Uservar totalSize int64db.Find(&users).Count(&totalSize)fmt.Println("記錄總數:", totalSize)
}

程序運行結果:

3.4 修改記錄

3.4.1 按照默認主鍵修改

基本語法:db.Save(&結構體實例)會按照結構體實例當中的主鍵字段找到對應數據庫記錄進行修改

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 查詢user_id為1的記錄var stu Userdb.Where("user_id = ?", 1).Find(&stu)// 修改stu姓名為wjj1stu.UserName = "wjj1"// 修改(按照主鍵修改)db.Save(&stu)
}

程序運行結果:

3.4.2 修改指定字段

上述按照默認主鍵修改的方式修改了全部字段,如果我們只想修改特定單個字段可以使用以下方式:

基本語法:db.Model(&結構體實例).Where(條件).Update(字段, 修改值)

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 修改user_id為1的記錄 user_name為wjjvar stu Userdb.Model(&stu).Where("user_id = ?", 1).Update("user_name", "wjj")
}

程序運行結果:

3.4.3 修改多個字段

我們還可以指定多個字段進行修改

基本語法:db.Model(&結構體實例).Where(條件).updates(修改實例),其中修改實例可以是結構體也可以是map對象

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 修改user_id為1的記錄 user_name為WJJ, user_pwd為"999"var stu Uservar fields = map[string]interface{}{"user_name": "WJJ", "user_pwd": "999"}db.Model(&stu).Where("user_id = ?", 1).Updates(fields)
}

程序運行結果:

3.5 刪除記錄

3.5.1 按照默認主鍵刪除

基本語法:db.Delete(&結構體實例)會自動按照主鍵找到表中記錄,然后刪除

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 按照默認主鍵刪除var user = User{UserId: 1}db.Delete(&user)
}

程序運行結果:

3.5.2 指定條件刪除

我們想更加精細化的控制刪除條件就需要借助 Where 函數:

基本語法:db.Where(條件).Delete(&結構體實例)

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 結構體聲明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 連接數據庫var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 按照條件刪除db.Where("user_id = ?", 10).Delete(&User{})
}

程序運行結果:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66242.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66242.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66242.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【MySQL實戰】mysql_exporter+Prometheus+Grafana

要在Prometheus和Grafana中監控MySQL數據庫&#xff0c;如下圖&#xff1a; 可以使用mysql_exporter。 以下是一些步驟來設置和配置這個監控環境&#xff1a; 1. 安裝和配置Prometheus&#xff1a; - 下載和安裝Prometheus。 - 在prometheus.yml中配置MySQL通過添加以下內…

【Apache Doris】周FAQ集錦:第 29 期

引言 歡迎查閱本周的 Apache Doris 社區 FAQ 欄目&#xff01; 在這個欄目中&#xff0c;每周將篩選社區反饋的熱門問題和話題&#xff0c;重點回答并進行深入探討。旨在為廣大用戶和開發者分享有關 Apache Doris 的常見問題。 通過這個每周 FAQ 欄目&#xff0c;希望幫助社…

Linux:文件描述符fd、系統調用open

目錄 一、文件基礎認識 二、C語言操作文件的接口 1.> 和 >> 2.理解“當前路徑” 三、相關系統調用 1.open 2.文件描述符 3.一切皆文件 4.再次理解重定向 一、文件基礎認識 文件 內容 屬性。換句話說&#xff0c;如果在電腦上新建了一個空白文檔&#xff0…

鴻蒙動態路由實現方案

背景 隨著CSDN 鴻蒙APP 業務功能的增加&#xff0c;以及為了與iOS、Android 端統一頁面跳轉路由&#xff0c;以及動態下發路由鏈接&#xff0c;路由重定向等功能。鴻蒙動態路由方案的實現迫在眉睫。 實現方案 鴻蒙版本動態路由的實現原理&#xff0c;類似于 iOS與Android的實…

計算機網絡 (42)遠程終端協議TELNET

前言 Telnet&#xff08;Telecommunication Network Protocol&#xff09;是一種網絡協議&#xff0c;屬于TCP/IP協議族&#xff0c;主要用于提供遠程登錄服務。 一、概述 Telnet協議是一種遠程終端協議&#xff0c;它允許用戶通過終端仿真器連接到遠程主機&#xff0c;并在遠程…

汽車網絡信息安全-ISO/SAE 21434解析(上)

目錄 概述 第四章-概述 1. 研究對象和范圍 2. 風險管理 第五章-組織級網絡安全管理 1. 網絡安全治理&#xff08;cybersecurity governance&#xff09; 2. 網絡安全文化&#xff08;cybersecurity culture) 3. 信息共享&#xff08;Information Sharing) 4. 管理體系…

【0393】Postgres內核 checkpointer process ③ 構建 WAL records 工作緩存區

1. 初始化 ThisTimeLineID、RedoRecPtr 函數 InitXLOGAccess() 內部會初始化 ThisTimeLineID、wal_segment_size、doPageWrites 和 RedoRecPtr 等全局變量。 下面是這四個變量初始化前的值: (gdb) p ThisTimeLineID $125 = 0 (gdb) p wal_segment_size $126 = 16777216 (gdb…

cursor+deepseek構建自己的AI編程助手

文章目錄 準備工作在Cursor中添加deepseek 準備工作 下載安裝Cursor &#xff08;默認安裝在C盤&#xff09; 注冊deepseek獲取API key 在Cursor中添加deepseek 1、打開cursor&#xff0c;選擇設置 選擇Model&#xff0c;添加deepseek-chat 注意這里去掉其他的勾選項&…

微調神經機器翻譯模型全流程

MBART: Multilingual Denoising Pre-training for Neural Machine Translation 模型下載 mBART 是一個基于序列到序列的去噪自編碼器&#xff0c;使用 BART 目標在多種語言的大規模單語語料庫上進行預訓練。mBART 是首批通過去噪完整文本在多種語言上預訓練序列到序列模型的方…

潯川社團官方文章被 Devpress 社區收錄!

潯川社團官方文章被 Devpress 社區收錄&#xff01; 親愛的潯川社團成員們以及關注我們的朋友們&#xff1a; 在這個充滿活力與機遇的社團發展歷程中&#xff0c;我們迎來了一則令人振奮的喜訊&#xff01;潯川社團精心創作的官方文章&#xff0c;成功被 Devpress 社區收錄啦&a…

STM32網絡通訊之CubeMX實現LWIP項目設計(十五)

STM32F407 系列文章 - ETH-LWIP-CubeMX&#xff08;十五&#xff09; 目錄 前言 一、軟件設計 二、CubeMX實現 1.配置前準備 2.CubeMX配置 1.ETH模塊配置 2.時鐘模塊配置 3.中斷模塊配置 4.RCC及SYS配置 5.LWIP模塊配置 3.生成代碼 1.main文件 2.用戶層源文件 3.…

簡單組合邏輯

多路選擇器 在多路數據傳輸過程中&#xff0c;能夠將任意一路選出來的電路叫做數據選擇器&#xff0c;也稱多路選擇器。對于一個具有2^n個輸入和一個輸出的多路選擇器&#xff0c;有n個選擇變量&#xff0c;多路選擇器也是FPGA內部的一個基本資源&#xff0c;主要用于內部信號的…

【Unity-Game4Automation PRO 插件】

Game4Automation PRO 插件 是一個用于 Unity 引擎 的工業自動化仿真工具&#xff0c;它提供了對工業自動化領域的仿真和虛擬調試支持&#xff0c;特別是在與工業機器人、生產線、PLC 系統的集成方面。該插件旨在將工業自動化的實時仿真與游戲開發的高質量 3D 可視化能力結合起來…

【安卓開發】【Android】總結:安卓技能樹

【持續更新】 對筆者在安卓開發的實踐中認為必要的知識點和遇到的問題進行總結。 一、基礎知識部分 1、Android Studio軟件使用 軟件界面 最新的版本是瓢蟲&#xff08;Ladybug&#xff09;&#xff0c;bug的確挺多。筆者更習慣使用電鰻&#xff08;Electric Eel&#xff0…

鴻蒙打包發布

HarmonyOS應用/元服務發布&#xff08;打包發布&#xff09; https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/ide-publish-app-V13?catalogVersionV13 密鑰&#xff1a;包含非對稱加密中使用的公鑰和私鑰&#xff0c;存儲在密鑰庫文件中&#xff0c;格式…

Spring Boot 下的Swagger 3.0 與 Swagger 2.0 的詳細對比

先說結論&#xff1a; Swgger 3.0 與Swagger 2.0 區別很大&#xff0c;Swagger3.0用了最新的注釋實現更強大的功能&#xff0c;同時使得代碼更優雅。 就個人而言&#xff0c;如果新項目推薦使用Swgger 3.0&#xff0c;對于工具而言新的一定比舊的好&#xff1b;對接于舊項目原…

神經網絡基礎-價格分類案例

文章目錄 1. 需求分析2. 導入所需工具包3. 構建數據集4. 構建分類網絡模型5. 訓練模型6. 模型訓練7. 評估模型8. 模型優化 學習目標&#xff1a; 掌握構建分類模型流程動手實踐整個過程 1. 需求分析 小明創辦了一家手機公司&#xff0c;他不知道如何估算手機產品的價格。為了…

SAP 固定資產常用的數據表有哪些,他們是怎么記錄數據的?

在SAP系統中&#xff0c;固定資產管理&#xff08;FI-AA&#xff09;涉及多個核心數據表&#xff0c;用于記錄資產主數據、折舊、交易等。以下是常用的數據表及其記錄數據的邏輯&#xff1a; 1. ANKT - 資產主數據表 功能&#xff1a;存儲資產主數據的文本描述。 字段&#x…

光伏儲能電解水制氫仿真模型Matlab/Simulink

今天更新的內容為光伏儲能制氫技術&#xff0c;這個方向我之前在21年就系統研究并發表過相關文章&#xff0c;經過這幾年的發展&#xff0c;綠色制氫技術也受到更多高校的注意&#xff0c;本篇博客也是在原先文章的基礎上進行更新。 首先讓大家熟悉一下綠氫制取技術這個概念&a…

Redis 3.2.1在Win10系統上的安裝教程

諸神緘默不語-個人CSDN博文目錄 這個文件可以跟我要&#xff0c;也可以從官網下載&#xff1a;https://github.com/MicrosoftArchive/redis/releases 這個是微軟以前維護的Windows版Redis安裝包&#xff0c;如果想要比較新的版本可以從別人維護的項目里下&#xff08;https://…