Skip to content

Golang原生database-sql 包的纯 Go SQLite 驱动程序使用

仓库地址: https://github.com/glebarez/go-sqlite

这是 Golang 原生 database/sql 包的纯 Go SQLite 驱动程序。 该驱动程序本身嵌入了基于 Go 的 SQLite 实现(因此,不需要单独安装 SQLite)

使用示例

go
package bootstrap

import (
	"database/sql"
	_ "github.com/glebarez/go-sqlite"
	"go.uber.org/zap"
	"log"
	"low-file/src/global"
	"os"
	"path/filepath"
)

var createTableStatements = []string{
	// 文件记录表
	`
	    CREATE TABLE IF NOT EXISTS file_records (
	        id INTEGER PRIMARY KEY AUTOINCREMENT,
	        file_name TEXT NOT NULL,
	        file_path TEXT NOT NULL,
	        file_size INTEGER NOT NULL,
	        create_time INTEGER NOT NULL
	    )
	`,
}

func initSqlite() {
	// 获取数据库文件路径(分离目录和文件名)
	dataDir := filepath.Join(global.BasePath, "storage/data") // 目录路径
	dbFile := filepath.Join(dataDir, "low-file.db")           // 文件路径

	// 创建数据目录(仅创建目录部分)
	if err := os.MkdirAll(dataDir, 0755); err != nil {
		log.Fatalf("sqlite目录创建失败: %v (路径: %s)", err, dataDir)
	}

	// 验证目录权限(可选)
	if fileInfo, err := os.Stat(dataDir); err != nil {
		log.Fatalf("sqlite目录访问失败: %v (路径: %s)", err, dataDir)
	} else if !fileInfo.IsDir() {
		log.Fatalf("sqlite路径不是目录: %s", dataDir)
	} else if fileInfo.Mode().Perm()&0200 == 0 {
		log.Fatalf("sqlite目录不可写: %s (权限: %s)", dataDir, fileInfo.Mode().String())
	}

	// 初始化数据库连接
	db, err := sql.Open("sqlite", dbFile+"?_foreign_keys=1&_journal_mode=WAL")
	if err != nil {
		log.Fatal("sqlite数据库连接失败:", err)
	}

	// 配置连接池(SQLite推荐设置)
	db.SetMaxOpenConns(1) // 重要!避免数据库锁定
	db.SetMaxIdleConns(1)

	// 验证连接
	if err := db.Ping(); err != nil {
		log.Fatal("sqlite数据库连接不可用:", err)
	}

	global.SQLite = db
	// 初始化表
	initTable()
	// 记录版本信息
	var version string
	if err := global.SQLite.QueryRow("SELECT sqlite_version()").Scan(&version); err != nil {
		global.Logger.Error("获取SQLite版本失败", zap.Error(err))
	} else {
		global.Logger.Info("SQLite初始化完成",
			zap.String("version", version),
			zap.String("path", dbFile))
	}
}

func initTable() {
	for _, val := range createTableStatements {
		_, err := global.SQLite.Exec(val)
		if err != nil {
			log.Fatal("初始化表失败:", err)
		}
	}

}

分页查询示例

go
package handlers

import (
	"github.com/gin-gonic/gin"
	"low-file/src/common/model"
	"low-file/src/global"
	"math"
)

type FileRecordListQueryParam struct {
	model.PageQuery
}

func FileRecordList(c *gin.Context) {
	resHandler, _ := global.GetLoggerAndResponseHandler(c)

	// 1. 参数绑定与校验
	var pageQuery FileRecordListQueryParam
	if err := c.ShouldBind(&pageQuery); err != nil {
		global.ResFail(resHandler.WithMsg("查询参数绑定失败").WithError(err))
		return
	}

	// 参数默认值设置
	if pageQuery.PageNum < 1 {
		pageQuery.PageNum = 1
	}
	if pageQuery.PageSize <= 0 || pageQuery.PageSize > 100 {
		pageQuery.PageSize = 10
	}

	// 2. 查询总数(带错误处理)
	var count int64
	err := global.SQLite.QueryRow(
		`SELECT COUNT(*) FROM file_records`,
	).Scan(&count)
	if err != nil {
		global.ResFail(resHandler.WithMsg("总数查询失败").WithError(err))
		return
	}

	// 快速返回空结果
	if count == 0 {
		global.ResOk(resHandler.WithData(gin.H{
			"rows":  []interface{}{},
			"total": 0,
		}))
		return
	}

	// 3. 分页查询(添加 ORDER BY 保证顺序)
	offset := (pageQuery.PageNum - 1) * pageQuery.PageSize
	rows, err := global.SQLite.Query(
		`SELECT * FROM file_records 
         ORDER BY create_time DESC 
         LIMIT ? OFFSET ?`,
		pageQuery.PageSize, offset,
	)
	if err != nil {
		global.ResFail(resHandler.WithMsg("分页查询失败").WithError(err))
		return
	}
	defer rows.Close() // 确保关闭结果集

	// 4. 数据解析
	var records []model.FileRecord
	for rows.Next() {
		var s model.FileRecord
		if err := rows.Scan(&s.Id, &s.FileName, &s.FilePath, &s.FileSize, &s.CreateTime); err != nil {
			global.ResFail(resHandler.WithMsg("解析记录行失败").WithError(err))
			return
		}
		records = append(records, s)
	}

	// 5. 检查遍历错误
	if err := rows.Err(); err != nil {
		global.ResFail(resHandler.WithMsg("结果集遍历错误").WithError(err))
		return
	}

	// 6. 返回完整分页信息
	_ = int(math.Ceil(float64(count) / float64(pageQuery.PageSize)))
	global.ResOk(resHandler.WithData(gin.H{
		"rows":  records,
		"total": count,
	}))
}
/src/technology/dateblog/2025/05/20250524-golang%E5%8E%9F%E7%94%9Fdatabase-sql-%E5%8C%85%E7%9A%84%E7%BA%AF-go-sqlite-%E9%A9%B1%E5%8A%A8%E7%A8%8B%E5%BA%8F%E4%BD%BF%E7%94%A8.html