亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 SQL 和 gRPC 時如何使用 Scan 和 Value?

使用 SQL 和 gRPC 時如何使用 Scan 和 Value?

Go
FFIVE 2023-08-07 15:01:50
有人可以解釋如何在下面的示例中正確使用Scan()and嗎?Value()我正在嘗試使用以下示例:https://github.com/jinzhu/gorm/issues/2017#issuecomment-537627961https://github.com/travisjeffery/proto-go-sql/blob/master/_example/person_sql.go我的原型:message Timestamp {  google.protobuf.Timestamp timestamp = 1;}message User {  uint32 ID = 1;  Timestamp createdAt = 2;}代碼(需要修復time.Now()):package v1import (        "database/sql/driver"        "fmt"        "time"        "github.com/golang/protobuf/ptypes")func (u *User) Create() {  u.CreatedAt = time.Now() // FIXME: ERROR. How do I make use of Scan() and Value() here?  // saving to SQL database}func (ts *Timestamp) Scan(value interface{}) error {    switch t := value.(type) {    case time.Time:            var err error            ts.Timestamp, err = ptypes.TimestampProto(t)            if err != nil {                    return err            }    default:            return fmt.Errorf("Not a protobuf Timestamp")    }    return nil}func (ts Timestamp) Value() (driver.Value, error) {        return ptypes.Timestamp(ts.Timestamp)}
查看完整描述

1 回答

?
智慧大石

TA貢獻1946條經驗 獲得超3個贊

掃描器和評估器接口實際上并不是您自己使用的東西,至少在數據庫中存儲自定義類型時不是這樣。Scan()我將首先介紹和函數的使用Value(),然后解決您的問題。

當您獲得sql.Row結果并想要將結果集中的值分配(掃描)到自定義類型的變量中時。文檔顯示該sql.Row.Scan()函數接受 0 個或多個類型的參數interface{},基本上是任何東西。

在可以掃描值的支持類型列表中,最后一行是重要的一行:

任何實現掃描儀的類型(請參閱掃描儀文檔)

通過 function?func (ts *Timestamp) Scan(value interface{}) error {,該Timestamp類型現在實現了該Scanner接口,從而允許sql.Row向該類型分配值。該Scanner接口的文檔位于Scan()我上面鏈接的 文檔的正下方。

當然,這可以幫助您從數據庫讀取值,但在存儲這些類型時卻無濟于事。為此,您需要Valuer接口。如果您還沒有猜到,該func (ts Timestamp) Value() (driver.Value, error)函數確實使您的Timestamp類型實現了此接口。

Valuer接口的要點是允許一種將任何類型轉換為 a 的方法driver.Value,驅動程序可以使用該類型并將其存儲在數據庫中


解決問題

首先,我必須假設您的協議輸出已寫入包中v1。如果不是,它對你來說不會有很好的效果。

有問題的行確實是您標記的行:

u.CreatedAt?=?time.Now()

首先,User.CreatedAt類型為Timestamp,它本身就是一條包含單個時間戳的消息。要將CreatedAt時間設置為time.Now(),您需要CreatedAt正確初始化該字段:

u.CreatedAt?=?&Timestamp{
????Timestamp:?ptypes.TimestampNow(),?//?this?returns?a?PROTOBUF?TYPE!
????}

已經Scan在你的函數中這樣做了Value?,所以我真的不明白你為什么不在這里這樣做......


建議

如果協議輸出確實寫入了v1包,我真的真的會刪除該User.Create()函數。事實上,我會直接殺死它。您的協議緩沖區用于通信。通過 RPC 公開您的程序。這是一個 API。這些message類型本質上是請求和響應對象(如果您愿意的話,可以美化 DTO)。您正在Create向其中添加此功能,這會將它們變成 AR 類型。它使您的 protobuf 包無法使用。gRPC 的美妙之處在于您可以生成 golang、C++、Python...代碼,其他人可以使用這些代碼來調用您的程序。如果你讓你的 gRPC 包依賴于數據庫,就像你所做的那樣,我個人永遠不會使用它。


查看完整回答
反對 回復 2023-08-07
  • 1 回答
  • 0 關注
  • 127 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號