Go語言使用sqlx操作MySQL
Go 語言以其高效和簡潔的語法逐漸受到開發(fā)者的青睞。在實(shí)際開發(fā)中,數(shù)據(jù)庫操作是不可避免的任務(wù)之一。雖然標(biāo)準(zhǔn)庫提供了 database/sql 包來支持?jǐn)?shù)據(jù)庫操作,但使用起來略顯繁瑣。
sqlx 包作為一個(gè)擴(kuò)展庫,它在 database/sql 的基礎(chǔ)上,提供了更高級別的便利,極大地簡化了數(shù)據(jù)庫操作。本文章將介紹如何通過 github.com/jmoiron/sqlx 包來操作 MySQL 數(shù)據(jù)庫。
準(zhǔn)備工作
首先,確保你的 Go 環(huán)境已經(jīng)搭建完畢,并且 MySQL 數(shù)據(jù)庫已安裝并正在運(yùn)行。接下來,安裝 sqlx 包及 MySQL 驅(qū)動(dòng):
go get github.com/jmoiron/sqlx go get github.com/go-sql-driver/mysql
連接 MySQL 數(shù)據(jù)庫
在使用數(shù)據(jù)庫之前,我們需要建立與 MySQL 的連接。在 Go 語言中,通常使用一個(gè)連接字符串來指定數(shù)據(jù)庫的一些信息。以下是一個(gè)示例代碼,演示如何連接 MySQL 數(shù)據(jù)庫:
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql" // 一定不能忘記導(dǎo)入數(shù)據(jù)庫驅(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ù)庫連接池的最大連接數(shù)
db.SetMaxIdleConns(10) // 設(shè)置數(shù)據(jù)庫連接池的最大空閑連接數(shù)
return
}
在這個(gè)例子中,請?zhí)鎿Q為你自己的MySQL 配置。
數(shù)據(jù)庫操作
1. 創(chuàng)建表
接下來,讓我們創(chuàng)建一個(gè)示例表。我們可以使用 Exec 方法執(zhí)行 SQL 語句來創(chuàng)建表。
func CreateTable(db *sqlx.DB) (err error) {
// 寫SQL語句
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ù)來操作
// 使用命名參數(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. 測試一下代碼
func Run() {
// 初始化數(shù)據(jù)庫
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é)
通過 sqlx 包,我們可以更簡單地在 Go 中與 MySQL 數(shù)據(jù)庫進(jìn)行交互,減少了樣板代碼并提高了代碼的可讀性。
到此這篇關(guān)于Go語言使用sqlx操作MySQL的文章就介紹到這了,更多相關(guān)Go sqlx操作MySQL內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go Antlr重構(gòu)腳本解釋器實(shí)現(xiàn)示例
這篇文章主要為大家介紹了go Antlr重構(gòu)腳本解釋器實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
掌握Golang中的select語句實(shí)現(xiàn)并發(fā)編程
Golang中的select語句用于在多個(gè)通道間選擇可讀或可寫的操作,并阻塞等待其中一個(gè)通道進(jìn)行操作。可以用于實(shí)現(xiàn)超時(shí)控制、取消和中斷操作等。同時(shí),select語句支持default分支,用于在沒有任何通道可操作時(shí)執(zhí)行默認(rèn)操作2023-04-04
Go語言error的設(shè)計(jì)理念及背景演化詳解
這篇文章主要為大家介紹了Go語言error的設(shè)計(jì)理念及背景演化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12

