Beego
上手資源
安裝
按照官網指令即可
Routers
基本語法
beego.Router("/api/:id", &controllers.RController{})
beego.Router("/api/list", &RestController{}, "*:ListFood") # * = ANY, 可替換為 post / put
beego.Router("/api/list", &RestController{}, "get,post:ApiFunc") # 指定兩個 Http method 到同一個 func
beego.Router("/api/list", &RestController{}, "get:GetFunc;post:PostFunc") # 指定到不同 Http method 即不同的 Func
beego.AutoRouter("&controllers.ObjectController{}) # 自動 Match /object/blog/2013/09/12 -> ObjectController 的 blog 方法,參數: map[0: 2013 1:09 2:12]
Match
/api:id
: Match /api/123
(即使沒有 :id
, :id
相當於 .*
任意字元)
/api/:id!
: Match /api/123
(:id
一定要有值)
/api/:id([0-9]+)
= api/:id:int
: 指定要配對的字元
/news/:all
: Match /news/path/to/123.html
(:all
是框架自定義的)
/news/*
: 與 :all
一樣,差別在於 *
會將變數給 splat
而不是 all
/user/:username([\w]+)
= /user/:username:string
: Match username = 字串
/download/*.*
: Match /download/file/api.xml
404
beego.ErrorHandler("404", page_not_found)
func page_not_found(rw http.ResponseWriter, r *http.Request) {
rw.Write([]byte("404"))
}
match url path 直接在 router 層輸出
import "github.com/astaxie/beego/context"
beego.Get("/gl", func(ctx *context.Context) {
ctx.Output.Body([]byte("ok"))
})
Controllers
基本語法
輸出字串
this.Ctx.WriteString("hello")
this.Ctx.Output.Body([]byte("ok"))
產生 view
this.Data["show"] = "Test"
this.TplName = "user/index.tpl"
改變輸出的 status code
this.Ctx.Output.SetStatus(400)
取得 parameters 變數
取得 form 變數
this.Ctx.Input.Param("user_id") // 注意!有 `:`
取得 router 對應的變數 (url params mapping)
router:
beego.Router("/users/:user_id/", &controllers.UserController{}, "post:update")
this.Ctx.Input.Param(":user_id") // 注意!有 `:`
讓 struct int 參數支援選填
因為 int 初始值為 0, 所以這裡用 pointer 來支援 nil, 再額外判斷如果有值再放到 struct 裡
type AddReq struct {
Gender *int
}
req := AddReq{}
age, err := this.GetInt("age")
if err == nil {
req.Age = &age
}
log.Println(*req.Age)
conf
取得變數值
單一值
httpport = 8080
beego.AppConfig.String("httpport") # dev
Section 值/陣列
[demo]
peers = one;two;three
beego.AppConfig.Strings("demo::peers") # [one two three]
根據環境不同讀取不同的設定檔
app.conf
runmode = dev
sessionon = true # 啟用 session, 預設使用 mem
copyrequestbody = true # 要打開,否則 this.Ctx.Input.RequestBody 抓不到資料
[dev]
host = 127.0.0.1
[prod]
host = 137.111.120.179
取變數時 :
beego.AppConfig.String("runmode")
log
在 beego 目錄下產生 log file, 更多參數請參考官方文件
beego.SetLogger(logs.AdapterFile, `{"filename":"project.log"}`)
beego.Run()
// logs.SetLogger(logs.AdapterMultiFile, ``{"filename":"test.log","separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"]}``)
ORM
Beego orm 相當地方便,雖然 beego orm 是包在 beego 裡面,但是它分的相當的乾淨,你可以在任何 project 上引入, 以下是使用 MySQL 的 example :
import (
"fmt"
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql" // 一定要 import
)
// 這是你的 Model, 用來跟 User Table Mapping 的,欄位名的規則是: user_id (mysql column name) => UserId (struct field)
type User struct {
Id int
UserId string
Email string
Name string
}
func init() {
orm.RegisterModel(new(User))
}
func main() {
orm.RegisterDataBase("default", "mysql", "username:password@/your_db_name?charset=utf8") // 第一個一定要是 default
orm.SetMaxIdleConns("default", 5)
orm.SetMaxOpenConns("default", 30)
o := orm.NewOrm()
user := User{UserId: "2c024jka-cc06-4fc1-8fd3-f1c72dw22dac"} // 相當於是 WHERE 條件
err := o.Read(&user, "user_id")
if err == orm.ErrNoRows {
fmt.Println("Not found")
} else if err == orm.ErrMissPK {
fmt.Println("Missed PK key")
} else {
fmt.Println(user.Email)
}
}
WHERE 多項條件
user := User{UserId: "2c024jka-cc06-4fc1-8fd3-f1c72dw22dac", Name: "Jex"}
err := o.Read(&user, "user_id", "name")
切換到另一個 DB
err = orm.Using("another_db")
SELECT 取一筆 record (limit: 1)
var users []orm.Params
num, err := o.QueryTable(new(model.User)).Filter("user_id", user_id).OrderBy("-created_at").Limit(1).Values(&users)
var d Device
err := o.QueryTable(new(Device)).Filter("did", "A123").One(&d)
user := User{UserId: "2c024jka-cc06-4fc1-8fd3-f1c72dw22dac"}
err := o.Read(&user, "user_id")
Read vs Values : Read 取不到值時會擲 error, Values 則不會
Count
num, err = o.QueryTable(new(model.User)).Filter("user_id", user_id).Count()
Update 特定欄位
affected_num, err := o.QueryTable(new(model.User)).Filter("user_id", user_id).Update(orm.Params{
"name": name,
})
Update 特定欄位
o := orm.NewOrm()
user.Name = "Jex"
user.Address = "Taiwan ... "
o.Update(user, "name", "address")
Raw Query
_, err = j.Service.MySQL.Raw("UPDATE user SET name = ? WHERE uid = ?", 'Bob', 'uid00001').Exec()