orm: delete the old docs
Showing
11 changed files
with
0 additions
and
1445 deletions
orm/docs/zh/Cmd.md
deleted
100644 → 0
| 1 | ## 命令模式 | ||
| 2 | |||
| 3 | 注册模型与数据库以后,调用 RunCommand 执行 orm 命令 | ||
| 4 | |||
| 5 | ```go | ||
| 6 | func main() { | ||
| 7 | // orm.RegisterModel... | ||
| 8 | // orm.RegisterDataBase... | ||
| 9 | ... | ||
| 10 | orm.RunCommand() | ||
| 11 | } | ||
| 12 | ``` | ||
| 13 | |||
| 14 | ```bash | ||
| 15 | go build main.go | ||
| 16 | ./main orm | ||
| 17 | # 直接执行可以显示帮助 | ||
| 18 | # 如果你的程序可以支持的话,直接运行 go run main.go orm 也是一样的效果 | ||
| 19 | ``` | ||
| 20 | |||
| 21 | ## 自动建表 | ||
| 22 | |||
| 23 | ```bash | ||
| 24 | ./main orm syncdb -h | ||
| 25 | Usage of orm command: syncdb: | ||
| 26 | -db="default": DataBase alias name | ||
| 27 | -force=false: drop tables before create | ||
| 28 | -v=false: verbose info | ||
| 29 | ``` | ||
| 30 | |||
| 31 | 使用 `-force=1` 可以 drop table 后再建表 | ||
| 32 | |||
| 33 | 使用 `-v` 可以查看执行的 sql 语句 | ||
| 34 | |||
| 35 | ## 打印建表SQL | ||
| 36 | |||
| 37 | ```bash | ||
| 38 | ./main orm sqlall -h | ||
| 39 | Usage of orm command: syncdb: | ||
| 40 | -db="default": DataBase alias name | ||
| 41 | ``` | ||
| 42 | |||
| 43 | 默认使用别名为 default 的数据库 |
orm/docs/zh/CustomFields.md
deleted
100644 → 0
| 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 |
orm/docs/zh/Models.md
deleted
100644 → 0
| 1 | ## 模型定义 | ||
| 2 | |||
| 3 | 复杂的模型定义不是必须的,此功能用作数据库数据转换和[自动建表](Cmd.md#自动建表) | ||
| 4 | |||
| 5 | 默认的表名使用驼峰转蛇形,比如 AuthUser -> auth_user | ||
| 6 | |||
| 7 | **自定义表名** | ||
| 8 | |||
| 9 | ```go | ||
| 10 | type User struct { | ||
| 11 | Id int | ||
| 12 | Name string | ||
| 13 | } | ||
| 14 | |||
| 15 | func (u *User) TableName() string { | ||
| 16 | return "auth_user" | ||
| 17 | } | ||
| 18 | ``` | ||
| 19 | |||
| 20 | 如果[前缀设置](Orm.md#registermodelwithprefix)为`prefix_`那么表名为:prefix_auth_user | ||
| 21 | |||
| 22 | ## Struct Tag 设置参数 | ||
| 23 | ```go | ||
| 24 | orm:"null;rel(fk)" | ||
| 25 | ``` | ||
| 26 | |||
| 27 | 多个设置间使用 `;` 分隔,设置的值如果是多个,使用 `,` 分隔。 | ||
| 28 | |||
| 29 | #### 忽略字段 | ||
| 30 | |||
| 31 | 设置 `-` 即可忽略 struct 中的字段 | ||
| 32 | |||
| 33 | ```go | ||
| 34 | type User struct { | ||
| 35 | ... | ||
| 36 | AnyField string `orm:"-"` | ||
| 37 | ... | ||
| 38 | ``` | ||
| 39 | |||
| 40 | #### auto | ||
| 41 | |||
| 42 | 当 Field 类型为 int, int32, int64 时,可以设置字段为自增健 | ||
| 43 | |||
| 44 | 当模型定义里没有主键时,符合上述类型且名称为 `Id` 的 Field 将被视为自增健。 | ||
| 45 | |||
| 46 | #### pk | ||
| 47 | |||
| 48 | 设置为主键,适用于自定义其他类型为主键 | ||
| 49 | |||
| 50 | #### null | ||
| 51 | |||
| 52 | 数据库表默认为 `NOT NULL`,设置 null 代表 `ALLOW NULL` | ||
| 53 | |||
| 54 | #### blank | ||
| 55 | |||
| 56 | 设置 string 类型的字段允许为空,否则 clean 会返回错误 | ||
| 57 | |||
| 58 | #### index | ||
| 59 | |||
| 60 | 为字段增加索引 | ||
| 61 | |||
| 62 | #### unique | ||
| 63 | |||
| 64 | 为字段增加 unique 键 | ||
| 65 | |||
| 66 | #### column | ||
| 67 | |||
| 68 | 为字段设置 db 字段的名称 | ||
| 69 | ```go | ||
| 70 | Name `orm:"column(user_name)"` | ||
| 71 | ``` | ||
| 72 | #### default | ||
| 73 | |||
| 74 | 为字段设置默认值,类型必须符合 | ||
| 75 | ```go | ||
| 76 | type User struct { | ||
| 77 | ... | ||
| 78 | Status int `orm:"default(1)"` | ||
| 79 | ``` | ||
| 80 | #### size | ||
| 81 | |||
| 82 | string 类型字段默认为 varchar(255) | ||
| 83 | |||
| 84 | 设置 size 以后,db type 将使用 varchar(size) | ||
| 85 | |||
| 86 | ```go | ||
| 87 | Title string `orm:"size(60)"` | ||
| 88 | ``` | ||
| 89 | #### digits / decimals | ||
| 90 | |||
| 91 | 设置 float32, float64 类型的浮点精度 | ||
| 92 | ```go | ||
| 93 | Money float64 `orm:"digits(12);decimals(4)"` | ||
| 94 | ``` | ||
| 95 | 总长度 12 小数点后 4 位 eg: `99999999.9999` | ||
| 96 | |||
| 97 | #### auto_now / auto_now_add | ||
| 98 | ```go | ||
| 99 | Created time.Time `auto_now_add` | ||
| 100 | Updated time.Time `auto_now` | ||
| 101 | ``` | ||
| 102 | * auto_now 每次 model 保存时都会对时间自动更新 | ||
| 103 | * auto_now_add 第一次保存时才设置时间 | ||
| 104 | |||
| 105 | 对于批量的 update 此设置是不生效的 | ||
| 106 | |||
| 107 | #### type | ||
| 108 | |||
| 109 | 设置为 date 时,time.Time 字段的对应 db 类型使用 date | ||
| 110 | |||
| 111 | ```go | ||
| 112 | Created time.Time `orm:"auto_now_add;type(date)"` | ||
| 113 | ``` | ||
| 114 | |||
| 115 | 设置为 text 时,string 字段对应的 db 类型使用 text | ||
| 116 | |||
| 117 | ```go | ||
| 118 | Content string `orm:"type(text)"` | ||
| 119 | ``` | ||
| 120 | |||
| 121 | ## 表关系设置 | ||
| 122 | |||
| 123 | #### rel / reverse | ||
| 124 | |||
| 125 | **RelOneToOne**: | ||
| 126 | ```go | ||
| 127 | type User struct { | ||
| 128 | ... | ||
| 129 | Profile *Profile `orm:"null;rel(one);on_delete(set_null)"` | ||
| 130 | ``` | ||
| 131 | 对应的反向关系 **RelReverseOne**: | ||
| 132 | ```go | ||
| 133 | type Profile struct { | ||
| 134 | ... | ||
| 135 | User *User `orm:"reverse(one)" json:"-"` | ||
| 136 | ``` | ||
| 137 | **RelForeignKey**: | ||
| 138 | ```go | ||
| 139 | type Post struct { | ||
| 140 | ... | ||
| 141 | User*User `orm:"rel(fk)"` // RelForeignKey relation | ||
| 142 | ``` | ||
| 143 | 对应的反向关系 **RelReverseMany**: | ||
| 144 | ```go | ||
| 145 | type User struct { | ||
| 146 | ... | ||
| 147 | Posts []*Post `orm:"reverse(many)" json:"-"` // fk 的反向关系 | ||
| 148 | ``` | ||
| 149 | **RelManyToMany**: | ||
| 150 | ```go | ||
| 151 | type Post struct { | ||
| 152 | ... | ||
| 153 | Tags []*Tag `orm:"rel(m2m)"` // ManyToMany relation | ||
| 154 | ``` | ||
| 155 | 对应的反向关系 **RelReverseMany**: | ||
| 156 | ```go | ||
| 157 | type Tag struct { | ||
| 158 | ... | ||
| 159 | Posts []*Post `orm:"reverse(many)" json:"-"` | ||
| 160 | ``` | ||
| 161 | #### rel_table / rel_through | ||
| 162 | |||
| 163 | 此设置针对 `orm:"rel(m2m)"` 的关系字段 | ||
| 164 | |||
| 165 | rel_table 设置自动生成的 m2m 关系表的名称 | ||
| 166 | rel_through 如果要在 m2m 关系中使用自定义的 m2m 关系表 | ||
| 167 | 通过这个设置其名称,格式为 pkg.path.ModelName | ||
| 168 | eg: app.models.PostTagRel | ||
| 169 | PostTagRel 表需要有到 Post 和 Tag 的关系 | ||
| 170 | |||
| 171 | 当设置 rel_table 时会忽略 rel_through | ||
| 172 | |||
| 173 | #### on_delete | ||
| 174 | |||
| 175 | 设置对应的 rel 关系删除时,如何处理关系字段。 | ||
| 176 | |||
| 177 | cascade 级联删除(默认值) | ||
| 178 | set_null 设置为 NULL,需要设置 null = true | ||
| 179 | set_default 设置为默认值,需要设置 default 值 | ||
| 180 | do_nothing 什么也不做,忽略 | ||
| 181 | |||
| 182 | ```go | ||
| 183 | type User struct { | ||
| 184 | ... | ||
| 185 | Profile *Profile `orm:"null;rel(one);on_delete(set_null)"` | ||
| 186 | ... | ||
| 187 | type Profile struct { | ||
| 188 | ... | ||
| 189 | User *User `orm:"reverse(one)" json:"-"` | ||
| 190 | |||
| 191 | // 删除 Profile 时将设置 User.Profile 的数据库字段为 NULL | ||
| 192 | ``` | ||
| 193 | |||
| 194 | |||
| 195 | ## 模型字段与数据库类型的对应 | ||
| 196 | |||
| 197 | 在此列出 orm 推荐的对应数据库类型,自动建表功能也会以此为标准。 | ||
| 198 | |||
| 199 | 默认所有的字段都是 **NOT NULL** | ||
| 200 | |||
| 201 | #### MySQL | ||
| 202 | |||
| 203 | | go |mysql | ||
| 204 | | :--- | :--- | ||
| 205 | | int, int32, int64 - 设置 auto 或者名称为 `Id` 时 | integer AUTO_INCREMENT | ||
| 206 | | bool | bool | ||
| 207 | | string - 默认为 size 255 | varchar(size) | ||
| 208 | | string - 设置 type(text) 时 | longtext | ||
| 209 | | time.Time - 设置 type 为 date 时 | date | ||
| 210 | | time.TIme | datetime | ||
| 211 | | byte | tinyint unsigned | ||
| 212 | | rune | integer | ||
| 213 | | int | integer | ||
| 214 | | int8 | tinyint | ||
| 215 | | int16 | smallint | ||
| 216 | | int32 | integer | ||
| 217 | | int64 | bigint | ||
| 218 | | uint | integer unsigned | ||
| 219 | | uint8 | tinyint unsigned | ||
| 220 | | uint16 | smallint unsigned | ||
| 221 | | uint32 | integer unsigned | ||
| 222 | | uint64 | bigint unsigned | ||
| 223 | | float32 | double precision | ||
| 224 | | float64 | double precision | ||
| 225 | | float64 - 设置 digits, decimals 时 | numeric(digits, decimals) | ||
| 226 | |||
| 227 | #### Sqlite3 | ||
| 228 | |||
| 229 | | go | sqlite3 | ||
| 230 | | :--- | :--- | ||
| 231 | | int, int32, int64 - 设置 auto 或者名称为 `Id` 时 | integer AUTOINCREMENT | ||
| 232 | | bool | bool | ||
| 233 | | string - 默认为 size 255 | varchar(size) | ||
| 234 | | string - 设置 type(text) 时 | text | ||
| 235 | | time.Time - 设置 type 为 date 时 | date | ||
| 236 | | time.TIme | datetime | ||
| 237 | | byte | tinyint unsigned | ||
| 238 | | rune | integer | ||
| 239 | | int | integer | ||
| 240 | | int8 | tinyint | ||
| 241 | | int16 | smallint | ||
| 242 | | int32 | integer | ||
| 243 | | int64 | bigint | ||
| 244 | | uint | integer unsigned | ||
| 245 | | uint8 | tinyint unsigned | ||
| 246 | | uint16 | smallint unsigned | ||
| 247 | | uint32 | integer unsigned | ||
| 248 | | uint64 | bigint unsigned | ||
| 249 | | float32 | real | ||
| 250 | | float64 | real | ||
| 251 | | float64 - 设置 digits, decimals 时 | decimal | ||
| 252 | |||
| 253 | #### PostgreSQL | ||
| 254 | |||
| 255 | | go | postgres | ||
| 256 | | :--- | :--- | ||
| 257 | | int, int32, int64 - 设置 auto 或者名称为 `Id` 时 | serial | ||
| 258 | | bool | bool | ||
| 259 | | string - 默认为 size 255 | varchar(size) | ||
| 260 | | string - 设置 type(text) 时 | text | ||
| 261 | | time.Time - 设置 type 为 date 时 | date | ||
| 262 | | time.TIme | timestamp with time zone | ||
| 263 | | byte | smallint CHECK("column" >= 0 AND "column" <= 255) | ||
| 264 | | rune | integer | ||
| 265 | | int | integer | ||
| 266 | | int8 | smallint CHECK("column" >= -127 AND "column" <= 128) | ||
| 267 | | int16 | smallint | ||
| 268 | | int32 | integer | ||
| 269 | | int64 | bigint | ||
| 270 | | uint | bigint CHECK("column" >= 0) | ||
| 271 | | uint8 | smallint CHECK("column" >= 0 AND "column" <= 255) | ||
| 272 | | uint16 | integer CHECK("column" >= 0) | ||
| 273 | | uint32 | bigint CHECK("column" >= 0) | ||
| 274 | | uint64 | bigint CHECK("column" >= 0) | ||
| 275 | | float32 | double precision | ||
| 276 | | float64 | double precision | ||
| 277 | | float64 - 设置 digits, decimals 时 | numeric(digits, decimals) | ||
| 278 | |||
| 279 | |||
| 280 | ## 关系型字段 | ||
| 281 | |||
| 282 | 其字段类型取决于对应的主键。 | ||
| 283 | |||
| 284 | * RelForeignKey | ||
| 285 | * RelOneToOne | ||
| 286 | * RelManyToMany | ||
| 287 | * RelReverseOne | ||
| 288 | * RelReverseMany | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
orm/docs/zh/Models.sql
deleted
100644 → 0
| 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; |
orm/docs/zh/Object.md
deleted
100644 → 0
| 1 | ## 对象的CRUD操作 | ||
| 2 | |||
| 3 | 对 object 操作简单的三个方法 Read / Insert / Update / Delete | ||
| 4 | ```go | ||
| 5 | o := orm.NewOrm() | ||
| 6 | user := new(User) | ||
| 7 | user.Name = "slene" | ||
| 8 | |||
| 9 | fmt.Println(o.Insert(user)) | ||
| 10 | |||
| 11 | user.Name = "Your" | ||
| 12 | fmt.Println(o.Update(user)) | ||
| 13 | fmt.Println(o.Read(user)) | ||
| 14 | fmt.Println(o.Delete(user)) | ||
| 15 | ``` | ||
| 16 | ### Read | ||
| 17 | ```go | ||
| 18 | o := orm.NewOrm() | ||
| 19 | user := User{Id: 1} | ||
| 20 | |||
| 21 | err = o.Read(&user) | ||
| 22 | |||
| 23 | if err == sql.ErrNoRows { | ||
| 24 | fmt.Println("查询不到") | ||
| 25 | } else if err == orm.ErrMissPK { | ||
| 26 | fmt.Println("找不到主键") | ||
| 27 | } else { | ||
| 28 | fmt.Println(user.Id, user.Name) | ||
| 29 | } | ||
| 30 | ``` | ||
| 31 | ### Insert | ||
| 32 | ```go | ||
| 33 | o := orm.NewOrm() | ||
| 34 | var user User | ||
| 35 | user.Name = "slene" | ||
| 36 | user.IsActive = true | ||
| 37 | |||
| 38 | fmt.Println(o.Insert(&user)) | ||
| 39 | fmt.Println(user.Id) | ||
| 40 | ``` | ||
| 41 | 创建后会自动对 auto 的 field 赋值 | ||
| 42 | |||
| 43 | ### Update | ||
| 44 | ```go | ||
| 45 | o := orm.NewOrm() | ||
| 46 | user := User{Id: 1} | ||
| 47 | if o.Read(&user) == nil { | ||
| 48 | user.Name = "MyName" | ||
| 49 | o.Update(&user) | ||
| 50 | } | ||
| 51 | ``` | ||
| 52 | ### Delete | ||
| 53 | ```go | ||
| 54 | o := orm.NewOrm() | ||
| 55 | o.Delete(&User{Id: 1}) | ||
| 56 | ``` | ||
| 57 | Delete 操作会对反向关系进行操作,此例中 Post 拥有一个到 User 的外键。删除 User 的时候。如果 on_delete 设置为默认的级联操作,将删除对应的 Post | ||
| 58 | |||
| 59 | 删除以后会清除 auto field 的值 |
orm/docs/zh/Orm.md
deleted
100644 → 0
| 1 | ## Orm 使用方法 | ||
| 2 | |||
| 3 | beego/orm 的使用例子 | ||
| 4 | |||
| 5 | 后文例子如无特殊说明都以这个为基础。 | ||
| 6 | |||
| 7 | ##### models.go: | ||
| 8 | |||
| 9 | ```go | ||
| 10 | package main | ||
| 11 | |||
| 12 | import ( | ||
| 13 | "github.com/astaxie/beego/orm" | ||
| 14 | ) | ||
| 15 | |||
| 16 | type User struct { | ||
| 17 | Id int | ||
| 18 | Name string | ||
| 19 | Profile *Profile `orm:"rel(one)"` // OneToOne relation | ||
| 20 | } | ||
| 21 | |||
| 22 | type Profile struct { | ||
| 23 | Id int | ||
| 24 | Age int16 | ||
| 25 | User *User `orm:"reverse(one)"` // 设置反向关系(可选) | ||
| 26 | } | ||
| 27 | |||
| 28 | func init() { | ||
| 29 | // 需要在init中注册定义的model | ||
| 30 | orm.RegisterModel(new(User), new(Profile)) | ||
| 31 | } | ||
| 32 | ``` | ||
| 33 | |||
| 34 | ##### main.go | ||
| 35 | |||
| 36 | ```go | ||
| 37 | package main | ||
| 38 | |||
| 39 | import ( | ||
| 40 | "fmt" | ||
| 41 | "github.com/astaxie/beego/orm" | ||
| 42 | _ "github.com/go-sql-driver/mysql" | ||
| 43 | ) | ||
| 44 | |||
| 45 | func init() { | ||
| 46 | orm.RegisterDriver("mysql", orm.DR_MySQL) | ||
| 47 | |||
| 48 | orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8", 30) | ||
| 49 | } | ||
| 50 | |||
| 51 | func main() { | ||
| 52 | o := orm.NewOrm() | ||
| 53 | o.Using("default") // 默认使用 default,你可以指定为其他数据库 | ||
| 54 | |||
| 55 | profile := new(Profile) | ||
| 56 | profile.Age = 30 | ||
| 57 | |||
| 58 | user := new(User) | ||
| 59 | user.Profile = profile | ||
| 60 | user.Name = "slene" | ||
| 61 | |||
| 62 | fmt.Println(o.Insert(profile)) | ||
| 63 | fmt.Println(o.Insert(user)) | ||
| 64 | } | ||
| 65 | ``` | ||
| 66 | |||
| 67 | ## 数据库的设置 | ||
| 68 | |||
| 69 | 目前 orm 支持三种数据库,以下为测试过的 driver | ||
| 70 | |||
| 71 | 将你需要使用的 driver 加入 import 中 | ||
| 72 | |||
| 73 | ```go | ||
| 74 | import ( | ||
| 75 | _ "github.com/go-sql-driver/mysql" | ||
| 76 | _ "github.com/lib/pq" | ||
| 77 | _ "github.com/mattn/go-sqlite3" | ||
| 78 | ) | ||
| 79 | ``` | ||
| 80 | |||
| 81 | #### RegisterDriver | ||
| 82 | |||
| 83 | 三种默认数据库类型 | ||
| 84 | |||
| 85 | ```go | ||
| 86 | orm.DR_MySQL | ||
| 87 | orm.DR_Sqlite | ||
| 88 | orm.DR_Postgres | ||
| 89 | ``` | ||
| 90 | |||
| 91 | ```go | ||
| 92 | // 参数1 driverName | ||
| 93 | // 参数2 数据库类型 | ||
| 94 | // 这个用来设置 driverName 对应的数据库类型 | ||
| 95 | // mysql / sqlite3 / postgres 这三种是默认已经注册过的,所以可以无需设置 | ||
| 96 | orm.RegisterDriver("mymysql", orm.DR_MySQL) | ||
| 97 | ``` | ||
| 98 | |||
| 99 | #### RegisterDataBase | ||
| 100 | |||
| 101 | orm 必须注册一个别名为 `default` 的数据库,作为默认使用。 | ||
| 102 | |||
| 103 | ```go | ||
| 104 | // 参数1 数据库的别名,用来在orm中切换数据库使用 | ||
| 105 | // 参数2 driverName | ||
| 106 | // 参数3 对应的链接字符串 | ||
| 107 | // 参数4 设置最大的空闲连接数,使用 golang 自己的连接池 | ||
| 108 | orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8", 30) | ||
| 109 | ``` | ||
| 110 | |||
| 111 | #### 时区设置 | ||
| 112 | |||
| 113 | orm 默认使用 time.Local 本地时区 | ||
| 114 | |||
| 115 | * 作用于 orm 自动创建的时间 | ||
| 116 | * 从数据库中取回的时间转换成 orm 本地时间 | ||
| 117 | |||
| 118 | 如果需要的话,你也可以进行更改 | ||
| 119 | |||
| 120 | ```go | ||
| 121 | // 设置为 UTC 时间 | ||
| 122 | orm.DefaultTimeLoc = time.UTC | ||
| 123 | ``` | ||
| 124 | |||
| 125 | orm 在进行 RegisterDataBase 的同时,会获取数据库使用的时区,然后在 time.Time 类型存取的时做相应转换,以匹配时间系统,从而保证时间不会出错。 | ||
| 126 | |||
| 127 | **注意:** 鉴于 Sqlite3 的设计,存取默认都为 UTC 时间 | ||
| 128 | |||
| 129 | ## 注册模型 | ||
| 130 | |||
| 131 | 如果使用 orm.QuerySeter 进行高级查询的话,这个是必须的。 | ||
| 132 | |||
| 133 | 反之,如果只使用 Raw 查询和 map struct,是无需这一步的。您可以去查看 [Raw SQL 查询](Raw.md) | ||
| 134 | |||
| 135 | #### RegisterModel | ||
| 136 | |||
| 137 | 将你定义的 Model 进行注册,最佳设计是有单独的 models.go 文件,在他的 init 函数中进行注册。 | ||
| 138 | |||
| 139 | |||
| 140 | 迷你版 models.go | ||
| 141 | ```go | ||
| 142 | package main | ||
| 143 | |||
| 144 | import "github.com/astaxie/beego/orm" | ||
| 145 | |||
| 146 | type User struct { | ||
| 147 | Id int | ||
| 148 | Name string | ||
| 149 | } | ||
| 150 | |||
| 151 | func init(){ | ||
| 152 | orm.RegisterModel(new(User)) | ||
| 153 | } | ||
| 154 | ``` | ||
| 155 | |||
| 156 | RegisterModel 也可以同时注册多个 model | ||
| 157 | |||
| 158 | ```go | ||
| 159 | orm.RegisterModel(new(User), new(Profile), new(Post)) | ||
| 160 | ``` | ||
| 161 | |||
| 162 | 详细的 struct 定义请查看文档 [模型定义](Models.md) | ||
| 163 | |||
| 164 | #### RegisterModelWithPrefix | ||
| 165 | |||
| 166 | 使用表名前缀 | ||
| 167 | |||
| 168 | ```go | ||
| 169 | orm.RegisterModelWithPrefix("prefix_", new(User)) | ||
| 170 | ``` | ||
| 171 | |||
| 172 | 创建后的表名为 prefix_user | ||
| 173 | |||
| 174 | ## ORM 接口使用 | ||
| 175 | |||
| 176 | 使用 orm 必然接触的 Ormer 接口,我们来熟悉一下 | ||
| 177 | |||
| 178 | ```go | ||
| 179 | var o Ormer | ||
| 180 | o = orm.NewOrm() // 创建一个 Ormer | ||
| 181 | // NewOrm 的同时会执行 orm.BootStrap (整个 app 只执行一次),用以验证模型之间的定义并缓存。 | ||
| 182 | ``` | ||
| 183 | |||
| 184 | * type Ormer interface { | ||
| 185 | * [Read(Modeler) error](Object.md#read) | ||
| 186 | * [Insert(Modeler) (int64, error)](Object.md#insert) | ||
| 187 | * [Update(Modeler) (int64, error)](Object.md#update) | ||
| 188 | * [Delete(Modeler) (int64, error)](Object.md#delete) | ||
| 189 | * [M2mAdd(Modeler, string, ...interface{}) (int64, error)](Object.md#m2madd) | ||
| 190 | * [M2mDel(Modeler, string, ...interface{}) (int64, error)](Object.md#m2mdel) | ||
| 191 | * [LoadRel(Modeler, string) (int64, error)](Object.md#loadRel) | ||
| 192 | * [QueryTable(interface{}) QuerySeter](#querytable) | ||
| 193 | * [Using(string) error](#using) | ||
| 194 | * [Begin() error](Transaction.md) | ||
| 195 | * [Commit() error](Transaction.md) | ||
| 196 | * [Rollback() error](Transaction.md) | ||
| 197 | * [Raw(string, ...interface{}) RawSeter](#raw) | ||
| 198 | * [Driver() Driver](#driver) | ||
| 199 | * } | ||
| 200 | |||
| 201 | |||
| 202 | #### QueryTable | ||
| 203 | |||
| 204 | 传入表名,或者 Modeler 对象,返回一个 [QuerySeter](Query.md#queryseter) | ||
| 205 | |||
| 206 | ```go | ||
| 207 | o := orm.NewOrm() | ||
| 208 | var qs QuerySeter | ||
| 209 | qs = o.QueryTable("user") | ||
| 210 | // 如果表没有定义过,会立刻 panic | ||
| 211 | ``` | ||
| 212 | |||
| 213 | #### Using | ||
| 214 | |||
| 215 | 切换为其他数据库 | ||
| 216 | |||
| 217 | ```go | ||
| 218 | orm.RegisterDataBase("db1", "mysql", "root:root@/orm_db2?charset=utf8", 30) | ||
| 219 | orm.RegisterDataBase("db2", "sqlite3", "data.db", 30) | ||
| 220 | |||
| 221 | o1 := orm.NewOrm() | ||
| 222 | o1.Using("db1") | ||
| 223 | |||
| 224 | o2 := orm.NewOrm() | ||
| 225 | o2.Using("db2") | ||
| 226 | |||
| 227 | // 切换为其他数据库以后 | ||
| 228 | // 这个 Ormer 对象的其下的 api 调用都将使用这个数据库 | ||
| 229 | |||
| 230 | ``` | ||
| 231 | |||
| 232 | 默认使用 `default` 数据库,无需调用 Using | ||
| 233 | |||
| 234 | #### Raw | ||
| 235 | |||
| 236 | 使用 sql 语句直接进行操作 | ||
| 237 | |||
| 238 | Raw 函数,返回一个 [RawSeter](Raw.md) 用以对设置的 sql 语句和参数进行操作 | ||
| 239 | |||
| 240 | ```go | ||
| 241 | o := NewOrm() | ||
| 242 | var r RawSeter | ||
| 243 | r = o.Raw("UPDATE user SET name = ? WHERE name = ?", "testing", "slene") | ||
| 244 | ``` | ||
| 245 | |||
| 246 | #### Driver | ||
| 247 | |||
| 248 | 返回当前 orm 使用的 db 信息 | ||
| 249 | |||
| 250 | ```go | ||
| 251 | type Driver interface { | ||
| 252 | Name() string | ||
| 253 | Type() DriverType | ||
| 254 | } | ||
| 255 | ``` | ||
| 256 | |||
| 257 | ```go | ||
| 258 | orm.RegisterDataBase("db1", "mysql", "root:root@/orm_db2?charset=utf8", 30) | ||
| 259 | orm.RegisterDataBase("db2", "sqlite3", "data.db", 30) | ||
| 260 | |||
| 261 | o1 := orm.NewOrm() | ||
| 262 | o1.Using("db1") | ||
| 263 | dr := o1.Driver() | ||
| 264 | fmt.Println(dr.Name() == "db1") // true | ||
| 265 | fmt.Println(dr.Type() == orm.DR_MySQL) // true | ||
| 266 | |||
| 267 | o2 := orm.NewOrm() | ||
| 268 | o2.Using("db2") | ||
| 269 | dr = o2.Driver() | ||
| 270 | fmt.Println(dr.Name() == "db2") // true | ||
| 271 | fmt.Println(dr.Type() == orm.DR_Sqlite) // true | ||
| 272 | |||
| 273 | ``` | ||
| 274 | |||
| 275 | ## 调试模式打印查询语句 | ||
| 276 | |||
| 277 | 简单的设置 Debug 为 true 打印查询的语句 | ||
| 278 | |||
| 279 | 可能存在性能问题,不建议使用在产品模式 | ||
| 280 | |||
| 281 | ```go | ||
| 282 | func main() { | ||
| 283 | orm.Debug = true | ||
| 284 | ... | ||
| 285 | ``` | ||
| 286 | |||
| 287 | 默认使用 os.Stderr 输出日志信息 | ||
| 288 | |||
| 289 | 改变输出到你自己的 io.Writer | ||
| 290 | |||
| 291 | ```go | ||
| 292 | var w io.Writer | ||
| 293 | ... | ||
| 294 | // 设置为你的 io.Writer | ||
| 295 | ... | ||
| 296 | orm.DebugLog = orm.NewLog(w) | ||
| 297 | ``` | ||
| 298 | |||
| 299 | 日志格式 | ||
| 300 | |||
| 301 | ```go | ||
| 302 | [ORM] - 时间 - [Queries/数据库名] - [执行操作/执行时间] - [SQL语句] - 使用标点 `,` 分隔的参数列表 - 打印遇到的错误 | ||
| 303 | ``` | ||
| 304 | |||
| 305 | ```go | ||
| 306 | [ORM] - 2013-08-09 13:18:16 - [Queries/default] - [ db.Exec / 0.4ms] - [INSERT INTO `user` (`name`) VALUES (?)] - `slene` | ||
| 307 | [ORM] - 2013-08-09 13:18:16 - [Queries/default] - [ db.Exec / 0.5ms] - [UPDATE `user` SET `name` = ? WHERE `id` = ?] - `astaxie`, `14` | ||
| 308 | [ORM] - 2013-08-09 13:18:16 - [Queries/default] - [db.QueryRow / 0.4ms] - [SELECT `id`, `name` FROM `user` WHERE `id` = ?] - `14` | ||
| 309 | [ORM] - 2013-08-09 13:18:16 - [Queries/default] - [ db.Exec / 0.4ms] - [INSERT INTO `post` (`user_id`,`title`,`content`) VALUES (?, ?, ?)] - `14`, `beego orm`, `powerful amazing` | ||
| 310 | [ORM] - 2013-08-09 13:18:16 - [Queries/default] - [ db.Query / 0.4ms] - [SELECT T1.`name` `User__Name`, T0.`user_id` `User`, T1.`id` `User__Id` FROM `post` T0 INNER JOIN `user` T1 ON T1.`id` = T0.`user_id` WHERE T0.`id` = ? LIMIT 1000] - `68` | ||
| 311 | [ORM] - 2013-08-09 13:18:16 - [Queries/default] - [ db.Exec / 0.4ms] - [DELETE FROM `user` WHERE `id` = ?] - `14` | ||
| 312 | [ORM] - 2013-08-09 13:18:16 - [Queries/default] - [ db.Query / 0.3ms] - [SELECT T0.`id` FROM `post` T0 WHERE T0.`user_id` IN (?) ] - `14` | ||
| 313 | [ORM] - 2013-08-09 13:18:16 - [Queries/default] - [ db.Exec / 0.4ms] - [DELETE FROM `post` WHERE `id` IN (?)] - `68` | ||
| 314 | ``` | ||
| 315 | |||
| 316 | 日志内容包括 **所有的数据库操作**,事务,Prepare,等 |
orm/docs/zh/Query.md
deleted
100644 → 0
| 1 | ## 高级查询 | ||
| 2 | |||
| 3 | orm 以 **QuerySeter** 来组织查询,每个返回 **QuerySeter** 的方法都会获得一个新的 **QuerySeter** 对象。 | ||
| 4 | |||
| 5 | 基本使用方法: | ||
| 6 | ```go | ||
| 7 | o := orm.NewOrm() | ||
| 8 | |||
| 9 | // 获取 QuerySeter 对象,user 为表名 | ||
| 10 | qs := o.QueryTable("user") | ||
| 11 | |||
| 12 | // 也可以直接使用对象作为表名 | ||
| 13 | user := new(User) | ||
| 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 | ```go | ||
| 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__lt", 1000) | ||
| 33 | // WHERE profile.age IN (18, 20) AND NOT profile_id < 1000 | ||
| 34 | ``` | ||
| 35 | ## Operators | ||
| 36 | |||
| 37 | 当前支持的操作符号: | ||
| 38 | |||
| 39 | * [exact](#exact) / [iexact](#iexact) 等于 | ||
| 40 | * [contains](#contains) / [icontains](#icontains) 包含 | ||
| 41 | * [gt / gte](#gt / gte) 大于 / 大于等于 | ||
| 42 | * [lt / lte](#lt / lte) 小于 / 小于等于 | ||
| 43 | * [startswith](#startswith) / [istartswith](#istartswith) 以...起始 | ||
| 44 | * [endswith](#endswith) / [iendswith](#iendswith) 以...结束 | ||
| 45 | * [in](#in) | ||
| 46 | * [isnull](#isnull) | ||
| 47 | |||
| 48 | 后面以 `i` 开头的表示:大小写不敏感 | ||
| 49 | |||
| 50 | #### exact | ||
| 51 | |||
| 52 | Filter / Exclude / Condition expr 的默认值 | ||
| 53 | ```go | ||
| 54 | qs.Filter("name", "slene") // WHERE name = 'slene' | ||
| 55 | qs.Filter("name__exact", "slene") // WHERE name = 'slene' | ||
| 56 | // 使用 = 匹配,大小写是否敏感取决于数据表使用的 collation | ||
| 57 | qs.Filter("profile", nil) // WHERE profile_id IS NULL | ||
| 58 | ``` | ||
| 59 | #### iexact | ||
| 60 | ```go | ||
| 61 | qs.Filter("name__iexact", "slene") | ||
| 62 | // WHERE name LIKE 'slene' | ||
| 63 | // 大小写不敏感,匹配任意 'Slene' 'sLENE' | ||
| 64 | ``` | ||
| 65 | #### contains | ||
| 66 | ```go | ||
| 67 | qs.Filter("name__contains", "slene") | ||
| 68 | // WHERE name LIKE BINARY '%slene%' | ||
| 69 | // 大小写敏感, 匹配包含 slene 的字符 | ||
| 70 | ``` | ||
| 71 | #### icontains | ||
| 72 | ```go | ||
| 73 | qs.Filter("name__icontains", "slene") | ||
| 74 | // WHERE name LIKE '%slene%' | ||
| 75 | // 大小写不敏感, 匹配任意 'im Slene', 'im sLENE' | ||
| 76 | ``` | ||
| 77 | #### in | ||
| 78 | ```go | ||
| 79 | qs.Filter("profile__age__in", 17, 18, 19, 20) | ||
| 80 | // WHERE profile.age IN (17, 18, 19, 20) | ||
| 81 | ``` | ||
| 82 | #### gt / gte | ||
| 83 | ```go | ||
| 84 | qs.Filter("profile__age__gt", 17) | ||
| 85 | // WHERE profile.age > 17 | ||
| 86 | |||
| 87 | qs.Filter("profile__age__gte", 18) | ||
| 88 | // WHERE profile.age >= 18 | ||
| 89 | ``` | ||
| 90 | #### lt / lte | ||
| 91 | ```go | ||
| 92 | qs.Filter("profile__age__lt", 17) | ||
| 93 | // WHERE profile.age < 17 | ||
| 94 | |||
| 95 | qs.Filter("profile__age__lte", 18) | ||
| 96 | // WHERE profile.age <= 18 | ||
| 97 | ``` | ||
| 98 | #### startswith | ||
| 99 | ```go | ||
| 100 | qs.Filter("name__startswith", "slene") | ||
| 101 | // WHERE name LIKE BINARY 'slene%' | ||
| 102 | // 大小写敏感, 匹配以 'slene' 起始的字符串 | ||
| 103 | ``` | ||
| 104 | #### istartswith | ||
| 105 | ```go | ||
| 106 | qs.Filter("name__istartswith", "slene") | ||
| 107 | // WHERE name LIKE 'slene%' | ||
| 108 | // 大小写不敏感, 匹配任意以 'slene', 'Slene' 起始的字符串 | ||
| 109 | ``` | ||
| 110 | #### endswith | ||
| 111 | ```go | ||
| 112 | qs.Filter("name__endswith", "slene") | ||
| 113 | // WHERE name LIKE BINARY '%slene' | ||
| 114 | // 大小写敏感, 匹配以 'slene' 结束的字符串 | ||
| 115 | ``` | ||
| 116 | #### iendswith | ||
| 117 | ```go | ||
| 118 | qs.Filter("name__startswith", "slene") | ||
| 119 | // WHERE name LIKE '%slene' | ||
| 120 | // 大小写不敏感, 匹配任意以 'slene', 'Slene' 结束的字符串 | ||
| 121 | ``` | ||
| 122 | #### isnull | ||
| 123 | ```go | ||
| 124 | qs.Filter("profile__isnull", true) | ||
| 125 | qs.Filter("profile_id__isnull", true) | ||
| 126 | // WHERE profile_id IS NULL | ||
| 127 | |||
| 128 | qs.Filter("profile__isnull", false) | ||
| 129 | // WHERE profile_id IS NOT NULL | ||
| 130 | ``` | ||
| 131 | ## 高级查询接口使用 | ||
| 132 | |||
| 133 | QuerySeter 是高级查询使用的接口,我们来熟悉下他的接口方法 | ||
| 134 | |||
| 135 | * type QuerySeter interface { | ||
| 136 | * [Filter(string, ...interface{}) QuerySeter](#filter) | ||
| 137 | * [Exclude(string, ...interface{}) QuerySeter](#exclude) | ||
| 138 | * [SetCond(*Condition) QuerySeter](#setcond) | ||
| 139 | * [Limit(int, ...int64) QuerySeter](#limit) | ||
| 140 | * [Offset(int64) QuerySeter](#offset) | ||
| 141 | * [OrderBy(...string) QuerySeter](#orderby) | ||
| 142 | * [RelatedSel(...interface{}) QuerySeter](#relatedsel) | ||
| 143 | * [Count() (int64, error)](#count) | ||
| 144 | * [Update(Params) (int64, error)](#update) | ||
| 145 | * [Delete() (int64, error)](#delete) | ||
| 146 | * [PrepareInsert() (Inserter, error)](#prepareinsert) | ||
| 147 | * [All(interface{}) (int64, error)](#all) | ||
| 148 | * [One(Modeler) error](#one) | ||
| 149 | * [Values(*[]Params, ...string) (int64, error)](#values) | ||
| 150 | * [ValuesList(*[]ParamsList, ...string) (int64, error)](#valueslist) | ||
| 151 | * [ValuesFlat(*ParamsList, string) (int64, error)](#valuesflat) | ||
| 152 | * } | ||
| 153 | |||
| 154 | * 每个返回 QuerySeter 的 api 调用时都会新建一个 QuerySeter,不影响之前创建的。 | ||
| 155 | |||
| 156 | * 高级查询使用 Filter 和 Exclude 来做常用的条件查询。囊括两种清晰的过滤规则:包含, 排除 | ||
| 157 | |||
| 158 | #### Filter | ||
| 159 | |||
| 160 | 用来过滤查询结果,起到 **包含条件** 的作用 | ||
| 161 | |||
| 162 | 多个 Filter 之间使用 `AND` 连接 | ||
| 163 | ```go | ||
| 164 | qs.Filter("profile__isnull", true).Filter("name", "slene") | ||
| 165 | // WHERE profile_id IS NULL AND name = 'slene' | ||
| 166 | ``` | ||
| 167 | |||
| 168 | #### Exclude | ||
| 169 | |||
| 170 | 用来过滤查询结果,起到 **排除条件** 的作用 | ||
| 171 | |||
| 172 | 使用 `NOT` 排除条件 | ||
| 173 | |||
| 174 | 多个 Exclude 之间使用 `AND` 连接 | ||
| 175 | ```go | ||
| 176 | qs.Exclude("profile__isnull", true).Filter("name", "slene") | ||
| 177 | // WHERE NOT profile_id IS NULL AND name = 'slene' | ||
| 178 | ``` | ||
| 179 | |||
| 180 | #### SetCond | ||
| 181 | |||
| 182 | 自定义条件表达式 | ||
| 183 | |||
| 184 | ```go | ||
| 185 | cond := NewCondition() | ||
| 186 | cond1 := cond.And("profile__isnull", false).AndNot("status__in", 1).Or("profile__age__gt", 2000) | ||
| 187 | |||
| 188 | qs := orm.QueryTable("user") | ||
| 189 | qs = qs.SetCond(cond1) | ||
| 190 | // WHERE ... AND ... AND NOT ... OR ... | ||
| 191 | |||
| 192 | cond2 := cond.AndCond(cond1).OrCond(cond.And("name", "slene")) | ||
| 193 | qs = qs.SetCond(cond2).Count() | ||
| 194 | // WHERE (... AND ... AND NOT ... OR ...) OR ( ... ) | ||
| 195 | ``` | ||
| 196 | |||
| 197 | #### Limit | ||
| 198 | |||
| 199 | 限制最大返回数据行数,第二个参数可以设置 `Offset` | ||
| 200 | ```go | ||
| 201 | var DefaultRowsLimit = 1000 // orm 默认的 limit 值为 1000 | ||
| 202 | |||
| 203 | // 默认情况下 select 查询的最大行数为 1000 | ||
| 204 | // LIMIT 1000 | ||
| 205 | |||
| 206 | qs.Limit(10) | ||
| 207 | // LIMIT 10 | ||
| 208 | |||
| 209 | qs.Limit(10, 20) | ||
| 210 | // LIMIT 10 OFFSET 20 | ||
| 211 | |||
| 212 | qs.Limit(-1) | ||
| 213 | // no limit | ||
| 214 | |||
| 215 | qs.Limit(-1, 100) | ||
| 216 | // LIMIT 18446744073709551615 OFFSET 100 | ||
| 217 | // 18446744073709551615 是 1<<64 - 1 用来指定无 limit 限制 但有 offset 偏移的情况 | ||
| 218 | ``` | ||
| 219 | |||
| 220 | #### Offset | ||
| 221 | |||
| 222 | 设置 偏移行数 | ||
| 223 | ```go | ||
| 224 | qs.Offset(20) | ||
| 225 | // LIMIT 1000 OFFSET 20 | ||
| 226 | ``` | ||
| 227 | |||
| 228 | #### OrderBy | ||
| 229 | |||
| 230 | 参数使用 **expr** | ||
| 231 | |||
| 232 | 在 expr 前使用减号 `-` 表示 `DESC` 的排列 | ||
| 233 | ```go | ||
| 234 | qs.OrderBy("id", "-profile__age") | ||
| 235 | // ORDER BY id ASC, profile.age DESC | ||
| 236 | |||
| 237 | qs.OrderBy("-profile__age", "profile") | ||
| 238 | // ORDER BY profile.age DESC, profile_id ASC | ||
| 239 | ``` | ||
| 240 | |||
| 241 | #### RelatedSel | ||
| 242 | |||
| 243 | 关系查询,参数使用 **expr** | ||
| 244 | ```go | ||
| 245 | var DefaultRelsDepth = 5 // 默认情况下直接调用 RelatedSel 将进行最大 5 层的关系查询 | ||
| 246 | |||
| 247 | qs := o.QueryTable("post") | ||
| 248 | |||
| 249 | qs.RelateSel() | ||
| 250 | // INNER JOIN user ... LEFT OUTER JOIN profile ... | ||
| 251 | |||
| 252 | qs.RelateSel("user") | ||
| 253 | // INNER JOIN user ... | ||
| 254 | // 设置 expr 只对设置的字段进行关系查询 | ||
| 255 | |||
| 256 | // 对设置 null 属性的 Field 将使用 LEFT OUTER JOIN | ||
| 257 | ``` | ||
| 258 | |||
| 259 | #### Count | ||
| 260 | 依据当前的查询条件,返回结果行数 | ||
| 261 | ```go | ||
| 262 | cnt, err := o.QueryTable("user").Count() // SELECT COUNT(*) FROM USER | ||
| 263 | fmt.Printf("Count Num: %s, %s", cnt, err) | ||
| 264 | ``` | ||
| 265 | |||
| 266 | #### Update | ||
| 267 | 依据当前查询条件,进行批量更新操作 | ||
| 268 | ```go | ||
| 269 | num, err := o.QueryTable("user").Filter("name", "slene").Update(orm.Params{ | ||
| 270 | "name": "astaxie", | ||
| 271 | }) | ||
| 272 | fmt.Printf("Affected Num: %s, %s", num, err) | ||
| 273 | // SET name = "astaixe" WHERE name = "slene" | ||
| 274 | ``` | ||
| 275 | |||
| 276 | #### Delete | ||
| 277 | 依据当前查询条件,进行批量删除操作 | ||
| 278 | ```go | ||
| 279 | num, err := o.QueryTable("user").Filter("name", "slene").Delete() | ||
| 280 | fmt.Printf("Affected Num: %s, %s", num, err) | ||
| 281 | // DELETE FROM user WHERE name = "slene" | ||
| 282 | ``` | ||
| 283 | |||
| 284 | #### PrepareInsert | ||
| 285 | |||
| 286 | 用于一次 prepare 多次 insert 插入,以提高批量插入的速度。 | ||
| 287 | |||
| 288 | ```go | ||
| 289 | var users []*User | ||
| 290 | ... | ||
| 291 | qs := o.QueryTable("user") | ||
| 292 | i, _ := qs.PrepareInsert() | ||
| 293 | for _, user := range users { | ||
| 294 | id, err := i.Insert(user) | ||
| 295 | if err != nil { | ||
| 296 | ... | ||
| 297 | } | ||
| 298 | } | ||
| 299 | // PREPARE INSERT INTO user (`name`, ...) VALUES (?, ...) | ||
| 300 | // EXECUTE INSERT INTO user (`name`, ...) VALUES ("slene", ...) | ||
| 301 | // EXECUTE ... | ||
| 302 | // ... | ||
| 303 | i.Close() // 别忘记关闭 statement | ||
| 304 | ``` | ||
| 305 | |||
| 306 | #### All | ||
| 307 | 返回对应的结果集对象 | ||
| 308 | ```go | ||
| 309 | var users []*User | ||
| 310 | num, err := o.QueryTable("user").Filter("name", "slene").All(&users) | ||
| 311 | fmt.Printf("Returned Rows Num: %s, %s", num, err) | ||
| 312 | ``` | ||
| 313 | |||
| 314 | #### One | ||
| 315 | |||
| 316 | 尝试返回单条记录 | ||
| 317 | |||
| 318 | ```go | ||
| 319 | var user *User | ||
| 320 | err := o.QueryTable("user").Filter("name", "slene").One(&user) | ||
| 321 | if err == orm.ErrMultiRows { | ||
| 322 | // 多条的时候报错 | ||
| 323 | fmt.Printf("Returned Multi Rows Not One") | ||
| 324 | } | ||
| 325 | if err == orm.ErrNoRows { | ||
| 326 | // 没有找到记录 | ||
| 327 | fmt.Printf("Not row found") | ||
| 328 | } | ||
| 329 | ``` | ||
| 330 | |||
| 331 | #### Values | ||
| 332 | 返回结果集的 key => value 值 | ||
| 333 | |||
| 334 | key 为 Model 里的 Field name,value 的值 以 string 保存 | ||
| 335 | |||
| 336 | ```go | ||
| 337 | var maps []orm.Params | ||
| 338 | num, err := o.QueryTable("user").Values(&maps) | ||
| 339 | if err != nil { | ||
| 340 | fmt.Printf("Result Nums: %d\n", num) | ||
| 341 | for _, m := range maps { | ||
| 342 | fmt.Println(m["Id"], m["Name"]) | ||
| 343 | } | ||
| 344 | } | ||
| 345 | ``` | ||
| 346 | |||
| 347 | 返回指定的 Field 数据 | ||
| 348 | |||
| 349 | **TODO**: 暂不支持级联查询 **RelatedSel** 直接返回 Values | ||
| 350 | |||
| 351 | 但可以直接指定 expr 级联返回需要的数据 | ||
| 352 | |||
| 353 | ```go | ||
| 354 | var maps []orm.Params | ||
| 355 | num, err := o.QueryTable("user").Values(&maps, "id", "name", "profile", "profile__age") | ||
| 356 | if err != nil { | ||
| 357 | fmt.Printf("Result Nums: %d\n", num) | ||
| 358 | for _, m := range maps { | ||
| 359 | fmt.Println(m["Id"], m["Name"], m["Profile"], m["Profile__Age"]) | ||
| 360 | // map 中的数据都是展开的,没有复杂的嵌套 | ||
| 361 | } | ||
| 362 | } | ||
| 363 | ``` | ||
| 364 | |||
| 365 | #### ValuesList | ||
| 366 | |||
| 367 | 顾名思义,返回的结果集以slice存储 | ||
| 368 | |||
| 369 | 结果的排列与 Model 中定义的 Field 顺序一致 | ||
| 370 | |||
| 371 | 返回的每个元素值以 string 保存 | ||
| 372 | |||
| 373 | ```go | ||
| 374 | var lists []orm.ParamsList | ||
| 375 | num, err := o.QueryTable("user").ValuesList(&lists) | ||
| 376 | if err != nil { | ||
| 377 | fmt.Printf("Result Nums: %d\n", num) | ||
| 378 | for _, row := range lists { | ||
| 379 | fmt.Println(row) | ||
| 380 | } | ||
| 381 | } | ||
| 382 | ``` | ||
| 383 | |||
| 384 | 当然也可以指定 expr 返回指定的 Field | ||
| 385 | |||
| 386 | ```go | ||
| 387 | var lists []orm.ParamsList | ||
| 388 | num, err := o.QueryTable("user").ValuesList(&lists, "name", "profile__age") | ||
| 389 | if err != nil { | ||
| 390 | fmt.Printf("Result Nums: %d\n", num) | ||
| 391 | for _, row := range lists { | ||
| 392 | fmt.Printf("Name: %s, Age: %s\m", row[0], row[1]) | ||
| 393 | } | ||
| 394 | } | ||
| 395 | ``` | ||
| 396 | |||
| 397 | #### ValuesFlat | ||
| 398 | |||
| 399 | 只返回特定的 Field 值,讲结果集展开到单个 slice 里 | ||
| 400 | |||
| 401 | ```go | ||
| 402 | var list orm.ParamsList | ||
| 403 | num, err := o.QueryTable("user").ValuesFlat(&list, "name") | ||
| 404 | if err != nil { | ||
| 405 | fmt.Printf("Result Nums: %d\n", num) | ||
| 406 | fmt.Printf("All User Names: %s", strings.Join(list, ", ") | ||
| 407 | } | ||
| 408 | ``` | ||
| 409 | |||
| 410 | |||
| 411 |
orm/docs/zh/README.md
deleted
100644 → 0
| 1 | 最新文档请查看 beedoc | ||
| 2 | |||
| 3 | * [中文](http://beego.me/docs/Models_Overview?lang=zh) | ||
| 4 | * [English](http://beego.me/docs/Models_Overview?lang=en) | ||
| 5 | |||
| 6 | ## 文档目录 | ||
| 7 | |||
| 8 | 1. [Orm 使用方法](Orm.md) | ||
| 9 | - [数据库的设置](Orm.md#数据库的设置) | ||
| 10 | * [驱动类型设置](Orm.md#registerdriver) | ||
| 11 | * [参数设置](Orm.md#registerdatabase) | ||
| 12 | * [时区设置](Orm.md#时区设置) | ||
| 13 | - [注册模型](Orm.md#注册模型) | ||
| 14 | - [ORM 接口使用](Orm.md#orm-接口使用) | ||
| 15 | - [调试模式打印查询语句](Orm.md#调试模式打印查询语句) | ||
| 16 | 2. [对象的CRUD操作](Object.md) | ||
| 17 | 3. [高级查询](Query.md) | ||
| 18 | - [使用的表达式语法](Query.md#expr) | ||
| 19 | - [支持的操作符号](Query.md#operators) | ||
| 20 | - [高级查询接口使用](Query.md#高级查询接口使用) | ||
| 21 | 4. [使用SQL语句进行查询](Raw.md) | ||
| 22 | 5. [事务处理](Transaction.md) | ||
| 23 | 6. [模型定义](Models.md) | ||
| 24 | - [Struct Tag 设置参数](Models.md#struct-tag-设置参数) | ||
| 25 | - [表关系设置](Models.md#表关系设置) | ||
| 26 | - [模型字段与数据库类型的对应](Models.md#模型字段与数据库类型的对应) | ||
| 27 | 7. [命令模式](Cmd.md) | ||
| 28 | - [自动建表](Cmd.md#自动建表) | ||
| 29 | - [打印建表SQL](Cmd.md#打印建表sql) | ||
| 30 | 8. [Test ORM](Test.md) | ||
| 31 | 9. Custom Fields | ||
| 32 | 10. Faq | ||
| 33 | |||
| 34 | |||
| 35 | ### 文档更新记录 | ||
| 36 | |||
| 37 | * 2013-08-20: 这里不再更新,最新文档在 beedoc, [中文](http://beego.me/docs/Models_Overview?lang=zh) / [English](http://beego.me/docs/Models_Overview?lang=en) | ||
| 38 | * 2013-08-19: 增加[自动建表](Cmd.md#自动建表)功能 | ||
| 39 | * 2013-08-13: ORM 的 [时区设置](Orm.md#时区设置) | ||
| 40 | * 2013-08-13: [模型字段与数据库类型的对应](Models.md#模型字段与数据库类型的对应) 推荐的数据库对应使用的类型 |
orm/docs/zh/Raw.md
deleted
100644 → 0
| 1 | ## 使用SQL语句进行查询 | ||
| 2 | |||
| 3 | * 使用 Raw SQL 查询,无需使用 ORM 表定义 | ||
| 4 | * 多数据库,都可直接使用占位符号 `?`,自动转换 | ||
| 5 | * 查询时的参数,支持使用 Model Struct 和 Slice, Array | ||
| 6 | |||
| 7 | ```go | ||
| 8 | ids := []int{1, 2, 3} | ||
| 9 | p.Raw("SELECT name FROM user WHERE id IN (?, ?, ?)", ids) | ||
| 10 | ``` | ||
| 11 | |||
| 12 | 创建一个 **RawSeter** | ||
| 13 | |||
| 14 | ```go | ||
| 15 | o := NewOrm() | ||
| 16 | var r RawSeter | ||
| 17 | r = o.Raw("UPDATE user SET name = ? WHERE name = ?", "testing", "slene") | ||
| 18 | ``` | ||
| 19 | |||
| 20 | * type RawSeter interface { | ||
| 21 | * [Exec() (int64, error)](#exec) | ||
| 22 | * [QueryRow(...interface{}) error](#queryrow) | ||
| 23 | * [QueryRows(...interface{}) (int64, error)](#queryrows) | ||
| 24 | * [SetArgs(...interface{}) RawSeter](#setargs) | ||
| 25 | * [Values(*[]Params) (int64, error)](#values) | ||
| 26 | * [ValuesList(*[]ParamsList) (int64, error)](#valueslist) | ||
| 27 | * [ValuesFlat(*ParamsList) (int64, error)](#valuesflat) | ||
| 28 | * [Prepare() (RawPreparer, error)](#prepare) | ||
| 29 | * } | ||
| 30 | |||
| 31 | #### Exec | ||
| 32 | |||
| 33 | 执行sql语句 | ||
| 34 | |||
| 35 | ```go | ||
| 36 | num, err := r.Exec() | ||
| 37 | ``` | ||
| 38 | |||
| 39 | #### QueryRow | ||
| 40 | |||
| 41 | TODO | ||
| 42 | |||
| 43 | #### QueryRows | ||
| 44 | |||
| 45 | TODO | ||
| 46 | |||
| 47 | #### SetArgs | ||
| 48 | |||
| 49 | 改变 Raw(sql, args...) 中的 args 参数,返回一个新的 RawSeter | ||
| 50 | |||
| 51 | 用于单条 sql 语句,重复利用,替换参数然后执行。 | ||
| 52 | |||
| 53 | ```go | ||
| 54 | num, err := r.SetArgs("arg1", "arg2").Exec() | ||
| 55 | num, err := r.SetArgs("arg1", "arg2").Exec() | ||
| 56 | ... | ||
| 57 | ``` | ||
| 58 | #### Values / ValuesList / ValuesFlat | ||
| 59 | |||
| 60 | Raw SQL 查询获得的结果集 Value 为 `string` 类型,NULL 字段的值为空 `` | ||
| 61 | |||
| 62 | #### Values | ||
| 63 | |||
| 64 | |||
| 65 | 返回结果集的 key => value 值 | ||
| 66 | |||
| 67 | ```go | ||
| 68 | var maps []orm.Params | ||
| 69 | num, err = o.Raw("SELECT user_name FROM user WHERE status = ?", 1).Values(&maps) | ||
| 70 | if err == nil && num > 0 { | ||
| 71 | fmt.Println(maps[0]["user_name"]) // slene | ||
| 72 | } | ||
| 73 | ``` | ||
| 74 | |||
| 75 | #### ValuesList | ||
| 76 | |||
| 77 | 返回结果集 slice | ||
| 78 | |||
| 79 | ```go | ||
| 80 | var lists []orm.ParamsList | ||
| 81 | num, err = o.Raw("SELECT user_name FROM user WHERE status = ?", 1).ValuesList(&lists) | ||
| 82 | if err == nil && num > 0 { | ||
| 83 | fmt.Println(lists[0][0]) // slene | ||
| 84 | } | ||
| 85 | ``` | ||
| 86 | |||
| 87 | #### ValuesFlat | ||
| 88 | |||
| 89 | 返回单一字段的平铺 slice 数据 | ||
| 90 | |||
| 91 | ```go | ||
| 92 | var list orm.ParamsList | ||
| 93 | num, err = o.Raw("SELECT id FROM user WHERE id < ?", 10).ValuesList(&list) | ||
| 94 | if err == nil && num > 0 { | ||
| 95 | fmt.Println(list) // []{"1","2","3",...} | ||
| 96 | } | ||
| 97 | ``` | ||
| 98 | |||
| 99 | #### Prepare | ||
| 100 | |||
| 101 | 用于一次 prepare 多次 exec,以提高批量执行的速度。 | ||
| 102 | |||
| 103 | ```go | ||
| 104 | p, err := o.Raw("UPDATE user SET name = ? WHERE name = ?").Prepare() | ||
| 105 | num, err := p.Exec("testing", "slene") | ||
| 106 | num, err = p.Exec("testing", "astaxie") | ||
| 107 | ... | ||
| 108 | ... | ||
| 109 | p.Close() // 别忘记关闭 statement | ||
| 110 | ``` | ||
| 111 | |||
| 112 | ## FAQ | ||
| 113 | |||
| 114 | 1. 我的 app 需要支持多类型数据库,如何在使用 Raw SQL 的时候判断当前使用的数据库类型。 | ||
| 115 | |||
| 116 | 使用 Ormer 的 [Driver方法](Orm.md#driver) 可以进行判断 |
orm/docs/zh/Test.md
deleted
100644 → 0
| 1 | ## Test ORM | ||
| 2 | |||
| 3 | 测试代码参见 | ||
| 4 | |||
| 5 | ```bash | ||
| 6 | models_test.go // 表定义 | ||
| 7 | orm_test.go // 测试用例 | ||
| 8 | ``` | ||
| 9 | |||
| 10 | #### MySQL | ||
| 11 | ```bash | ||
| 12 | mysql -u root -e 'create database orm_test;' | ||
| 13 | export ORM_DRIVER=mysql | ||
| 14 | export ORM_SOURCE="root:@/orm_test?charset=utf8" | ||
| 15 | go test -v github.com/astaxie/beego/orm | ||
| 16 | ``` | ||
| 17 | |||
| 18 | |||
| 19 | #### Sqlite3 | ||
| 20 | ```bash | ||
| 21 | touch /path/to/orm_test.db | ||
| 22 | export ORM_DRIVER=sqlite3 | ||
| 23 | export ORM_SOURCE=/path/to/orm_test.db | ||
| 24 | go test -v github.com/astaxie/beego/orm | ||
| 25 | ``` | ||
| 26 | |||
| 27 | |||
| 28 | #### PostgreSQL | ||
| 29 | ```bash | ||
| 30 | psql -c 'create database orm_test;' -U postgres | ||
| 31 | export ORM_DRIVER=postgres | ||
| 32 | export ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable" | ||
| 33 | go test -v github.com/astaxie/beego/orm | ||
| 34 | ``` | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or sign in to post a comment