## 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, 返回的时候需要做一下处理, 第一种情况则可以直接返回给前端使用,根据自己的实际情况做出合理的选择即可