beego中的orm学习
标签:beego orm
因为我没怎么用过orm,一般就直接用着sql驱动直接上了。数据库上的也有一段时间了,对于各种关系忘得也是差不多了。
这里主要是官方写的不是特别好,比如官方中文文档在这里给出的models.go的例子,让人看的很迷茫。
package main
import (
"github.com/astaxie/beego/orm"
)
type User struct {
Id int
Name string
Profile *Profile `orm:"rel(one)"` // OneToOne relation
Post []*Post `orm:"reverse(many)"` // 设置一对多的反向关系
}
type Profile struct {
Id int
Age int16
User *User `orm:"reverse(one)"` // 设置一对一反向关系(可选)
}
type Post struct {
Id int
Title string
User *User `orm:"rel(fk)"` //设置一对多关系
Tags []*Tag `orm:"rel(m2m)"`
}
type Tag struct {
Id int
Name string
Posts []*Post `orm:"reverse(many)"`
}
func init() {
// 需要在init中注册定义的model
orm.RegisterModel(new(User), new(Post), new(Profile), new(Tag))
}
这……我知道那些标签能够用反射获得,可是orm后面的那些什么一对一、一对多关系都是什么东西?下面将记录一些我在orm学习的一些坑点,以及数据库知识与orm知识的回顾与结合。
参数设置
orm中的参数设置,比如rel、default之类的,定义在官方文档的模型定义这里。模型定义功能主要用于数据库数据转换和自动建表,对于我这种比较喜欢把所有相关的语句放在一个地方,同时又不想写SQL语句的人而言,这个功能还是值得深入研究的。(毕竟能够在本语言内解决的东西最好还是不要再加技术栈)
设置参数:orm:"null;rel(fk)"
,多个设置之间使用;
进行分隔。设置的值如果是多个,使用,
进行分隔。
忽略字段
设置-
可忽略struct中的字段,比如
type User struct {
...
AnyField string `orm:"-"`
...
}
auto
当Field类型为int等类型的时候,可以设置字段为自增键(extra:auto_increment)。当模型定义中没有主键时,符合上述类型且名称为Id
的Field将被视为自增键。
pk
primary key,设置为逐渐。适用于定义其他名称与类型为主键。
null
数据库表默认为NOT NULL
,设置null代表允许,即ALLOW NULL
,比如Name string orm:"null"
index
为单个字段增加索引(模型定义的开头有提到复合索引)
unique
为单个字段增加unique键
column
为字段设置db字段的名称(不设置将会自动转换,转换规则也是在模型定义页面的开头)。
Name string `orm:"column(user_name)"`
size
string类型默认为varchar(255),设置size之后会变为varchar(size)
Title string `orm:"size(60)"`
digits/decimals
设置float32,float64类型的浮点精度
Money float64 `orm:"digits(12);decimals(4)"`
即总长度12,小数点后4位
auto_now/auto_now_add
Created time.Time `orm:"auto_now_add;type(datetime)"`
Updated time.Time `orm:"auto_now;type(datetime)"`
- auto_now每次model保存时都会对时间自动更新
- auto_now_add第一次保存时才设置时间
对于批量的update此设置是不生效的。
type
设置为date时,time.Time字段的对应db类型使用date。设置为datetime时,time.Time字段的对应db类型使用datetime
default
为字段设置默认值,类型必须符合(目前仅用于级联删除时的默认值)
Comment
type User struct {
...
Status int `orm:"default(1)" description:(这是状态字段)`
...
}
为字段添加注释,注释中禁止包含引号
表关系设置
rel/reverse
关系参考了Django ORM 一对一、一对多、多对多详解,例子使用的是官方中文教程的例子。
一对一关系
子表从母表中选出一条数据一一对应,母表中选出来一条就少一条,子表中不可以再选择母表中已经选择的数据。
从数学的角度上来说,就是将子表作为定义域,母表作为值域的单射(不确定是否是满射,好像可以不是的样子)
RelOneToOne:
type User struct {
...
Profile *Profile `orm:"null;rel(one);on_delete(set_null)"`
...
}
对应的反向关系RelReverseOne
type Profile struct {
...
User *User `orm:"reverse(one)"`
...
}
实验打出来的表格信息:
create table `user`
-- --------------------------------------------------
-- Table Structure for `main.User`
-- --------------------------------------------------
CREATE TABLE IF NOT EXISTS `user` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`profile_id` integer UNIQUE
) ENGINE=InnoDB;
create table `profile`
-- --------------------------------------------------
-- Table Structure for `main.Profile`
-- --------------------------------------------------
CREATE TABLE IF NOT EXISTS `profile