Golang ORM類庫:GORM的使用總結


Golang ORM類庫:GORM的使用總結

技術概述

ORM(Object Relation Mapping 關系對象映射),就是把對象模型表示的對象映射到基於SQL的關系模型數據庫結構中,在具體的操作實體對象的時候,不需要直接與復雜的 SQL語句打交道,只需簡單的操作實體對象的屬性和方法。而GORM就是基於Go語言實現的ORM庫。在使用Go語言開發項目的時候,我們可以利用GORM來實現對數據庫的操作,進行簡單的CRUD操作。

技術詳述

使用流程

使用GORM

1.導入GROM和數據庫驅動

可以使用一下命令安裝GROM和數據庫驅動

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

但是這是一種比較傳統的方法。我們還可以在項目中使用go.mod文件設置項目需要添加的依賴包:

go 1.15

require (
	gorm.io/driver/mysql v1.0.5
	gorm.io/gorm v1.21.8
)

像上面這樣定義好需要添加的依賴包之后,就可以直接執行下面這一條指令讓go.mod文件自動引入所有依賴包:

go mod download

執行完上述指令若沒有任何反應則說明已經成功將GORM和數據庫驅動的依賴包導入了

2.定義數據庫連接信息

在項目中的.env文件中編寫數據庫連接的信息,可以大致按照如下格式編寫,但需要根據具體項目要求修改具體信息,比如這里使用的數據庫是MySQL的,如果使用的是其他數據庫(PostgreSQL等),則需要修改MYSQL_DSN的內容:

MYSQL_DSN="root:12345678@tcp(localhost:3306)/pingleme?charset=utf8&parseTime=True&loc=Local"
REDIS_ADDR="pingleme.top:6379"
REDIS_PW="Test1234"
REDIS_DB=""
SESSION_SECRET="setOnProducation"
GIN_MODE="debug"
LOG_LEVEL="debug"
LOG_PATH="./.log/system.log"
LOG_MAX_SIZE="50"
LOG_MAX_AGE="30"
LOG_MAX_BACKUP="0"
LOG_COMPRESS="false"
LOG_JSON_FORMAT="false"
LOG_SHOW_LINES="true"
LOG_SHOW_IN_CONSOLE="true"
DB_LOG_LEVEL="info"

在這里可能會遇到一些連接問題,會在之后的“遇到的問題和解決過程”模塊解釋

3.獲取數據庫連接

完成以上准備工作后,需要先獲取數據庫的連接:

package main

import (
  "gorm.io/gorm"
  "gorm.io/driver/mysql"
)

func main() {
  db, err := gorm.Open("mysql", &gorm.Config{})
  if err != nil {
    panic("failed to connect database")
  }
  defer db.Close()
  db.SingularTable(true)
}

4.定義數據庫模型

GORM 傾向於約定,而不是配置。默認情況下,GORM 使用 ID 作為主鍵,使用結構體名的 蛇形復數 作為表名,字段名的 蛇形 作為列名,並使用 CreatedAt、UpdatedAt 字段追蹤創建、更新時間。

定義數據庫模型就是將數據庫的表結構對應到struct中,比如如下的用戶表表結構:

CREATE TABLE `users` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `uid` varchar(191) NOT NULL,
  `password_digest` longtext NOT NULL,
  `user_name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uid` (`uid`),
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

可以定義對應的struct:

// User 用戶模型
type User struct {
	gorm.Model
	UID            string `gorm:"not null;unique"`
	PasswordDigest string `gorm:"not null"`
	UserName       string `gorm:"type:varchar(20);not null"`
}

struct的每個字段都對應着數據庫表中的字段,而數據庫字段的屬性則由gorm聲明的結構標記來定義。比如,"type:varchar(20)"定義了字段的類型與長度、"not null"則聲明了字段是非空的,這些都與數據庫中的聲明一一對應。更多的屬性定義可以查看官方文檔給出的GORM模型定義

5.CRUD操作

5.1 創建
user := User{UID: "221801114", PasswordDigest: "123456", UserName: "silicon"}

result := db.Create(&user) // 通過數據的指針來創建

user.ID             // 返回插入數據的主鍵
result.Error        // 返回 error
result.RowsAffected // 返回插入記錄的條數
5.2 查詢
// 獲取第一條記錄(主鍵升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;

// 獲取一條記錄,沒有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;

// 獲取最后一條記錄(主鍵降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;

// 獲取全部記錄
result := db.Find(&users)
// SELECT * FROM users;

result := db.First(&user)
result.RowsAffected // 返回找到的記錄數
result.Error        // returns error

// 檢查 ErrRecordNotFound 錯誤
errors.Is(result.Error, gorm.ErrRecordNotFound)
5.3 更新
db.First(&user)

user.PasswordDigest = "12345678"
db.Save(&user)
// UPDATE users SET uid='221801114', passworddigest="12345678", birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=1;
5.4 刪除

刪除記錄時需要帶主鍵,否則會導致批量刪除:

// user 的 ID 是 `1`
db.Delete(&user)
// DELETE from users where id = 1;

// 帶額外條件的刪除
db.Where("uid = ?", "221801114").Delete(&user)
// DELETE from users where id = 1 AND uid = "221801114";

遇到的問題和解決過程

1. 數據庫連接字符串出錯

問題描述

當時配置數據庫信息的時候沒有按照規范書寫連接串,導致數據庫連接失敗,錯誤代碼如下:

MYSQL_DSN="root:12345678/pingleme?charset=utf8&parseTime=True&loc=Local"

解決

應當要將端口號等信息放在“@tcp()”的括號中,具體可以按照如下格式修改:

MYSQL_DSN="user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"

2.數據庫字段包含sql的關鍵字

問題描述

我在設計一個數據庫表結構的時候,誤將sql語句的關鍵字"index"作為數據庫字段的名字:

CREATE TABLE `scoring_items` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `created_at` datetime(3) DEFAULT NULL,
  `updated_at` datetime(3) DEFAULT NULL,
  `deleted_at` datetime(3) DEFAULT NULL,
  `homework_id` bigint unsigned NOT NULL,
  `description` varchar(255) NOT NULL,
  `score` bigint NOT NULL DEFAULT '-1',
  `option` tinyint NOT NULL,
  `note` varchar(255) DEFAULT NULL,
  `assistant_id` bigint NOT NULL,
  `level` bigint NOT NULL DEFAULT '0',
  `index` bigint NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_scoring_items_deleted_at` (`deleted_at`),
  KEY `fk_homeworks_scoring_items` (`homework_id`),
  CONSTRAINT `fk_homeworks_scoring_items` FOREIGN KEY (`homework_id`) REFERENCES `homeworks` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

以致於我對這一個數據庫表的如下查詢操作屢次失敗,找不出原因:

result = Repo.DB.Order("index desc").Where("homework_id = ?", ID).Find(&items)

解決

在使用該字段進行查詢時,應該將該字段的名稱包含在``之間,就可以避免與sql的沖突。比如,可以將上面的查詢操作改為如下形式:

result = Repo.DB.Order("`index` desc").Where("homework_id = ?", ID).Find(&items)

總結

通過上述的介紹,就可以大致地使用GO提供的ORM類庫GORM輕松的進行簡單的CRUD操作了。學會了GORM,就不需要自己維護sql語句了。

參考文獻

GORM指南


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM