摘要:db, err := sql.Open("mysql", "root:password@tcp(localhost:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local")
在Go语言中操作MySQL数据库涉及以下步骤:
1. 安装MySQL驱动
使用go get安装官方推荐的MySQL驱动:
bash
go get -u github.com/go-sql-driver/mysql
2. 导入必要的包
go
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
3. 连接数据库
go
func main {
// 连接字符串格式:用户名:密码@协议(地址)/数据库名?参数
db, err := sql.Open("mysql", "root:password@tcp(localhost:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
log.Fatal(err)
}
defer db.Close
// 验证连接
err = db.Ping
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected successfully")
}
4. 创建表
go
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100),
created_at DATETIME
)`)
if err != nil {
log.Fatal(err)
}
5. 插入数据(使用参数化查询防止SQL注入)
go
res, err := db.Exec(
"INSERT INTO users (username, email, created_at) VALUES (?, ?, ?)",
"john_doe", "john@example.com", time.Now,
)
if err != nil {
log.Fatal(err)
}
id, _ := res.LastInsertId
fmt.Println("Inserted ID:", id)
6. 查询数据
单行查询:
go
var user struct {
ID int
Username string
Email string
CreatedAt time.Time
}
err = db.QueryRow("SELECT id, username, email, created_at FROM users WHERE id = ?", 1).Scan(
&user.ID, &user.Username, &user.Email, &user.CreatedAt,
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", user)
多行查询:
go
rows, err := db.Query("SELECT id, username, email, created_at FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close
var users struct {
ID int
Username string
Email string
CreatedAt time.Time
}
for rows.Next {
var u struct {
ID int
Username string
Email string
CreatedAt time.Time
}
err := rows.Scan(&u.ID, &u.Username, &u.Email, &u.CreatedAt)
if err != nil {
log.Fatal(err)
}
users = append(users, u)
}
if err = rows.Err; err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", users)
7. 更新和删除数据
更新:
go
_, err = db.Exec("UPDATE users SET email = ? WHERE id = ?", "new@example.com", 1)
if err != nil {
log.Fatal(err)
}
删除:
go
_, err = db.Exec("DELETE FROM users WHERE id = ?", 1)
if err != nil {
log.Fatal(err)
}
8. 事务处理
go
tx, err := db.Begin
if err != nil {
log.Fatal(err)
}
// 确保事务回滚或提交
defer func {
if err != nil {
tx.Rollback
return
}
tx.Commit
}
// 执行事务内的操作
_, err = tx.Exec("INSERT INTO users (username, email) VALUES (?, ?)", "jane", "jane@example.com")
if err != nil {
log.Fatal(err)
}
9. 处理NULL值
使用sql.NullString等类型处理可能为NULL的字段:
go
var email sql.NullString
err = db.QueryRow("SELECT email FROM users WHERE id = ?", 1).Scan(&email)
if err != nil {
log.Fatal(err)
}
if email.Valid {
fmt.Println("Email:", email.String)
} else {
fmt.Println("Email is NULL")
}
10. 连接池配置
优化数据库连接池:
go
db.SetMaxOpenConns(25) // 最大打开连接数
db.SetMaxIdleConns(25) // 最大空闲连接数
db.SetConnMaxLifetime(5 * time.Minute) // 连接最大存活时间
完整示例代码
[参考之前的代码示例,整合上述所有操作。]
注意事项
错误处理:务必检查每个数据库操作的错误。资源释放:使用defer rows.Close确保释放查询结果。SQL注入:始终使用参数化查询,避免拼接SQL字符串。时区处理:连接字符串中添加parseTime=True&loc=Local确保正确解析时间。通过以上步骤,你可以在Go中高效、安全地操作MySQL数据库。
来源:老客数据一点号