2015-10-16 41 views
-2

我想返回給定的一個屬性,可以是user_id,電子郵件或名稱的所有用戶信息。golang返回第一個字段從結構

u := User{ 
Email: "[email protected]" 
}) 
k := User { 
Name: "john" 
} 

ReturnUserInfo(u) 
ReturnUserInfo(k) 

我調用了只傳遞一個字段的User結構的函數。然後我想解析這個字段,而不用明文地說電子郵件。最後,我通過傳遞一個隱含的字段(USER_ID或電子郵件等)

func ReturnUserInfo(u User) (y User){ 
    // Retrieve first field from u and set them to field and value. 
    // NOT explicitly stating field := email, value := u.Email 

    db, _ := sql.Open("mysql", "root:[email protected]/users") 
    _ := db.QueryRow("SELECT user_id, name, email FROM users WHERE ? = ?", field, value).Scan(
     &u.User_id, &u.Name, &u.Email) 
    y = User{ 
     User_id: u.User_id, 
     Name: u.Name, 
     Email: u.Email, 
    } 
    return y 

} 

我不知道如果我能做到這一點在Golang獲得用戶信息,但我創建這個功能,所以我做的不必明確告訴Go去尋找一個特定的屬性來返回用戶的信息。

+1

由於只有兩個選項,因此按名稱明確指出字段有什麼問題?這是一個簡單的if-else語句來寫出你的where子句。如果你的真實用例有很多字段,而不僅僅是一對夫婦,那麼我可以理解想要使用反射,但它是編寫查詢的不可預知的方式。就像你可以談論所有的領域,並使用數組中的第一個值來設置你的位置,但是當具有值的第一項是一些隨機無意義的非識別列時會發生什麼? – evanmcdonnal

+0

我想寫這樣的函數並不實際,特別是現在我想到了驗證。我會用你建議的if-else結構。 – goda

回答

0

你想要什麼有幾個不好或至少有爭議的設計決定。

1)SQL語句不能使用「WHERE?=?」。列的名稱不能用?替換,只有值可以。它不是由golang引起的,而是由數據庫引起的,因爲它在獲取請求時創建一個計劃如何獲取數據(使用哪種索引或全表掃描或...)。

這意味着您必須爲每個列創建不同的查詢字符串,您要在where子句中使用。它可以看起來像這樣:

func GetUserInfoByColumn(field string) *User, error { 
query := fmt.Sprintf("SELECT user_id, name, email FROM users WHERE %s = ?", column) 
    var u User 
    err := db.QueryRow(query, value).Scan(&u.User_id, &u.Name, &u.Email) 
    if err != nil {return nil, err} 
    return &u, nil 
    } 

更有效的是使用閉包並在那裏創建查詢。

2)db.QueryRow看起來像另一個問題。只有您確定只有一行符合您的標準,您才能使用它。如果您不確定,請使用db.Query。

3)在你可以使用反射來獲得struct中所有項目的名稱。但是如果你的結構只有很少的字段,那就太複雜了。在我們的例子中,你可以簡單地創建所有必要的功能。

4)我不明白你爲什麼試圖填充總是隻有一個結構域,並把過濾器放入結構。有沒有更好的功能,只需在適當的代碼位置調用UserInfoByName或UserInfoByEmail?爲什麼你試圖選擇過濾器認證領域?

+0

我可以寫出明確的功能,我首先做了。我認爲我可以讓一個功能處理所有這些功能。但共識是,它會導致太多的複雜性,這是有道理的sql – goda

+0

使用閉包使寫入功能更容易。他們可以簡單地編寫一個函數,該函數的參數是字段,並返回給你一個函數,選擇這個字段。 – lofcek