如果你曾经在Go语言连接MySQL时遇到过各种奇葩错误,别担心,你不是一个人——我见过太多人在同一个坑里翻车了!
一、MySQL驱动:数据库连接的“护照”
在Go语言中连接MySQL数据库,首先需要安装MySQL驱动程序。这就像你要去国外旅游,必须先办好护照一样重要。
1.1 安装MySQL驱动
打开终端,执行以下命令:
go get -u github.com/go-sql-driver/mysql
这个命令会从GitHub下载并安装MySQL驱动到你的Go环境中。
常见坑点:如果你使用了Go模块,请确保在go.mod文件中 require了该驱动,特别是在项目中首次使用时。
1.2 导入必要的包
在Go代码中,需要导入以下包:
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
注意这里的下划线前缀:这表示我们只导入包中的初始化函数,而不直接使用包中的其他函数或变量。这种用法叫做空白导入,对于数据库驱动来说是必须的。
小知识:为什么需要这样导入?因为Go语言的database/sql包采用了驱动注册机制,空白导入会调用MySQL包中的init函数,将驱动自动注册到sql包中。
二、建立数据库连接:打开MySQL的"大门"
2.1 连接字符串的奥秘
连接字符串是建立数据库连接的关键,它告诉Go程序如何连接到你的MySQL数据库。基本格式如下:
dsn := "username:password@tcp(127.0.0.1:3306)/dbname"
让我们拆解这个连接字符串的各个部分:
- username:你的MySQL用户名
- password:对应用户的密码
- tcp(127.0.0.1:3306):MySQL服务器地址和端口(默认3306)
- dbname:要连接的数据库名称
实际示例:如果你的用户是"root",密码是"123456",数据库是"testdb",那么连接字符串就是:
dsn := "root:123456@tcp(127.0.0.1:3306)/testdb"
2.2 实际连接代码
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// 配置数据库连接
dsn := "username:password@tcp(127.0.0.1:3306)/dbname"
// 打开数据库连接
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal("数据库连接失败:", err)
}
defer db.Close()
// 测试连接是否真正成功
err = db.Ping()
if err != nil {
log.Fatal("数据库连接测试失败:", err)
}
fmt.Println("数据库连接成功!")
}
重要提示:sql.Open()函数并不会立即建立数据库连接,它只是初始化一个数据库对象。实际的连接会在第一次执行查询时建立。使用db.Ping()可以主动测试连接是否可用,这是一个很好的编程习惯。
三、执行查询:与数据库的"对话"
连接成功后,我们就可以与MySQL数据库进行"对话"了。Go语言提供了多种执行SQL语句的方法,让我们一起来看看吧。
3.1 查询数据(SELECT)
查询数据使用db.Query()方法,适用于需要返回结果集的SELECT语句:
// 执行查询
rows, err := db.Query("SELECT id, name, email FROM users WHERE age = ?", 30)
if err != nil {
log.Fatal("查询失败:", err)
}
defer rows.Close() // 重要:记得关闭rows释放连接
// 遍历结果集
for rows.Next() {
var id int
var name string
var email string
// 将当前行数据扫描到变量中
if err := rows.Scan(&id, &name, &email); err != nil {
log.Fatal("数据扫描失败:", err)
}
fmt.Printf("ID: %d, Name: %s, Email: %s\n", id, name, email)
}
// 检查遍历过程中是否出错
if err := rows.Err(); err != nil {
log.Fatal("遍历结果集时出错:", err)
}
关键点分析:
- 使用参数化查询:在查询中使用
?作为占位符,可以防止SQL注入攻击。 - 一定要关闭rows:使用
defer rows.Close()确保结果集被正确关闭,否则会导致连接泄露。 - 遍历结果集:使用
rows.Next()循环遍历所有行,使用rows.Scan()将列值赋给变量。 - 错误检查:遍历完成后检查
rows.Err(),确保没有中途出错。
3.2 插入数据(INSERT)
插入数据使用db.Exec()方法,适用于INSERT、UPDATE、DELETE等不返回结果集的操作:
// 执行插入操作
result, err := db.Exec(
"INSERT INTO users (name, email, age) VALUES (?, ?, ?)",
"张三", "zhangsan@example.com", 25
)
if err != nil {
log.Fatal("插入失败:", err)
}
// 获取插入的ID
lastInser

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



