昨天发布了mysql的安装和一些预备知识,还没有涉及到代码,今天开始深入探讨如何在 Golang 中实现基本的 MySQL 数据库操作,包括如何连接数据库、执行 SQL 语句,以及如何管理事务。通过代码示例和详细讲解,相信各位优秀的开发伙伴能快速掌握这些基础技能。
1 连接数据库
在 Golang 中,常用的 MySQL 驱动是 `github.com/go-sql-driver/mysql`。该驱动提供了高效的数据库连接和操作接口。
首先,安装 MySQL 驱动:
go get -u github.com/go-sql-driver/mysql
数据库连接示例
以下代码展示了如何使用 sql.Open 和 db.Ping 方法连接 MySQL 数据库。
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// 数据库连接信息
dsn := "root:root123@tcp(127.0.0.1:3306)/mysql"
// 打开数据库连接
db, err := sql.Open("mysql", dsn)
if err != nil { // 如果连接失败,则退出程序
log.Fatalf("数据库连接失败: %v\n", err)
}
defer db.Close() // 在函数结束时关闭数据库连接
// 测试数据库连接
err = db.Ping()
if err != nil { // 如果连接失败,则退出程序
log.Fatalf("无法连接到数据库: %v\n", err)
}
fmt.Println("成功连接到数据库")
}注意
- DSN 格式:确保提供正确的用户名、密码、地址和数据库名称。
- 连接池管理:sql.Open 不会真正打开连接,而是为连接池创建一个句柄。
- 连接关闭:始终在函数结束前调用 defer db.Close() 释放资源。
2 执行 SQL 语句
Golang 提供了 Exec、Query 和 QueryRow 等方法,用于执行 SQL 语句和查询操作。
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
// 插入数据
func insertData(db *sql.DB) { // 定义一个函数,用于插入数据
sql := "INSERT INTO users (name, age) VALUES (?, ?)" // 定义SQL语句
result, err := db.Exec(sql, "风云", 35) // 执行SQL语句,并获取结果
if err != nil { // 如果插入失败,则退出程序
log.Fatalf("插入数据失败: %v\n", err)
}
id, _ := result.LastInsertId() // 获取插入数据的ID
fmt.Printf("插入成功,ID: %d\n", id)
}
// 查询数据
func queryData(db *sql.DB) { // 定义一个函数,用于查询数据
sql := "SELECT id, name, age FROM users" // 定义SQL语句
rows, err := db.Query(sql)
if err != nil { // 如果查询失败,则退出程序
log.Fatalf("查询数据失败: %v\n", err)
}
defer rows.Close() // 关闭结果集
for rows.Next() {
var id int
var name string
var age int
if err := rows.Scan(&id, &name, &age); err != nil {
log.Fatalf("读取行数据失败: %v\n", err)
}
fmt.Printf("ID: %d, Name: %s, Age: %d\n", id, name, age)
}
}
// 更新数据
func updateData(db *sql.DB) { // 定义一个函数,用于更新数据
sql := "UPDATE users SET age = ? WHERE name = ?"
result, err := db.Exec(sql, 30, "Alice") // 执行SQL语句,并获取结果
if err != nil { // 如果更新失败,则退出程序
log.Fatalf("更新数据失败: %v\n", err)
}
rowsAffected, _ := result.RowsAffected()
fmt.Printf("更新成功,影响行数: %d\n", rowsAffected)
}
// 删除数据
func deleteData(db *sql.DB) { // 定义一个函数,用于删除数据
sql := "DELETE FROM users WHERE name = ?"
result, err := db.Exec(sql, "Alice") // 执行SQL语句,并获取结果
if err != nil { // 如果删除失败,则退出程序
log.Fatalf("删除数据失败: %v\n", err)
}
rowsAffected, _ := result.RowsAffected()
fmt.Printf("删除成功,影响行数: %d\n", rowsAffected)
}
func main() {
// 数据库连接信息
dsn := "netwindcloud:netwindcloud123@tcp(127.0.0.1:3306)/netwindcloud"
// 打开数据库连接
db, err := sql.Open("mysql", dsn)
if err != nil { // 如果连接失败,则退出程序
log.Fatalf("数据库连接失败: %v\n", err)
}
defer db.Close() // 在函数结束时关闭数据库连接
// 测试数据库连接
err = db.Ping()
if err != nil { // 如果连接失败,则退出程序
log.Fatalf("无法连接到数据库: %v\n", err)
}
fmt.Println("成功连接到数据库")
// 调用 insertData 函数
// insertData(db)
queryData(db) // 调用 queryData 函数
updateData(db) // 调用 updateData 函数
// deleteData(db) // 调用 deleteData 函数
}3 事务操作
事务是一组操作的集合,这些操作要么全部成功,要么全部回滚。
事务基本用法
使用 Begin 开启事务,Commit 提交事务,Rollback 回滚事务。
func transactionExample(db *sql.DB) { // 定义一个函数,用于执行事务
tx, err := db.Begin()
if err != nil { // 如果事务开启失败,则退出程序
log.Fatalf("事务开启失败: %v\n", err)
}
// 执行第一条语句
_, err = tx.Exec("UPDATE accounts SET balance = balance - 100 WHERE id = ?", 1)
if err != nil { // 如果更新失败,则回滚事务
tx.Rollback() // 回滚事务
log.Fatalf("更新账户余额失败: %v\n", err)
}
// 执行第二条语句
_, err = tx.Exec("UPDATE accounts SET balance = balance + 100 WHERE id = ?", 2)
if err != nil { // 如果更新失败,则回滚事务
tx.Rollback() // 回滚事务
log.Fatalf("更新账户余额失败: %v\n", err)
}
// 提交事务
err = tx.Commit()
if err != nil {
log.Fatalf("提交事务失败: %v\n", err)
}
fmt.Println("事务执行成功")
}注意事项
- 异常处理:在事务中,任何错误都需要立即回滚。
- 事务嵌套:Golang 不支持事务嵌套,需要手动管理逻辑。
















