3.2goweb框架GORM

GORM 是 Go 語言中功能強大的 ORM(對象關系映射)框架,支持 MySQL、PostgreSQL、SQLite、SQL Server 等主流數據庫。以下是 GORM 的核心概念和用法詳解:


??一、基礎入門??

1. 安裝
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql  # 按需選擇數據庫驅動

所以我們看到安裝的最新版本是 1.26.0.這個不是Gorm1.0的意思。是GORM2.0.參考官方2.0的文檔。https://gorm.io/zh_CN/docs/

2. 連接數據庫
import ("gorm.io/driver/mysql""gorm.io/gorm"
)dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

Gorm 有一個?默認 logger 實現,默認情況下,它會打印慢 SQL 和錯誤

Logger 接受的選項不多,您可以在初始化時自定義它,例如:

newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold:              time.Second,   // Slow SQL thresholdLogLevel:                   logger.Silent, // Log levelIgnoreRecordNotFoundError: true,           // Ignore ErrRecordNotFound error for loggerParameterizedQueries:      true,           // Don't include params in the SQL logColorful:                  false,          // Disable color},
)// Globally mode
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{Logger: newLogger,
})// Continuous session mode
tx := db.Session(&Session{Logger: newLogger})
tx.First(&user)
tx.Model(&user).Update("Age", 18)
日志級別

GORM 定義了這些日志級別:SilentErrorWarnInfo


??二、模型定義??

1. 結構體與表映射
type User struct {gorm.Model        // 內置字段:ID, CreatedAt, UpdatedAt, DeletedAtName       string `gorm:"size:255"`Age        intEmail      string `gorm:"uniqueIndex size:255"` // 唯一索引
}
2. 自定義表名
func (User) TableName() string {return "custom_users" // 自定義表名
}
3.自動遷移

GORM 提供的自動遷移功能是指它能夠根據定義的 Go 結構體(模型)自動創建、更新或刪除數據庫中的表結構,以此保持模型和數據庫表結構的一致性。這一功能極大地簡化了數據庫表結構管理的流程。例如,當你新增一個字段到結構體中,自動遷移會嘗試在數據庫表中添加該字段;若刪除了結構體中的某個字段,自動遷移也可能根據配置刪除表中的相應列。

工作原理
  1. 解析模型定義:GORM 會解析你定義的 Go 結構體,識別其中的字段、類型、標簽等信息。例如,對于以下?User?結構

type User struct {gorm.Model        // 內置字段:ID, CreatedAt, UpdatedAt, DeletedAtName       string `gorm:"size:255"`Age        intEmail      string `gorm:"uniqueIndex size:255"` // 唯一索引
}func (User) TableName() string {return "custom_users" // 自定義表名
}

GORM 會分析出?User?表應該包含?idcreated_atupdated_atdeleted_at(來自?gorm.Model)、nameemail?和?age?這些字段,并且?email?字段需要有唯一約束。
2.?生成 SQL 語句:根據解析結果,GORM 生成相應的 SQL 語句。如果數據庫中不存在?custom_users表,會生成?CREATE TABLE?語句來創建表;若表已存在,會生成?ALTER TABLE?語句來更新表結構。
3.?執行 SQL 語句:GORM 將生成的 SQL 語句發送到數據庫執行,從而完成表結構的創建或更新。

使用示例
package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 模型定義
type User struct {gorm.Model        // 內置字段:ID, CreatedAt, UpdatedAt, DeletedAtName       string `gorm:"size:255"`Age        intEmail      string `gorm:"uniqueIndex size:255"` // 唯一索引
}func (User) TableName() string {return "custom_users" // 自定義表名
}func main() {dsn := "user: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 {panic("failed to connect database")}// 自動遷移 User 模型db.AutoMigrate(&User{})
}

輸出結果:

在上述代碼中,調用?db.AutoMigrate(&User{})?會根據?User?結構體的定義在數據庫中創建或更新?User?表。

注意事項
  • 數據丟失風險:自動遷移可能會導致數據丟失。例如,當你刪除結構體中的某個字段時,自動遷移可能會刪除數據庫表中的相應列,該列的數據就會丟失。所以在生產環境中最好不要使用該功能。

??三、CRUD 操作??

