Go語(yǔ)言使用sqlx操作MySQL
Go 語(yǔ)言以其高效和簡(jiǎn)潔的語(yǔ)法逐漸受到開發(fā)者的青睞。在實(shí)際開發(fā)中,數(shù)據(jù)庫(kù)操作是不可避免的任務(wù)之一。雖然標(biāo)準(zhǔn)庫(kù)提供了 database/sql
包來(lái)支持?jǐn)?shù)據(jù)庫(kù)操作,但使用起來(lái)略顯繁瑣。
sqlx
包作為一個(gè)擴(kuò)展庫(kù),它在 database/sql
的基礎(chǔ)上,提供了更高級(jí)別的便利,極大地簡(jiǎn)化了數(shù)據(jù)庫(kù)操作。本文章將介紹如何通過(guò) github.com/jmoiron/sqlx
包來(lái)操作 MySQL 數(shù)據(jù)庫(kù)。
準(zhǔn)備工作
首先,確保你的 Go 環(huán)境已經(jīng)搭建完畢,并且 MySQL 數(shù)據(jù)庫(kù)已安裝并正在運(yùn)行。接下來(lái),安裝 sqlx
包及 MySQL 驅(qū)動(dòng):
go get github.com/jmoiron/sqlx go get github.com/go-sql-driver/mysql
連接 MySQL 數(shù)據(jù)庫(kù)
在使用數(shù)據(jù)庫(kù)之前,我們需要建立與 MySQL 的連接。在 Go 語(yǔ)言中,通常使用一個(gè)連接字符串來(lái)指定數(shù)據(jù)庫(kù)的一些信息。以下是一個(gè)示例代碼,演示如何連接 MySQL 數(shù)據(jù)庫(kù):
package main import ( "fmt" _ "github.com/go-sql-driver/mysql" // 一定不能忘記導(dǎo)入數(shù)據(jù)庫(kù)驅(qū)動(dòng) "github.com/jmoiron/sqlx" ) var db *sqlx.DB type User struct { ID int64 `db:"id"` Name string `db:"name"` Age int `db:"age"` } func initDB() (err error) { dsn := "root:123456@tcp(127.0.0.1:3306)/sql_test?charset=utf8mb4&parseTime=True" // 也可以使用 MustConnect 連接不成功就直接 panic // db = sqlx.MustConnect("mysql", dsn) db, err = sqlx.Connect("mysql", dsn) if err != nil { fmt.Printf("connect DB failed, err:%v\n", err) return } db.SetMaxOpenConns(20) // 設(shè)置數(shù)據(jù)庫(kù)連接池的最大連接數(shù) db.SetMaxIdleConns(10) // 設(shè)置數(shù)據(jù)庫(kù)連接池的最大空閑連接數(shù) return }
在這個(gè)例子中,請(qǐng)?zhí)鎿Q為你自己的MySQL 配置。
數(shù)據(jù)庫(kù)操作
1. 創(chuàng)建表
接下來(lái),讓我們創(chuàng)建一個(gè)示例表。我們可以使用 Exec
方法執(zhí)行 SQL 語(yǔ)句來(lái)創(chuàng)建表。
func CreateTable(db *sqlx.DB) (err error) { // 寫SQL語(yǔ)句 sqlStr := `create table if not exists users ( id bigint primary key auto_increment, name varchar(20), age int default 1 );` _, err = db.Exec(sqlStr) return err }
在 main
函數(shù)中調(diào)用 CreateTable(db)
,以確保在連接后創(chuàng)建表。
2. 插入數(shù)據(jù)
// 插入用戶并獲取 ID func insertUser(db *sqlx.DB, name string, age int) (int64, error) { result, err := db.Exec("INSERT INTO users(name, age) VALUES(?, ?)", name, age) if err != nil { return 0, err } id, err := result.LastInsertId() if err != nil { return 0, err } return id, nil }
3. 查詢數(shù)據(jù)
// 查詢單條用戶記錄 func getUser(db *sqlx.DB, id int64) (*User, error) { var user User err := db.Get(&user, "SELECT * FROM users WHERE id=?", id) if err != nil { return nil, err } return &user, nil } // 查詢所有用戶記錄 func getAllUsers(db *sqlx.DB, id int64) ([]User, error) { var users []User err := db.Select(&users, "SELECT * FROM users where id > ?", id) if err != nil { return nil, err } return users, nil }
4. 更新數(shù)據(jù)
// 更新用戶信息 func updateUser(db *sqlx.DB, id int64, name string, age int) (int64, error) { result, err := db.Exec("UPDATE users SET name=?, age=? WHERE id=?", name, age, id) if err != nil { return 0, err } rowsAffected, err := result.RowsAffected() if err != nil { return 0, err } return rowsAffected, nil }
5. 刪除數(shù)據(jù)
// 刪除用戶記錄 func deleteUser(db *sqlx.DB, id int64) (int64, error) { result, err := db.Exec("DELETE FROM users WHERE id=?", id) if err != nil { return 0, err } rowsAffected, err := result.RowsAffected() if err != nil { return 0, err } return rowsAffected, nil }
6. 使用命名參數(shù)來(lái)操作
// 使用命名參數(shù)插入用戶 func insertUserNamed(db *sqlx.DB, name string, age int) (int64, error) { query := `INSERT INTO users(name, age) VALUES(:name, :age)` result, err := db.NamedExec(query, map[string]interface{}{ "name": name, "age": age, }) if err != nil { return 0, err } id, err := result.LastInsertId() if err != nil { return 0, err } return id, nil } // 使用命名參數(shù)查詢用戶 func getUsersNamed(db *sqlx.DB, name string) ([]User, error) { query := `SELECT * FROM users WHERE name = :name` var users []User rows, err := db.NamedQuery(query, map[string]interface{}{ "name": name, }) if err != nil { return nil, err } defer rows.Close() for rows.Next() { var user User err := rows.StructScan(&user) if err != nil { fmt.Printf("scan failed, err:%v\n", err) continue } users = append(users, user) } return users, nil }
7. 測(cè)試一下代碼
func Run() { // 初始化數(shù)據(jù)庫(kù) err := initDB() if err != nil { fmt.Printf("init DB failed, err:%v\n", err) return } defer db.Close() // 注意這行代碼要寫在上面err判斷的下面 // 創(chuàng)建表 err = CreateTable(db) if err != nil { fmt.Printf("create table failed, err:%v\n", err) return } // 插入數(shù)據(jù) id, err := insertUser(db, "Alex", 18) if err != nil { fmt.Printf("insert user failed, err:%v\n", err) return } fmt.Println("insert success, the id is:", id) // 查詢單條數(shù)據(jù) user, err := getUser(db, id) if err != nil { fmt.Printf("get user failed, err:%v\n", err) return } fmt.Printf("user:%#v\n", user) // 查詢多條數(shù)據(jù) users, err := getAllUsers(db, 0) if err != nil { fmt.Printf("get all users failed, err:%v\n", err) return } fmt.Printf("users:%#v\n", users) // 更新數(shù)據(jù) rowsAffected, err := updateUser(db, id, "Alex", 20) if err != nil { fmt.Printf("update user failed, err:%v\n", err) return } fmt.Println("update success, affected rows:", rowsAffected) // 刪除數(shù)據(jù) rowsAffected, err = deleteUser(db, id) if err != nil { fmt.Printf("delete user failed, err:%v\n", err) return } fmt.Println("delete success, affected rows:", rowsAffected) // 使用命名參數(shù)插入數(shù)據(jù) id, err = insertUserNamed(db, "Alex", 19) if err != nil { fmt.Printf("insert user named failed, err:%v\n", err) return } fmt.Println("insert named success, the id is:", id) // 使用命名參數(shù)查詢數(shù)據(jù) users, err = getUsersNamed(db, "Alex") if err != nil { fmt.Printf("get users named failed, err:%v\n", err) return } fmt.Printf("users named:%#v\n", users) fmt.Println("exec SQL success") }
我們可以看到,使用 sqlx
還是要比 database/sql
要簡(jiǎn)潔許多。
總結(jié)
通過(guò) sqlx
包,我們可以更簡(jiǎn)單地在 Go 中與 MySQL 數(shù)據(jù)庫(kù)進(jìn)行交互,減少了樣板代碼并提高了代碼的可讀性。
到此這篇關(guān)于Go語(yǔ)言使用sqlx操作MySQL的文章就介紹到這了,更多相關(guān)Go sqlx操作MySQL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Go語(yǔ)言編寫簡(jiǎn)潔代碼的最佳實(shí)踐
簡(jiǎn)潔的代碼對(duì)于創(chuàng)建可維護(hù)、可閱讀和高效的軟件至關(guān)重要,Go 是一種強(qiáng)調(diào)簡(jiǎn)單和代碼整潔的語(yǔ)言,在本文中,我們將結(jié)合代碼示例,探討編寫簡(jiǎn)潔 Go 代碼的最佳實(shí)踐,需要的朋友可以參考下2023-09-09go Antlr重構(gòu)腳本解釋器實(shí)現(xiàn)示例
這篇文章主要為大家介紹了go Antlr重構(gòu)腳本解釋器實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08掌握Golang中的select語(yǔ)句實(shí)現(xiàn)并發(fā)編程
Golang中的select語(yǔ)句用于在多個(gè)通道間選擇可讀或可寫的操作,并阻塞等待其中一個(gè)通道進(jìn)行操作??梢杂糜趯?shí)現(xiàn)超時(shí)控制、取消和中斷操作等。同時(shí),select語(yǔ)句支持default分支,用于在沒(méi)有任何通道可操作時(shí)執(zhí)行默認(rèn)操作2023-04-04go語(yǔ)言Timer計(jì)時(shí)器的用法示例詳解
Go語(yǔ)言的標(biāo)準(zhǔn)庫(kù)里提供兩種類型的計(jì)時(shí)器Timer和Ticker。這篇文章通過(guò)實(shí)例代碼給大家介紹go語(yǔ)言Timer計(jì)時(shí)器的用法,代碼簡(jiǎn)單易懂,感興趣的朋友跟隨小編一起看看吧2020-05-05Go語(yǔ)言error的設(shè)計(jì)理念及背景演化詳解
這篇文章主要為大家介紹了Go語(yǔ)言error的設(shè)計(jì)理念及背景演化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12詳解golang中發(fā)送http請(qǐng)求的幾種常見情況
這篇文章主要介紹了詳解golang中發(fā)送http請(qǐng)求的幾種常見情況,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12