为什么在一些Go库(如gorm)中的结构体中使用SQL标签?

huangapple go评论74阅读模式
英文:

Why use sql tags in struct in some go libs like gorm?

问题

我知道在Go语言中结构体中标签的必要性,以及如何通过反射来访问它们。但是我搜索了一下,没有找到一个可靠的答案来解释为什么在编写用于SQL结果的结构体时应该使用SQL标签。我浏览了许多示例代码,人们在结构体中使用了sql:"index"sql:"primary_key"

现在我已经在数据库层面上进行了索引,这样就足够了吗?我是否需要使用sql:"index"来获得最佳结果?就像我在数据库中定义了主键属性一样,我是否还需要指定sql:"primary_key"

我的代码似乎在没有这些标签的情况下也能正常工作。只是想知道它们的好处和用法。

英文:

Well I know the necessity of tags in struct in golang and how is it accessed by reflect in golang. But I have searched and could not find a reliable answer to the question of why I should use sql tags in struct while writing struct for sql results. I have explored many sample code and people are using sql:"index" in the struct and sql:"primary_key" in the struct.

Now I have done indexing in the database layer, isn’t it enough? Should I have to use sql:"index" too get the best results? Like so I have defined primary key attribute in the database should I have to specify sql:"primary_key" as well?

My code seems to work fine without those. Just want to know their benefit and usages.

答案1

得分: 9

我认为你指的是像gorm这样的ORM库。

在这种情况下,像sql:"primary_key"sql:"index"这样的元数据只是告诉ORM在设置表或迁移表时创建索引。

gorm中的一些示例可能包括:索引、主键、外键、多对多关系,或者在尝试将现有模式适应到gorm模型时,显式设置类型,例如:

type Address struct {
    ID       int
    Address1 string         `sql:"not null;unique"` // 将字段设置为非空和唯一
    Address2 string         `sql:"type:varchar(100);unique"`
    Post     sql.NullString `sql:"not null"`
}
英文:

I think you are referring to an ORM library like gorm

In that case, metadata like sql:"primary_key" or sql:"index" will just tell the ORM to create an index while trying to setup the tables or maybe migrate them.

A couple of examples in gorm could be: indexes, primary keys, foreign keys, many2many relations or when trying to adapt an exiting schema into your gorm models, setting the type explicitly, like for example:

type Address struct {
    ID       int
    Address1 string         `sql:"not null;unique"` // Set field as not nullable and unique
    Address2 string         `sql:"type:varchar(100);unique"`
    Post     sql.NullString `sql:"not null"`
}

答案2

得分: 0

根据你使用的包和使用情况而定。对于 CRUD 操作来说,通常情况下是足够的,除非包的文档明确说明需要添加标签,尽管这种情况很少但可能存在。有些包可能会在内部进行一些魔法操作,这可能会导致 bug 的出现。如果你了解这些行为,或者在代码中非常明确地处理了这些情况,那么你可能会避免这些问题。

索引标签主要是为了使用包的迁移工具,将你的模型声明转换为 SQL 查询语句(CREATE 语句)。所以,如果你总是想自己处理这些操作,那么可能就不需要添加这些标签了。

但是,如果你使用的包要求添加标签,你可能会遇到 bug。例如,在使用 gorm 时,Model 方法接受一个结构体指针作为输入。如果这个结构体有一个名为 ID 的字段,gorm 会将其作为主键处理,也就是说,如果 ID 的值为 "4",它会自动添加一个 WHERE id=4 的条件。如果你的结构体中有 ID 字段,甚至不需要添加 primary_key 标签,它仍然会被当作主键处理。当你既有一个“非主键”的 ID 字段,又有另一个你实际上用作主键的字段时,这种行为可能会导致问题。gorm 的另一个例子可以参考这里。可能的行为还包括检查可空属性,并在插入语句中涉及到一个 NOT NULL 字段的值为 NULL 时抛出错误。

另外,给你的结构体添加标签可以被视为一种良好的实践,因为它提供了在数据库中的属性的上下文信息。

英文:

Depends on the package you are using and your use-case. Is it enough for CRUD? Almost always, unless the package says so which is often rare but possible. Few packages sometime do under the hood magic which may give rise to bugs. If you are aware of these behaviours, or are quite explicit in your code, you'll probably avoid it.

Indexing tags mostly allows you to use package's migration tools translating your model declaration into sql queries (CREATE statements). So if you always want to do this by yourself, then you probably needn't bother adding such tags.

But you may find yourself a bug if your package requires a tag. For example, in case of gorm, the Model method takes a struct pointer as an input. If this struct has a field named ID it uses it as a primary key, that is, say ID has a value of "4", it will add a WHERE id=4 automatically. In case your struct has ID, you needn't even add a primary_key tag and it will still be treated as one. This behaviour may cause issues when you have both a "non-primary-key" ID field, and another field which you are actually using as the primary key. Another example for gorm is this. A possible behaviour can also be checking for nullable property and throwing an error if an INSERT statement involves a NOT NULL field getting a NULL value.

On a different note, adding tags to your structs can be considered good practice since it gives context of its properties in the DB.

huangapple
  • 本文由 发表于 2015年11月22日 02:28:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/33847013.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定