前言
這周的時候,和老鐵就GoLang中mysql的“effect rows”這個問題討論起來。
關鍵點在於:在進行update操作的時候,如果不進行更新(也可以理解爲當前數據庫就是這樣子了)或者沒這條數據,effect rows都會爲0。
假設一個場景,需要區分這兩種情況,就沒法解決了。
正文
解決方案尋找過程
1. 命令行驗證
通過命令行操作數據庫,可以看到,mysql客戶端是區分了matched的行數和changed的行數,是可以區分出來上文的情況的。
2. go-mysql包源碼
終於找到方式了,那麼go的mysql包是不是可以?
後面發現golang的mysql包結果的定義是這樣:
type Result interface {
LastInsertId() (int64, error)
RowsAffected() (int64, error)
}
竟然沒有!!想象中的,Rows matched!!
3. 網上搜索
那隻好在網上尋找解決方案:
這個老外說不可能,what·s your problem?
後面發現CLIENT_FOUND_ROWS蘊含着巨大的能量。
對於update且是CLIENT_FOUND_ROWS時affected_rows返回的是found的行數。
對於update且不是CLIENT_FOUND_ROWS是返回的是實際更新的行數。
4.實戰驗證
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// 這裏是默認情況:db, err := sql.Open("mysql", "root:@/test")
// 這裏是能區分的情況
db, err := sql.Open("mysql", "root:@/test?clientFoundRows=true")
if err != nil {
panic(1)
}
stmt, err := db.Prepare("update test set name=? where id=?")
if err != nil {
panic(1)
}
res, err := stmt.Exec("34", 1)
effectRow, _ := res.RowsAffected()
fmt.Println(effectRow)
}
以上代碼單純考慮解決的角度看的,實際情況還需要考慮:
1.如果有使用mysql中間價的話,是不是開放了這個配置clientFoundRows?(因爲據我瞭解這個不是單純的開一個配置,對於中間價連接池的改造是有一定工作的)
2.開了這個配置之後,對於項目中現存的所有sql語句是否會產生未知的影響?
結論
記住clientFoundRows參數可以區分。
如果你覺得有收穫~可以關注我的公衆號【咖啡色的羊駝】~第一時間收到我的分享和知識梳理~