复杂的模型定义不是必须的,此功能用作数据库数据转换和自动建表

默认的表名规则,使用驼峰转蛇形:

AuthUser -> auth_user
Auth_User -> auth__user
DB_AuthUser -> d_b__auth_user

  

除了开头的大写字母以外,遇到大写会增加 _,原名称中的下划线保留。

自定义表名

type User struct {
Id int
Name string
} func (u *User) TableName() string {
return "auth_user"
}

  

如果前缀设置为 prefix_ 那么表名为:prefix_auth_user

自定义索引

为单个或多个字段增加索引

type User struct {
Id int
Name string
Email string
} // 多字段索引
func (u *User) TableIndex() [][]string {
return [][]string{
[]string{"Id", "Name"},
}
} // 多字段唯一键
func (u *User) TableUnique() [][]string {
return [][]string{
[]string{"Name", "Email"},
}
}

  

自定义引擎

仅支持 MySQL

默认使用的引擎,为当前数据库的默认引擎,这个是由你的 mysql 配置参数决定的。

你可以在模型里设置 TableEngine 函数,指定使用的引擎

type User struct {
Id int
Name string
Email string
} // 设置引擎为 INNODB
func (u *User) TableEngine() string {
return "INNODB"
}

  

设置参数

orm:"null;rel(fk)"

  

多个设置间使用 ; 分隔,设置的值如果是多个,使用 , 分隔。

忽略字段

设置 - 即可忽略 struct 中的字段

type User struct {
...
AnyField string `orm:"-"`
...
}

auto

当 Field 类型为 int, int32, int64, uint, uint32, uint64 时,可以设置字段为自增健

  • 当模型定义里没有主键时,符合上述类型且名称为 Id 的 Field 将被视为自增健。

鉴于 go 目前的设计,即使使用了 uint64,但你也不能存储到他的最大值。依然会作为 int64 处理。

pk

设置为主键,适用于自定义其他类型为主键

null

数据库表默认为 NOT NULL,设置 null 代表 ALLOW NULL

Name string `orm:"null"`

index

为单个字段增加索引

unique

为单个字段增加 unique 键

Name string `orm:"unique"`

column

为字段设置 db 字段的名称

Name string `orm:"column(user_name)"`

size

string 类型字段默认为 varchar(255)

设置 size 以后,db type 将使用 varchar(size)

Title string `orm:"size(60)"`

digits / decimals

设置 float32, float64 类型的浮点精度

Money float64 `orm:"digits(12);decimals(4)"`

总长度 12 小数点后 4 位 eg: 99999999.9999

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

Created time.Time `orm:"auto_now_add;type(date)"`

设置为 datetime 时,time.Time 字段的对应 db 类型使用 datetime

Created time.Time `orm:"auto_now_add;type(datetime)"`

  

default

为字段设置默认值,类型必须符合(目前仅用于级联删除时的默认值)

type User struct {
...
Status int `orm:"default(1)"`
...
}

  

表关系设置

rel / reverse

RelOneToOne:

type User struct {
...
Profile *Profile `orm:"null;rel(one);on_delete(set_null)"`
...
}

  

对应的反向关系 RelReverseOne:

type Profile struct {
...
User *User `orm:"reverse(one)"`
...
}

  

RelForeignKey:

type Post struct {
...
User *User `orm:"rel(fk)"` // RelForeignKey relation
...
}

对应的反向关系 RelReverseMany:

type User struct {
...
Posts []*Post `orm:"reverse(many)"` // fk 的反向关系
...
}

RelManyToMany:

type Post struct {
...
Tags []*Tag `orm:"rel(m2m)"` // ManyToMany relation
...
}

  

对应的反向关系 RelReverseMany:

type Tag struct {
...
Posts []*Post `orm:"reverse(many)"`
...
}

  

rel_table / rel_through

此设置针对 orm:"rel(m2m)" 的关系字段

rel_table       设置自动生成的 m2m 关系表的名称
rel_through 如果要在 m2m 关系中使用自定义的 m2m 关系表
通过这个设置其名称,格式为 pkg.path.ModelName
eg: app.models.PostTagRel
PostTagRel 表需要有到 Post 和 Tag 的关系

当设置 rel_table 时会忽略 rel_through

设置方法:

orm:"rel(m2m);rel_table(the_table_name)"

orm:"rel(m2m);rel_through(pkg.path.ModelName)"

  

on_delete

设置对应的 rel 关系删除时,如何处理关系字段。

cascade        级联删除(默认值)
set_null 设置为 NULL,需要设置 null = true
set_default 设置为默认值,需要设置 default 值
do_nothing 什么也不做,忽略
type User struct {
...
Profile *Profile `orm:"null;rel(one);on_delete(set_null)"`
...
}
type Profile struct {
...
User *User `orm:"reverse(one)"`
...
} // 删除 Profile 时将设置 User.Profile 的数据库字段为 NULL

关于 on_delete 的相关例子

type User struct {
Id int
Name string
} type Post struct {
Id int
Title string
User *User `orm:"rel(fk)"`
}

假设 Post -> User 是 ManyToOne 的关系,也就是外键。

o.Filter("Id", 1).Delete()

这个时候即会删除 Id 为 1 的 User 也会删除其发布的 Post

不想删除的话,需要设置 set_null

type Post struct {
Id int
Title string
User *User `orm:"rel(fk);null;on_delete(set_null)"`
}

那这个时候,删除 User 只会把对应的 Post.user_id 设置为 NULL

当然有时候为了高性能的需要,多存点数据无所谓啊,造成批量删除才是问题。

type Post struct {
Id int
Title string
User *User `orm:"rel(fk);null;on_delete(do_nothing)"`
}

那么只要删除的时候,不操作 Post 就可以了

