xorm 快速入门 ===== * [1.创建Orm引擎](#10) * [2.定义表结构体](#20) * [2.1.名称映射规则](#21) * [2.2.前缀映射,后缀映射和缓存映射](#22) * [2.3.使用Table和Tag改变名称映射](#23) * [2.4.Column属性定义](#24) * [2.5.Go与字段类型对应表](#25) * [3.表结构操作](#30) * [3.1 获取数据库信息](#31) * [3.2 表操作](#32) * [3.3 创建索引和唯一索引](#33) * [3.4 同步数据库结构](#34) * [4.插入数据](#50) * [5.查询和统计数据](#60) * [5.1.查询条件方法](#61) * [5.2.临时开关方法](#62) * [5.3.Get方法](#63) * [5.4.Find方法](#64) * [5.5.Iterate方法](#65) * [5.6.Count方法](#66) * [5.7.Rows方法](#67) * [6.更新数据](#70) * [6.1.乐观锁](#71) * [7.删除数据](#80) * [8.执行SQL查询](#90) * [9.执行SQL命令](#100) * [10.事务处理](#110) * [11.缓存](#120) * [12.事件](#125) * [13.xorm工具](#130) * [13.1.反转命令](#131) * [14.Examples](#140) * [15.案例](#150) * [16.那些年我们踩过的坑](#160) * [17.讨论](#170) ## 1.创建Orm引擎 在xorm里面,可以同时存在多个Orm引擎,一个Orm引擎称为Engine。因此在使用前必须调用NewEngine,如: ```Go import ( _ "github.com/go-sql-driver/mysql" "github.com/go-xorm/xorm" ) engine, err := xorm.NewEngine("mysql", "root:123@/test?charset=utf8") defer engine.Close() ``` or ```Go import ( _ "github.com/mattn/go-sqlite3" "github.com/go-xorm/xorm" ) engine, err = xorm.NewEngine("sqlite3", "./test.db") defer engine.Close() ``` 一般如果只针对一个数据库进行操作,只需要创建一个Engine即可。Engine支持在多GoRutine下使用。 xorm当前支持五种驱动四个数据库如下: <<<<<<< HEAD ======= * Mysql: [github.com/Go-SQL-Driver/MySQL](https://github.com/Go-SQL-Driver/MySQL) >>>>>>> master * MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv) * SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) * Postgres: [github.com/lib/pq](https://github.com/lib/pq) * MsSql: [github.com/lunny/godbc](https://githubcom/lunny/godbc) NewEngine传入的参数和`sql.Open`传入的参数完全相同,因此,使用哪个驱动前,请查看此驱动中关于传入参数的说明文档。 在engine创建完成后可以进行一些设置,如: 1.错误显示设置,默认如下均为`false` * `engine.ShowSQL = true`,则会在控制台打印出生成的SQL语句; * `engine.ShowDebug = true`,则会在控制台打印调试信息; * `engine.ShowError = true`,则会在控制台打印错误信息; * `engine.ShowWarn = true`,则会在控制台打印警告信息; 2.如果希望用其它方式记录,则可以`engine.Logger`赋值为一个`io.Writer`的实现。比如记录到Log文件,则可以: ```Go f, err := os.Create("sql.log") if err != nil { println(err.Error()) return } engine.Logger = f ``` ## 2.定义表结构体 xorm支持将一个struct映射为数据库中对应的一张表。映射规则如下: ### 2.1.名称映射规则 名称映射规则主要负责结构体名称到表名和结构体field到表字段的名称映射。由xorm.IMapper接口的实现者来管理,xorm内置了两种IMapper实现:`SnakeMapper` 和 `SameMapper`。SnakeMapper支持struct为驼峰式命名,表结构为下划线命名之间的转换;SameMapper支持结构体名称和对应的表名称以及结构体field名称与对应的表字段名称相同的命名。 当前SnakeMapper为默认值,如果需要改变时,在engine创建完成后使用 ```Go engine.SetMapper(SameMapper{}) ``` 同时需要注意的是: <<<<<<< HEAD * 如果你使用了别的命名规则映射方案,也可以自己实现一个IMapper。 * 表名称和字段名称的映射规则默认是相同的,当然也可以设置为不同,如: ======= * 如果你使用了别的命名规则映射方案,也可以自己实现一个IMapper。 * 表名称和字段名称的映射规则默认是相同的,当然也可以设置为不同,如: >>>>>>> master ```Go engine.SetTableMapper(SameMapper{}) engine.SetColumnMapper(SnakeMapper{}) ``` ### 2.2.前缀映射,后缀映射和缓存映射 * 通过`engine.NewPrefixMapper(SnakeMapper{}, "prefix")`可以在SnakeMapper的基础上在命名中添加统一的前缀,当然也可以把SnakeMapper{}换成SameMapper或者你自定义的Mapper。 * 通过`engine.NewSufffixMapper(SnakeMapper{}, "suffix")`可以在SnakeMapper的基础上在命名中添加统一的后缀,当然也可以把SnakeMapper{}换成SameMapper或者你自定义的Mapper。 <<<<<<< HEAD * ======= * 通过`eneing.NewCacheMapper(SnakeMapper{})`可以组合其它的映射规则,起到在内存中缓存曾经映射过的命名映射。 >>>>>>> master ### 2.3.使用Table和Tag改变名称映射 如果所有的命名都是按照IMapper的映射来操作的,那当然是最理想的。但是如果碰到某个表名或者某个字段名跟映射规则不匹配时,我们就需要别的机制来改变。 * 如果struct拥有`Tablename() string`的成员方法,那么此方法的返回值即是该struct默认对应的数据库表名。 * 通过`engine.Table()`方法可以改变struct对应的数据库表的名称,通过sturct中field对应的Tag中使用`xorm:"'column_name'"`可以使该field对应的Column名称为指定名称。这里使用两个单引号将Column名称括起来是为了防止名称冲突,因为我们在Tag中还可以对这个Column进行更多的定义。如果名称不冲突的情况,单引号也可以不使用。 ### 2.4.Column属性定义 我们在field对应的Tag中对Column的一些属性进行定义,定义的方法基本和我们写SQL定义表结构类似,比如: ``` type User struct { Id int64 Name string `xorm:"varchar(25) not null unique 'usr_name'"` } ``` 对于不同的数据库系统,数据类型其实是有些差异的。因此xorm中对数据类型有自己的定义,基本的原则是尽量兼容各种数据库的字段类型,具体的字段对应关系可以查看[字段类型对应表](https://github.com/go-xorm/xorm/blob/master/docs/COLUMNTYPE.md)。对于使用者,一般只要使用自己熟悉的数据库字段定义即可。 具体的映射规则如下,另Tag中的关键字均不区分大小写,字段名区分大小写:
name | 当前field对应的字段的名称,可选,如不写,则自动根据field名字和转换规则命名,如与其它关键字冲突,请使用单引号括起来。 |
pk | 是否是Primary Key,如果在一个struct中有多个字段都使用了此标记,则这多个字段构成了复合主键,单主键当前支持int32,int,int64,uint32,uint,uint64,string这7种Go的数据类型,复合主键支持这7种Go的数据类型的组合。 |
当前支持30多种字段类型,详情参见 [字段类型](https://github.com/go-xorm/xorm/blob/master/docs/COLUMNTYPE.md) | 字段类型 |
autoincr | 是否是自增 |
[not ]null 或 notnull | 是否可以为空 |
unique或unique(uniquename) | 是否是唯一,如不加括号则该字段不允许重复;如加上括号,则括号中为联合唯一索引的名字,此时如果有另外一个或多个字段和本unique的uniquename相同,则这些uniquename相同的字段组成联合唯一索引 |
index或index(indexname) | 是否是索引,如不加括号则该字段自身为索引,如加上括号,则括号中为联合索引的名字,此时如果有另外一个或多个字段和本index的indexname相同,则这些indexname相同的字段组成联合索引 |
extends | 应用于一个匿名结构体之上,表示此匿名结构体的成员也映射到数据库中 |
- | 这个Field将不进行字段映射 |
-> | 这个Field将只写入到数据库而不从数据库读取 |
<- | 这个Field将只从数据库读取,而不写入到数据库 |
created | 这个Field将在Insert时自动赋值为当前时间 |
updated | 这个Field将在Insert或Update时自动赋值为当前时间 |
version | 这个Field将会在insert时默认为1,每次更新自动加1 |
default 0 | 设置默认值,紧跟的内容如果是Varchar等需要加上单引号 |