1. 創建記錄
// 創建單條
user := User{Name: "Alice", Age: 25}
db.Create(&user)// 批量插入
users := []User{{Name: "Bob"}, {Name: "Charlie"}}
db.CreateInBatches(users, 100) // 每批100條
2. 查詢數據
var users []User// 查詢全部
db.Find(&users)// 條件查詢
db.Where("age > ?", 18).Find(&users)
db.First(&user, 1)        // 查找ID=1的第一條記錄
db.Last(&user)            // 最后一條記錄// 高級查詢
db.Select("name, age").Where("age > ?", 20).Order("age desc").Limit(10).Find(&users)
3. 更新數據
// 更新單個字段
db.Model(&user).Update("Age", 30)// 批量更新
db.Model(&User{}).Where("age < ?", 30).Update("Age", gorm.Expr("Age + ?", 1))
4. 刪除數據
// 軟刪除(默認使用 DeletedAt 字段)
db.Delete(&user)// 硬刪除(物理刪除)
db.Unscoped().Delete(&user)

??四、關聯關系??

一對一關聯

package mainimport "gorm.io/gorm"// User 用戶模型
type User struct {gorm.ModelName    stringProfile Profile
}// Profile 個人資料模型
type Profile struct {gorm.ModelUserID  uintAddress string
}

在這個例子中,User?結構體包含一個?Profile?字段,Profile?結構體包含一個?UserID?字段作為外鍵,關聯到?User?表。

遷移和操作示例
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)func ConnectDB() (*gorm.DB, error) {dsn := "user: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 {return nil, err}return db, nil
}func main() {db, err := ConnectDB()if err != nil {panic("failed to connect database")}// 自動遷移模型db.AutoMigrate(&User{}, &Profile{})// 創建用戶和關聯的個人資料user := User{Name: "John Doe",Profile: Profile{Address: "123 Main St",},}db.Create(&user)// 查詢用戶及其個人資料var retrievedUser Userdb.Preload("Profile").First(&retrievedUser, user.ID)fmt.Printf("User: %s, Address: %s\n", retrievedUser.Name, retrievedUser.Profile.Address)
}

在這個例子中,我們使用?Preload?方法預加載用戶的個人資料。

一對多關聯

一對多關聯表示一個模型的一條記錄可以關聯到另一個模型的多條記錄。例如,一個用戶可以有多個帖子。

package mainimport "gorm.io/gorm"// User 用戶模型
type User struct {gorm.ModelName  stringPosts []Post
}// Post 帖子模型
type Post struct {gorm.ModelTitle  stringUserID uint
}

在這個例子中,User?結構體包含一個?Posts?切片,Post?結構體包含一個?UserID?字段作為外鍵,關聯到?User?表。

遷移和操作示例
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)func ConnectDB() (*gorm.DB, error) {dsn := "user: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 {return nil, err}return db, nil
}func main() {db, err := ConnectDB()if err != nil {panic("failed to connect database")}// 自動遷移模型db.AutoMigrate(&User{}, &Post{})// 創建用戶和關聯的帖子user := User{Name: "John Doe",Posts: []Post{{Title: "First Post"},{Title: "Second Post"},},}db.Create(&user)// 查詢用戶及其帖子var retrievedUser Userdb.Preload("Posts").First(&retrievedUser, user.ID)fmt.Printf("User: %s, Posts count: %d\n", retrievedUser.Name, len(retrievedUser.Posts))
}

在這個例子中,我們同樣使用?Preload?方法預加載用戶的所有帖子。

多對多關聯

多對多關聯表示一個模型的一條記錄可以關聯到另一個模型的多條記錄,反之亦然。例如,一個用戶可以有多個角色,一個角色可以被多個用戶擁有。

定義模型
package mainimport "gorm.io/gorm"// User 用戶模型
type User struct {gorm.ModelName  stringRoles []Role `gorm:"many2many:user_roles;"`
}// Role 角色模型
type Role struct {gorm.ModelName  stringUsers []User `gorm:"many2many:user_roles;"`
}

在這個例子中,User?結構體和?Role?結構體都包含一個切片,通過?many2many?標簽指定關聯表為?user_roles

遷移和操作示例
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)func ConnectDB() (*gorm.DB, error) {dsn := "user: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 {return nil, err}return db, nil
}func main() {db, err := ConnectDB()if err != nil {panic("failed to connect database")}// 自動遷移模型db.AutoMigrate(&User{}, &Role{})// 創建用戶和角色user := User{Name: "John Doe"}role := Role{Name: "Admin"}db.Create(&user)db.Create(&role)// 關聯用戶和角色db.Model(&user).Association("Roles").Append(&role)// 查詢用戶及其角色var retrievedUser Userdb.Preload("Roles").First(&retrievedUser, user.ID)fmt.Printf("User: %s, Roles count: %d\n", retrievedUser.Name, len(retrievedUser.Roles))
}

我們使用?Association?方法將用戶和角色關聯起來,然后使用?Preload?方法預加載用戶的所有角色。

  • 預加載:使用?Preload?方法可以在查詢主模型時同時加載關聯的模型數據,避免 N+1 查詢問題。
  • 關聯操作:對于多對多關聯,可以使用?Association?方法進行關聯的添加、刪除等操作。
  • 遷移:在使用關聯關系之前,需要確保模型已經通過?AutoMigrate?方法進行了遷移,以創建相應的表和外鍵約束。

