如果您想在編組/編組來自MongoDB的數據時更改值或進行類型轉換,可以通過實現自定義編組/解組邏輯來完成。
您可以通過執行bson.Getter
和bson.Setter
接口來完成此操作。在這些方法裏面,你可以做任何你想要的值,這些值是封送/解組的。
最簡單的就是用一個附加字段,一個將time.Time
類型的擴展您clientConfigData
類型,值需要:
type clientConfigData struct {
SMTPAssoc int `bson:"smtp_assoc"`
PlanType string `bson:"plan_type"`
EndDateStr string `bson:"end_date"`
EndDate time.Time `bson:"-"`
}
它標記值bson:"-"
,因爲我們不希望這樣做出現在MongoDB中。
而且現在的自定義編組/ unmarhsaling邏輯:
const endDateLayout = "2006-01-02 15:04:05" // Use your layout here
func (c *clientConfigData) SetBSON(raw bson.Raw) (err error) {
type my clientConfigData
if err = raw.Unmarshal((*my)(c)); err != nil {
return
}
c.EndDate, err = time.Parse(endDateLayout, c.EndDateStr)
return
}
func (c *clientConfigData) GetBSON() (interface{}, error) {
c.EndDateStr = c.EndDate.Format(endDateLayout)
type my *clientConfigData
return my(c), nil
}
這裏會發生什麼事是,SetBSON()
負責人向「填充」的結構值從MongoDB中來的原始值,並且GetBSON()
負責提供你想要保存的值(編組)。
當裝載:與從DB(EndDateStr
)附帶的string
日期值SetBSON()
第一解組原樣,然後適當地設置EndDate
場(是time.Time
類型的)的值。
保存時:GetBSON()
首先從EndDate
場充滿EndDateStr
場(即保存在一個),然後簡單地返回,這表明它是確定保存。
有一點需要注意:SetBSON()
和GetBSON()
都在裏面創建了一個新的my
類型。這是爲了避免堆棧溢出。簡單地返回clientConfigData
類型的值是不好的,因爲我們實現了bson.Getter
和bson.Setter
,所以SetBSON()
和GetBSON()
會被無休止地調用。新的my
類型沒有這些方法,因此不會發生無窮無盡的「遞歸」(關鍵字type
創建一個新類型,並且它不會「繼承」底層類型的方法)。
另請參閱相關的/類似的問題:Set default date when inserting document with time.Time field
所以如果我們不執行'bson.Getter'和'bson.Setter'我們可以簡單地返回'clienConfigData'吧?但在這種情況下,我們最好不要。它是否正確? –
你的問題沒有意義,因爲添加'GetBSON()'和'SetBSON()'**是實現'Getter'和'Setter'('Getter'和'Setter'是定義'GetBSON )'和'SetBSON()')。如果您不添加這些方法,則不會返回任何內容。 – icza
非常感謝@icza –