## 4.2 表名和表结构处理 通过第二章的示例, 我们知道了传入table的格式有3种, 分别是`struct`,`map`,`string` ### 1.初始化链接 ```go func DB() gorose.IOrm { engin.NewOrm() } db := DB() ``` ### 2.类型定义 ```go // struct类型 type Users struct { Uid int64 `gorose:"uid"` Name string `gorose:"name"` Age int64 `gorose:"age"` State int64 `gorose:"-"` } func (u Users) TableName() string { return "users" } // 一条数据的map类型 type userMap gorose.Map func (u userMap) TableName() string { return "users" } // 多条数据的map类型 type userMap2 []gorose.Map func (u userMap2) TableName() string { return "users" } ``` > 说明: `TableName()`是为了获取表的实际名字, 如果名字刚好是表名(Users=>Users),可以不添加`TableName()`. State int64 `gorose:"ignore"`: 这里的`State`字段不在表中,可以通过`ignore`忽略掉 ### 3.操作示例 - struct类型 ```go // struct类型的一条数据, 这里默认会加上limit 1, 节省空间 var u Users // var u = Users{} err := db.Table(&u).Select() ``` ```go // struct类型的多条数据 var u []Users // var u = []Users{} err := db.Table(&u).Limit(5).Select() ``` - map类型 ```go // map类型的一条数据, 这里默认会加上limit 1, 节省空间 // 注意: 这里是map类型, 必须初始化 var u = userMap{} // var u = make(userMap) err := db.Table(&u).Select() ``` ```go // map类型的多条数据 // 注意: 这里是map类型, 必须初始化 // 这里的多条数据, 只能预先定义为 userMap2, 不能像 struct 的多条那样直接复用[]Users // 因为需要获取对应的 TableName(), 当然, 如果名字刚好是表名,可以不添加`TableName()` var u = userMap2{} // var u = make(userMap2) err := db.Table(&u).Limit(5).Select() ``` - string类型 ```go // map类型的一条数据, 这里默认会加上limit 1, 节省空间 res,err := db.Table("users").First() ``` ```go // map类型的多条数据 res,err := db.Table("users").Limit(5).Get() fmt.Println(res) ``` > 说明: 只有传入string类型的表名才能使用`First()`和`Get()`, 否则没有数据, 而且这里的数据是放在返回参数中, 并非绑定到数据对象上 ## 关于tag名字和ignore名字 ```go engin,err:=gorose.Open() engin.TagName("orm").IgnoreName("ignore") ``` 以上初始化配置, 可以自定义struct的tag名字和ignore标记,如下可以通过上述配置正常解析: ```go type Users struct { Uid int64 `orm:"uid"` Name string `orm:"name"` Age int64 `orm:"age"` State int64 `orm:"ignore"` } ``` 而对应的gorose的默认的tag为`gorose`,默认的ignore为`-`,如: ```go type Users struct { Uid int64 `gorose:"uid"` Name string `gorose:"name"` Age int64 `gorose:"age"` State int64 `gorose:"-"` } ``` 此为gorose默认标识 ## 关于struct字段类型的特殊说明 ### 一. 时间字段类型的处理 关于时间字段, 官方文档中给出了说明和解决方案, 有`string`类型和`time.Time`类型 在新版本的go中, 都默认使用了 time.Time 作为默认的类型, 我们可以采用如下的方法正确使用他 1. 在链接数据库的时候, 我们需要设置dsn的parseTime参数值为true, 则默认查询数据类型为`time.Time` ``` root:root@tcp(localhost:3306)/test?charset=utf8mb4&parseTime=true ``` 2. 如果不设置 parseTime参数值为true, 则使用 string 类型 ### 二. 其他字段类型的处理 当我们设计表的时候, 最好设置字段为 `not null`, 比如varchar可以设置为 `default ''`来代替. 这里不仅仅是数据库优化问题, 同时, 在这里, 当一个字段的值为null时, struct会导致查询为空的情况. 如果确实已经设置为null了, 那我们就需要特别注意了, 对字段类型要做一些特殊的处理.根据官方文档给出的方案,我们可以做如下处理: 1. 使用对应类型的指针, 即 *string, *int64 等 2. 使用`database/sql`给出的类型 sql.NullString, sql.NullInt64 等 以上两种方式都可以避免查询为空的情况, 第二种用法的结果是一个struct, 返回的时候需要做一下处理, 第一种情况则可以直接返回给前端使用,根据自己的实际情况做出合理的选择即可