ORM, 即 Object Relational Mapping, 是一种程序技术, 用于实现面向对象编程语言里不同类型系统的数据之间的转换。
使用这种技术可以很方便的切换不同的数据库系统,比方说从关系型数据库切换到非关系型数据库。
go get github.com/astaxie/beego/orm
如果想更新,可自行加上 -u
参数。
$ go get -u github.com/go-sql-driver/mysql
数据库操作一般在 models 中执行,在 models 下创建文件 models.go:
package models
import (
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql"
)
// Model Struct
type User struct {
id int // ID 默认是主键,自增。若换了名称,比方说 Name,那么就需要用反引号注解: `orm:pk,auto`
Name string `orm:"size(100)"` // 相当于 mysql 里面的 varchar(100)
}
func init() {
// set default database
orm.RegisterDataBase("default", "mysql", "root:1234@tcp(127.0.0.1:3306)/jiuyi?charset=utf8", 30)
// register model
orm.RegisterModel(new(User))
// create table
orm.RunSyncdb("default", false, true)
}
package main
import (
_ "quickstart/models"
_ "quickstart/routers"
"github.com/astaxie/beego"
)
func main() {
beego.Run()
}
用 bee run
运行一下,不用开浏览器,然后就会发现数据库里面多了一张表 user
。
通过 beego.Controller.Ctx.WriteString()
方法可以直接向 http response body 中输出字符串, 打开 http 跟踪可以看到, 在 http response body 中只有 Hello World!
, 都没有 html 标签。
beego 中的函数定义如下:
// WriteString Write string to response body.
// it sends response body.
func (ctx *Context) WriteString(content string) {
ctx.ResponseWriter.Write([]byte(content))
}
示例:
beego.Controller.Ctx.WriteString("Hello World!")
beego.Controller.Data["名字"] = 数据
beego.Controller.TplName = 模板文件
beego.Controller.Data["json"] = 数据
beego.Controller.ServeJSON()
beego.Controller.Data["jsonp"] = 数据
beego.Controller.ServeJSONP()
beego.Controller.Data["xml"] = 数据
beego.Controller.ServeXML()
main.go:
beego.Router("/user", &controllers.UserController{})
default.go:
type UserController struct {
beego.Controller
}
func (c *UserController) Get() {
c.Ctx.WriteString("hello world")
}
上面的
Ctx
是 context 的意思, 可以理解为当前页面的句柄。
同一个文件是同一个 package 的, 所以可以这样创建新的 user.go
:
package controllers
import (
"github.com/astaxie/beego"
)
// 上面这几行和同目录下的 default.go 是一样的
type UserController struct {
beego.Controller
}
func (c *UserController) Get() {
c.Ctx.WriteString("hello world")
}
main.go:
beego.Router("/user", &controllers.UserController{}, "get:GetInfo")
user.go:
func (c *UserController) GetInfo() {
c.Ctx.WriteString("getinfo response success")
}
这样的话, 访问 /user
得到的结果是 getinfo response success
。
main.go:
beego.Router("/user/?:id", &controllers.UserController{}, "get:GetInfo")
user.go:
func (c *UserController) GetInfo() {
id := c.Ctx.Input.Param(":id")
c.Ctx.WriteString("getInfo data, id = " + id)
}
然后访问: http://localhost:8080/user/12, 输出:
getInfo data, id = 12
上面仅是一个示例, 实际上有很多种方式, 更多可参数官方文档: 路由设置
官方文档最好的参考书, 没有之一。
上面 ?:id
其实用到了正则路由, ?
在正则里匹配 一个或多个
, 它与 *
就一个区别, *
可以匹配 0
个。
获取路由中点的两个部分
main.go:
beego.Router("/user/*.*", &controllers.UserController{}, "get:GetInfo")
user.go:
func (c *UserController) GetInfo() {
path := c.Ctx.Input.Param(":path")
ext := c.Ctx.Input.Param(":ext")
c.Ctx.WriteString("getInfo data, path = " + path + ", ext = " + ext)
}
上面中为什么要用
:path
和:ext
? 因为 beego 就是这么定义的, 见文档: 正则路由
访问 http://localhost:8080/user/hello.exe, 结果如下:
getInfo data, path = hello, ext = exe
获取路由中点的全部
main.go:
beego.Router("/user/*", &controllers.UserController{}, "get:GetInfo")
user.go:
func (c *UserController) GetInfo() {
splat := c.Ctx.Input.Param(":splat")
c.Ctx.WriteString("getInfo data, splat = " + splat)
}
访问 http://localhost:8080/user/hello.exe, 结果如下:
getInfo data, splat = hello.exe
POST 请求路由
上面的示例都是 GET 请求的, 下面来一个 POST 请求的。注意一个接口可以同时响应 GET 和 POST 请求, 比方上面例子可以这样写:
beego.Router("/user/*", &controllers.UserController{}, "get:GetInfo;post:PostData")
模仿发 POST:
$ curl -d "mydata" localhost:8080/user
beego 自定义的静态文件路径是的 static 目录下, 比如, 我们可以访问 http://api.jiuyi.com:8080/static/img/180.jpg(我们在这个目录下放了一张 180.jpg 照片), 但是这个是可以增加的(static 默认是可以访问的)。
我们在项目根目录下创建了一个文件夹 down
, 然后把 180.jpg 放到这里面。
beego.SetStaticPath("download1", "down")
然后, 我们就可以通过 http://api.jiuyi.com:8080/download1/180.jpg 来访问这个 180.jpg 了, 但是注意使用 down 是访问不了的: http://api.jiuyi.com:8080/down/180.jpg
我们要访问到的一个主页是 “http://api.jiuyi.com:8080/static/html/index.html”,这样是能打开的,或者这样 “http://api.jiuyi.com:8080/static/html/”,也是能打开的,如果我们想要打开 “http://api.jiuyi.com:8080” 就能看到网页,那么我们需要将 “/static/html/index.html” 改写成 “/” 才行,在代码中我们这么做:
import (
_ "quickstart/models"
_ "quickstart/routers"
"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
"net/http"
"strings"
)
func main() {
ignoreStaticPath()
beego.BConfig.WebConfig.Session.SessionOn = true
beego.Run()
}
func ignoreStaticPath() {
//透明 static
beego.InsertFilter("/", beego.BeforeRouter, TransparentStatic)
beego.InsertFilter("/*", beego.BeforeRouter, TransparentStatic)
}
func TransparentStatic(ctx *context.Context) {
orpath := ctx.Request.URL.Path
beego.Debug("request url: ", orpath)
//如果请求 uri 还有 api 字段,说明是指令应该取消静态资源路径重定向
if strings.Index(orpath, "api") >= 0 {
return
}
http.ServeFile(ctx.ResponseWriter, ctx.Request, "static/html/" + ctx.Request.URL.Path)
}
这样就可以了。