### Column屬性定義
我們在field對應的Tag中對Column的一些屬性進行定義,定義的方法基本和我們寫SQL定義表結構類似,比如:
~~~
type User struct {
Id int64
Name string `xorm:"varchar(25) notnull unique 'usr_name'"`
}
~~~
對于不同的數據庫系統,數據類型其實是有些差異的。因此xorm中對數據類型有自己的定義,基本的原則是盡量兼容各種數據庫的字段類型,具體的字段對應關系可以查看[字段類型對應表](#)。對于使用者,一般只要使用自己熟悉的數據庫字段定義即可。
具體的Tag規則如下,另Tag中的關鍵字均不區分大小寫,但字段名根據不同的數據庫是區分大小寫:
| name | 當前field對應的字段的名稱,可選,如不寫,則自動根據field名字和轉換規則命名,如與其它關鍵字沖突,請使用單引號括起來。 |
|-----|-----|
| pk | 是否是Primary Key,如果在一個struct中有多個字段都使用了此標記,則這多個字段構成了復合主鍵,單主鍵當前支持int32,int,int64,uint32,uint,uint64,string這7種Go的數據類型,復合主鍵支持這7種Go的數據類型的組合。 |
| 當前支持30多種字段類型,詳情參見本文最后一個表格 | 字段類型 |
| autoincr | 是否是自增 |
| [not ]null 或 notnull | 是否可以為空 |
| unique或unique(uniquename) | 是否是唯一,如不加括號則該字段不允許重復;如加上括號,則括號中為聯合唯一索引的名字,此時如果有另外一個或多個字段和本unique的uniquename相同,則這些uniquename相同的字段組成聯合唯一索引 |
| index或index(indexname) | 是否是索引,如不加括號則該字段自身為索引,如加上括號,則括號中為聯合索引的名字,此時如果有另外一個或多個字段和本index的indexname相同,則這些indexname相同的字段組成聯合索引 |
| extends | 應用于一個匿名成員結構體或者非匿名成員結構體之上,表示此結構體的所有成員也映射到數據庫中,不過extends只加載一級深度 |
| - | 這個Field將不進行字段映射 |
| -> | 這個Field將只寫入到數據庫而不從數據庫讀取 |
| <- | 這個Field將只從數據庫讀取,而不寫入到數據庫 |
| created | 這個Field將在Insert時自動賦值為當前時間 |
| updated | 這個Field將在Insert或Update時自動賦值為當前時間 |
| deleted | 這個Field將在Delete時設置為當前時間,并且當前記錄不刪除 |
| version | 這個Field將會在insert時默認為1,每次更新自動加1 |
| default 0 | 設置默認值,緊跟的內容如果是Varchar等需要加上單引號 |
另外有如下幾條自動映射的規則:
-
1.如果field名稱為`Id`而且類型為`int64`并且沒有定義tag,則會被xorm視為主鍵,并且擁有自增屬性。如果想用`Id`以外的名字或非int64類型做為主鍵名,必須在對應的Tag上加上`xorm:"pk"`來定義主鍵,加上`xorm:"autoincr"`作為自增。這里需要注意的是,有些數據庫并不允許非主鍵的自增屬性。
-
2.string類型默認映射為`varchar(255)`,如果需要不同的定義,可以在tag中自定義,如:`varchar(1024)`
-
3.支持`type MyString string`等自定義的field,支持Slice, Map等field成員,這些成員默認存儲為Text類型,并且默認將使用Json格式來序列化和反序列化。也支持數據庫字段類型為Blob類型。如果是Blob類型,則先使用Json格式序列化再轉成[]byte格式。如果是[]byte或者[]uint8,則不做轉換二十直接以二進制方式存儲。具體參見 [Go與字段類型對應表](#)
-
4.實現了Conversion接口的類型或者結構體,將根據接口的轉換方式在類型和數據庫記錄之間進行相互轉換,這個接口的優先級是最高的。
~~~
type Conversion interface {
FromDB([]byte) error
ToDB() ([]byte, error)
}
~~~
-
5.如果一個結構體包含一個Conversion的接口類型,那么在獲取數據時,必須要預先設置一個實現此接口的struct或者struct的指針。此時可以在此struct中實現`BeforeSet(name string, cell xorm.Cell)`方法來進行預先給Conversion賦值。例子參見 [testConversion](https://github.com/go-xorm/tests/blob/master/base.go#L1826)
下表為xorm類型和各個數據庫類型的對應表:
| xorm | mysql | sqlite3 | postgres | remark |
|-----|-----|-----|-----|-----|
| BIT | BIT | INTEGER | BIT | |
| TINYINT | TINYINT | INTEGER | SMALLINT | |
| SMALLINT | SMALLINT | INTEGER | SMALLINT | |
| MEDIUMINT | MEDIUMINT | INTEGER | INTEGER | |
| INT | INT | INTEGER | INTEGER | |
| INTEGER | INTEGER | INTEGER | INTEGER | |
| BIGINT | BIGINT | INTEGER | BIGINT | |
| |
| CHAR | CHAR | TEXT | CHAR | |
| VARCHAR | VARCHAR | TEXT | VARCHAR | |
| TINYTEXT | TINYTEXT | TEXT | TEXT | |
| TEXT | TEXT | TEXT | TEXT | |
| MEDIUMTEXT | MEDIUMTEXT | TEXT | TEXT | |
| LONGTEXT | LONGTEXT | TEXT | TEXT | |
| |
| BINARY | BINARY | BLOB | BYTEA | |
| VARBINARY | VARBINARY | BLOB | BYTEA | |
| |
| DATE | DATE | NUMERIC | DATE | |
| DATETIME | DATETIME | NUMERIC | TIMESTAMP | |
| TIME | TIME | NUMERIC | TIME | |
| TIMESTAMP | TIMESTAMP | NUMERIC | TIMESTAMP | |
| TIMESTAMPZ | TEXT | TEXT | TIMESTAMP with zone | timestamp with zone info |
| |
| REAL | REAL | REAL | REAL | |
| FLOAT | FLOAT | REAL | REAL | |
| DOUBLE | DOUBLE | REAL | DOUBLE PRECISION | |
| |
| DECIMAL | DECIMAL | NUMERIC | DECIMAL | |
| NUMERIC | NUMERIC | NUMERIC | NUMERIC | |
| |
| TINYBLOB | TINYBLOB | BLOB | BYTEA | |
| BLOB | BLOB | BLOB | BYTEA | |
| MEDIUMBLOB | MEDIUMBLOB | BLOB | BYTEA | |
| LONGBLOB | LONGBLOB | BLOB | BYTEA | |
| BYTEA | BLOB | BLOB | BYTEA | |
| |
| BOOL | TINYINT | INTEGER | BOOLEAN | |
| SERIAL | INT | INTEGER | SERIAL | auto increment |
| BIGSERIAL | BIGINT | INTEGER | BIGSERIAL | auto increment |