1. Data Structures

The data structures of the query results are as follows:

  1. type Value = *gvar.Var // Returns table record value
  2. type Record map[string]Value // Returns table record key-value pairs
  3. type Result []Record // Returns a list of table records
  1. Value/Record/Result are result data types for ORM operations.
  2. Result represents a list of table records, Record represents a single table record, and Value represents a single key-value pair in a record.
  3. Value is an alias type for *gvar.Var, a runtime generic type to support different field types in database tables, facilitating subsequent data type conversion.

For example:

ORM Result - Types - 图1

ORM Result - Types - 图2

ORM Result - Types - 图3

2. Record Data Record

API documentation: https://pkg.go.dev/github.com/gogf/gf/v2/database/gdb

gdb provides a high degree of flexibility and simplicity for table record operations, supporting not only access/manipulation of table records in the form of map but also converting them to struct for processing. Here, we will demonstrate this feature with a simple example.

First, our user table structure is like this (a sample table for simple design):

  1. CREATE TABLE `user` (
  2. `uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `name` varchar(30) NOT NULL DEFAULT '' COMMENT 'Nickname',
  4. `site` varchar(255) NOT NULL DEFAULT '' COMMENT 'Homepage',
  5. PRIMARY KEY (`uid`)
  6. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Next, our table data is as follows:

  1. uid name site
  2. 1 john https://goframe.org

Finally, our example program is as follows:

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. "github.com/gogf/gf/v2/os/gctx"
  5. )
  6. type User struct {
  7. Uid int
  8. Name string
  9. }
  10. func main() {
  11. var (
  12. user *User
  13. ctx = gctx.New()
  14. )
  15. err := g.DB().Model("user").Where("uid", 1).Scan(&user)
  16. if err != nil {
  17. g.Log().Header(false).Fatal(ctx, err)
  18. }
  19. if user != nil {
  20. g.Log().Header(false).Print(ctx, user)
  21. }
  22. }

After execution, the output is:

  1. {"Uid":1,"Name":"john"}

Here, we define a custom struct containing only Uid and Name properties. As you can see, its properties do not match the fields of the data table, which is one of the flexible features of ORM: supporting specified attribute retrieval.

The gdb.Model.Scan method can convert the queried records into struct objects or arrays of struct objects. Since the parameter passed here is &user i.e., **User type, it will be converted into a struct object. If a []*User type parameter is passed, it will be converted into a struct array. Please see subsequent examples for more. For a detailed introduction to the method, please refer to the chaining operations section.

Attribute Field Mapping Rules:

Note that the key names in map are uid,name,site, while the attributes in struct are Uid,Name. How are they mapped? There are a few simple rules:

  1. The matching attribute in struct must be public (starting with a capital letter).
  2. Key names in the results will automatically match struct attributes in a case-insensitive, and ignoring -/_/space symbols manner.
  3. If the match is successful, the key value is assigned to the attribute. If it cannot be matched, the key value is ignored.

Here are a few matching examples:

  1. Key Name Struct Attribute Match
  2. name Name match
  3. Email Email match
  4. nickname NickName match
  5. NICKNAME NickName match
  6. Nick-Name NickName match
  7. nick_name NickName match
  8. nick_name Nick_Name match
  9. NickName Nick_Name match
  10. Nick-Name Nick_Name match

ORM Result - Types - 图4tip

The conversion from a database result set to struct relies on the gconv.Struct method. Therefore, if you want to achieve custom attribute conversion, and for more detailed mapping rules, please refer to the section on Type Conversion - Struct.

3. Result Data Collection

The Result/Record data types, based on the requirement to manipulate the result set, often need to use specific fields in the records as keys for data retrieval. They include multiple methods for converting to Map/List, as well as common conversions to JSON/XML data structures.

API documentation: https://pkg.go.dev/github.com/gogf/gf/v2/database/gdb

Due to the simplicity of the methods, there are no examples here. However, pay attention to two frequently used methods: Record.Map and Result.List, which are used to convert the ORM query result information into data types suitable for display. Since the field values of the result set are natively of []byte type, although a new Value type has been encapsulated and provides dozens of common type conversion methods (for more, please read the section on Generic), most often we need to directly return the result Result or Record as json or xml data structures, requiring conversion.

Usage example:

  1. package main
  2. import (
  3. "database/sql"
  4. "github.com/gogf/gf/v2/frame/g"
  5. "github.com/gogf/gf/v2/os/gctx"
  6. )
  7. type User struct {
  8. Uid int
  9. Name string
  10. Site string
  11. }
  12. func main() {
  13. var (
  14. user []*User
  15. ctx = gctx.New()
  16. )
  17. err := g.DB().Model("user").Where("uid", 1).Scan(&user)
  18. if err != nil && err != sql.ErrNoRows {
  19. g.Log().Header(false).Fatal(ctx, err)
  20. }
  21. if user != nil {
  22. g.Log().Header(false).Print(ctx, user)
  23. }
  24. }

After execution, the output is:

  1. [{"Uid":1,"Name":"john","Site":"https://goframe.org"}]