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
2.5 KiB
后端开发指南 (Go + SQLite)
概述
使用 Go 语言开发后端,结合 SQLite 作为数据库,适用于个人工具站或中小型应用。强调单二进制部署、少依赖和快速迭代。
关键原则
- 单二进制优先:使用
embed内嵌静态资源和 SQL 迁移文件,避免外部依赖。 - API 与静态资源分工:Go 提供 API,静态资源可由 Go 内嵌或外部服务。
- 数据库设计: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