
文档教程【免费下载链接】build-web-application-with-golangA golang ebook intro how to build a web with golang项目地址https://gitcode.com/gh_mirrors/bu/build-web-application-with-golang点击查看免费下载本章示例ch.5.5是 build-web-application-with-golang 英文版《第 5.5 章Develop ORM based on beedb》配套的可运行代码用于演示如何使用 beedb 这个轻量级 Go ORM 对 SQLite3 数据库完成完整的增删改查CRUD操作。本篇文章以 ch.5.5 的 readme.md 给出的六步搭建流程为主线结合仓库中的 schema.sql 表结构与 main.go 源码逐行讲解帮助你在一台干净的环境上从零跑通「安装 SQLite3 → 建库建表 → 拉取依赖 → 运行 ORM 示例」的完整链路并理解 beedb 的 Save / Insert / Find / Update / Delete 等核心 API 的底层行为。一、示例背景beedb ORM 与 SQLite3 的搭配第 5.5 章介绍的 beedb 是作者用 Go 开发的一个轻量级 ORM对象关系映射库它遵循database/sql标准接口因此任何实现了该接口的数据库驱动都可以接入。章节文档 en/05.5.md 明确说明beedb 项目已不再维护但代码仍然可用它支持基础的 ORM 功能但不支持 struct 之间的关联查询关联查询需要借助链式 API 手写 Join 完成见下文。在 main.go 中可以看到本章示例采用了两个外部依赖import ( database/sql fmt github.com/astaxie/beedb // beedb ORM 本体 _ github.com/mattn/go-sqlite3 // SQLite3 驱动匿名导入仅注册驱动 time )_匿名导入github.com/mattn/go-sqlite3是 Go 中注册数据库驱动的标准写法之后sql.Open(sqlite3, ./foo.db)才能识别sqlite3这个驱动名。这意味着只要驱动实现了database/sql接口beedb 理论上都可以无缝接入——文档中列出的已测试驱动还包括 MySQL、PostgreSQL、mymysql、ADODB、Oracle、ODBC 等。二、Step 1安装 SQLite3 客户端readme 的第一步是下载并安装 sqlite3。SQLite 是嵌入式数据库无需独立的服务端进程只需一个命令行客户端工具即可操作数据库文件。在 Debian/Ubuntu 系 Linux 上sudo apt-get install sqlite3在 macOS 上brew install sqlite3在 Windows 上从 SQLite 官网下载预编译的sqlite-tools压缩包解压后将sqlite3.exe放入 PATH 即可安装完成后可用sqlite3 --version验证。除了命令行工具外github.com/mattn/go-sqlite3驱动的编译还依赖 CGO 与 C 编译器gcc/clang因此运行本示例的机器需要具备 C 编译环境且在CGO_ENABLED1状态下执行go run否则会报cgo相关编译错误。三、Step 2创建名为 foo 的数据库文件readme 第二步要求在项目目录下执行sqlite3 foo.db该命令会做两件事如果foo.db不存在则创建这个数据库文件然后进入 sqlite 交互式命令行。退出后文件会保存在当前目录。注意 main.go 中定义了const DB_PATH ./foo.db即程序读取的是相对路径下的数据库文件所以运行go run main.go时必须保证当前工作目录与foo.db所在目录一致建议直接在ch.5.5目录内操作。四、Step 3导入 schema.sql 建表readme 第三步要求把 schema.sql 中的建表语句在 sqlite 中执行sqlite .read schema.sql.read是 sqlite3 客户端的内置命令用于批量执行文件中的 SQL 语句。schema.sql 共定义了两张表恰好对应 beedb 的 struct 到数据表映射关系CREATE TABLE userinfo ( uid INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR(64) NULL, department VARCHAR(64) NULL, created DATE NULL ); CREATE TABLE userdetail ( uid INT(10) NULL, intro TEXT NULL, profile TEXT NULL, PRIMARY KEY (uid) );两张表的含义如下userinfo用户信息表uid是自增主键INTEGER PRIMARY KEY AUTOINCREMENTusername、department是长度 64 的可空字符串created是日期字段。它对应 main.go 中的Userinfo结构体type Userinfo struct { Uid int beedb:PK // 显式声明主键字段 Username string Department string Created string }注意 en/05.5.md 特别强调的规则beedb 会把驼峰命名自动转换为小写蛇形命名——结构体名UserInfo映射为表user_info字段Username映射为列username。这正是示例选择userinfo表并直接使用字段名Username/Department/Created的原因。同时由于主键不是默认的id必须用beedb:PK标签章节文档中的写法是PK显式声明Uid是主键。userdetail用户详情表uid为主键intro、profile为 TEXT 类型。该表用于演示 beedb 的关联查询Join能力。五、Step 4验证表结构并退出 sqlite建表完成后readme 要求用.tables命令确认表已创建成功sqlite .tables userinfo userdetail输出中应同时出现userinfo与userdetail。如果想进一步核对列定义可以补充执行sqlite .schema userinfo查看单张表的完整 DDL。确认无误后退出交互式命令行sqlite .exit至此数据库文件foo.db已经包含两张空表可以交给 Go 程序使用了。六、Step 5go get 安装远程依赖包readme 第五步是运行go get拉取远程依赖。结合 main.go 的 import 列表本项目实际需要安装的是go get github.com/astaxie/beedb go get github.com/mattn/go-sqlite3在 Go Modules 环境下Go 1.11也可以直接进入ch.5.5目录执行go mod init ch.5.5 go mod tidy让工具自动解析并下载这两个依赖随后会生成go.mod/go.sum锁定依赖版本。需要说明的是章节文档 en/05.5.md 中注明 beedb 已停止维护其 API 停留在示例所使用的形态本示例恰好完整覆盖了它提供的全部核心方法。七、Step 6运行 main.go 并理解 CRUD 全流程执行go run main.go程序会在foo.db上依次执行插入 → 查询 → 更新 → 高级查询 → 删除的完整链路每步都会向标准输出打印操作名称与结果。下面结合 main.go 源码逐段拆解。7.1 初始化从 database/sql 到 beedb程序入口先通过标准库打开数据库连接再创建 beedb 的 ORM 对象func main() { db, err : sql.Open(sqlite3, DB_PATH) checkError(err) orm beedb.New(db) // ... }beedb.New(db)是初始化核心它接收*sql.DB作为第一个参数。章节文档 en/05.5.md 说明该方法实际上还有第二个可选参数用于指定数据库引擎——使用 MySQL/SQLite 时可直接省略使用 SQLServer 需传beedb.New(db, mssql)PostgreSQL 需传beedb.New(db, pg)。示例中orm是包级变量var orm beedb.Model后续所有操作都通过它完成。如需观察 beedb 生成的 SQL可以在初始化后开启调试开关beedb.OnDebug true该开关见 en/05.5.md 初始化章节。7.2 插入数据struct 与 map 两种姿势方式一传入 struct使用Savefunc insertUsingStruct() int64 { var obj Userinfo obj.Username Test Add User obj.Department Test Add Department obj.Created getTimeStamp() checkError(orm.Save(obj)) fmt.Printf(%v\n, obj) return int64(obj.Uid) }orm.Save(obj)会依据结构体字段映射生成INSERT语句记录插入成功后beedb 会把数据库自增产生的uid回填到obj.Uid——这正是函数末尾能读取到obj.Uid并作为返回值的原因。getTimeStamp()使用time.Now().Format(2006-01-02 15:04:05)生成 Go 标准格式的时间字符串与created列的 DATE 类型对应。方式二传入 map使用链式SetTable().Insert()func insertUsingMap() int64 { add : make(map[string]interface{}) add[username] astaxie add[department] cloud develop add[created] getTimeStamp() id, err : orm.SetTable(userinfo).Insert(add) checkError(err) fmt.Println(Last row inserted id , id) return id }这里体现了 beedb 的链式调用风格SetTable(userinfo)显式指定目标表map 方式无法从类型推断表名必须指定Insert(add)返回最后插入的行 id。章节文档 en/05.5.md 还补充了批量插入接口InsertBatch(addslice)接受[]map[string]interface{}。7.3 查询数据Find 与 FindAll按主键/条件查单条记录func getOneUserInfo(id int64) Userinfo { var obj Userinfo checkError(orm.Where(uid?, id).Find(obj)) return obj }Where(uid?, id)是标准的占位符条件写法结果映射到Userinfo结构体。章节文档中还展示了另一种简写orm.Where(3).Find(user)——当第一个参数是整数时等价于Where(主键?, 值)。带 Limit 的批量查询func getAllUserInfo(id int64) []Userinfo { var alluser []Userinfo checkError(orm.Limit(10).Where(uid?, id).FindAll(alluser)) return alluser }FindAll将多行结果填充到结构体切片Limit(10)限制返回条数。章节文档说明Limit支持两个参数Limit(条数, 起始位置)第二个参数缺省为 0例如orm.Where(id ?, 3).Limit(10, 20).FindAll(allusers)表示从第 20 条开始取 10 条。7.4 更新数据Save 的“插入/更新二象性”与 map 批量更新struct 方式func updateUserinfo(id int64) { var obj Userinfo obj.Uid int(id) // 主键有值 obj.Username Update Username obj.Department Update Department obj.Created getTimeStamp() checkError(orm.Save(obj)) // beedb 自动识别为 UPDATE }Save是本章最值得注意的 API章节文档 en/05.5.md 明确指出当主键已经有值如自增 ID 回填后时beedb 执行的是 UPDATE 而非 INSERT。因此同一方法同时承担了新增与修改两种职责。map 方式支持单条与批量func updateUsingMap(id int64) { t : make(map[string]interface{}) t[username] updateastaxie // 单条更新示例注释掉orm.SetTable(userinfo).SetPK(uid).Where(2).Update(t) // 批量更新更新所有 uid id 的记录 lastId, err : orm.SetTable(userinfo).Where(uid?, id).Update(t) checkError(err) fmt.Println(Last row updated id , lastId) }源码注释中保留了单条更新的写法需要理解三个链式方法详见 en/05.5.md.SetPK(uid)告诉 ORM 表的主键列是uid.Where(2)整数参数即Where(uid?, 2)的简写.Update(t)接受 map 并生成UPDATE语句示例中省略SetPK直接Where(uid?, id)则按条件批量更新。7.5 高级查询Select / FindMap / GroupBy / Having / Join以下四个函数集中演示了 beedb 的链式查询扩展能力全部返回[]map[string][]byte类型需要自行转换后再使用。投影查询 返回 mapfunc getMapsFromSelect(id int64) []map[string][]byte { c, err : orm.SetTable(userinfo).SetPK(uid).Where(id).Select(uid,username).FindMap() checkError(err) fmt.Printf(%v\n, c) return c }.Select(uid,username)限定只取这两列不指定则默认返回全部字段.Where(id)整数简写按主键过滤.FindMap()以 map 形式返回结果避免为每类查询都定义结构体。分组与聚合过滤func groupby() { b, err : orm.SetTable(userinfo).GroupBy(username).Having(usernameupdateastaxie).FindMap() checkError(err) fmt.Printf(%v\n, b) }.GroupBy(username)与.Having(usernameupdateastaxie)分别对应 SQL 的GROUP BY与HAVING子句组合后可对分组结果做条件过滤。表关联 Joinfunc joinTables(id int64) { a, err : orm.SetTable(userinfo).Join(LEFT, userdetail, userinfo.uiduserdetail.uid).Where(userinfo.uid?, id).Select(userinfo.uid,userinfo.username,userdetail.profile).FindMap() checkError(err) fmt.Printf(%v\n, a) }这是章节文档「Association queries」一节给出的简陋关联方案beedb 本身不支持 struct 间的 ORM 关联但可以通过.Join()直接拼接 SQL。.Join()三个参数分别是连接类型INNER / LEFT / OUTER / CROSS 等、被连接的表名、连接条件。示例用LEFT JOIN userdetail按uid关联并投影出userinfo与userdetail两侧的字段——这正是前面单独建userdetail表的意义所在。7.6 删除数据三种删除粒度按对象删除单条func deleteWithUserinfo(id int64) { obj : getOneUserInfo(id) id, err : orm.Delete(obj) // 依据主键删除 checkError(err) fmt.Println(Last row deleted id , id) }先查出对象再orm.Delete(obj)beedb 依据对象主键生成DELETE语句。按条件批量删除func deleteRows() { id, err : orm.SetTable(userinfo).Where(uid?, 2).DeleteRow() checkError(err) fmt.Println(Last row updated id , id) }SetTable Where DeleteRow()组合相当于原生DELETE FROM userinfo WHERE uid ?一次删除满足条件的所有行。按对象集合删除全部func deleteAllUserinfo(id int64) { alluser : getAllUserInfo(id) id, err : orm.DeleteAll(alluser) // 删除切片中所有对象 checkError(err) fmt.Println(Last row updated id , id) }DeleteAll接受结构体切片逐条或批量删除查询到的所有记录适合先查后删的清理场景。八、运行结果与排查要点程序正常执行时会依次打印Inserting、Updating、Querying、Deleting等阶段标记以及每条记录的结构体/ map 内容与受影响行 id。若某一步失败checkError(err)会直接panic并终止程序因此任何一步输出异常都可通过 panic 堆栈快速定位。常见问题与对策go: cannot find module ...类错误说明依赖未拉取回到 Step 5 执行go get或在模块目录执行go mod tidy。#cgo/exec: gcc: executable file not foundgo-sqlite3需要 CGO 与 C 编译器请安装 gcc/clang 并确保CGO_ENABLED1。no such table: userinfo说明schema.sql未正确导入或当前目录下没有foo.db回到 Step 3/4 用.tables验证。unable to open database fileDB_PATH是相对路径./foo.db请确认go run main.go的执行目录与建库目录一致。九、相关章节与资源章节正文完整讲解 beedb 的安装、初始化、CRUD、关联查询与未来规划en/05.5.md本示例的六步搭建说明原文readme.md建表语句schema.sql可运行源码含全部 CRUD 函数main.go上一章PostgreSQL 数据库操作en/05.4.md下一章NoSQL 数据库操作en/05.6.md同样基于 SQLite3 的姊妹示例5.3 章 MySQL 操作en/code/src/apps/ch.5.3/readme.md赞分享文档教程【免费下载链接】build-web-application-with-golangA golang ebook intro how to build a web with golang项目地址https://gitcode.com/gh_mirrors/bu/build-web-application-with-golang点击查看免费下载相关推荐基于 beedb 开发 Go 轻量级 ORMstruct 映射与 CRUD 全流程实战build-web-application-with-golang 第 5.5 节基于 beedb 开发 Go 轻量级 ORMstruct 映射与 CRUD 全流程实战build web application with golang 第文档教程用 beedb ORM 操作 SQLite3ch.5.5 示例的环境搭建与 CRUD 实战用 beedb ORM 操作 SQLite3ch.5.5 示例的环境搭建与 CRUD 实战 本篇指南围绕《Build Web Application with文档教程build-web-application-with-golang ORM教程基于beedb开发数据访问层build web application with golang ORM教程基于beedb开发数据访问层 你是否还在为Golang Web开发中的数据访问层文档教程上一篇你的Windows资源管理器也能拥有Windows 11的优雅毛玻璃效果下一篇3步快速美化Windows资源管理器免费实现毛玻璃和Mica效果终极教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考