GO web 數(shù)據(jù)庫預處理的實現(xiàn)
上一篇文章我們進行了數(shù)據(jù)操作,都是使用占位符的方式來操作的
咱們其實可以使用 mysql 預處理的方式來操作這些
那么我們一起來看看什么是已處理呢?
什么是預處理?
了解什么是預處理,我們可以來對比一下,普通的 sql 語句執(zhí)行過程和 預處理的執(zhí)行過程
普通 sql 語句執(zhí)行過程:
- 客戶端對 SQL 語句進行 占位符 替換得到完整的 sql 語句
- 客戶端發(fā)送完整 sql 語句到 mysql 服務端
- mysql 服務端執(zhí)行完整的 sql 語句并將結(jié)果返回給客戶端
預處理執(zhí)行過程:
- 把 sql 語句分成兩部
- 命令部分
- 數(shù)據(jù)部分
- 先把命令部分發(fā)送給 mysql 服務端,mysql 服務端進行 sql 預處理
- 然后把數(shù)據(jù)部分發(fā)送給 mysql 服務端, mysql 服務端對 sql 語句進行占位符替換
- mysql 服務端執(zhí)行完整的 sql 語句并將結(jié)果返回給客戶端
通過步驟和流程,我們大概知道預處理肯定比普通的 sql 執(zhí)行快
那么預處理有啥好處?
優(yōu)化 mysql 服務器重復執(zhí)行 sql 的方法,可以提升服務器性能,提前讓服務器編譯,一次編譯多次 執(zhí)行,節(jié)省后續(xù)編譯的成本
避免 sql 注入的問題
//預處理 插入數(shù)據(jù)操作
func prepareInfo(db *sql.DB) {
sqlInfo := "insert into user (name,age)values(?,?)"
stmt, err := db.Prepare(sqlInfo)
if err != nil {
fmt.Println("Exec err : ", err)
return
}
ret, err := stmt.Exec("花豬2", 28)
if err != nil {
fmt.Println("stmt Exec err : ", err)
return
}
ret, err = stmt.Exec("花豬3", 28)
if err != nil {
fmt.Println("stmt Exec err : ", err)
return
}
rows, err := ret.RowsAffected()
if err != nil {
fmt.Println("stmt Exec err : ", err)
return
}
fmt.Println("rows = ", rows)
}
Go實現(xiàn) MySQL 的事務
開啟事務處理,會有回滾機制,全部成功了,且提交成功,才算事務處理成功
- func (db *DB) Begin() (*Tx, error) 事務開始
- func (tx *Tx) Commit() error 事務提交
- func (tx *Tx) Rollback() error 事務回滾
func trasaction(db *sql.DB) {
//開啟一個事務
tx, err := db.Begin()
if err != nil {
if tx != nil {
tx.Rollback()
}
fmt.Printf("Begin err :%v", err)
return
}
sqlStr := "update user set name='xxx' where id=?"
_, err = tx.Exec(sqlStr, 9)
if err != nil {
if tx != nil {
tx.Rollback()
}
fmt.Printf("Exec err :%v", err)
return
}
sqlStr = "update user set name='xxx' where id=?"
_, err = tx.Exec(sqlStr, 6)
if err != nil {
if tx != nil {
tx.Rollback()
}
fmt.Printf("Exec err :%v", err)
return
}
//提交事務
err = tx.Commit()
if err != nil {
if tx != nil {
tx.Rollback()
}
fmt.Printf("Commit err :%v", err)
return
}
fmt.Println("commit success ")
}
sqlx使用
咱們還可以使用第三方庫 sqlx
- 安裝第三方庫 sqlx ,go get github.com/jmoiron/sqlx
- 第三方庫可以提交高開發(fā)效率,簡化開發(fā)操作
package main
import (
"fmt"
"github.com/jmoiron/sqlx"
_ "github.com/go-sql-driver/mysql" // 注釋掉后異常 _ 調(diào)用初始化函數(shù)
)
var db *sqlx.DB
func insertInfo() {
sqlStr := "insert into user(name,age)values(?,?)"
res, err := db.Exec(sqlStr, "xxx", 2)
if err != nil {
fmt.Printf("Exec err : %v", err)
return
}
id, err := res.LastInsertId()
if err != nil {
fmt.Printf("LastInsertId err : %v", err)
return
}
fmt.Printf("id == %d", id)
rows, err := res.RowsAffected()
if err != nil {
fmt.Printf("RowsAffected err : %v", rows)
return
}
fmt.Printf("rows == %d", rows)
return
}
func main() {
var err error
dsn := "root:123456@tcp(127.0.0.1:3306)/go_test?charset=utf8mb4"
db, err = sqlx.Connect("mysql", dsn)
if err != nil {
fmt.Printf("Connect err : %v\n", err)
return
}
db.SetMaxOpenConns(20)
db.SetMaxIdleConns(10)
//插入數(shù)據(jù)
insertInfo()
}
gin + mysql + rest full api
當然 之前說到的 http 包里面的方法實現(xiàn),我們也不需要用它了,咱們也可以交給框架,真的是可以做到高效實現(xiàn)業(yè)務,但同時,自己下來還是要去對具體的實現(xiàn)原理多研究研究
實踐如下步驟:
- 導入 github.com/gin-gonic/gin 庫
- 建立 users 表, id,name,telephone字段
CREATE TABLE `users` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `name` VARCHAR(20) DEFAULT '', `telephone` VARCHAR(20) DEFAULT '', PRIMARY KEY(`id`) )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

上圖是實踐過程中產(chǎn)生的數(shù)據(jù)
- 包裝對數(shù)據(jù)庫的增刪改查操作
- 寫路由的操作
到此這篇關(guān)于GO web 數(shù)據(jù)庫預處理的實現(xiàn)的文章就介紹到這了,更多相關(guān)GO 數(shù)據(jù)庫預處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言題解LeetCode268丟失的數(shù)字示例詳解
這篇文章主要為大家介紹了Go語言題解LeetCode268丟失的數(shù)字示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
jenkins配置golang?代碼工程自動發(fā)布的實現(xiàn)方法
這篇文章主要介紹了jenkins配置golang?代碼工程自動發(fā)布,jks是個很好的工具,使用方法也很多,我只用了它簡單的功能,對jenkins配置golang相關(guān)知識感興趣的朋友一起看看吧2022-07-07
golang中的select關(guān)鍵字用法總結(jié)
這篇文章主要介紹了golang中的select關(guān)鍵字用法總結(jié),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06

