Golang數(shù)據(jù)庫(kù)編程之GORM庫(kù)入門
我們知道使用Go語言的標(biāo)準(zhǔn)庫(kù)sql/database包操作數(shù)據(jù)庫(kù)的過程,雖然使用sql/database包操作數(shù)據(jù)也是挺方便的,但是需要自己寫每一條SQL語句,因此我們可能會(huì)自己再度進(jìn)行封裝,以便更好地使用,而使用現(xiàn)有Go語言開源ORM框架則是代替自己封裝的一個(gè)更好的方式。
ORM,即對(duì)象關(guān)系映射(Object Relational Mapping),可以簡(jiǎn)單理解為將關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)表映射為編程語言中的具體的數(shù)據(jù)類型(如struct),而GORM庫(kù)就是一個(gè)使用Go語言實(shí)現(xiàn)的且功能非常完善易使用的ORM框架。
下面一起來探索一下如何使用GORM框架吧!
特性
關(guān)聯(lián) (Has One, Has Many, Belongs To, Many To Many, 多態(tài))
鉤子 (在創(chuàng)建/保存/更新/刪除/查找之前或之后)
預(yù)加載
事務(wù)
復(fù)合主鍵
SQL 生成器
數(shù)據(jù)庫(kù)自動(dòng)遷移
自定義日志
可擴(kuò)展性, 可基于 GORM 回調(diào)編寫插件
如何安裝
安裝GORM非常簡(jiǎn)單,使用go get -u就可以在GOPATH目錄下安裝最新GROM框架。
go?get?-u?github.com/jinzhu/gorm安裝之后,便可以使用import關(guān)鍵字導(dǎo)入GORM庫(kù),開始使用啦!
import?"github.com/jinzhu/gorm"
支持的數(shù)據(jù)庫(kù)
GORM框架支持MySQL,SQL Server,Sqlite3,PostgreSQL四種數(shù)據(jù)庫(kù)驅(qū)動(dòng),如果我們要連接這些數(shù)據(jù)庫(kù),則需要導(dǎo)入不同的驅(qū)動(dòng)包及定義不同格式的DSN(Data Source Name)。
MySQL
1. 導(dǎo)入
import?_?"github.com/jinzhu/gorm/dialects/mysql"
//或者//import?_?"github.com/go-sql-driver/mysql"
2. DSN
//user指用戶名,password指密碼,dbname指數(shù)據(jù)庫(kù)名
"user:password@/dbname?charset=utf8&parseTime=True&loc=Local"
SQL Server
1. 導(dǎo)入
import?_?"github.com/jinzhu/gorm/dialects/mssql"
2. DSN
//username指用戶名,password指密碼,host指主機(jī)地址,port指端口號(hào),database指數(shù)據(jù)庫(kù)名
"sqlserver://username:password@host:port?database=dbname"
Sqlite3
1. 導(dǎo)入
import?_?"github.com/jinzhu/gorm/dialects/sqlite"
2. DSN
連接Sqlite3數(shù)據(jù)庫(kù)的DSN只需要指定Sqlite3的數(shù)據(jù)庫(kù)文件的路徑即可,如:
//數(shù)據(jù)庫(kù)路徑
/tmp/gorm.db
PostgreSQL
1. 導(dǎo)入
import?_?"github.com/jinzhu/gorm/dialects/postgres"
2. DSN
//host指主機(jī)地址,port指端口號(hào),user指用戶名,dbname指數(shù)據(jù)庫(kù)名,password指密碼
host=myhost?port=myport?user=gorm?dbname=gorm?password=mypassword
連接數(shù)據(jù)庫(kù)
上面我們定義了連接不同的數(shù)據(jù)庫(kù)的DSN,下面演示如果連接數(shù)據(jù)庫(kù),使用gorm.Open()方法可以初始化并返回一個(gè)gorm.DB結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體封裝了GORM框架所有的數(shù)據(jù)庫(kù)操作方法,下面是gorm.Open()方法的定義:
func?Open(dialect?string,?args?...interface{})?(db?*DB,?err?error)
示例代碼:
package?main
import?"github.com/jinzhu/gorm"
import?_?"github.com/jinzhu/gorm/dialects/mysql"//導(dǎo)入連接MySQL數(shù)據(jù)庫(kù)的驅(qū)動(dòng)包
//DSN
const?DSN?=?"root:123456@tcp(localhost:3306)/test?charset=utf8&parseTime=True&loc=Local"
//指定驅(qū)動(dòng)
const?DRIVER?=?"mysql"
var?db?*gorm.DB
func?init()?{
????var?err?error
????db,err?=?gorm.Open(DRIVER,DSN)
????if?err?!=?nil{
????????panic(err)
????}
}
func?main(){
????defer?db.Close()//退出前執(zhí)行關(guān)閉
????//調(diào)用db執(zhí)行具體的邏輯
}
gorm.DB結(jié)構(gòu)體,這樣在下面的例子可以直接使用變量db直接進(jìn)行數(shù)據(jù)庫(kù)操作。基本操作
使用gorm.Open()函數(shù)返回一個(gè)gorm.DB結(jié)構(gòu)體后,我們可以使用gorm.DB結(jié)構(gòu)體提供的方法操作數(shù)據(jù)庫(kù),下面我們演示如何使用gorm.DB進(jìn)行創(chuàng)建、查詢、更新、刪除等最基本的操作。
其實(shí)gorm.DB是在Go語言的database/sql庫(kù)中的sql.DB結(jié)構(gòu)體上再封裝,因?yàn)?code style="padding: 0.2em 0.4em;outline: 0px;font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 12px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;">gorm.DB提供許多和sql.DB一樣的方法,如下所示:
func?(s?*DB)?Exec(sql?string,?values?...interface{})?*DB
func?(s?*DB)?Row()?*sql.Row
func?(s?*DB)?Rows()?(*sql.Rows,?error)
func?(s?*DB)?Scan(dest?interface{})?*DB
gorm.DB結(jié)構(gòu)體中的DB()方法,可以返回一個(gè)sql.DB對(duì)象,如下:func?(s?*DB)?DB()?*sql.DB
gorm.DB結(jié)構(gòu)體中一些更簡(jiǎn)便的方法進(jìn)行數(shù)據(jù)庫(kù)基本操作,不過,在演示之前,我們需要先定義一個(gè)模型,如下:type?User?struct?{
????Id???????int???//對(duì)應(yīng)數(shù)據(jù)表的自增id
????Username?string
????Password?string
????Email????string
????Phone????string
}
User的結(jié)構(gòu)體,GROM支持將結(jié)構(gòu)體按規(guī)則映射為某個(gè)數(shù)據(jù)表的一行,結(jié)構(gòu)體的每個(gè)字段表示數(shù)據(jù)表的列,結(jié)構(gòu)體的字段首字母必須是大寫的。創(chuàng)建
使用gorm.DB中的Create()方法,GORM會(huì)根據(jù)傳給Create()方法的模型,向數(shù)據(jù)表插入一行。
func?(s?*DB)?Create(value?interface{})?*DB??//創(chuàng)建一行
func?(s?*DB)?NewRecord(value?interface{})?bool?//根據(jù)自增id判斷主鍵是否存在