???

  • ??循環引用??:確保模型間沒有相互嵌套導致無限遞歸。
  • ??性能優化??:避免?SELECT *,明確指定需要的字段。
  • ??索引優化??:在頻繁查詢的字段上添加索引(如?gorm:"index")。

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

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

相關文章

第三部分:特征提取與目標檢測

像邊緣、角點、特定的紋理模式等都是圖像的特征。提取這些特征是許多計算機視覺任務的關鍵第一步&#xff0c;例如圖像匹配、對象識別、圖像拼接等。目標檢測則是在圖像中找到特定對象&#xff08;如人臉、汽車等&#xff09;的位置。 本部分將涵蓋以下關鍵主題&#xff1a; …

Canvas基礎篇:圖形繪制

Canvas基礎篇&#xff1a;圖形繪制 圖形繪制moveTo()lineTo()lineTo繪制一條直線代碼示例效果預覽 lineTo繪制平行線代碼示例效果預覽 lineTo繪制矩形代碼示例效果預覽 arc()arc繪制一個圓代碼實現效果預覽 arc繪制一段弧代碼實現效果預覽 arcTo()rect()曲線 結語 圖形繪制 在…

瑞芯微芯片算法開發初步實踐

文章目錄 一、算法開發的一般步驟1.選擇合適的深度學習框架2.對于要處理的問題進行分類&#xff0c;是回歸問題還是分類問題。3.對數據進行歸納和整理4.對輸入的數據進行歸一化和量化&#xff0c;保證模型運行的效率和提高模型運行的準確度5.在嵌入式處理器上面運行模型&#x…

計算機畢業設計--基于深度學習(U-Net與多尺度ViT)的模糊車牌圖像清晰化復原算法設計與實現(含Github代碼+Web端在線體驗鏈接)

基于深度學習的U-Net架構下多尺度Transformer車牌圖像去模糊算法設計與實現 如果想對舊照片進行模糊去除&#xff0c;劃痕修復、清晰化&#xff0c;請參考這篇CSDN作品&#x1f447; 計算機畢業設計–基于深度學習的圖像修復&#xff08;清晰化劃痕修復色彩增強&#xff09;算…

(Go Gin)Gin學習筆記(四)Gin的數據渲染和中間件的使用:數據渲染、返回JSON、淺.JSON()源碼、中間件、Next()方法

