Go标准库的database/sql包提供了通用的SQL数据库接口。
go get -u github.com/go-sql-driver/mysql
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// 连接字符串格式: username:password@tcp(host:port)/database
dsn := "root:password@tcp(localhost:3306)/testdb"
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 验证连接
if err := db.Ping(); err != nil {
log.Fatal(err)
}
fmt.Println("数据库连接成功")
}
db.SetMaxOpenConns(25) // 最大打开连接数
db.SetMaxIdleConns(5) // 最大空闲连接数
db.SetConnMaxLifetime(5 * time.Minute) // 连接最大生命周期
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,
age INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)`
_, err := db.Exec(query)
return err
}
func insertUser(db *sql.DB, name, email string, age int) (int64, error) {
query := "INSERT INTO users (name, email, age) VALUES (?, ?, ?)"
result, err := db.Exec(query, name, email, age)
if err != nil {
return 0, err
}
// 获取插入的ID
id, err := result.LastInsertId()
if err != nil {
return 0, err
}
return id, nil
}
type User struct {
ID int
Name string
Email string
Age int
CreatedAt time.Time
}
func getUserByID(db *sql.DB, id int) (*User, error) {
query := "SELECT id, name, email, age, created_at FROM users WHERE id = ?"
user := &User{}
err := db.QueryRow(query, id).Scan(
&user.ID,
&user.Name,
&user.Email,
&user.Age,
&user.CreatedAt,
)
if err == sql.ErrNoRows {
return nil, fmt.Errorf("用户不存在")
}
if err != nil {
return nil, err
}
return user, nil
}
func getAllUsers(db *sql.DB) ([]*User, error) {
query := "SELECT id, name, email, age, created_at FROM users"
rows, err := db.Query(query)
if err != nil {
return nil, err
}
defer rows.Close()
var users []*User
for rows.Next() {
user := &User{}
err := rows.Scan(
&user.ID,
&user.Name,
&user.Email,
&user.Age,
&user.CreatedAt,
)
if err != nil {
return nil, err
}
users = append(users, user)
}
// 检查遍历过程中的错误
if err = rows.Err(); err != nil {
return nil, err
}
return users, nil
}
func updateUser(db *sql.DB, id int, name, email string) error {
query := "UPDATE users SET name = ?, email = ? WHERE id = ?"
result, err := db.Exec(query, name, email, id)
if err != nil {
return err
}
// 检查影响的行数
rowsAffected, err := result.RowsAffected()
if err != nil {
return err
}
if rowsAffected == 0 {
return fmt.Errorf("用户不存在")
}
return nil
}
func deleteUser(db *sql.DB, id int) error {
query := "DELETE FROM users WHERE id = ?"
result, err := db.Exec(query, id)
if err != nil {
return err
}
rowsAffected, err := result.RowsAffected()
if err != nil {
return err
}
if rowsAffected == 0 {
return fmt.Errorf("用户不存在")
}
return nil
}
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
}
GORM是Go最流行的ORM库,提供了更简洁的数据库操作API。
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
dsn := "root:password@tcp(localhost:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("连接数据库失败")
}
// 自动迁移
db.AutoMigrate(&User{})
}
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"size:100;not null"`
Email string `gorm:"size:100;uniqueIndex;not null"`
Age int
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
// 创建
user := User{Name: "Alice", Email: "alice@example.com", Age: 25}
db.Create(&user)
// 查询单条
var user User
db.First(&user, 1) // 根据主键查询
db.First(&user, "email = ?", "alice@example.com") // 条件查询
// 查询多条
var users []User
db.Find(&users) // 查询所有
db.Where("age > ?", 18).Find(&users) // 条件查询
// 更新
db.Model(&user).Update("name", "Bob")
db.Model(&user).Updates(User{Name: "Bob", Age: 30})
// 删除
db.Delete(&user, 1) // 软删除
type User struct {
gorm.Model
Name string
Orders []Order
}
type Order struct {
gorm.Model
UserID uint
Amount float64
}
// 预加载
var users []User
db.Preload("Orders").Find(&users)
// 创建关联
user := User{Name: "Alice"}
order := Order{Amount: 100.0}
user.Orders = append(user.Orders, order)
db.Create(&user)