数据库概述 #

一、数据库类型 #

1.1 关系型数据库 #

数据库 说明
MySQL 最流行的开源数据库
PostgreSQL 功能强大的开源数据库
SQLite 轻量级嵌入式数据库
SQL Server 微软企业级数据库
Oracle 企业级商业数据库

1.2 NoSQL数据库 #

数据库 说明
MongoDB 文档数据库
Redis 键值存储
Cassandra 分布式数据库
DynamoDB AWS托管数据库

二、数据库驱动 #

2.1 MySQL #

bash
go get github.com/go-sql-driver/mysql

2.2 PostgreSQL #

bash
go get github.com/lib/pq

2.3 SQLite #

bash
go get github.com/mattn/go-sqlite3

三、ORM选择 #

3.1 GORM #

最流行的Go ORM框架。

bash
go get gorm.io/gorm
go get gorm.io/driver/mysql

3.2 sqlx #

轻量级SQL扩展。

bash
go get github.com/jmoiron/sqlx

3.3 ent #

Facebook开源的实体框架。

bash
go get entgo.io/ent

四、数据库连接 #

4.1 基本连接 #

go
package main

import (
    "database/sql"
    "fmt"
    "github.com/go-sql-driver/mysql"
    "github.com/labstack/echo/v4"
)

var db *sql.DB

func initDB() error {
    cfg := mysql.Config{
        User:   "root",
        Passwd: "password",
        Net:    "tcp",
        Addr:   "localhost:3306",
        DBName: "myapp",
    }
    
    var err error
    db, err = sql.Open("mysql", cfg.FormatDSN())
    if err != nil {
        return err
    }
    
    return db.Ping()
}

func main() {
    if err := initDB(); err != nil {
        panic(err)
    }
    defer db.Close()
    
    e := echo.New()
    e.GET("/users", getUsers)
    e.Start(":8080")
}

func getUsers(c echo.Context) error {
    rows, err := db.Query("SELECT id, name FROM users")
    if err != nil {
        return err
    }
    defer rows.Close()
    
    var users []map[string]interface{}
    for rows.Next() {
        var id int
        var name string
        if err := rows.Scan(&id, &name); err != nil {
            return err
        }
        users = append(users, map[string]interface{}{
            "id":   id,
            "name": name,
        })
    }
    
    return c.JSON(http.StatusOK, users)
}

4.2 连接池配置 #

go
func initDB() error {
    db, err = sql.Open("mysql", dsn)
    if err != nil {
        return err
    }
    
    db.SetMaxOpenConns(25)
    db.SetMaxIdleConns(5)
    db.SetConnMaxLifetime(5 * time.Minute)
    
    return db.Ping()
}

五、配置管理 #

5.1 配置文件 #

config/config.yaml

yaml
database:
  driver: mysql
  host: localhost
  port: 3306
  name: myapp
  user: root
  password: secret
  max_open_conns: 25
  max_idle_conns: 5
  conn_max_lifetime: 5m

5.2 读取配置 #

go
type DatabaseConfig struct {
    Driver          string
    Host            string
    Port            int
    Name            string
    User            string
    Password        string
    MaxOpenConns    int
    MaxIdleConns    int
    ConnMaxLifetime time.Duration
}

func loadConfig() *DatabaseConfig {
    return &DatabaseConfig{
        Driver:          viper.GetString("database.driver"),
        Host:            viper.GetString("database.host"),
        Port:            viper.GetInt("database.port"),
        Name:            viper.GetString("database.name"),
        User:            viper.GetString("database.user"),
        Password:        viper.GetString("database.password"),
        MaxOpenConns:    viper.GetInt("database.max_open_conns"),
        MaxIdleConns:    viper.GetInt("database.max_idle_conns"),
        ConnMaxLifetime: viper.GetDuration("database.conn_max_lifetime"),
    }
}

六、数据库迁移 #

6.1 使用GORM自动迁移 #

go
func autoMigrate() error {
    return db.AutoMigrate(
        &User{},
        &Post{},
        &Comment{},
    )
}

6.2 使用迁移工具 #

bash
go install -tags 'mysql' github.com/golang-migrate/migrate/v4/cmd/migrate@latest

migrate create -ext sql -dir migrations create_users_table

migrations/000001_create_users_table.up.sql

sql
CREATE TABLE users (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

七、事务处理 #

7.1 基本事务 #

go
func transferMoney(fromID, toID int64, amount float64) error {
    tx, err := db.Begin()
    if err != nil {
        return err
    }
    
    defer func() {
        if err != nil {
            tx.Rollback()
        }
    }()
    
    _, 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 tx.Commit()
}

7.2 GORM事务 #

go
func transferMoney(db *gorm.DB, fromID, toID uint, amount float64) error {
    return db.Transaction(func(tx *gorm.DB) error {
        var from Account
        if err := tx.First(&from, fromID).Error; err != nil {
            return err
        }
        
        var to Account
        if err := tx.First(&to, toID).Error; err != nil {
            return err
        }
        
        if from.Balance < amount {
            return errors.New("余额不足")
        }
        
        if err := tx.Model(&from).Update("balance", from.Balance-amount).Error; err != nil {
            return err
        }
        
        if err := tx.Model(&to).Update("balance", to.Balance+amount).Error; err != nil {
            return err
        }
        
        return nil
    })
}

八、数据库测试 #

8.1 使用SQLite测试 #

go
func setupTestDB() *gorm.DB {
    db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
    if err != nil {
        panic(err)
    }
    
    db.AutoMigrate(&User{})
    
    return db
}

func TestGetUsers(t *testing.T) {
    db := setupTestDB()
    
    db.Create(&User{Name: "张三", Email: "zhangsan@example.com"})
    
    var users []User
    db.Find(&users)
    
    assert.Equal(t, 1, len(users))
}

九、总结 #

数据库集成要点:

要点 说明
驱动选择 MySQL、PostgreSQL、SQLite
ORM选择 GORM、sqlx、ent
连接池 MaxOpenConns、MaxIdleConns
配置管理 YAML、环境变量
事务处理 Begin、Commit、Rollback

准备好学习GORM集成了吗?让我们进入下一章!

最后更新:2026-03-28