1. 數據渲染 1.1 各種數據格式的響應 json、結構體、XML、YAML類似于java的properties、ProtoBuf 1.1.1 返回JSON package mainimport ("github.com/gin-gonic/gin""net/http" )func main() {r : gin.Default()r.POST("/demo", func(res *gi…

實驗:串口通信

/************************************************* * AT89C52 串口通信實驗&#xff08;實用修正版&#xff09; * 特點&#xff1a; * 1. 解決所有編譯警告 * 2. 保持代碼簡潔 * 3. 完全功能正常 ************************************************/ #include <re…

智駕賽道的諾曼底登陸,Momenta上海車展雄起

作者 |蘆葦 編輯 |德新 今年的上海車展依舊熱鬧非凡&#xff0c;但火熱的車市背后也是暗流涌動。尤其對智駕供應商而言&#xff0c;「智駕平權」帶動了解決方案大量上車&#xff0c;各大主機廠紛紛選定各自的主要供應商&#xff0c;這也意味著賽道機會越發收斂。 正如汽車品牌…

Java 事務詳解

目錄 一、事務的基本概念1.1 什么是事務?1.2 事務的 ACID 特性二、Java 事務管理的實現方式2.1 JDBC 事務管理2.2 Spring 事務管理2.2.1 添加 Spring 依賴2.2.2 配置 Spring 事務管理2.2.3 使用 Spring 事務注解三、事務隔離級別四、最佳實踐4.1 盡量縮小事務范圍4.2 合理選擇…

DirectX12(D3D12)基礎教程七 深度模板視圖\剔除\謂詞

本章主要講遮擋&#xff0c;作者認為比較復雜有難度的知識點&#xff0c;作為基礎教程不會深入講解。 GPU渲染管線 主要包括以下階段 輸入裝配&#xff08;IA&#xff09;&#xff1a;讀取頂點數據 &#xff0c;定義頂點數據結構頂點著色&#xff08;VS&#xff09;&#xf…

溫補晶振(TCXO)穩定性優化:從實驗室到量產的關鍵技術

在現代通信、航空航天、5G基站等對頻率穩定性要求極高的領域&#xff0c;溫補晶振&#xff08;TCXO&#xff09;扮演著不可或缺的角色。其穩定性直接影響系統的性能與可靠性&#xff0c;因此&#xff0c;對TCXO穩定性優化技術的研究與實踐至關重要。 一、溫度補償算法&#xff…

C++,設計模式,【建造者模式】

文章目錄 通俗易懂的建造者模式&#xff1a;手把手教你造電腦一、現實中的建造者困境二、建造者模式核心思想三、代碼實戰&#xff1a;組裝電腦1. 產品類 - 電腦2. 抽象建造者 - 裝機師傅3. 具體建造者 - 電競主機版4. 具體建造者 - 辦公主機版5. 指揮官 - 裝機總控6. 客戶端使…

前端基礎之《Vue(13)—重要API》

重要的API 一、nextTick() 1、寫法 Vue.$nextTick()或者this.$nextTick() 原因&#xff1a; set操作代碼是同步的&#xff0c;但是代碼背后的行為是異步的。set操作修改聲明式變量&#xff0c;觸發re-render生成新的虛擬DOM&#xff0c;進一步執行diff運算&#xff0c;找到…

Windows 中搭建 browser-use WebUI 1.4

目錄 1. 背景介紹2. 搭建過程3. 補充 1. 背景介紹 背景&#xff1a;想要在 Windows 中復現 browser-use WebUI pickle反序列化漏洞&#xff0c;該漏洞在 v1.7 版本中已經修復&#xff0c;所以需要搭建 小于 1.7 版本的環境&#xff0c;我這里搭建的是 1.4 版本。 項目地址&am…

【數據通信完全指南】從物理層到協議棧的深度解析

目錄 1. 通信技術演進與核心挑戰1.1 從電報到5G的技術變遷1.2 現代通信系統的三大瓶頸 2. 通信系統架構深度解構2.1 OSI七層模型運作原理2.2 TCP/IP協議棧實戰解析 3. 物理層關鍵技術實現3.1 信號調制技術演進路線3.2 信道復用方案對比 4. 數據傳輸可靠性保障4.1 CRC校驗算法數…

CMD與PowerShell:Windows命令行工具的對比與使用指南

CMD與PowerShell&#xff1a;Windows命令行工具的對比與使用指南 文章目錄 CMD與PowerShell&#xff1a;Windows命令行工具的對比與使用指南引言1. CMD&#xff08;命令提示符&#xff09;簡介1.1 什么是CMD&#xff1f;1.2 CMD的特點1.3 常用CMD命令示例1.4 CMD的優勢與局限 2…

93. 后臺線程與主線程更新UI Maui例子 C#例子

在.NET MAUI開發中&#xff0c;多線程是常見的需求&#xff0c;但UI更新必須在主線程上執行。今天&#xff0c;我們來探討一個簡單而優雅的解決方案&#xff1a;MainThread.InvokeOnMainThreadAsync。 一、背景 在跨平臺應用開發中&#xff0c;后臺線程常用于執行耗時操作&am…

海思正式公開了星閃BS21E的SDK

今天海思正式在Gitee平臺發布了BS21E的SDK&#xff1a;fbb_bs2x: fbb_bs2x代碼倉為支持bs21e解決方案SDK。技術論壇&#xff1a;https://developers.hisilicon.com/forum/0133146886267870001 fbb_bs2x代碼倉為支持bs21e解決方案SDK&#xff0c;該SDK包從統一開發平臺FBB&#…

QML學習:使用QML實現抽屜式側邊欄菜單

文章目錄 前言一、環境配置二、實現步驟三、示例完整代碼四、注意事項總結 前言 最近在進行QML的學習&#xff0c;發現一個比較有意思的交互設計&#xff1a;抽屜式側邊欄菜單&#xff0c;出于開發實戰需求&#xff0c;最終實現了一個支持手勢拖拽、彈性動畫、蒙層效果和??智…

峰終定律——AI與思維模型【85】

一、定義 峰終定律思維模型是指人們對一段經歷的評價主要取決于這段經歷中的高峰時刻&#xff08;無論是正向的還是負向的&#xff09;以及結束時的感受&#xff0c;而不是整個經歷的平均感受。也就是說&#xff0c;如果在一段體驗的高峰和結尾階段給人們留下積極、強烈的印象…

【補題】Codeforces Round 664 (Div. 1) A. Boboniu Chats with Du

題意&#xff1a;給出n&#xff0c;d&#xff0c;m三個值&#xff0c;分別代表&#xff0c;有多少個值ai&#xff0c;使用超過m的ai&#xff0c;需要禁言d天&#xff0c;如果不足也能使用&#xff0c;m代表區分點&#xff0c;問能得到最大的值有多少。 思路&#xff1a; …