### 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 |