gorm中的核心数据结构。小编来告诉你更多相关信息。
gorm中的核心数据结构
一个电脑小知识,为大家介绍gorm中的核心数据结构方面的介绍,下面为您详细介绍
今天咱们一起来学习下gorm中的几个核心数据结构。
通过了解gorm底层的数据结构,能够让我们了解gorm底层的实现,以便更好的使用gorm。
在gorm中主要有5个核心结构:DB、Config、Statment、Clause和Schema。
接下来我们就详细的看下每种数据结构以及各结构之间的关系。
一、DB
在使用gorm的时候,我们首先会使用gorm.Open方法和数据库建立连接,同时并返回一个gorm.DB结构。如下:
var db *gorm.DBdsn := \"username:password@tcp(127.0.0.1:3306)/test01?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms\"config := &gorm.Config{ NamingStrategy: schema.NamingStrategy{ SingularTable: true, // 禁用表名复数 },}db, _ := gorm.Open(mysql.Open(dsn), config)
如上,db变量就是*gorm.DB类型的,如下:
// DB GORM DB definitiontype DB struct { *Config Error error RowsAffected int64 Statement *Statement clone int}
大家看,DB结构里包含了嵌入的结构*Config,还有一个Statement结构。
二、Config结构
Config结构是包含在DB结构内的。顾名思义,Config就是和数据库相关的一些配置。
在gorm.Open函数中传入的,如上面我们对数据表命名的配置中禁用了表名的复数形式。如下:
config := &gorm.Config{ NamingStrategy: schema.NamingStrategy{ SingularTable: true, // 禁用表名复数 },}
这个的作用就是我们在建立和表对应的Model结构体时,结构体的名称会转换成对应的表名,但使用的是单数形式。
例如,我们有一个MTest的Model结构体。
那么,默认情况下,gorm会把该model转换成对应的m_tests表名。
而如果做了对应的配置:SingularTable:True,gorm就会把该model转换成对应的m_test表名。
以下就是Config结构中的核心字段(我们省略了一些):
// Config GORM configtype Config struct { // NamingStrategy tables, columns naming strategy NamingStrategy schema.Namer // DryRun generate sql without execute DryRun bool // ConnPool db conn pool ConnPool ConnPool // Dialector database dialector Dialector // Plugins registered plugins Plugins map[string]Plugin callbacks *callbacks}
在该结构中,各字段如下:
- ConnPool:是和数据库建立的真实连接。
- Dialector:是连接器。这个是一个接口,以适配各种类型的数据库。比如MySQL、ClickHouse等。比如,在最开始传入Open函数的第一个参数mysql.Open(dsn)就是一个Dialector,说明要连接的是mysql数据库。后续所有操作都是针对mysql数据库的。
gorm中的核心数据结构。小编来告诉你更多相关信息。
gorm中的核心数据结构
- callbacks:callbacks是一个结构体,该结构体包含了一个map结构的processors的字段。该processors是实际的执行器。会有4个对应的processor,分别为:CREATE、QUERY、DELETE和UPDATE。用于分别执行对应的语句。
- DryRun:该参数是一个是否执行最终sql语句的一个开关。如果为false,则执行sql语句,否则只将对应的函数编译成sql语句,但不实际执行。
三、Statement
statement代表的是语句,这里就包含了sql种涉及到的所有语句了。其结构如下:
type Statement struct { *DB TableExpr *clause.Expr //表表达式 Table string //表名 Model interface{} //model结构体 Dest interface{} // 接收查询结果的变量 ReflectValue reflect.Value //model类型的value值 Clauses map[string]clause.Clause //sql语句 BuildClauses []string Distinct bool //是否去重 Selects []string // 要查询的字段列表 Omits []string // 忽略的字段 Joins []join // join的表 Preloads map[string][]interface{} Settings sync.Map ConnPool ConnPool Schema *schema.Schema // 对应的表的模式 Context context.Context SQL strings.Builder //最终编译好的sql语句 Vars []interface{} // 从句中涉及到的变量值}
这里只列出了一些关键的字段。我们分类讲解一些这些关键字段。
表相关字段
TableExpr和Table:这两个字段都是通过DB.Table(name string, args …interface{})函数指定的。
比如我们常用的DB.Table(“m_test”)就可以指定要查询的表名。
Model和Schema字段
通过model字段可以指定和数据表对应的结构体类型。
然后gorm再通过model结构体转换成对应的表的建表模式,并将其复制到Schema字段中。
Dest字段
Dest字段用来接收从数据表中查询的结果。
我们看Dest的类型是interface{},也就是说可以是任意类型。
Dest一般是通过Find函数、Save、Create等函数传进来的。如下各函数的原型:
// dest会复制给Dest字段func (db *DB) Find(dest interface{}, conds ...interface{}) (tx *DB)// 会将value参数赋值给Dest字段func (db *DB) Save(value interface{}) (tx *DB)// 会将value参数赋值给Dest字段func (db *DB) Create(value interface{}) (tx *DB)
同时,这里还会有一个特点,就是当Model字段为nil时,会将Dest字段赋值给Model字段。
这也就是为什么我们在使用gorm的时候,给Find函数传一个Model类型的dest就能定位到对应的表,并将数据获取出来。
而给Find函数传递一个map类型的dest,就必须要通过Table函数指定一个表名的原因。如下:
gorm中的核心数据结构。小编来告诉你更多相关信息。
gorm中的核心数据结构
// 定义一个MTest的modeltype MTest struct { Id int64 Name string `gorm:\"DEFAULT:John\"`}// 定义一个model变量var row MTest// 未指定表,依然能从m_test表中查找到数据err := db.Find(&row)// 示例二// 定义一个MTest的modeltype MTest struct { Id int64 Name string `gorm:\"DEFAULT:John\"`}// 定义一个map类型用来接收数据var row = make(map[string]interface{},0)// 需要指定model,才能从m_test表中查找到数据err := db.Model(MTest{}).Find(&row)
四、Schema
type Schema struct { Name string //model的名称 ModelType reflect.Type Table string //表名 PrioritizedPrimaryField *Field //最优先的主键ID DBNames []string //通过在model中指定tag(COLUMN)来和数据表中的字段关联 PrimaryFields []*Field //主键字段集合 PrimaryFieldDBNames []string //主键字段集合(数据库中的字段名) Fields []*Field //结构体中的字段名、数据库中的字段名 FieldsByName map[string]*Field //以结构体中的字段名为key的map FieldsByBindName map[string]*Field // embedded fields is \'Embed.Field\' 嵌入的字段名称 FieldsByDBName map[string]*Field // 以数据库中的字段名为key的map FieldsWithDefaultDBValue []*Field // fields with default value assigned by database 有默认值的字段 Relationships Relationships //相关联的表}
在该结构体中,最核心的字段就是Fields字段。
该Fields字段就是从对应的Model结构体中通过reflect解析出来的字段。该字段默认是跟数据表中的字段一一对应的。
五、Clause
在sql语句中,各个关键词对应的就是从句,即Clause。
比如Select、From、Where、Order、Group By、Limit等等。
在gorm中,会通过对应名称的函数来组织对应的从句。比如Where从句:
// 组织成Where从句func (db *DB) Where(query interface{}, args ...interface{}) (tx *DB)// 组织成GroupBy从句func (db *DB) Group(name string) (tx *DB)
比如以下就是指定了Where的从句:
type MTest struct { Id int64 Name string `gorm:\"DEFAULT:John\"`}var row MTesterr := db.Where(\"id=?\", 1).Find(&row)
在gorm中,将各个从句定义成了对应的类型。
同时,这些类型又实现了Clause接口类型。
如下是Clause接口的定义:
// Interface clause interfacetype Interface interface { Name() string Build(Builder) MergeClause(*Clause)}
在这个接口中,有一个Build函数需要额外注意。
各个具体的从句就是通过Build这个函数来转换成对应的sql语句的。比如Where从句:
// Build build where clausefunc (where Where) Build(builder Builder) { // Switch position if the first query expression is a single Or condition for idx, expr := range where.Exprs { if v, ok := expr.(OrConditions); !ok || len(v.Exprs) > 1 { if idx != 0 { where.Exprs[0], where.Exprs[idx] = where.Exprs[idx], where.Exprs[0] } break } } buildExprs(where.Exprs, builder, AndWithSpace)}
gorm中的核心数据结构。小编来告诉你更多相关信息。
gorm中的核心数据结构
总结
我们从DB结构开始,逐级的讲解了gorm中核心的数据结构:DB、Statement、Schema、Clause以及Config。
同时,通过示例指出各个结构值是如何被赋值的。
通过了解核心数据结构,能够帮助我们更好的使用gorm。
上述分享的gorm中的核心数据结构的相关内容,希望对您有所帮助!
阅读前请先查看【免责声明】本文内容由互联网用户自发贡献,该文观点仅代表作者本人,本站仅供展示。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 1217266901@qq.com 举报,一经查实,本站将立刻删除。 转载请注明出处:https://jingfakeji.com/tech/34484.html