beego——模型定义的更多相关文章

  1. [Beego模型] 四、使用SQL语句进行查询

    [Beego模型] 一.ORM 使用方法 [Beego模型] 二.CRUD 操作 [Beego模型] 三.高级查询 [Beego模型] 四.使用SQL语句进行查询 [Beego模型] 五.构造查询 [ ...

  2. [Beego模型] 三、高级查询

    [Beego模型] 一.ORM 使用方法 [Beego模型] 二.CRUD 操作 [Beego模型] 三.高级查询 [Beego模型] 四.使用SQL语句进行查询 [Beego模型] 五.构造查询 [ ...

  3. [Beego模型] 一、ORM 使用方法

    [Beego模型] 一.ORM 使用方法 [Beego模型] 二.CRUD 操作 [Beego模型] 三.高级查询 [Beego模型] 四.使用SQL语句进行查询 [Beego模型] 五.构造查询 [ ...

  4. Entity Framework 6 Recipes 2nd Edition(11-1)译 -> 从“模型定义”函数返回一个标量值

    第11章函数 函数提供了一个有力代码复用机制, 并且让你的代码保持简洁和易懂. 它们同样也是EF运行时能利用的数据库层代码.函数有几类: Rowset Functions, 聚合函数, Ranking ...

  5. Entity Framework 6 Recipes 2nd Edition(11-2)译 -> 用”模型定义”函数过滤实体集

    11-2. 用”模型定义”函数过滤实体集 问题 想要创建一个”模型定义”函数来过滤一个实体集 解决方案 假设我们已有一个客户(Customer)和票据Invoice)模型,如Figure 11-2所示 ...

  6. Entity Framework 6 Recipes 2nd Edition(11-2)译 -> 为一个”模型定义”函数返回一个计算列

    11-3. 为一个”模型定义”函数返回一个计算列 问题 想从”模型定义”函数里返回一个计算列 解决方案 假设我们有一个员工(Employee)实体,属性有: FirstName, LastName,和 ...

  7. Entity Framework 6 Recipes 2nd Edition(11-4)译 -> 在”模型定义”函数里调用另一个”模型定义”函数

    11-4.在”模型定义”函数里调用另一个”模型定义”函数 问题 想要用一个”模型定义”函数去实现另一个”模型定义”函数 解决方案 假设我们已有一个公司合伙人关系连同它们的结构模型,如Figure 11 ...

  8. Entity Framework 6 Recipes 2nd Edition(11-5)译 -> 从”模型定义”函数返回一个匿名类型

    11-5. 从”模型定义”函数返回一个匿名类型 问题 想创建一个返回一个匿名类型的”模型定义”函数 解决方案 假设已有游客(Visitor) 预订(reservation)房间(hotel ) 的模型 ...

  9. Entity Framework 6 Recipes 2nd Edition(11-6)译 -> 从一个”模型定义”函数里返回一个复杂类型

    11-6.从一个”模型定义”函数里返回一个复杂类型 问题 想要从一个”模型定义”函数返回一个复杂类型 解决方案 假设我们有一个病人(patient)和他们访客(visit)的模型,如 Figure 1 ...

随机推荐

  1. 如何利用gdb调试程序?

    程序的大体意思就是各一个数组赋值,然后输出来程序已经写在了上面,下面我们就来看一下如何产生带有调试信息的编译文件,这里我们要使用gcc的-g参数,用于在编译文件中加入一些调试信息.发现加了-g和没有加 ...

  2. linux内核开机logo显示调试

    要使内核支持开机logo显示需要配置内核 配置如下: make menuconfig: Device Drivers  --->     Graphics support  --->    ...

  3. Tuning 04 Sizing the Buffer Cache

    Buffer Cache 特性 The buffer cache holds copies of the data blocks from the data files. Because the bu ...

  4. 对sql初始化的值的处理

    要把数据库的值置为数据库初始化时候的值(带隐式的null值)的sql语句. UPDATE member_base_info SET orderType =NULL,getaimAddress=NULL ...

  5. ajax取消重复请求

    var pendingRequests = {}; $.ajaxPrefilter(function(options, originalOptions, jqXHR) { var key = opti ...

  6. 2017 ACM区域赛(南宁站) 参赛流水账

    day0: 早上四点起床赶飞机,还好没有吵醒室友导致被打死.本来想在飞机上准备一下下周的小测,结果飞机一点都不平稳,只能全程和队友吹逼聊天.下午在宾馆里和johann通关了一部合金弹头,重温了童年的经 ...

  7. 从头认识java-17.4 具体解释同步(2)-具体解释竞争条件

    这一章节我们来具体讨论一下竞争条件. 1.为什么会引起竞争条件? 因为操作缺失原子性. 2.什么是原子性? 所谓原子操作是指不会被线程调度机制打断的操作:这样的操作一旦開始,就一直运行到结束.中间不会 ...

  8. requirejs学习(一)

    requirejs学习(一) 随着网站功能逐渐丰富,网页中的js也变得越来越复杂和臃肿,各种依赖(插件等)也逐渐增多,原有通过script标签来导入一个个的js文件这种方式已经不能满足现在的需求,我们 ...

  9. Java逍遥游记读书笔记<一>

    前言 必须先来一句,这是入门级别,高手勿喷~ 写Android的时候总有一些语句不是很理解,其实大部分是Java的内容,所以想系统的学下Java. 这本书——<Java逍遥游记>是在图书馆 ...

  10. 一起talk C栗子吧(第二十五回:C语言实例--二分查找)

    各位看官们,大家好,上一回中咱们说的是顺序查找的样例,这一回咱们说的样例是:二分查找.闲话休 提,言归正转. 让我们一起talk C栗子吧. 看官们,我们在上一回中说了查找的相关内容,而且介绍了一种查 ...