## 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, 返回的時候需要做一下處理, 第一種情況則可以直接返回給前端使用,根據自己的實際情況做出合理的選擇即可