Xorm Column属性定义

我们在 field 对应的 Tag 中,对 Column 一些属性进行了定义,定义的方法类似于定义表结构的 SQL 语句,比如:

type User struct {
    Id   int64
    Name string  `xorm:"varchar(25) notnull unique 'usr_name' comment('姓名')"`
}

对于不同的数据库系统,数据类型其实是有些差异的。因此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或default(0)设置默认值,紧跟的内容如果是Varchar等需要加上单引号
json表示内容将先转成Json格式,然后存储到数据库中,数据库中的字段类型可以为Text或者二进制
comment设置字段的注释(当前仅支持mysql)

另外有如下几条自动映射的规则:

  • 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

下表为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

Go与字段类型对应表:如果我们不使用 tag 来定义 field 对应的数据库字段类型,那么系统会自动给出一个默认的字段类型,对应表如下:go类型值方法xorm类型 implemented Conversion Conversion.ToD ...