beego orm使用
初始化
建立新beego專案
bee new test
在main.go中開始測試
模型關係
# 外來鍵始終在子表上
#一個使用者對應一個簡介;一個簡介對應一個使用者;
one2one:User(子表) -> Profile(主表);one2one:Profile -> User
#一個郵件對應一個使用者;一個使用者有多個郵件;
one2many:Post(子表) -> User(主表);many2one:User -> Post
#一個郵件對應多個標籤;一個標籤對應多個郵件;
many2many:Post(子表) -> Tag(主表);many2many:Tag -> Post
新建4個結構體
使用標籤`orm:"column(id)`對屬性進行標註,用於解析。
標註邏輯外來鍵,自動建表時不會生成外來鍵。
`orm:"rel(one)"` 表示one2one
`orm:"rel(fk)"` 表示one2many
`orm:"rel(m2m)"` 表示many2many
`orm:"reverse(one)"` `orm:"reverse(one)"` 標註反向關係
type User struct {
⇥ Id int `orm:"column(id);auto" description:"id"`
⇥ Name string `orm:"column(name)" description:"name"`
⇥ Profile *Profile `orm:"rel(one)"` // OneToOne relation
⇥ //Posts []*Post `orm:"reverse(many)"` //one2many情況下,不要寫reverse
}
type Profile struct {
⇥ Id int `orm:"column(id);auto" description:"id"`
⇥ Age int16 `orm:"column(age)" description:"age"`
⇥ //User *User `orm:"reverse(one)"` // Reverse relationship (optional)
}
type Post struct {
⇥ Id int `orm:"column(id);auto" description:"id"`
⇥ Title string `orm:"column(title)" description:"title"`
⇥ User *User `orm:"rel(fk)"` // OneToMany relation
⇥ Tags []*Tag `orm:"rel(m2m)"` // m2m relation
}
type Tag struct {
⇥ Id int `orm:"column(id);auto" description:"id"`
⇥ Name string `orm:"column(name)" description:"name"`
⇥ Posts []*Post `orm:"reverse(many)"`
}
初始化操作
//ormer
var O orm.Ormer
func init() {
⇥ //註冊驅動
⇥ orm.RegisterDriver("mysql", orm.DRMySQL)
⇥ //註冊預設資料庫
⇥ orm.RegisterDataBase("default", "mysql", "root:root@tcp(192.168.99.100:3308)/test?charset=utf8")
⇥ //註冊model
⇥ orm.RegisterModel(new(User), new(Profile), new(Post), new(Tag))
⇥ //自動建表
⇥ orm.RunSyncdb("default", false, true)
⇥ //初始化ormer
⇥ O = orm.NewOrm()
⇥ //初始化資料
⇥ datainit()
}
生成的database資訊
執行之前,需要建立資料庫test,並配置資料庫資訊,字元編碼全部設定為utf8
執行:註冊model,自動建表 即可得到如下資訊。
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| post |
| post_tags |
| profile |
| tag |
| user |
+----------------+
5 rows in set (0.00 sec)
mysql> desc post;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | | | |
| user_id | int(11) | NO | | NULL | |
+---------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> desc post_tags;
+---------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| post_id | int(11) | NO | | NULL | |
| tag_id | int(11) | NO | | NULL | |
+---------+------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> desc profile;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| age | smallint(6) | NO | | 0 | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> desc tag;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | | |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> desc user;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | | |
| profile_id | int(11) | NO | UNI | NULL | |
+------------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
database生成規則
1.新增rel(one)、rel(fk)的屬性會生成 表名_id的欄位,rel(one)時生成欄位key為unique
type User struct {
Profile *Profile `orm:"rel(one)"`
}
type Profile struct {
User *User `orm:"reverse(one)"` //可以省略
}
---->
mysql> desc user;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | | |
| profile_id | int(11) | NO | UNI | NULL | |
+------------+--------------+------+-----+---------+----------------+
2.rel(m2m)、reverse(many)這一對欄位 會生成關係對應表 子表_主表s 主鍵自增
type Post struct {
Tags []*Tag `orm:"rel(m2m)"` // m2m relation
}
type Tag struct {
Posts []*Post `orm:"reverse(many)"`
}
---->
mysql> desc post_tags;
+---------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| post_id | int(11) | NO | | NULL | |
| tag_id | int(11) | NO | | NULL | |
+---------+------------+------+-----+---------+----------------+
初始化資料
func datainit() {
⇥ //rel : 自動生成外來鍵為 表名_id
⇥ sql1 := "insert into user (name,profile_id) values ('ming',1),('hua',2),('qiang',3);"
⇥ sql2 := "insert into profile (age) values (16),(14),(15);"
⇥ sql3 := "insert into tag (name) values ('offical'),('beta'),('dev');"
⇥ sql4 := "insert into post (title,user_id) values ('paper1',1),('paper2',1),('paper3',2),('paper4',3),('paper5',3);"
⇥ // m2m 生成的 表名:子表_主表s 主鍵自增
⇥ sql5 := "insert into post_tags (tag_id, post_id) values (1,1),(1,3),(2,2),(3,3),(2,4),(3,4),(3,5); "
//使用Raw().Exec()執行sql
⇥ O.Raw(sql1).Exec()
⇥ O.Raw(sql2).Exec()
⇥ O.Raw(sql3).Exec()
⇥ O.Raw(sql4).Exec()
⇥ O.Raw(sql5).Exec()
}
查詢
one2one查詢
func one2one() {
⇥ //one to one :主表Profile 子表User [常用方式:使用級聯查詢全部資料]
⇥ fmt.Println("one2one-------------------------------")
⇥ //1.通過已知的 子表User資料,查詢主表Profile資料
⇥ user := &User{Id: 1}
⇥ O.Read(user) //查詢子表
⇥ if user.Profile != nil {
⇥ ⇥ O.Read(user.Profile)
⇥ }
⇥ fmt.Println("1.二次查詢 user now:", user)
⇥ fmt.Println("1.二次查詢 profile now:", user.Profile)
⇥ fmt.Println("-------------------------------")
⇥ //2.級聯查詢
⇥ user = &User{}
⇥ O.QueryTable("user").Filter("Id", 1).RelatedSel().One(user)
⇥ fmt.Println("2.級聯查詢 user:", user)
⇥ fmt.Println("2.級聯查詢 profile:", user.Profile)
⇥ fmt.Println("-------------------------------")
⇥ //3.reverse查詢 通過子表條件 查詢主表 ,此時並沒有獲取另一個表的資料
⇥ profile := Profile{}
⇥ O.QueryTable("profile").Filter("User__Id", 1).One(&profile)
⇥ fmt.Println("3.reserve 查詢 profile:", profile, "條件 user id:1")
⇥ profiles := []*Profile{}
⇥ O.QueryTable("profile").Filter("User__Name", "ming").One(&profiles)
⇥ for _, a := range profiles {
⇥ ⇥ fmt.Println("3.reserve 查詢 profile:", a, "條件 user name:ming")
⇥ }
⇥ fmt.Println("-------------------------------")
}
one2many查詢
func one2many() {
⇥ //one to many : 主表User 子表Post [常用方式:使用級聯查詢全部資料]
⇥ fmt.Println("one2many-------------------------------")
⇥ //1.級聯查詢
⇥ var posts []*Post
⇥ O.QueryTable("post").Filter("User__Id", 1).RelatedSel().All(&posts)
⇥ for _, v := range posts {
⇥ ⇥ fmt.Println("1.級聯查詢 post:", v)
⇥ ⇥ fmt.Println("1.級聯查詢 post.user.name:", v.User.Name)
⇥ }
⇥ fmt.Println("-------------------------------")
⇥ //2.reverse 查詢
⇥ var user User
⇥ err := O.QueryTable("user").Filter("Post__Title", "paper1").Limit(1).One(&user)
⇥ if err == nil {
⇥ ⇥ fmt.Println("2.reverse 查詢 user:", user)
⇥ } else {
⇥ ⇥ fmt.Println("err:", err)
⇥ }
⇥ fmt.Println("-------------------------------")
}
many2many查詢
func many2many() {
⇥ //many to many : 主表 Tag 子表Post
⇥ //1.reverse 查詢
⇥ fmt.Println("many2many-------------------------------")
⇥ var posts []*Post
⇥ O.QueryTable("post").Filter("Tags__Tag__Name", "offical").All(&posts)
⇥ for _, v := range posts {
⇥ ⇥ fmt.Println("1.reverse 查詢 post:", v)
⇥ }
⇥ fmt.Println("-------------------------------")
⇥ //reverse 查詢
⇥ var tags []*Tag
⇥ O.QueryTable("tag").Filter("Posts__Post__Title", "paper1").All(&tags)
⇥ for _, x := range tags {
⇥ ⇥ fmt.Println("2.reverse 查詢 tag:", x)
⇥ }
⇥ fmt.Println("-------------------------------")
⇥ //3.級聯查詢
⇥ //可以建立post_tags表的結構體MapPostTag,包含Post、Tag
⇥ //使用O.QueryTable("post_tags").RelatedSel().All(&MapPostTag)進行查詢
}
比較
我們常用的left join 查詢全部資料的兩種方式:
var entry Entry
O.QueryTable("子表").RelatedSel().All(&entry)
var maps []orm.Params
sql:="xxx;"
O.Raw(sql).Values(&maps)
通過如下程式碼進行返回比較響應json
//定義controller
type UserController struct {
⇥ beego.Controller
}
//定義urlmap到具體方法
func (c *UserController) URLMapping() {
⇥ c.Mapping("GetAll", c.GetAll)
}
func main() {
⇥ //註冊路由
⇥ beego.Router("/user", &UserController{}, "get:GetAll")
⇥ //啟動
⇥ beego.Run()
}
/*
//使用relatedsel自動級聯查詢
func (c *UserController) GetAll() {
⇥ var users []*User
⇥ O.QueryTable("user").RelatedSel().All(&users)
⇥ c.Data["json"] = users
⇥ c.ServeJSON()
}
*/
//使用原生sql進行查詢
func (c *UserController) GetAll() {
⇥ var maps []orm.Params
⇥ sql := `
⇥ ⇥ select * from user t1
⇥ ⇥ left join profile t2 on t1.profile_id=t2.id
⇥ `
⇥ O.Raw(sql).Values(&maps)
⇥ c.Data["json"] = maps
⇥ c.ServeJSON()
}
使用relatedsel自動級聯查詢 json:
[
{
"Id": 1,
"Name": "ming",
"Profile": {
"Id": 1,
"Age": 16
}
},
{
"Id": 2,
"Name": "hua",
"Profile": {
"Id": 2,
"Age": 14
}
},
{
"Id": 3,
"Name": "qiang",
"Profile": {
"Id": 3,
"Age": 15
}
}
]
使用原生sql進行查詢 json:
[
{
"age": "16",
"id": "1",
"name": "ming",
"profile_id": "1"
},
{
"age": "14",
"id": "2",
"name": "hua",
"profile_id": "2"
},
{
"age": "15",
"id": "3",
"name": "qiang",
"profile_id": "3"
}
]
load related查詢
func loadRelatedField() {
⇥ //適用於所有關係模型 one2one one2m m2m
⇥ fmt.Println("one2one:loadRelated---------------------")
⇥ user := User{Id: 1}
⇥ if err := O.Read(&user); err == nil {
⇥ ⇥ O.LoadRelated(&user, "Profile") //引數中寫入需要關聯的欄位即可
⇥ ⇥ fmt.Println("user:", user)
⇥ ⇥ fmt.Println("user.profile:", user.Profile)
⇥ }
⇥ post := Post{Id: 1}
⇥ if err := O.Read(&post); err == nil {
⇥ ⇥ O.LoadRelated(&post, "Tags")
⇥ ⇥ for _, v := range post.Tags {
⇥ ⇥ ⇥ fmt.Println("tag:", v)
⇥ ⇥ }
⇥ }
⇥ tag := Tag{Id: 1}
⇥ if err := O.Read(&tag); err == nil {
⇥ ⇥ O.LoadRelated(&tag, "Posts")
⇥ ⇥ for _, v := range tag.Posts {
⇥ ⇥ ⇥ fmt.Println("post:", v)
⇥ ⇥ }
⇥ }
}
插入
單表插入
⇥ //單表插入
⇥ fmt.Println("單表插入-------------")
⇥ profile:=Profile{Age:18}
⇥ id,err:=O.Insert(&profile)
⇥ fmt.Println("返回插入的id:",id)
one2one one2many插入
⇥ //one2one插入
⇥ err := O.Begin() //開啟事物
⇥ //插入主表
⇥ profile := Profile{Age: 19}
⇥ id, err := O.Insert(&profile)
⇥ if err != nil {
⇥ ⇥ O.Rollback()
⇥ } else {
⇥ ⇥ fmt.Println("success insert profile")
⇥ }
⇥ //插入子表
⇥ user := User{Name: "kakaxi", Profile: &Profile{Id: int(id)}}
⇥ _, err = O.Insert(&user)
⇥ if err != nil {
⇥ ⇥ O.Rollback()
⇥ } else {
⇥ ⇥ fmt.Println("success insert user")
⇥ }
⇥ err = O.Commit()
m2m插入
//m2m
//比如知道一個郵件物件post,一個標記物件tag,插入他們的對應關係
O.Begin()
//step1:插入post,獲取m2m物件
user := User{Id: 1}
O.Read(&user) //讀取user
post := Post{Title: "kakaxi開啟寫輪眼了", User: &user} //拼接post
id, err := O.Insert(&post) //插入post
if err != nil {
O.Rollback()
return err
} else {
fmt.Println("insert post success")
}
post = Post{Id: int(id)}
m2m := O.QueryM2M(&post, "Tags") //建立m2m物件,Tags為關聯屬性
//step2:插入tag
tag := Tag{Name: "娛樂"}
_, err = O.Insert(&tag)
if err != nil {
O.Rollback()
return err
} else {
fmt.Println("insert tag success")
}
//step3:插入關係表
num, err := m2m.Add(&tag)
if err != nil {
O.Rollback()
return err
} else {
fmt.Println("insert post_tags success,added nums:", num)
}
O.Commit()
return nil
更新
單表更新
o := orm.NewOrm()
user := User{Id: 1}
if o.Read(&user) == nil {
user.Name = "MyName"
if num, err := o.Update(&user); err == nil {
fmt.Println(num)
}
}
// Only update Name
o.Update(&user, "Name")
// Update multiple fields
// o.Update(&user, "Field1", "Field2", ...)
更新
。。。我已經不想學更新了,直接用Raw(sql).Exec()執行吧
刪除
單表刪除
o := orm.NewOrm()
if num, err := o.Delete(&User{Id: 1}); err == nil {
fmt.Println(num)
}
相關文章
- Go實戰專案-Beego的orm的基本使用GoORM
- golang beego orm 查詢條件 or andGolangORM
- beego orm中時區的問題GoORM
- beego的ORM-配置資料庫GoORM資料庫
- 求救Beego大神們,Beego orm 怎麼限制Relation裡返回的Variable?GoORM
- beego ORM 建立模型,生成表。遇到的一些坑。GoORM模型
- orm使用ORM
- 建議beego的ORM,可以實現表欄位註釋的新增GoORM
- 國內哪些公司在使用BeegoGo
- 使用beego擼了一個社群Go
- 非框架內使用 ORM框架ORM
- django中orm的使用DjangoORM
- 【Golang】基於beego/orm實現相同表結構不同表名的分表方法實現GolangORM
- Beego 再出發Go
- NET8 ORM 使用AOT SqlSugarORMSqlSugar
- orm中使用modelForm新增資料ORM
- 使用C++的ORM框架QxORMC++ORM框架
- beego 使用 coding 的 webhook 2.0 進行自動部署GoWebHook
- beego 怎麼與vue.js一起使用?GoVue.js
- django指令碼orm中使用原生sqlDjango指令碼ORMSQL
- hisql ORM 查詢語句使用教程SQLORM
- windows 安裝beegoWindowsGo
- docker建立beego映象DockerGo
- Beego Models之二Go
- beego tag詳解Go
- beego如何與vue一起結合使用 跨域?GoVue跨域
- .Net Core 3.0 MVC 中使用 SqlSugar ORM框架MVCSqlSugarORM框架
- 靈活使用 SQLAlchemy 中的 ORM 查詢SQLORM
- ent orm筆記2---schema使用(下)ORM筆記
- ent orm筆記2---schema使用(上)ORM筆記
- beego建立專案流程Go
- beego框架程式碼分析Go框架
- beego 架構(API 版)Go架構API
- Beego 框架巔峰之路Go框架
- JSON欄位型別在ORM中的使用JSON型別ORM
- ORM框架之GreenDao3.0使用詳解(二)ORM框架
- [beego新手入門]基於web框架-beego的RESTful API的構建之旅GoWeb框架RESTAPI
- ORM 陷阱ORM