beego orm 多對多查詢

首先糾正一下beego的文檔json

rel_table
設置自動生成的 m2m 關係表的名稱

rel_through
若是要在 m2m 關係中使用自定義的 m2m 關係表
經過這個設置其名稱,格式爲 pkg.path.ModelName
eg: app.models.PostTagRel
PostTagRel 表須要有到 Post 和 Tag 的關係app

實際上rel_through的格式並非pkg.path.ModelName,正確的姿式是:測試

// 不要照抄哈,這裏只是eg應該怎麼使用
learnBeego/myApp/models.RoleUser

在這裏卡了一天,後來仍是在google的幫助下找到了問題,bd能搜索出關於go的東西實在太少了ui

舉個例子

需求:用戶、角色。
咱們要實現 一個用戶能夠有多個角色,一個角色能夠有多個用戶google

數據表設計

用戶表 user設計

id username passwrod created_at updated_at
1 testa 123456 2018-01-01 12:36:47 2018-01-01 12:36:47
2 testb 654321 2018-01-01 12:36:47 2018-01-01 12:36:47

角色表 rolecode

id name created_at updated_at
1 測試角色A 2018-01-01 12:36:47 2018-01-01 12:36:47
2 測試角色B 2018-01-01 12:36:47 2018-01-01 12:36:47

角色用戶關係表 role_userorm

id user_id role_id created_at updated_at
1 1 1 2018-01-01 12:36:47 2018-01-01 12:36:47
2 1 2 2018-01-01 12:36:47 2018-01-01 12:36:47
3 2 1 2018-01-01 12:36:47 2018-01-01 12:36:47

模型

用戶模型文檔

注意! 使用多對多時,想要獲取關係字段是須要手動完成的,orm不會爲你自動完成這些查詢操做,不要覺得設置完 rel_through就完事了!
type User struct {
    Id    int64
    Username    string    `orm:"size(128);unique" valid:"Required"`
    password    string    `orm:"size(128);" json:"-" valid:"Required"`
    CreatedAt    time.Time    `orm:"auto_now_add;type(datetime)"`
    UpdatedAt    time.Time    `orm:"auto_now;type(datetime)"`
    Roles    []*Role    `orm:"rel(m2m);rel_through(learnBeego/myApp/models.RoleUser)"`
}

func init() {
    orm.RegisterModel(new(User))
}

func (m *User) TableName() string {
    return "user"
}

// 經過用戶ID獲取用戶信息及用戶所屬的角色
func GetUserById(id int64) (v *User, err error) {
    o := orm.NewOrm()
    v = &User{Id: id}
    if err = o.QueryTable(new(User)).Filter("Id",id).RelatedSel().One(v); err == nil {
        // 獲取關係字段,o.LoadRelated(v, "Roles") 這是關鍵
        // 查找該用戶所屬的角色
        if _, err = o.LoadRelated(v, "Roles");err!=nil{
            return nil, err
        }
        return v, nil
    }
    return nil, err
}

角色模型string

type Role struct {
    Id    int64
    Name    string
    CreatedAt    time.Time    `orm:"auto_now_add;type(datetime)"`
    UpdatedAt    time.Time    `orm:"auto_now;type(datetime)"`
    Users    []*User    `orm:"reverse(many)"`
}

func init() {
    orm.RegisterModel(new(Role))
}

func (m *Role) TableName() string {
    return "role"
}

用戶角色關係模型

type RoleUser struct {
    Id    int64
    User    *User    `orm:"rel(fk)"`
    Role    *Role    `orm:"rel(fk)"`
    CreatedAt    time.Time    `orm:"type(datetime)"`
    UpdatedAt    time.Time    `orm:"type(datetime)"`
}

func init() {
    orm.RegisterModel(new(RoleUser))
}

func (m *RoleUser) TableName() string {
    return "role_user"
}

最後在控制器中

...

func (c *UserController) GetOne() {
    idStr := c.Ctx.Input.Param(":id")
    id, _ := strconv.ParseInt(idStr, 0, 64)
    v, err := models.GetUserById(id)
    if err != nil {
        c.Data["json"] = "找不到匹配的數據"
    } else {
        c.Data["json"] = v
    }
    c.ServeJSON()
}

...

最後,測試

假如GetOne()對應的URL是localhost:8080/v1/user/:id
請求http://localhost"8080/v1/user/1時,返回的數據

{
    "Id": 1,
    "Username": "testa",
    "CreatedAt": "2018-01-01T12:36:47+08:00",
    "UpdatedAt": "2018-01-01T12:36:47+08:00",
    "Roles":[
        {
            "Id": 1,
            "Name": "測試角色A",
            "CreatedAt": "2018-01-01T12:36:47+08:00",
            "UpdatedAt": "2018-01-01T12:36:47+08:00",
        },
        {
            "Id": 2,
            "Name": "測試角色B",
            "CreatedAt": "2018-01-01T12:36:47+08:00",
            "UpdatedAt": "2018-01-01T12:36:47+08:00",
        },
    ]
}
相關文章
相關標籤/搜索