GoFrame 鏈?zhǔn)讲僮?模型創(chuàng)建

2022-04-01 16:14 更新

模型創(chuàng)建

Model

?Model?方法用于創(chuàng)建基于數(shù)據(jù)表的?Model?對象。常見的,也可以使用?g?對象管理模塊中的?Model?方法在默認(rèn)的數(shù)據(jù)庫配置上創(chuàng)建?Model?對象。

使用示例:

g.Model("user")
// 或者或者
g.DB().Model("user")

此外,在某些場景下,我們也可以通過?DB?方法切換當(dāng)前模型的數(shù)據(jù)庫對象,例如:

m := g.Model("user")
m  = m.DB(g.DB("user-center"))

其效果與以下操作是一樣的:

m := g.DB("user-center").Model("user")

Raw

?Raw?方法用于創(chuàng)建一個(gè)基于原始?SQL?語句的?Model?對象。也可以使用?g?對象管理模塊中的?ModelRaw?方法通過給定的?SQL?語句在默認(rèn)的數(shù)據(jù)庫配置上創(chuàng)建?Model?對象。

s := "SELECT * FROM `user` WHERE `status` IN(?)"
m := g.ModelRaw(s, g.Slice{1,2,3}).WhereLT("age", 18).Limit(10).OrderAsc("id").All()
// SELECT * FROM `user` WHERE `status` IN(1,2,3) AND `age`<18 ORDER BY `id` ASC LIMIT 10

鏈?zhǔn)桨踩?

鏈?zhǔn)桨踩皇悄P筒僮鞯膬煞N方式區(qū)別:一種會修改當(dāng)前?model?對象(不安全,默認(rèn)),一種不會(安全)但是模型屬性修改/條件疊加需要使用賦值操作,僅此而已。

默認(rèn)情況

在默認(rèn)情況下,?gdb?是非鏈?zhǔn)桨踩模簿褪钦f鏈?zhǔn)讲僮鞯拿恳粋€(gè)方法都將對當(dāng)前操作的?Model?屬性進(jìn)行修改,因此該?Model?對象不可以重復(fù)使用。例如,當(dāng)存在多個(gè)分開查詢的條件時(shí),我們可以這么來使用?Model?對象:

user := g.Model("user")
user.Where("status IN(?)", g.Slice{1,2,3})
if vip {
    // 查詢條件自動(dòng)疊加,修改當(dāng)前模型對象
    user.Where("money>=?", 1000000)
} else {
    // 查詢條件自動(dòng)疊加,修改當(dāng)前模型對象
    user.Where("money<?",  1000000)
}
//  vip: SELECT * FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT * FROM user WHERE status IN(1,2,3) AND money < 1000000
r, err := user.All()
//  vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money < 1000000
n, err := user.Count()

可以看到,如果是分開執(zhí)行鏈?zhǔn)讲僮?,鏈?zhǔn)降拿恳粋€(gè)操作都會修改已有的?Model?對象,查詢條件會自動(dòng)疊加,因此?user?對象不可重復(fù)使用,否則條件會不停疊加。并且在這種使用方式中,每次我們需要操作?user?用戶表,都得使用?g.DB().Table("user")?這樣的語法創(chuàng)建一個(gè)新的?user?模型對象,相對來說會比較繁瑣。

默認(rèn)情況下,基于性能以及?GC?優(yōu)化考慮,模型對象為非鏈?zhǔn)桨踩?,防止產(chǎn)生過多的臨時(shí)模型對象。

Clone方法

此外,我們也可以手動(dòng)調(diào)動(dòng)?Clone?方法克隆當(dāng)前模型,創(chuàng)建一個(gè)新的模型來實(shí)現(xiàn)鏈?zhǔn)桨踩捎谑切碌哪P蛯ο?,因此并不?dān)心會修改已有的模型對象的問題。例如:

// 定義一個(gè)用戶模型單例
user := g.Model("user")
// 克隆一個(gè)新的用戶模型
m := user.Clone()
m.Where("status IN(?)", g.Slice{1,2,3})
if vip {
    m.And("money>=?", 1000000)
} else {
    m.And("money<?",  1000000)
}
//  vip: SELECT * FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT * FROM user WHERE status IN(1,2,3) AND money < 1000000
r, err := m.All()
//  vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money < 1000000
n, err := m.Count()

Safe方法

當(dāng)然,我們可以通過?Safe?方法設(shè)置當(dāng)前模型為鏈?zhǔn)桨踩膶ο?,后續(xù)的每一個(gè)鏈?zhǔn)讲僮鞫紝⒎祷匾粋€(gè)新的?Model?對象,該?Model?對象可重復(fù)使用。但需要特別注意的是,模型屬性的修改,或者操作條件的疊加,需要通過變量賦值的方式(?m = m.xxx?)覆蓋原有的模型對象來實(shí)現(xiàn)。例如:

// 定義一個(gè)用戶模型單例
user := g.Model("user").Safe()
m := user.Where("status IN(?)", g.Slice{1,2,3})
if vip {
    // 查詢條件通過賦值疊加
    m = m.And("money>=?", 1000000)
} else {
    // 查詢條件通過賦值疊加
    m = m.And("money<?",  1000000)
}
//  vip: SELECT * FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT * FROM user WHERE status IN(1,2,3) AND money < 1000000
r, err := m.All()
//  vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money < 1000000
n, err := m.Count()

可以看到,示例中的用戶模型單例對象?user?可以重復(fù)使用,而不用擔(dān)心被“污染”的問題。在這種鏈?zhǔn)桨踩姆绞较?,我們可以?chuàng)建一個(gè)用戶單例對象?user?,并且可以重復(fù)使用到后續(xù)的各種查詢中。但是存在多個(gè)查詢條件時(shí),條件的疊加需要通過模型賦值操作(?m = m.xxx?)來實(shí)現(xiàn)。

使用?Safe?方法標(biāo)記之后,每一個(gè)鏈?zhǔn)讲僮鞫紝?chuàng)建一個(gè)新的臨時(shí)模型對象(內(nèi)部自動(dòng)使用?Clone?實(shí)現(xiàn)模型克?。?,從而實(shí)現(xiàn)鏈?zhǔn)桨踩?。這種使用方式在模型操作中比較常見。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號