Golang MySQL操作实战
最近在学习Golang操作MySQL数据库,想请教几个实战问题:
- 如何用Golang建立MySQL连接池?最佳配置参数有哪些?
- 执行SQL查询时,如何处理结果集映射到结构体更高效?
- 事务操作有哪些需要注意的坑?比如错误处理和回滚机制
- 有没有推荐的ORM库?对比原生SQL各有什么优劣?
- 在大并发场景下,数据库操作有哪些性能优化技巧?
希望能分享一些实际项目中的经验,谢谢!
2 回复
使用Go操作MySQL,推荐使用database/sql和go-sql-driver/mysql。基本步骤:导入驱动、建立连接、执行SQL查询、处理结果。注意使用预处理防SQL注入,及时关闭连接和结果集。
更多关于Golang MySQL操作实战的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang MySQL 操作实战指南
1. 安装驱动
go get -u github.com/go-sql-driver/mysql
2. 基础连接与操作
连接数据库
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// 连接字符串格式: "用户名:密码@协议(地址:端口)/数据库名?参数"
dsn := "user:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True"
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("数据库连接成功!")
}
创建表
func createTable(db *sql.DB) error {
query := `
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)`
_, err := db.Exec(query)
return err
}
3. CRUD 操作
插入数据
func insertUser(db *sql.DB, name, email string) (int64, error) {
result, err := db.Exec(
"INSERT INTO users (name, email) VALUES (?, ?)",
name, email,
)
if err != nil {
return 0, err
}
return result.LastInsertId()
}
查询数据
type User struct {
ID int
Name string
Email string
CreatedAt time.Time
}
func getUserByID(db *sql.DB, id int) (*User, error) {
var user User
err := db.QueryRow(
"SELECT id, name, email, created_at FROM users WHERE id = ?",
id,
).Scan(&user.ID, &user.Name, &user.Email, &user.CreatedAt)
if err != nil {
return nil, err
}
return &user, nil
}
// 查询多条记录
func getAllUsers(db *sql.DB) ([]User, error) {
rows, err := db.Query("SELECT id, name, email, created_at FROM users")
if err != nil {
return nil, err
}
defer rows.Close()
var users []User
for rows.Next() {
var user User
err := rows.Scan(&user.ID, &user.Name, &user.Email, &user.CreatedAt)
if err != nil {
return nil, err
}
users = append(users, user)
}
return users, nil
}
更新数据
func updateUserEmail(db *sql.DB, id int, newEmail string) error {
_, err := db.Exec(
"UPDATE users SET email = ? WHERE id = ?",
newEmail, id,
)
return err
}
删除数据
func deleteUser(db *sql.DB, id int) error {
_, err := db.Exec("DELETE FROM users WHERE id = ?", id)
return err
}
4. 事务处理
func transferMoney(db *sql.DB, fromID, toID int, amount float64) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer func() {
if err != nil {
tx.Rollback()
return
}
err = tx.Commit()
}()
// 执行多个操作
_, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, fromID)
if err != nil {
return err
}
_, err = tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", amount, toID)
if err != nil {
return err
}
return nil
}
5. 连接池配置
func initDB() *sql.DB {
dsn := "user:password@tcp(127.0.0.1:3306)/testdb"
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal(err)
}
// 配置连接池
db.SetMaxOpenConns(25) // 最大连接数
db.SetMaxIdleConns(10) // 最大空闲连接数
db.SetConnMaxLifetime(5 * time.Minute) // 连接最大存活时间
return db
}
最佳实践
- 使用预处理语句防止 SQL 注入
- 及时关闭 rows 和 statements
- 合理配置连接池参数
- 使用事务保证数据一致性
- 正确处理错误和空值
这个指南涵盖了 Golang 操作 MySQL 的核心功能,可以直接在实际项目中使用。

