发布于2026-07-10 阅读(0)
扫一扫,手机访问
先说一个核心判断:Go 本身确实不内置 GUI,但搭配 SQLite 加上 Wails(或 Fyne、WebView)这类框架,就能做出真正可分发的桌面应用。很多人一开始纠结“能不能做”,其实真正该琢磨的是“连接池怎么配”“事务怎么控”“SQLite 文件路径怎么写才能跨平台”——这些才是踩坑重灾区。

桌面应用启动位置不确定,sql.Open("sqlite3", "/home/user/app.db") 在 Windows 或 macOS 上直接 panic。必须用相对路径加上可靠的运行时目录解析。
os.Executable() 获取二进制所在目录,再拼接 filepath.Join(dir, "data.db")os.Getwd() —— 用户双击图标启动时,工作目录可能是桌面或 Downloads,那结果就完全不可控了CREATE TABLE 初始化语句(别依赖外部 SQL 文件,用户可能连 SQL 是什么都不知道)看起来 db.Exec("INSERT ...") 立刻生效,其实是因为 SQLite 驱动默认启用了 auto-commit。一旦你显式调用 db.Begin(),后续所有操作都得手动 Commit() 或 Rollback(),否则事务挂起、连接卡死。
db.Exec 就行,不用事务tx, _ := db.Begin() 包裹,且 defer tx.Rollback() 要放在 tx.Commit() 前db.Exec,SQLite 返回 database is locked —— 这时候该加 _ "github.com/mattn/go-sqlite3?_busy_timeout=5000" 编译标签,或者改用连接池每次 HTTP 请求都 sql.Open 一次,很快会耗尽文件描述符;但全局变量又难测试。正确做法是把 *sql.DB 当作依赖注入到结构体里。
App 结构体,字段包含 db *sql.DBwails.Init() 前初始化 db,传给 App{db: db}Sa veUser)都绑定在该结构体上,复用同一个 dbdb.SetMaxOpenConns(1) 是合理选择 —— SQLite 是文件锁模型,开多连接没意义,反而增加冲突概率用 GORM 确实省事,但桌面应用里它默认开启日志、自动建表、外键约束,这些在打包后可能出问题。
gorm.Open(sqlite.Open("app.db"), &gorm.Config{SkipDefaultTransaction: true}) 关掉默认事务,避免隐式 Beginlogger.Default.LogMode(logger.Silent),否则控制台刷屏影响调试AutoMigrate 升级表结构 —— 用户已有数据,ALTER TABLE 失败会导致整个应用无法启动;改用手工 migration SQL + 版本号判断gorm.Model 的 ID uint 和 SQLite 的 INTEGER PRIMARY KEY 类型匹配问题,建议显式写 ID int64 `gorm:"primaryKey;autoIncrement"`最常被忽略的是数据库文件权限:macOS 上沙盒应用、Windows 上受控文件夹访问(Controlled Folder Access)会拦截写入,得提前用 os.Chmod 设为 0644,且路径不能落在系统保护目录里(比如 ~/Library/Application Support 需要额外 entitlements)。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8