ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

使用 Beego 框架实现博客系统的增删改查(CRUD):从路由、ORM 到模板渲染的完整实战

使用 Beego 框架实现博客系统的增删改查(CRUD):从路由、ORM 到模板渲染的完整实战 文档教程【免费下载链接】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点击查看免费下载本文是《Build Web Application with Golang》第 13 章构建 Web 框架的收官实战篇对应 pt-br/13.5.md。前四节分别完成了框架的项目规划、路由设计、控制器基类与日志与配置系统本节将把这些组件拼装成一个完整的博客系统实现博客的浏览、新建、编辑与删除。读完本文你将掌握基于 Beego 风格的 MVC 分层思想如何组织项目目录、注册 RESTful 路由、编写控制器与数据模型以及如何用模板完成页面渲染。博客项目目录结构本节实现的博客系统示例项目名beelog遵循 13.1 节的 MVC 目录规划完整结构如下/main.go 应用入口路由注册与启动 /views: 视图模板目录 /view.tpl 博客详情页 /new.tpl 新建博客表单页 /layout.tpl 公共布局模板菜单栏 /index.tpl 博客列表首页 /edit.tpl 编辑博客表单页 /models/model.go 数据模型层Blog 结构体与 ORM 操作 /controllers: 控制器目录 /index.go IndexController首页列表 /view.go ViewController查看详情 /new.go NewController新建 /delete.go DeleteController删除 /edit.go EditController编辑该结构与 13.1 节中规划的main.go / conf / controllers / models / utils / static / views七层目录一脉相承main.go负责初始化并注册路由controllers承载业务逻辑models封装数据库操作views存放 Gotemplate模板文件。从源码结构可以看出示例仓库中相同风格的 MVC 分层也出现在其他章节例如 pt-br/code/src/apps/ch.5.5/main.go 展示了 ORM 层的 CRUD 能力可作为模型层实现的对照参考。博客路由注册动态参数与正则约束路由是整个系统的入口。本节博客在main.go中注册了五条路由规则完整代码如下// 显示博客首页 beego.RegisterController(/, controllers.IndexController{}) // 查看博客详细信息 beego.RegisterController(/view/:id([0-9]), controllers.ViewController{}) // 新建博客博文 beego.RegisterController(/new, controllers.NewController{}) // 删除博文 beego.RegisterController(/delete/:id([0-9]), controllers.DeleteController{}) // 编辑博文 beego.RegisterController(/edit/:id([0-9]), controllers.EditController{})这三类路由模式在 13.2 节的路由实现中都有对应支撑静态路由/与/new直接映射到控制器实例动态参数路由:id会被路由器解析为命名参数存入this.Ctx.Params例如strconv.Atoi(this.Ctx.Params[:id])即可取出id正则约束路由:id([0-9])允许在参数名后以括号形式自定义匹配表达式底层实现将:id([0-9])拆分为参数名:id与正则([0-9])再编译为完整的 URL 正则参见 13.2 节 中ControllerRegistor.Add的解析逻辑从而保证/view/123命中而/view/abc被拒绝。在转发阶段路由器会先匹配静态文件路径再遍历已注册路由用正则子匹配填充参数 map并按请求方法GET/POST/PUT/DELETE 等通过反射调用控制器上对应的方法Get、Post等若全部未命中则返回http.NotFound。这正是博客五个控制器能够各自只实现Get()或同时实现Get()/Post()即可工作的原因。数据库结构设计博客系统使用最简单的单表存储博客信息MySQL 建表语句如下CREATE TABLE entries ( id INT AUTO_INCREMENT, title TEXT, content TEXT, created DATETIME, primary key (id) );entries表包含四个字段自增主键id、标题title、正文content与创建时间created。模型层的Blog结构体正是这张表的映射见下文模型层字段类型一一对应Id int、Title string、Content string、Created time.Time。控制器层五个控制器的完整实现Beego 风格的控制器通过内嵌beego.Controller基类获得完整的生命周期Init → Prepare → 方法处理 → Render → Finish详见 13.3 节子类只需覆写需要处理的 HTTP 方法。IndexController博客列表首页type IndexController struct { beego.Controller } func (this *IndexController) Get() { this.Data[blogs] models.GetAll() this.Layout layout.tpl this.TplNames index.tpl }控制器将查询结果写入this.Data[blogs]并指定布局模板layout.tpl与内容模板index.tpl。当AutoRender开启时框架会在Get()执行后自动调用Render()渲染页面。ViewController查看博客详情type ViewController struct { beego.Controller } func (this *ViewController) Get() { inputs : this.Input() id, _ : strconv.Atoi(this.Ctx.Params[:id]) this.Data[Post] models.GetBlog(id) this.Layout layout.tpl this.TplNames view.tpl }this.Input()返回请求的输入集合this.Ctx.Params[:id]是从 URL 动态参数中取出的字符串 id经strconv.Atoi转为整数后传给模型层查询。NewController新建博客type NewController struct { beego.Controller } func (this *NewController) Get() { this.Layout layout.tpl this.TplNames new.tpl } func (this *NewController) Post() { inputs : this.Input() var blog models.Blog blog.Title inputs.Get(title) blog.Content inputs.Get(content) blog.Created time.Now() models.SaveBlog(blog) this.Ctx.Redirect(302, /) }Get()仅渲染新建表单Post()接收表单提交的title与content字段填充Blog结构体Created取当前时间调用models.SaveBlog持久化后以 302 重定向回首页。同一个控制器同时处理 GET 与 POST正是 13.2 节 所强调的 REST 风格方法映射路由将请求按 HTTP 方法分派给控制器上的同名方法。EditController编辑博客type EditController struct { beego.Controller } func (this *EditController) Get() { inputs : this.Input() id, _ : strconv.Atoi(this.Ctx.Params[:id]) this.Data[Post] models.GetBlog(id) this.Layout layout.tpl this.TplNames edit.tpl } func (this *EditController) Post() { inputs : this.Input() var blog models.Blog blog.Id, _ strconv.Atoi(inputs.Get(id)) blog.Title inputs.Get(title) blog.Content inputs.Get(content) blog.Created time.Now() models.SaveBlog(blog) this.Ctx.Redirect(302, /) }编辑与新建的区别在于Get()需要先按:id查出原文章并注入this.Data[Post]供表单回显Post()除读取title/content外还通过隐藏字段id取得待更新的记录主键同样调用models.SaveBlog完成保存Beedb 的Save会根据结构体主键判断是插入还是更新。DeleteController删除博客type DeleteController struct { beego.Controller } func (this *DeleteController) Get() { id, _ : strconv.Atoi(this.Ctx.Params[:id]) blog : models.GetBlog(id) this.Data[Post] blog models.DelBlog(blog) this.Ctx.Redirect(302, /) }删除操作通过Get()触发先按:id取出文章对象再调用models.DelBlog(blog)删除最后 302 重定向回首页。五个控制器共用一套this.Layout layout.tpl的写法页面外观因此保持一致。模型层基于 Beedb ORM 的 CRUD 封装模型层位于models/model.go通过 Beedb ORM 操作 MySQL 数据库package models import ( database/sql github.com/astaxie/beedb _ github.com/ziutek/mymysql/godrv time ) type Blog struct { Id int PK Title string Content string Created time.Time } func GetLink() beedb.Model { db, err : sql.Open(mymysql, blog/astaxie/123456) if err ! nil { panic(err) } orm : beedb.New(db) return orm } func GetAll() (blogs []Blog) { db : GetLink() db.FindAll(blogs) return } func GetBlog(id int) (blog Blog) { db : GetLink() db.Where(id?, id).Find(blog) return } func SaveBlog(blog Blog) (bg Blog) { db : GetLink() db.Save(blog) return bg } func DelBlog(blog Blog) { db : GetLink() db.Delete(blog) return }要点说明连接建立GetLink()使用标准库database/sql打开mymysql驱动连接连接串为blog/astaxie/123456即 用户名/密码 形式再用beedb.New(db)包装为 ORM 句柄。从源码结构看GetLink在每个操作函数中被重复调用属于为演示简洁而采用的临时连接模式实际项目中建议复用连接或使用连接池主键标注Blog.Id上的PK标签告诉 Beedb 该字段是主键Save与Delete都依赖它定位记录查询 APIFindAll(blogs)批量查询映射到结构体切片Where(id?, id).Find(blog)支持带占位符的条件查询并映射到单个结构体写入与删除Save(blog)依据主键执行插入或更新Delete(blog)按主键删除。Beedb 的这套 APISave/Find/FindAll/Where/Delete与仓库中 pt-br/code/src/apps/ch.5.5/main.go 的完整演示一脉相承——该文件还展示了SetTable、Insert、Update、FindMap、GroupBy、Join等更多能力并包含Userinfo结构体主键标注与 ORM 初始化的完整示例适合作为深入学习 Beedb 的参考。视图层Go 模板渲染博客页面视图层由五个.tpl模板文件组成使用 Gotext/template语法。layout.tpl公共布局模板html head titleMy Blog/title style #menu { width: 200px; float: right; } /style /head body ul idmenu lia href/Home/a/li lia href/newNew Post/a/li /ul {{.LayoutContent}} /body /html布局模板定义了全站统一的 HTML 骨架与右侧导航菜单{{.LayoutContent}}是内容模板的注入占位符。渲染时框架将布局文件与控制器指定的内容模板一起解析执行对应 13.3 节 中Render()对Layout与TplNames的处理逻辑。index.tpl博客列表首页h1Blog posts/h1 ul {{range .blogs}} li a href/view/{{.Id}}{{.Title}}/a from {{.Created}} a href/edit/{{.Id}}Edit/a a href/delete/{{.Id}}Delete/a /li {{end}} /ul{{range .blogs}}遍历控制器注入的博客切片对应this.Data[blogs]每条记录渲染出标题链接、创建时间以及编辑、删除操作链接。链接中的{{.Id}}恰好匹配/view/:id([0-9])、/edit/:id([0-9])、/delete/:id([0-9])三条动态路由。view.tpl博客详情页h1{{.Post.Title}}/h1 {{.Post.Created}}br/ {{.Post.Content}}详情页直接输出this.Data[Post]中的标题、创建时间与正文。new.tpl新建博客表单页h1New Blog Post/h1 form action methodpost Title:input typetext nametitlebr Contenttextarea namecontent colspan3 rowspan10/textarea input typesubmit /form表单以methodpost提交到当前路径/new字段名title与content与NewController.Post()中inputs.Get(title)/inputs.Get(content)一一对应。edit.tpl编辑博客表单页h1Edit {{.Post.Title}}/h1 h1New Blog Post/h1 form action methodpost Title:input typetext nametitle value{{.Post.Title}}br Contenttextarea namecontent colspan3 rowspan10{{.Post.Content}}/textarea input typehidden nameid value{{.Post.Id}} input typesubmit /form编辑表单通过value{{.Post.Title}}与 textarea 内嵌{{.Post.Content}}实现内容回显并通过隐藏字段input typehidden nameid value{{.Post.Id}}把待更新记录的主键传给EditController.Post()。运行与验证将上述文件按目录结构放入$GOPATH/src/beelog下GOPATH 设置方式参见 13.1 节确保 MySQL 中已创建entries表然后启动应用go run main.go浏览器访问http://localhost:8080即可看到博客首页依次可以完成以下完整流程点击菜单New Post进入/new填写标题与内容并提交POST 请求被NewController.Post()处理并重定向回首页新文章出现在列表中点击文章标题进入/view/1查看详情命中ViewController.Get()点击Edit进入/edit/1表单回显原文修改后提交由EditController.Post()保存更新点击Delete访问/delete/1由DeleteController.Get()删除记录并重定向回首页。至此一个覆盖浏览GET/、GET/view/:id、新建GET/POST/new、编辑GET/POST/edit/:id、删除GET/delete/:id的完整博客系统便基于自研框架全部打通——路由、控制器、模型与视图四个层次各司其职也验证了前四节框架设计的正确性。若希望进一步扩展可以参照 13.4 节 将数据库连接串与端口等信息抽入app.conf配置文件并用beego.AppConfig.String(...)读取使系统具备更强的可配置性。赞分享文档教程【免费下载链接】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点击查看免费下载相关推荐使用 Beego 框架构建博客系统从 MVC 路由到博客文章增删改查的完整实战使用 Beego 框架构建博客系统从 MVC 路由到博客文章增删改查的完整实战 本指南以开源仓库 build web application with gol文档教程基于 Beego 框架实现博客增删改查第 13.5 节完整实战路由、控制器、ORM 与模板全解析基于 Beego 框架实现博客增删改查第 13.5 节完整实战路由、控制器、ORM 与模板全解析 导读 本节是《Build Web Application文档教程beego 实战用 Go 语言构建博客增删改查CRUD系统——build-web-application-with-golang 第 13.5 节详解beego 实战用 Go 语言构建博客增删改查CRUD系统——build web application with golang 第 13.5 节详解 导文档教程上一篇React-PDF预览导航控件实现PDF预览的页面导航控件下一篇Nerd Fonts 桑基图更新全流程指南从图标数据统计到 SankeyMATIC 出图与 Inkscape 精修创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表