Go原始碼分析系列 sql驅動載入

2021-10-22 09:35:04 字數 2339 閱讀 9601

對於開發人員來說,程式語言或是框架都只是工具,重要的是我們的思維方式,所以,我們有些東西,我們不僅要會用,更要知曉其原理和本質。

話不多說,進入正題:

服務端開發,少不了資料庫操作,就從最基礎的開始,那就先說一下go語言中提供的乙個sql框架(database/sql)。

這個框架很輕量,輕量到只提供了乙個架子,沒有任何具體實現,我們可以通過外掛程式的方式註冊自己想要使用的資料庫,比如mysql。

下面看一段基礎的使用**:

)var db *sql.db // 連線池物件

func initdb() (err error)

err = db.ping() // 連線伺服器校驗登入資訊

if err != nil

fmt.printf("open:%s success\n", dsn)

return

}**很簡單,就是建立乙個mysql的資料庫連線池物件,這段**裡面最重要的就是這一行**:

)如果不加這一句,在「sql.open("mysql", dsn)」的時候,就會告知你沒有mysql的驅動,至於原因,我們看一下「sql.open」的原始碼:

package sql

var (

...drivers = make(map[string]driver.driver)

)func register(name string, driver driver.driver)

func open(drivername, datasourcename string) (*db, error) ), nil

}

drivers預設是空的,也就是說,只能通過register註冊驅動後,才能使用,這就是關鍵點了。

為什麼要導「github.com/go-sql-driver/mysql」包呢?因為mysql包下的driver.go做的就是初始化註冊驅動的操作:

package mysql

func init() )

}

這也就解釋了,為什麼不導包,「sql.open("mysql", dsn)」就會報錯,也能充分體現出外掛程式化的靈活性。

func main() 

defer db.close()

var u user

sql := `select id,name from user where id=?;`

row := db.queryrow(sql, 2)

err = row.scan(&u.id, &u.name)

if err != nil

fmt.printf("scan success, u = %v\n", u)

}

關鍵**在「db.queryrow」和「row.scan」這兩行,在「db.queryrow」之後,如果沒有呼叫「row.scan」,連線池就會處於乙個保持連線的狀態,占用資源,達到一定數量執行緒將會阻塞,看一下「row.scan」中的**實現就明白了:

func (r *row) scan(dest ...inte***ce{}) error
scan操作將會關閉當前queryrow建立的連線池,所以,為了避免此情況,也有很多人會採用以下寫法:

db.queryrow(sql, 2).scan(&u.id, &u.name)
至於連線池的大小,可以通過以下方式設定(一般放在初始化的時候):

db.setmaxopenconns(10)
文章主題就到這裡。

這是我寫的第一篇原始碼分析的文章,這些原始碼都很簡單,但是我相信,本文的主題會有很多人聽到「必須匯入這個驅動才能連線mysql」這句話,就結束了,但這只是結論,即便記住了這個結論,對自己未來的成長用處也不大,但如果你看了這些原始碼,你能了解的不僅僅是為什麼會有這個結論,還會學習到,別人的程式設計風格和程式設計的方式,當然每個人看到的點可能都會不太一樣,但可以確定的是,這些東西隨著你的不斷積累,會潛移默化的帶給你一些思維方式的改變,所以,保持這個好奇心,持續學下去。

作者寄語:

我們缺乏的常常不是編碼能力,而是思考能力。

既然熱愛程式設計,那就靜下心來,要知道,每乙個台階,都可以是終點,也可以是新的起點。

go原始碼分析 channel

1 傳送者流程 1 常規檢查 傳送乙個已經關閉的chan會直接觸發panic 2 檢視接受則阻塞佇列中是否有sudog 對應的乙個goroutine,注意是dequeue操作 如果有則直接傳送訊息到阻塞的goroutine gp.param unsafe.pointer sg 直接進行指標賦值,具體...

Redis原始碼分析系列

redis目前熱門nosql記憶體資料庫,量不是很大,本系列是本人閱讀redis原始碼時記錄的筆記,由於時間倉促和水平有限,文中難免會有錯誤之處,歡迎讀者指出,共同學習進步,本文使用的redis版本是2.8.19。redis之hash資料結構 redis之intset資料結構 redis之skipl...

jQuery原始碼分析系列

斷斷續續地看jquery原始碼,第一次萌生看jq原始碼的念頭,當時還是版本1.7.2,由於工作中沒有用到jq的機會,連 有幾種用法都還不知道,就開始啃原始碼,痛苦自然是少不了的,於是不久就放棄扔一邊了。等到工作中終於就機會用jq了 撒花 又萌生了啃jq原始碼的念頭,此時jq版本已經是2.0了。鑑於瀏...