友情提示:此篇文章大約需要閱讀 6分鐘 41秒,不足之處請多指教,感謝你的閱讀。 訂閱本站
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括新津縣網(wǎng)站建設(shè)、新津縣網(wǎng)站制作、新津縣網(wǎng)頁制作以及新津縣網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,新津縣網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到新津縣省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!預(yù)處理預(yù)處理是 MySQL 為了防止客戶端頻繁請求的一種技術(shù),是對相同處理語句進(jìn)行預(yù)先加載在 MySQL 中,將操作變量數(shù)據(jù)用占位符來代替,減少對 MySQL 的頻繁請求,使得服務(wù)器高效運(yùn)行。
在這里客戶端并不是前臺(tái)后臺(tái)之間的 C/S 架構(gòu),而是后臺(tái)程序?qū)?shù)據(jù)庫服務(wù)器進(jìn)行操作的 C/S 架構(gòu),這樣就可以簡要地理解了后臺(tái)程序作為 Client 向 MySQL Server 請求并處理結(jié)果了。
相關(guān)學(xué)習(xí)推薦:GO語言教程
普通 SQL 執(zhí)行處理過程:
在客戶端準(zhǔn)備 SQL 語句;發(fā)送 SQL 語句到 MySQL 服務(wù)器;在 MySQL 服務(wù)器執(zhí)行該 SQL 語句;服務(wù)器將執(zhí)行結(jié)果返回給客戶端。預(yù)處理執(zhí)行處理過程:
將 SQL 拆分為結(jié)構(gòu)部分與數(shù)據(jù)部分;在執(zhí)行 SQL 語句的時(shí)候,首先將前面相同的命令和結(jié)構(gòu)部分發(fā)送給 MySQL 服務(wù)器,讓 MySQL 服務(wù)器事先進(jìn)行一次預(yù)處理(此時(shí)并沒有真正的執(zhí)行 SQL 語句);為了保證 SQL 語句的結(jié)構(gòu)完整性,在第一次發(fā)送 SQL 語句的時(shí)候?qū)⑵渲锌勺兊臄?shù)據(jù)部分都用一個(gè)數(shù)據(jù)占位符來表示;然后把數(shù)據(jù)部分發(fā)送給 MySQL 服務(wù)端,MySQL 服務(wù)端對 SQL 語句進(jìn)行占位符替換;MySQL 服務(wù)端執(zhí)行完整的 SQL 語句并將結(jié)果返回給客戶端。預(yù)處理優(yōu)點(diǎn)預(yù)處理語句大大減少了分析時(shí)間,只做了一次查詢(雖然語句多次執(zhí)行);綁定參數(shù)減少了服務(wù)器帶寬,只需發(fā)送查詢的參數(shù),而不是整個(gè)語句;預(yù)處理語句針對** SQL 注入**是非常有用的,因?yàn)閰?shù)值發(fā)送后使用不同的協(xié)議,保證了數(shù)據(jù)的合法性。Go 語言實(shí)現(xiàn)在 Go 語言中,使用db.Prepare()
方法實(shí)現(xiàn)預(yù)處理:
func (db *DB) Prepare(query string) (*Stmt, error)
Prepare 執(zhí)行預(yù)處理 SQL 語句,并返回 Stmt 結(jié)構(gòu)體指針,進(jìn)行數(shù)據(jù)綁定操作。
查詢操作使用db.Prepare()
方法聲明預(yù)處理 SQL,使用stmt.Query()
將數(shù)據(jù)替換占位符進(jìn)行查詢,更新、插入、刪除操作使用stmt.Exec()
來操作。
// 預(yù)處理查詢數(shù)據(jù)func prepareQuery() { sqlStr := "SELECT id,name,age FROM user WHERE id > ?" stmt, err := db.Prepare(sqlStr) if err != nil { fmt.Printf("prepare sql failed, err:%v\\n", err) return } rows, err := stmt.Query(1) if err != nil { fmt.Printf("exec failed, err:%v\\n", err) return } defer rows.Close() for rows.Next() { var u user err := rows.Scan(&u.id, &u.name, &u.age) if err != nil { fmt.Printf("scan data failed, err:%v\\n", err) return } fmt.Printf("id:%d, name:%s, age:%d\\n", u.id, u.name, u.age) }}預(yù)處理更新示例
// 預(yù)處理更新數(shù)據(jù)func prepareUpdate() { sqlStr := "UPDATE user SET age = ? WHERE id = ?" stmt, err := db.Prepare(sqlStr) if err != nil { fmt.Printf("prepare sql failed, err:%v\\n", err) return } _, err = stmt.Exec(18, 2) if err != nil { fmt.Printf("exec failed, err:%v\\n", err) return } fmt.Printf("prepare update data success")}預(yù)處理插入示例
// 預(yù)處理更新數(shù)據(jù)func prepareUpdate() { sqlStr := "UPDATE user SET age = ? WHERE id = ?" stmt, err := db.Prepare(sqlStr) if err != nil { fmt.Printf("prepare sql failed, err:%v\\n", err) return } _, err = stmt.Exec(18, 2) if err != nil { fmt.Printf("exec failed, err:%v\\n", err) return } fmt.Printf("prepare update data success")}預(yù)處理刪除示例
// 預(yù)處理刪除數(shù)據(jù)func prepareDelete() { sqlStr := "DELETE FROM user WHERE id = ?" stmt, err := db.Prepare(sqlStr) if err != nil { fmt.Printf("prepare sql failed, err:%v\\n", err) return } result, err := stmt.Exec(3) n, err := result.RowsAffected() if err != nil { fmt.Printf("delete rows failed, err:%v\\n", err) return } if n > 0 { fmt.Printf("delete data success") } else { fmt.Printf("delete data error") }