831eeca7 by slene

zh docs update

1 parent 2c5e062c
1 ## Custom Fields
2
3 TypeBooleanField = 1 << iota
4
5 // string
6 TypeCharField
7
8 // string
9 TypeTextField
10
11 // time.Time
12 TypeDateField
13 // time.Time
14 TypeDateTimeField
15
16 // int16
17 TypeSmallIntegerField
18 // int32
19 TypeIntegerField
20 // int64
21 TypeBigIntegerField
22 // uint16
23 TypePositiveSmallIntegerField
24 // uint32
25 TypePositiveIntegerField
26 // uint64
27 TypePositiveBigIntegerField
28
29 // float64
30 TypeFloatField
31 // float64
32 TypeDecimalField
33
34 RelForeignKey
35 RelOneToOne
36 RelManyToMany
37 RelReverseOne
38 RelReverseMany
...\ No newline at end of file ...\ No newline at end of file
1 ## Model Definition
2
3 比较全面的 Model 定义例子,后文所有的例子如无特殊说明都以这个为基础。
4
5 当前还没有完成自动创建表的功能,所以提供一个 [Models.sql](Models.sql) 测试
6
7 note: 根据文档的更新,随时都可能更新这个 Model
8
9 ##### models.go:
10
11 package main
12
13 import (
14 "github.com/astaxie/beego/orm"
15 "time"
16 )
17
18 type User struct {
19 Id int `orm:"auto"` // 设置为auto主键
20 UserName string `orm:"size(30);unique"` // 设置字段为unique
21 Email string `orm:"size(100)"` // 设置string字段长度时,会使用varchar类型
22 Password string `orm:"size(100)"`
23 Status int16 `orm:"choices(0,1,2,3);defalut(0)"` // choices设置可选值
24 IsStaff bool `orm:"default(false)"` // default设置默认值
25 IsActive bool `orm:"default(0)"`
26 Created time.Time `orm:"auto_now_add;type(date)"` // 创建时自动设置时间
27 Updated time.Time `orm:"auto_now"` // 每次更新时自动设置时间
28 Profile *Profile `orm:"null;rel(one);on_delete(set_null)"` // OneToOne relation, 级联删除时设置为NULL
29 Posts []*Post `orm:"reverse(many)" json:"-"` // fk 的反向关系
30 orm.Manager `json:"-"` // 每个model都需要定义orm.Manager
31 }
32
33 // 定义NewModel进行orm.Manager的初始化(必须)
34 func NewUser() *User {
35 obj := new(User)
36 obj.Manager.Init(obj)
37 return obj
38 }
39
40 type Profile struct {
41 Id int `orm:"auto"`
42 Age int16 ``
43 Money float64 ``
44 User *User `orm:"reverse(one)" json:"-"` // 设置反向关系(字段可选)
45 orm.Manager `json:"-"`
46 }
47
48 func (u *Profile) TableName() string {
49 return "profile" // 自定义表名
50 }
51
52 func NewProfile() *Profile {
53 obj := new(Profile)
54 obj.Manager.Init(obj)
55 return obj
56 }
57
58 type Post struct {
59 Id int `orm:"auto"`
60 User *User `orm:"rel(fk)"` // RelForeignKey relation
61 Title string `orm:"size(60)"`
62 Content string ``
63 Created time.Time ``
64 Updated time.Time ``
65 Tags []*Tag `orm:"rel(m2m)"` // ManyToMany relation
66 orm.Manager `json:"-"`
67 }
68
69 func NewPost() *Post {
70 obj := new(Post)
71 obj.Manager.Init(obj)
72 return obj
73 }
74
75 type Tag struct {
76 Id int `orm:"auto"`
77 Name string `orm:"size(30)"`
78 Status int16 `orm:"choices(0,1,2);default(0)"`
79 Posts []*Post `orm:"reverse(many)" json:"-"`
80 orm.Manager `json:"-"`
81 }
82
83 func NewTag() *Tag {
84 obj := new(Tag)
85 obj.Manager.Init(obj)
86 return obj
87 }
88
89 type Comment struct {
90 Id int `orm:"auto"`
91 Post *Post `orm:"rel(fk)"`
92 Content string ``
93 Parent *Comment `orm:"null;rel(fk)"` // null设置allow NULL
94 Status int16 `orm:"choices(0,1,2);default(0)"`
95 Created time.Time `orm:"auto_now_add"`
96 orm.Manager `json:"-"`
97 }
98
99 func NewComment() *Comment {
100 obj := new(Comment)
101 obj.Manager.Init(obj)
102 return obj
103 }
104
105 func init() {
106 // 需要在init中注册定义的model
107 orm.RegisterModel(new(User))
108 orm.RegisterModel(new(Profile))
109 orm.RegisterModel(new(Post))
110 orm.RegisterModel(new(Tag))
111 orm.RegisterModel(new(Comment))
112 }
113
114 ## Field Type
115
116 现在 orm 支持下面的字段形式
117
118 | go type | field type | mysql type
119 | :--- | :--- | :---
120 | bool | TypeBooleanField | tinyint
121 | string | TypeCharField | varchar
122 | string | TypeTextField | longtext
123 | time.Time | TypeDateField | date
124 | time.TIme | TypeDateTimeField | datetime
125 | int16 |TypeSmallIntegerField | int(4)
126 | int, int32 |TypeIntegerField | int(11)
127 | int64 |TypeBigIntegerField | bigint(20)
128 | uint, uint16 |TypePositiveSmallIntegerField | int(4) unsigned
129 | uint32 |TypePositiveIntegerField | int(11) unsigned
130 | uint64 |TypePositiveBigIntegerField | bigint(20) unsigned
131 | float32, float64 | TypeFloatField | double
132 | float32, float64 | TypeDecimalField | double(digits, decimals)
133
134 关系型的字段,其字段类型取决于对应的主键。
135
136 * RelForeignKey
137 * RelOneToOne
138 * RelManyToMany
139 * RelReverseOne
140 * RelReverseMany
141
142 ## Field Options
143
144 `orm:"null;rel(fk)"`
145
146 通常每个 Field 的 StructTag 里包含两种类型的设置,类似 null 的 bool 型设置,还有 类似 rel(fk) 的指定值设置,bool 型默认为 false,指定以后即表示为 true
147
148 多个设置间使用 `;` 分隔,设置的值如果是多个,使用 `,` 分隔。
149
150 #### auto
151
152 设置为 Autoincrement Primary Key
153
154 #### pk
155
156 设置为 Primary Key
157
158 #### null
159
160 数据库表默认为 `NOT NULL`,设置 null 代表 `ALLOW NULL`
161
162 #### blank
163
164 设置 string 类型的字段允许为空,否则 clean 会返回错误
165
166 #### index
167
168 为字段增加索引
169
170 #### unique
171
172 为字段增加 unique 键
173
174 #### column
175
176 为字段设置 db 字段的名称
177
178 UserName `orm:"column(db_user_name)"`
179
180 #### default
181
182 为字段设置默认值,类型必须符合
183
184 Status int `orm:"default(1)"`
185
186 #### choices
187
188 为字段设置一组可选的值,类型必须符合。其他值 clean 会返回错误
189
190 Status int `orm:"choices(1,2,3,4)"`
191
192 #### size (string)
193
194 string 类型字段设置 size 以后,db type 将使用 varchar
195
196 Title string `orm:"size(60)"`
197
198 #### digits / decimals
199
200 设置 float32, float64 类型的浮点精度
201
202 Money float64 `orm:"digits(12);decimals(4)"`
203
204 总长度 12 小数点后 4 位 eg: `99999999.9999`
205
206 #### auto_now / auto_now_add
207
208 Created time.Time `auto_now_add`
209 Updated time.Time `auto_now`
210
211 * auto_now 每次 model 保存时都会对时间自动更新
212 * auto_now_add 第一次保存时才设置时间
213
214 对于批量的 update 此设置是不生效的
215
216 #### type
217
218 设置为 date, time.Time 字段的对应 db 类型使用 date
219
220 Created time.Time `orm:"auto_now_add;type(date)"`
221
222 ## Relation Field Options
223
224 #### rel / reverse
225
226 RelOneToOne:
227
228 type User struct {
229 ...
230 Profile *Profile `orm:"null;rel(one);on_delete(set_null)"`
231
232 对应的反向关系 RelReverseOne:
233
234 type Profile struct {
235 ...
236 User *User `orm:"reverse(one)" json:"-"`
237
238 RelForeignKey:
239
240 type Post struct {
241 ...
242 User*User `orm:"rel(fk)"` // RelForeignKey relation
243
244 对应的反向关系 RelReverseMany:
245
246 type User struct {
247 ...
248 Posts []*Post `orm:"reverse(many)" json:"-"` // fk 的反向关系
249
250 RelManyToMany:
251
252 type Post struct {
253 ...
254 Tags []*Tag `orm:"rel(m2m)"` // ManyToMany relation
255
256 对应的反向关系 RelReverseMany:
257
258 type Tag struct {
259 ...
260 Posts []*Post `orm:"reverse(many)" json:"-"`
261
262 #### rel_table / rel_through
263
264 此设置针对 `orm:"rel(m2m)"` 的关系字段
265
266 rel_table 设置自动生成的 m2m 关系表的名称
267 rel_through 如果要在 m2m 关系中使用自定义的 m2m 关系表
268 通过这个设置其名称,格式为 pkg.path.ModelName
269 eg: app.models.PostTagRel
270 PostTagRel 表需要有到 Post 和 Tag 的关系
271
272 当设置 rel_table 时会忽略 rel_through
273
274 #### on_delete
275
276 设置对应的 rel 关系删除时,如何处理关系字段。
277
278 cascade 级联删除(默认值)
279 set_null 设置为 NULL,需要设置 null = true
280 set_default 设置为默认值,需要设置 default 值
281 do_nothing 什么也不做,忽略
282
283 type User struct {
284 ...
285 Profile *Profile `orm:"null;rel(one);on_delete(set_null)"`
286 ...
287 type Profile struct {
288 ...
289 User *User `orm:"reverse(one)" json:"-"`
290
291 删除 Profile 时将设置 User.Profile 的数据库字段为 NULL
...\ No newline at end of file ...\ No newline at end of file
1 SET NAMES utf8;
2 SET FOREIGN_KEY_CHECKS = 0;
3
4 -- ----------------------------
5 -- Table structure for `comment`
6 -- ----------------------------
7 DROP TABLE IF EXISTS `comment`;
8 CREATE TABLE `comment` (
9 `id` int(11) NOT NULL,
10 `post_id` bigint(200) NOT NULL,
11 `content` longtext NOT NULL,
12 `parent_id` int(11) DEFAULT NULL,
13 `status` smallint(4) NOT NULL,
14 `created` datetime NOT NULL,
15 PRIMARY KEY (`id`)
16 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
17
18 -- ----------------------------
19 -- Table structure for `post`
20 -- ----------------------------
21 DROP TABLE IF EXISTS `post`;
22 CREATE TABLE `post` (
23 `id` int(11) NOT NULL,
24 `user_id` int(11) NOT NULL,
25 `title` varchar(60) NOT NULL,
26 `content` longtext NOT NULL,
27 `created` datetime NOT NULL,
28 `updated` datetime NOT NULL,
29 PRIMARY KEY (`id`)
30 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
31
32 -- ----------------------------
33 -- Table structure for `post_tag_rel`
34 -- ----------------------------
35 DROP TABLE IF EXISTS `post_tag_rel`;
36 CREATE TABLE `post_tag_rel` (
37 `id` int(11) NOT NULL,
38 `post_id` int(11) NOT NULL,
39 `tag_id` int(11) NOT NULL,
40 PRIMARY KEY (`id`)
41 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
42
43 -- ----------------------------
44 -- Table structure for `tag`
45 -- ----------------------------
46 DROP TABLE IF EXISTS `tag`;
47 CREATE TABLE `tag` (
48 `id` int(11) NOT NULL,
49 `name` varchar(30) NOT NULL,
50 `status` smallint(4) NOT NULL,
51 PRIMARY KEY (`id`)
52 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
53
54 -- ----------------------------
55 -- Table structure for `user`
56 -- ----------------------------
57 DROP TABLE IF EXISTS `user`;
58 CREATE TABLE `user` (
59 `id` int(11) NOT NULL AUTO_INCREMENT,
60 `user_name` varchar(30) NOT NULL,
61 `email` varchar(100) NOT NULL,
62 `password` varchar(30) NOT NULL,
63 `status` smallint(4) NOT NULL,
64 `is_staff` tinyint(1) NOT NULL,
65 `is_active` tinyint(1) NOT NULL,
66 `created` date NOT NULL,
67 `updated` datetime NOT NULL,
68 `profile_id` int(11) DEFAULT NULL,
69 PRIMARY KEY (`id`)
70 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
71
72 -- ----------------------------
73 -- Table structure for `profile`
74 -- ----------------------------
75 DROP TABLE IF EXISTS `profile`;
76 CREATE TABLE `profile` (
77 `id` int(11) NOT NULL AUTO_INCREMENT,
78 `age` smallint(4) NOT NULL,
79 `money` double NOT NULL,
80 PRIMARY KEY (`id`)
81 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
82
83 SET FOREIGN_KEY_CHECKS = 1;
1 ## Object
2
3 对 object 操作的三个方法 Insert / Update / Delete
4
5 o := orm.NewOrm()
6 user := NewUser()
7 user.UserName = "slene"
8 user.Password = "password"
9 user.Email = "vslene@gmail.com"
10 obj := o.Object(user)
11 fmt.Println(obj.Insert())
12 user.UserName = "Your"
13 fmt.Println(obj.Update())
14 fmt.Println(obj.Delete())
15
16 ### Read
17
18 var user User
19 err := o.QueryTable("user").Filter("id", 1).One(&user)
20 if err != orm.ErrMultiRows {
21 fmt.Println(user.UserName)
22 }
23
24 ### Create
25
26 profile := NewProfile()
27 profile.Age = 30
28 profile.Money = 9.8
29
30 user := NewUser()
31 user.Profile = profile
32 user.UserName = "slene"
33 user.Password = "password"
34 user.Email = "vslene@gmail.com"
35 user.IsActive = true
36
37 fmt.Println(o.Object(profile).Insert())
38 fmt.Println(o.Object(user).Insert())
39 fmt.Println(user.Id)
40
41 创建后会自动对 auto 的 field 赋值
42
43 ### Update
44
45 var user User
46 err := o.QueryTable("user").Filter("id", 1).One(&user)
47 if err != orm.ErrMultiRows {
48 fmt.Println(user.UserName)
49 }
50 user.UserName = "MyName"
51 o.Object(&user).Update()
52
53 ### Delete
54
55 o.Object(user).Delete()
56
57 Delete 操作会对反向关系进行操作,此例中 Post 拥有一个到 User 的外键。删除 User 的时候。如果 on_delete 设置为默认的级联操作,将删除对应的 Post
58
59 删除以后会清除 auto field 的值
1 ## Orm
2
3 beego/orm 的使用方法
4
5 package main
6
7 import (
8 "fmt"
9 "github.com/astaxie/beego/orm"
10 _ "github.com/go-sql-driver/mysql"
11 )
12
13 func init() {
14 // 这个用来设置 driverName 对应的数据库类型
15 // mysql / sqlite3 / postgres 这三种是默认已经注册过的,所以可以无需设置
16 orm.RegisterDriver("mysql", orm.DR_MySQL)
17
18 // 参数1 自定义的数据库名称,用来在orm中切换数据库使用
19 // 参数2 driverName
20 // 参数3 对应的链接字符串
21 // 参数4 设置最大的空闲连接数,使用 golang 自己的连接池
22 orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8", 30)
23 }
24
25 func main() {
26 orm.BootStrap() // 强制在 main 函数里调用,检查 Model 关系,检测数据库参数,调用 orm 提供的 Command
27
28 o := orm.NewOrm()
29 o.Using("default") // 默认使用 default,你可以指定为其他数据库
30
31 profile := NewProfile()
32 profile.Age = 30
33 profile.Money = 9.8
34
35 user := NewUser()
36 user.Profile = profile
37 user.UserName = "slene"
38 user.Password = "password"
39 user.Email = "vslene@gmail.com"
40 user.IsActive = true
41
42 fmt.Println(o.Object(profile).Insert())
43 fmt.Println(o.Object(user).Insert())
44
45 var params []orm.Params
46 if cnt, err := o.QueryTable("user").RelatedSel().Limit(3).OrderBy("-id").Values(&params); err != nil {
47 fmt.Println(err)
48 } else {
49 fmt.Println(cnt)
50 for _, p := range params {
51 fmt.Println(p)
52 }
53 }
54
55 var users []*User
56 if cnt, err := o.QueryTable("user").RelatedSel().Limit(3).OrderBy("-id").All(&users); err != nil {
57 fmt.Println(err)
58 } else {
59 fmt.Println(cnt)
60 for _, u := range users {
61 fmt.Println(u.Id, u.Profile)
62 }
63 }
64 }
1 ## Query
2
3 orm 以 **QuerySeter** 来组织查询,每个返回 **QuerySeter** 的方法都会获得一个新的 **QuerySeter** 对象。
4
5 基本使用方法:
6
7 o := orm.NewOrm()
8
9 // 获取 QuerySeter 对象,user 为表名
10 qs := o.QueryTable("user")
11
12 // 也可以直接使用对象作为表名
13 user := NewUser()
14 qs = o.QueryTable(user) // 返回 QuerySeter
15
16 ### expr
17
18 QuerySeter 中用于描述字段和 sql 操作符使用简单的 expr 查询方法
19
20 字段组合的前后顺序依照表的关系,比如 User 表拥有 Profile 的外键,那么对 User 表查询对应的 Profile.Age 为条件,则使用 `Profile__Age` 注意,字段的分隔符号使用双下划线 `__`,除了描述字段, expr 的尾部可以增加操作符以执行对应的 sql 操作。比如 `Profile__Age__gt` 代表 Profile.Age > 18 的条件查询。
21
22 注释后面将描述对应的 sql 语句,仅仅是描述 expr 的类似结果,并不代表实际生成的语句。
23
24 qs.Filter("id", 1) // WHERE id = 1
25 qs.Filter("profile__age", 18) // WHERE profile.age = 18
26 qs.Filter("Profile__Age", 18) // 使用字段名和Field名都是允许的
27 qs.Filter("profile__age", 18) // WHERE profile.age = 18
28 qs.Filter("profile__age__gt", 18) // WHERE profile.age > 18
29 qs.Filter("profile__age__gte", 18) // WHERE profile.age >= 18
30 qs.Filter("profile__age__in", 18, 20) // WHERE profile.age IN (18, 20)
31
32 qs.Filter("profile__age__in", 18, 20).Exclude("profile__money__lt", 1000)
33 // WHERE profile.age IN (18, 20) AND NOT profile.money < 1000
34
35 ### Operators
36
37 当前支持的操作符号
38
39 #### exact
40
41 Filter / Exclude / Condition expr 的默认值
42
43 qs.Filter("user_name", "slene") // WHERE user_name = 'slene'
44 qs.Filter("user_name__exact", "slene") // WHERE user_name = 'slene'
45 qs.Filter("profile", nil) // WHERE profile_id IS NULL
46
47 #### iexact
48
49 qs.Filter("user_name__iexact", "slene")
50 // WHERE user_name LIKE 'slene'
51 // 大小写不敏感,匹配任意 'Slene' 'sLENE'
52
53 #### contains
54
55 qs.Filter("user_name__contains", "slene")
56 // WHERE user_name LIKE BINARY '%slene%'
57 // 大小写敏感, 匹配包含 slene 的字符
58
59 #### icontains
60
61 qs.Filter("user_name__icontains", "slene")
62 // WHERE user_name LIKE '%slene%'
63 // 大小写不敏感, 匹配任意 'im Slene', 'im sLENE'
64
65 #### in
66
67 qs.Filter("profile__age__in", 17, 18, 19, 20)
68 // WHERE profile.age IN (17, 18, 19, 20)
69
70 #### gt / gte
71
72 qs.Filter("profile__age__gt", 17)
73 // WHERE profile.age > 17
74
75 qs.Filter("profile__age__gte", 18)
76 // WHERE profile.age >= 18
77
78 #### lt / lte
79
80 qs.Filter("profile__age__lt", 17)
81 // WHERE profile.age < 17
82
83 qs.Filter("profile__age__lte", 18)
84 // WHERE profile.age <= 18
85
86 #### startswith
87
88 qs.Filter("user_name__startswith", "slene")
89 // WHERE user_name LIKE BINARY 'slene%'
90 // 大小写敏感, 匹配以 'slene' 起始的字符串
91
92 #### istartswith
93
94 qs.Filter("user_name__istartswith", "slene")
95 // WHERE user_name LIKE 'slene%'
96 // 大小写不敏感, 匹配任意以 'slene', 'Slene' 起始的字符串
97
98
99 #### endswith
100
101 qs.Filter("user_name__endswith", "slene")
102 // WHERE user_name LIKE BINARY '%slene'
103 // 大小写敏感, 匹配以 'slene' 结束的字符串
104
105 #### iendswith
106
107 qs.Filter("user_name__startswith", "slene")
108 // WHERE user_name LIKE '%slene'
109 // 大小写不敏感, 匹配任意以 'slene', 'Slene' 结束的字符串
110
111 #### isnull
112
113 qs.Filter("profile__isnull", true)
114 qs.Filter("profile_id__isnull", true)
115 // WHERE profile_id IS NULL
116
117 qs.Filter("profile__isnull", false)
118 // WHERE profile_id IS NOT NULL
119
120 ## QuerySeter
121
122 #### Filter
123
124 多个 Filter 之间使用 `AND` 连接
125
126 qs.Filter("profile__isnull", true).Filter("user_name", "slene")
127 // WHERE profile_id IS NULL AND user_name = 'slene'
128
129 #### Exclude
130
131 使用 `NOT` 排除条件
132
133 多个 Exclude 之间使用 `AND` 连接
134
135 qs.Exclude("profile__isnull", true).Filter("user_name", "slene")
136 // WHERE NOT profile_id IS NULL AND user_name = 'slene'
137
138 #### Limit
139
140 限制最大返回数据行数,第二个参数可以设置 `Offset`
141
142 var DefaultRowsLimit = 1000 // orm 默认的 limit 值为 1000
143
144 // 默认情况下 select 查询的最大行数为 1000
145 // LIMIT 1000
146
147 qs.Limit(10)
148 // LIMIT 10
149
150 qs.Limit(10, 20)
151 // LIMIT 10 OFFSET 20
152
153 qs.Limit(-1)
154 // no limit
155
156 qs.Limit(-1, 100)
157 // LIMIT 18446744073709551615 OFFSET 100
158 // 18446744073709551615 是 1<<64 - 1 用来指定无 limit 限制 但有 offset 偏移的情况
159
160 #### Offset
161
162 设置 偏移行数
163
164 qs.OFFSET(20)
165 // LIMIT 1000 OFFSET 20
166
167 #### OrderBy
168
169 参数使用 **expr**
170
171 在 expr 前使用减号 `-` 表示 `DESC` 的排列
172
173 qs.OrderBy("id", "-profile__age")
174 // ORDER BY id ASC, profile.age DESC
175
176 qs.OrderBy("-profile__money", "profile")
177 // ORDER BY profile.money DESC, profile_id ASC
178
179 #### RelatedSel
180
181 关系查询,参数使用 **expr**
182
183 var DefaultRelsDepth = 5 // 默认情况下直接调用 RelatedSel 将进行最大 5 层的关系查询
184
185 qs := o.QueryTable("post")
186
187 qs.RelateSel()
188 // INNER JOIN user ... LEFT OUTER JOIN profile ...
189
190 qs.RelateSel("user")
191 // INNER JOIN user ...
192 // 设置 expr 只对设置的字段进行关系查询
193
194 // 对设置 null 属性的 Field 将使用 LEFT OUTER JOIN
195
196
197
198
199
200
201
202
203
204
1 ## beego orm 介绍
2
3
4 ## 指南
5
6 1. [Model Definition](Models.md)
7 2. Custom Fields
8 3. [Orm](Orm.md)
9 4. [Object](Object.md)
10 5. [Query](Query.md)
11 6. Condition
12 7. Raw
13 8. Transaction
14 9. Faq
15
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!