Golang數據庫操縱對IN語句的支持


一:

在實際的工程項目中,SQL通常使用預編譯的形式進行執行操縱,可以有效的防止SQL注入的風險,提高編碼的規范性。
golang中使用sqlx進行sql查詢的時候,在使用in語句在一個集合中查詢的時候,若使用預編譯形式則通常有兩種形式:
方法一:
使用語言的for語句循環生成SQL語句中的“?”,類似這樣:

list:=[]int{1,2,4,66}
sql:="select * from books where book_id IN (%s)"
inStatus:=""
params:=make([]interface{},0)
for i:=0;i<len(list);i++{
    if i==0{
        inStatus+="?"
    }else{
        inStatus+=",?"
    }
    params=append(params , list[i])
}
sql = fmt.Sprintf(sql ,inStatus )
db.Exec(sql , params...)

 

方法二:
其實sqlx內置了一個In()方法用於處理這種情況,可以使得對in的處理十分優雅。
其實該方法的實現和我們方法一的處理原理類似。

// In expands slice values in args, returning the modified query string
// and a new arg list that can be executed by a database. The `query` should
// use the `?` bindVar.  The return value uses the `?` bindVar.

func In(query string, args ...interface{}) (string, []interface{}, error) 

輸入的參數query是一個sql語句,其中的需要使用In list的地方使用(?)代替,args為按照前后順序的查詢參數,按照實際對應?的次序的若干個參數。返回值有三個:
第一個,string,是處理完后的sql語句,其中的In查詢語句中的一個?已經按照實際的list長度進行處理,替換為多個“?”
第二個,[]interface{},查詢參數列表,
第三個,error,錯誤對象

bookList:=make([]Book , 0)
sql := "SELECT * FROM books where book_id IN (?) AND status != ? ORDER BY create_time DESC"
ids:=[]int{122,211,110}
sql, args, err := sqlx.In(sql, ids, model.StatusSelfDeleted) //model.StatusSelfDeleted="DELETED"
if err != nil {
    return bookList
}
err = db.Select(&bookList, sql, args...) //db為*sqlx.DB類型

其中sqlx.In函數返回的sql如下:

SELECT * FROM books where book_id IN (?,?,?) AND status != ? ORDER BY create_time DESC 

args為:

[122,211,110,"DELETED"]

 

二:

如果的數組中有兩個int,構建它:

SELECT some_column
FROM table_name
WHERE id IN (?, ?)

如果你有四個,構建:

SELECT some_column
FROM table_name
WHERE id IN (?, ?, ?, ?)

等等。你需要的是一個簡單的函數,可以產生n占位符; 有很多方法可以做到這一點:

func placeholders(n int) string {
    ps := make([]string, n)
    for i := 0; i < n; i++ {
        ps[i] = "?"
    }
    return strings.Join(ps, ",")
}

或者:

func placeholders(n int) string {
    var b strings.Builder
    for i := 0; i < n - 1; i++ {
        b.WriteString("?,")
    }
    if n > 0 {
        b.WriteString("?")
    }
    return b.String()
}
uery := fmt.Sprintf("select some_column from table_name where id in (%s)", placeholders(len(idsToGet)))
rows, err := db.Query(query, idsToGet...)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM