You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2.5 KiB

后端开发指南 (Go + SQLite)

概述

使用 Go 语言开发后端,结合 SQLite 作为数据库,适用于个人工具站或中小型应用。强调单二进制部署、少依赖和快速迭代。

关键原则

  1. 单二进制优先:使用 embed 内嵌静态资源和 SQL 迁移文件,避免外部依赖。
  2. API 与静态资源分工:Go 提供 API,静态资源可由 Go 内嵌或外部服务。
  3. 数据库设计:SQLite 单写者多读者模型,设置 busy_timeout 避免锁竞争。

示例代码结构

project/
├── cmd/
│   └── main.go          # 应用入口
├── internal/
│   ├── handlers/        # HTTP 处理器
│   ├── models/          # 数据模型
│   └── db/              # 数据库操作
├── web/                 # 前端静态文件 (若内嵌)
├── migrations/          # SQL 迁移文件
└── go.mod

示例 main.go

package main

import (
    "database/sql"
    "embed"
    "log"
    "net/http"
    "os"

    _ "github.com/mattn/go-sqlite3"
)

//go:embed web/dist/*
var webFS embed.FS

//go:embed migrations/*.sql
var migrationFS embed.FS

func main() {
    dbPath := os.Getenv("DB_PATH")
    if dbPath == "" {
        dbPath = "app.db"
    }

    db, err := sql.Open("sqlite3", dbPath+"?_busy_timeout=5000")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 运行迁移
    runMigrations(db)

    // 设置路由
    mux := http.NewServeMux()
    mux.HandleFunc("/api/", apiHandler)
    mux.Handle("/", http.FileServer(http.FS(webFS)))

    addr := os.Getenv("ADDR")
    if addr == "" {
        addr = ":8080"
    }

    log.Printf("Server starting on %s", addr)
    log.Fatal(http.ListenAndServe(addr, mux))
}

func runMigrations(db *sql.DB) {
    // 示例迁移逻辑
    _, err := db.Exec(`CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)`)
    if err != nil {
        log.Fatal(err)
    }
}

func apiHandler(w http.ResponseWriter, r *http.Request) {
    // 示例 API
    w.Write([]byte("Hello from API"))
}

数据库最佳实践

  • 使用 prepared statements 防止 SQL 注入。
  • 对于并发写,考虑使用 WAL 模式:PRAGMA journal_mode=WAL;
  • 迁移:使用版本控制的 SQL 文件,或库如 golang-migrate。

环境变量

  • DB_PATH: SQLite 文件路径
  • ADDR: 监听地址 (e.g., ":8080")

构建

go build -ldflags="-s -w" -o app cmd/main.go