示例
func?main()?{
????defer?db.Close()
????//具體的邏輯
????u?:=?&User{Username:?"test_one",?Password:?"testOne123456",?Email:?"[email protected]",?Phone:?"13711112222"}
????db.Create(u)
????if?db.NewRecord(u){
????????fmt.Println("寫入失敗")
????}else{
????????fmt.Println("寫入成功")
????}
}
查詢
GROM框架在sql/database包的原生基礎(chǔ)上封裝了簡(jiǎn)便的方法,可以直接調(diào)用便將數(shù)據(jù)映射到對(duì)應(yīng)的結(jié)構(gòu)體模型中,用起來非常簡(jiǎn)單,如下面這幾個(gè)方法:
//返回第一條
func?(s?*DB)?First(out?interface{},?where?...interface{})?*DB
//返回最后一條
func?(s?*DB)?Last(out?interface{},?where?...interface{})?*DB
//返回符合條件的內(nèi)容
func?(s?*DB)?Find(out?interface{},?where?...interface{})?*DB
//返回Count(*)結(jié)果
func?(s?*DB)?Count(value?interface{})?*DB
示例代碼
//Find方法示例 公眾號(hào):碼農(nóng)編程進(jìn)階筆記
func?find()?{
????var?users?=?make([]*User,?0)
????db.Model(&User2{}).Find(&users)
????fmt.Println(users)
}
//First方法示例
func?first()??{
????var?user1,user2?User
????db.First(&user1)
????fmt.Println(user1)
????db.First(&user2,"id?=??",20)
????fmt.Println(user2)
}
//Last方法示例
func?last()??{
????var?user1,user2?User
????db.Last(&user1)
????fmt.Println(user1)
????db.First(&user2,"id?=??",19)
????fmt.Println(user2)
}
//Count方法示例
func?count()??{
????var?count?int
????db.Model(&User{}).Count(&count)
????fmt.Println(count)
}
更新
更新數(shù)據(jù)可以使用gorm.DB的Save()或Update(),UpdateColumn(),UpdateColumns(),Updates()等方法,后面這四個(gè)方法需要與Model()方法一起使用。
func?(s?*DB)?Save(value?interface{})?*DB
func?(s?*DB)?Model(value?interface{})?*DB
//下面的方法需要與Model方法一起使用,通過Model方法指定更新數(shù)據(jù)的條件
func?(s?*DB)?Update(attrs?...interface{})?*DB
func?(s?*DB)?UpdateColumn(attrs?...interface{})?*DB
func?(s?*DB)?UpdateColumns(values?interface{})?*DB
func?(s?*DB)?Updates(values?interface{},?ignoreProtectedAttrs?...bool)?*DB
代碼示例
//Save()方法示例
func?save(){
????u?:=?&User{}
????db.First(u)
????u.Email?=?"[email protected]"
????db.Save(u)
????fmt.Println(u)
}
//Update方法示例
func?update()?{
????u?:=?&User{}
????db.First(u)
????db.Model(u).Update("username",?"hello")
}
//Updates方法示例
func?updates()?{
????u?:=?&User{}
????db.First(u)
????db.Model(&u).Updates(map[string]interface{}{"username":?"hello2"})
}

點(diǎn)個(gè)贊,證明你還愛我
刪除
使用gorm.DB的Delete()方法可以很簡(jiǎn)單地刪除滿足條件的記錄,下面是Delete()方法的定義:
//value如果有主鍵id,則包含在判斷條件內(nèi),通過where可以指定其他條件
func?(s?*DB)?Delete(value?interface{},?where?...interface{})?*DB
示例代碼
func?delete(){
????defer?db.Close()
????u?:=?&User{Id:?16}
????db.Delete(u)//根據(jù)id
????db.Delete(&User{},"username?=???","test_one")//根據(jù)額外條件刪除
}
小結(jié)
在這篇文章中我們只是講解使用GROM框架如何連接和簡(jiǎn)單操作數(shù)據(jù)庫(kù)而已,其實(shí)GROM框架還有許多更加高級(jí)功能,可以讓我們的開發(fā)變得更加簡(jiǎn)潔,在之后的文章中,我們?cè)龠M(jìn)行詳細(xì)講解吧。

