gorm 配置數據庫

介紹

GORM 是 Go 語言中最流行的 ORM(對象關系映射)庫之一,基于數據庫操作的封裝,提供類似 Django ORM / SQLAlchemy 的開發體驗。

特性描述
支持多種數據庫MySQL、PostgreSQL、SQLite、SQL Server、ClickHouse 等
自動遷移自動根據 struct 生成數據庫表結構
CRUD 操作簡潔簡潔直觀的增刪查改接口
支持事務內置事務管理
預加載一行代碼加載關聯數據(Preload)
鉤子函數提供 BeforeSave、AfterCreate 等生命周期鉤子
軟刪除提供內置軟刪除支持
自定義 SQL可執行原生 SQL 或復雜查詢
遷移、索引支持復合索引、唯一索引等設置
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

配置數據庫

一般來說,關于數據庫的配置 我喜歡放在 infra/* 這個文件夾下

這里以 pg 為例

pg_connection.go

package infraimport ("fmt""time""gin-api-template/utils""gorm.io/driver/postgres""gorm.io/gorm""gorm.io/gorm/logger"
)var DB *gorm.DB //定義一個全局變量 DB,用于保存數據庫連接句柄。可供全局調用。// InitPG 初始化 PostgreSQL 連接
func InitPG() {config := utils.AppConfigif config == nil {utils.LogError("Config not loaded")return}// 構建數據庫連接字符串dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Shanghai",config.DBHost,config.DBUser,config.DBPassword,config.DBName,config.DBPort,)// 配置 GORMgormConfig := &gorm.Config{}// 根據環境設置日志級別,開發模式下顯示 SQL 日志,生產模式下靜默。if utils.IsDevelopment() {gormConfig.Logger = logger.Default.LogMode(logger.Info)utils.LogInfo("PostgreSQL debug mode enabled")} else {gormConfig.Logger = logger.Default.LogMode(logger.Silent)}// 連接數據庫var err errorDB, err = gorm.Open(postgres.Open(dsn), gormConfig)if err != nil {utils.LogError("Failed to connect to PostgreSQL: " + err.Error())panic(err)}// 配置連接池sqlDB, err := DB.DB()if err != nil {utils.LogError("Failed to get PostgreSQL instance: " + err.Error())panic(err)}// 設置連接池參數sqlDB.SetMaxIdleConns(10)sqlDB.SetMaxOpenConns(100)sqlDB.SetConnMaxLifetime(time.Hour) //  每個連接的最大生命周期(如過期回收)utils.LogInfo("PostgreSQL connected successfully")
}// GetDB 獲取數據庫實例
func GetDB() *gorm.DB {return DB
}// ClosePG 關閉數據庫連接
func ClosePG() {if DB != nil {sqlDB, err := DB.DB()if err != nil {utils.LogError("Failed to get PostgreSQL instance for closing: " + err.Error())return}if err := sqlDB.Close(); err != nil {utils.LogError("Failed to close PostgreSQL: " + err.Error())} else {utils.LogInfo("PostgreSQL connection closed")}}
}

在 main.go

func main() {// 1. 加載配置config := utils.LoadConfig()// 2. 初始化 PostgreSQLinfra.InitPG()defer infra.ClosePG()
}

GetDB

func GetDB() *gorm.DB {return DB
}

這是一個全局訪問數據庫實例的 Getter 函數,它的作用很簡單:

讓你在項目中任何地方通過調用 infra.GetDB() 獲取一個 *gorm.DB 實例,從而操作數據庫。

  • ? 數據庫連接在 InitPG() 初始化時創建
  • ? GetDB() 不會重復建立連接,它只是返回之前初始化好的連接指針
  • ? 它也不會自動釋放連接
問題回答
GetDB() 會不會新建連接?不會,它只是返回初始化后的 *gorm.DB 實例。
GetDB() 會不會釋放連接?不會,連接釋放由 GORM 內部連接池自動管理或由 ClosePG() 完成。
如果不主動關閉會有問題嗎?一般不會,因為連接池會回收,但優雅關閉應用時應調用 ClosePG()。
多個請求并發使用 GetDB() 安全么?是安全的,GORM 是并發安全的,底層連接池會復用連接。

GORM 的 *gorm.DB 實例是線程安全的,不會持有數據庫連接本身,只有執行 SQL 時才從連接池中臨時借用連接,執行完立即歸還。

db := infra.GetDB()
db.Find(&users)

它的實際行為如下:

  1. db := GetDB():只是獲取一個 *gorm.DB 對象,不涉及任何連接。
  2. db.Find(&users):
    • 這一步 GORM 內部會調用 sql.DB.Conn(ctx) 或 sql.DB.QueryContext(ctx);
    • 從連接池借一個連接;
    • 執行 SQL;
    • 自動關閉 rows,釋放連接,連接歸還連接池 ?
rows, err := db.Raw("SELECT * FROM users").Rows()
defer rows.Close()  // 如果忘記寫這句,連接就不會釋放!!
場景是否占用連接
GetDB()? 不占用連接
db.Find()、db.First() 等? 使用連接 → 自動釋放
SSE/流式接口 + 查詢前置? 查詢連接已釋放,SSE 是純內存流
使用 Rows() 沒有手動 Close()?? 會占用連接池

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

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

相關文章

k8s4部署

configMap configmap概述:數據會存儲在etcd數據庫,其應用場景主要在應用程序的配置 configmap支持的類型(1)鍵值對(2)多行數據 pod使用configmap資源有兩種常見的方式(1)變量注入&a…

2025HNCTF - Crypto

Crypto lcgp 題目: from Crypto.Util.number import * import gmpy2 import random n getPrime(1024) flag bH&NCTF{ str(uuid.uuid4()).encode() b} flagbytes_to_long(flag) e 2024 cpow(e, flag, n)class LCG:def __init__(self, seed, a, b, m):sel…

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在離線機器上運行軟件,所以得把軟件用docker打包起來,大部分功能都沒問題,出了一個奇怪的事情。同樣的代碼,在本機上用vscode可以運行起來,但是打包之后在docker里出現了問題。使用的是dialog組件,…

前后端分離開發 和 前端工程化

來源:黑馬程序員JavaWeb開發教程,實現javaweb企業開發全流程(涵蓋SpringMyBatisSpringMVCSpringBoot等)_嗶哩嗶哩_bilibili 前后端混合開發: 需要使用前端的技術棧開發前端的功能,又需要使用Java的技術棧…

QT線程同步 QReadWriteLock并發訪問

QT多線程專欄共有17篇文章,從初識線程到、QMutex鎖、QSemaphore信號量、Emit、Sgnals、Slot主線程子線程互相傳值同步變量、QWaitCondition、QReadWriteLock、事件循環、QObjects、線程安全、線程同步、線程異步、QThreadPool線程池、ObjectThread多線程操作、 moveToThread等…

【物聯網-ModBus-RTU

物聯網-ModBus-RTU ■ 優秀博主鏈接■ ModBus-RTU介紹■(1)幀結構■(2)查詢功能碼 0x03■(3)修改單個寄存器功能碼 0x06■(4)Modbus RTU 串口收發數據分析 ■ 優秀博主鏈接 Modbus …

03.數據類型

數據類型 數據長什么樣數據需要多少空間來存放系統內置數據類型用戶定義數據類型 選擇正確的數據類型對于獲得高性能至關重要 三大原則: 更小的通常更好,盡量使用可正確存儲數據的最小數據類型簡單就好,簡單數據類型的操作通常需要更少的CPU周期盡量…

達夢數據庫字段類型 varchar 轉 text

達夢數據庫字段類型 varchar 轉 text 業務場景問題浮現問題處理方式一 總結 業務場景 在初次創建達夢數據庫表的時候,僅僅設定了基礎的表字段。然而,在預估字段值的長度時,常常會出現不夠準確的情況。例如,我創建了一張參數配置表…

MyBatis 緩存機制源碼深度解析:一級緩存與二級緩存

MyBatis 緩存機制源碼深度解析:一級緩存與二級緩存 一、一級緩存1.1 邏輯位置與核心源碼解析1.2 一級緩存容器:PerpetualCache1.3 createCacheKey 方法與緩存命中1.4 命中與失效時機1.5 使用方式 二、二級緩存2.1 邏輯位置與核心源碼解析2.2 查詢流程、命…

【題解-Acwing】1097. 池塘計數

題目:1097. 池塘計數 題目描述 農夫約翰有一片 N?M 的矩形土地。 最近,由于降雨的原因,部分土地被水淹沒了。 現在用一個字符矩陣來表示他的土地。 每個單元格內,如果包含雨水,則用”W”表示,如果不含…

基于Flask框架的前后端分離項目開發流程是怎樣的?

基于Flask框架的前后端分離項目開發流程可分為需求分析、架構設計、并行開發、集成測試和部署上線五個階段。以下是詳細步驟和技術要點: 一、需求分析與規劃 1. 明確項目邊界 功能范圍:確定核心功能(如用戶認證、數據管理、支付流程&#…

板凳-------Mysql cookbook學習 (十--2)

5.12 模式匹配中的大小寫問題 mysql> use cookbook Database changed mysql> select a like A, a regexp A; ------------------------------ | a like A | a regexp A | ------------------------------ | 1 | 1 | --------------------------…

編程實驗篇--線性探測哈希表

線性探測哈希表性能測試實驗報告 1. 實驗目的 編程實現線性探測哈希表。編程測試線性探測哈希表。了解線性探測哈希表的性能特征,并運行程序進行驗證。 2. 實驗背景與理論基礎 哈希表是一種高效的數據結構,用于實現符號表(Symbol Table&a…

使用Python提取PDF元數據的完整指南

PDF文檔中包含著豐富的元數據信息,這些信息對文檔管理和數據分析具有重要意義。本文將詳細介紹如何利用Python高效提取PDF元數據,并對比主流技術方案的優劣。 ## 一、PDF元數據概述 PDF元數據(Metadata)是包含在文檔中的結構化信…

【量化】策略交易類型

通過查找相關資料,這里羅列了一些常見的策略交易類型,如下: 📊 技術分析類策略 均線交叉策略(SMA、EMA)動量策略(Momentum)相對強弱指數策略(RSI)隨機指標策…

【Go語言基礎【17】】切片:一種動態數組

文章目錄 零、概述一、切片基礎1、切片的結構2、切片的創建方式3、切片的操作與擴容 二、切片的拷貝與共享內存三、切片作為函數參數 Go語言的切片(slice)是一種動態數組,提供了靈活、高效的元素序列操作。它基于底層數組實現,通過…

MybatisPlus使用DB靜態工具出現找不到實體類的報錯

報錯:Not Found TableInfoCache. 原因在于沒有創建實體類對應的mapper,并且該mapper還必須繼承baseMapper。 猜測大概的原理應該是DB會去查找實體類對應的mapper,然后通過mapper去查找對應的實體類。

Linux nano命令的基本使用

參考資料 GNU nanoを使いこなすnano基礎 目錄 一. 簡介二. 文件打開2.1 普通方式打開文件2.2 只讀方式打開文件 三. 文件查看3.1 打開文件時,顯示行號3.2 翻頁查看 四. 文件編輯4.1 Ctrl K 復制 和 Ctrl U 粘貼4.2 Alt/Esc U 撤回 五. 文件保存與退出5.1 Ctrl …

LLMs 系列科普文(15)

前面 14 篇文章,就是本系列科普文中想介紹的大部分技術內容。重點講述了訓練這些模型的三個主要階段和范式:預訓練、監督微調和強化學習。 我向你們展示了這些步驟大致對應于我們已用于教導兒童的過程。具體來說,我們將預訓練比作通過閱讀說…

深入理解匯編語言中的順序與分支結構

本文將結合Visual Studio環境配置、順序結構編程和分支結構實現,全面解析匯編語言中的核心編程概念。通過實際案例演示無符號/有符號數處理、分段函數實現和邏輯表達式短路計算等關鍵技術。 一、匯編環境配置回顧(Win32MASM) 在Visual Studi…