实例: 比如视频网站,一个视频可以使用一个唯一的数据结构来表示,结构中使用一个唯一的ID标明不同的视频,那么这个ID可以设置为主键。不同用户对这一个视频的评价信息也可以用一个数据结构来表示,那么就可以使用外键将不同的用户的评价和这个唯一的视频相关联。
//定义 Video 结构体:
//设置 Vid 为主键 Reply 为 1 对多关系
type Video struct {
Vid string `orm:"pk"`
Name string
Replys []*Reply `orm:"reverse(many)"`
}
//定义 Reply 结构体:
// 设置 外键
type Reply struct {
Id int
Cid string
Text string
Videoid *Video `orm:"rel(fk)"`
}
代码 vprof.go:
package main
import (
"fmt"
"github.com/astaxie/beego/orm"
)
type Video struct {
Vid string `orm:"pk"`
Name string
Replys []*Reply `orm:"reverse(many)"`
}
type Reply struct {
Id int
Cid string
Text string
Videoid *Video `orm:"rel(fk)"`
}
func init() {
// 需要在init中注册定义的model
fmt.Println("init db model")
orm.RegisterDriver("sqlite3", orm.DRSqlite)
orm.RegisterDataBase("default", "sqlite3", "data.db")
orm.RegisterModel(new(Video), new(PRofile), new(Reply), new(Tag))
orm.RunSyncdb("default", false, true)
}
main.go:
package main
import (
"fmt"
_ "www/ormdb/routers"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
_ "github.com/mattn/go-sqlite3"
)
func main() {
orm.Debug = true
o := orm.NewOrm()
o.Using("default") // 默认使用 default,你可以指定为其他数据库
video := new(Video)
video.Vid = "16BE901637CF7A9B2C"
video.Name = "kiki2002121718"
reply1 := new(Reply)
reply1.Videoid = video
reply1.Cid = "c1"
reply1.Text = "bucuo bucuo"
reply2 := new(Reply)
reply2.Videoid = video
reply2.Cid = "c2"
reply2.Text = "zhideyikan"
reply3 := new(Reply)
reply3.Videoid = video
reply3.Cid = "c3"
reply3.Text = "laji"
fmt.Println(o.Insert(video))
fmt.Println(o.Insert(reply1))
fmt.Println(o.Insert(reply2))
fmt.Println(o.Insert(reply3))
var reply []*Reply
qs := o.QueryTable("reply")
num, err := qs.Filter("videoid_id", "16BE901637CF7A9B2C").All(&reply)
fmt.Println(num, err)
for ix, iv := range reply {
fmt.Printf("get data %d \n", ix)
fmt.Printf("\t %+v \n", iv)
}
beego.Run()
}
实际运行后查看数据库可以看到:
CREATE TABLE `video` (
`vid` varchar(255) NOT NULL PRIMARY KEY,
`name` varchar(255) NOT NULL DEFAULT ''
);
CREATE TABLE `reply` (
`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT,
`cid` varchar(255) NOT NULL DEFAULT '' ,
`text` varchar(255) NOT NULL DEFAULT '' ,
`videoid_id` varchar(255) NOT NULL
);
INSERT INTO reply VALUES(1,'c1','bucuo bucuo','16BE901637CF7A9B2C');
INSERT INTO reply VALUES(2,'c2','zhideyikan','16BE901637CF7A9B2C');
INSERT INTO reply VALUES(3,'c3','laji','16BE901637CF7A9B2C');
实际上 reply 结构体中有一个 videoid_id 的成员,他的值就是video 结构体的主键值。可以看到 定义外键的语句:Videoid *Video
orm:"rel(fk)"
orm会处理成对应主键的变量。
通过 qs.Filter("videoid_id", "16BE901637CF7A9B2C").All(&reply)
语句即可查询到 video id 为 "16BE901637CF7A9B2C"的所有回复信息:
log 输出:
get data 0
&{Id:1 Cid:c1 Text:bucuo bucuo Videoid:0xc000068880}
get data 1
&{Id:2 Cid:c2 Text:zhideyikan Videoid:0xc0000688c0}
get data 2
&{Id:3 Cid:c3 Text:laji Videoid:0xc000068900}