//Install Library go get github.com/go-xorm/xorm //Xorm 命令行工具 go get github.com/go-xorm/cmd/xorm
// 数据库驱动 go get github.com/mattn/go-sqlite3 go get -u github.com/go-sql-driver/mysql
https://github.com/mattn/go-sqlite3 https://github.com/go-sql-driver/mysql
使用 xorm 命令行工具 sqlite3 先要编译一下 xorm
cd to %GOPATH%/src/github.com/go-xorm/cmd/xorm
run “go build -tags sqlite3”
a new “xorm” will be generated at current dir
copy the new “xorm” to %GOPATH%/bin
run your “xorm reverse …” again. Done!
xorm reverse sqlite3 test.db templates/goxorm
名称映射规则 xorm内置了三种IMapper实现:core.SnakeMapper,core.SameMapper和core.GonicMapper SnakeMapper支持struct为驼峰式命名,表结构为下划线命名之间的转换; SameMapper支持结构体名称和对应的表名称以及结构体field名称与对应的表字段名称相同的命名
engine.SetMapper(core.SnakeMapper{})
| name | 当前field对应的字段的名称 | | — | — | — | | pk | 是否是Primary Key | | name | 当前field对应的字段的名称 | | autoincr | 是否是自增 | | [not ]null 或 notnull | 是否可以为空 | | unique | 是否是唯一 | | index | 是否是索引 | | 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格式 |
连接数据库 import ( _ "github.com/mattn/go-sqlite3" "github.com/go-xorm/xorm" ) var engine *xorm.Enginefunc main () { var err error engine, err = xorm.NewEngine("sqlite3" , "./test.db" ) }
import ( _ "github.com/go-sql-driver/mysql" "github.com/go-xorm/xorm" ) var engine *xorm.Enginefunc main () { var err error engine, err = xorm.NewEngine("mysql" , "root:123@/test?charset=utf8" ) }
自动同步表结构 ync2会进行如下这些操作:
自动检测和创建表,这个检测是根据表的名字 自动检测和新增表中的字段,这个检测是根据字段名,同时对表中多余的字段给出警告信息 自动检测,创建和删除索引和唯一索引,这个检测是根据索引的一个或多个字段名,而不根据索引名称。因此这里需要注意,如果在一个有大量数据的表中引入新的索引,数据库可能需要一定的时间来建立索引。 自动转换varchar字段类型到text字段类型,自动警告其它字段类型在模型和数据库之间不一致的情况。 自动警告字段的默认值,是否为空信息在模型和数据库之间不匹配的情况
if err = x.Sync2(new (Account)); err != nil { log.Fatalf("Fail to sync database: %v\n" , err) }
查询 results, err := engine.Query("select * from user" ) type T_user struct { F_id int64 `xorm:"not null pk autoincr INT(11)"` F_ui_id int64 `xorm:"INT(11)"` F_group_id int64 `xorm:" INT(11)"` F_pwd string `xorm:"not null VARCHAR(32)"` F_name string `xorm:"not null VARCHAR(32)"` } user := &T_user{F_name: "admin" , F_pwd: "4acb4bc224acbbe3c2bfdcaa39a4324e" } has, err := engine.Get(user) fmt.Println(has) user := new (User) has, err := engine.Table("t_user" ).Where("f_name=? and f_pwd=?" , "admin" , "4acb4bc224acbbe3c2bfdcaa39a4324e" ).Get(user) fmt.Println(has) user := new (T_user) has, err := engine.Where("f_name=? and f_pwd=?" , "admin" , "4acb4bc224acbbe3c2bfdcaa39a4324e" ).Get(user) fmt.Println(has) 返回的结果为两个参数,一个has(bool 类型)为该条记录是否存在,第二个参数err为是否有错误。不管err是否为nil ,has都有可能为true 或者false 。
根据Id来获得单条数据 has, err := x.Id(id).Get(a)
逐条执行查询到的记录 Iterate方法提供逐条执行查询到的记录的方法,他所能使用的条件和Find方法完全相同
err := x.Where("id > ?=)" , 30 ).Iterate(new (Account), func (i int , bean interface {}) error { user := bean.(*Account) })
我们主要来看迭代函数的声明:它接受 2 个参数,第一个是当前记录所对应的索引(该索引和 ID 的值毫无关系,只是查询后结果的索引),第二个参数则是保存了相关类型的空接口,需要自行断言,例如示例中使用 bean.(*Account) 因为我们知道查询的结构是 Account。
查询特定字段 使用 Cols 方法可以指定查询特定字段,当只有结构中的某个字段的值对您有价值时,就可以使用它:
x.Cols("name" ).Iterate(new (Account), printFn) var printFn = func (idx int , bean interface {}) error { return nil }
此处,所查询出来的结构只有 Name 字段有值,其它字段均为零值。要注意的是,Cols 方法所接受的参数是数据表中对应的名称,而不是字段名称。
统计记录条数- Count方法 统计数据使用Count方法,Count方法的参数为struct的指针并且成为查询条件。
a := new (Account) total, err := x.Where("id >?" , 1 ).Count(a) total,err = x.Count(a)
更新 affected, err := engine.Exec("update user set .... where ..." ) a.Balance += deposit _, err = x.Update(a)
删除 方法 Delete 接受参数后,会自动根据传进去的值进行查找,然后删除。比如此处,我们指定了 Account 的 ID 字段,那么就会删除 ID 字段值与我们所赋值相同的记录;如果您只对 Name 字段赋值,那么 xorm 就会去查找 Name 字段值匹配的记录。如果多个字段同时赋值,则是多个条件同时满足的记录才会被删除。
删除操作针对的对象没有限制,凡是按照条件查找到的,都会被删除(单个与批量删除)。
_, err := x.Delete(&Account{Id: id}) if _, err := session.Exec("delete from userinfo where username = ?" , user2.Username); err != nil { return err }
事务及回滚 sess := x.NewSession() defer sess.Close()if err = sess.Begin(); err != nil { return err } if _, err = sess.Update(a1); err != nil { sess.Rollback() return err } return sess.Commit()
日志记录 一般情况下,使用x.ShowSQL = true来开启 xorm 最基本的日志功能,所有 SQL 都会被打印到控制台,但如果您想要将日志保存到文件,则可以在获取到 ORM 引擎之后,进行如下操作:
f, err := os.Create("sql.log" ) if err != nil { log.Fatalf("Fail to create log file: %v\n" , err) return } x.Logger = xorm.NewSimpleLogger(f)
LRU 缓存 只需要在获取到 ORM 引擎之后,进行如下操作 这样就算是使用最基本的缓存功能了。该功能还支持只缓存某些表或排除缓存某些表,详情可以参见 文章首部的官方文档。
cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), 1000 ) x.SetDefaultCacher(cacher)
表操作 是否存在 { exists, _ := engine.IsTableExist(&tOpLog{}) fmt.Println(exists) } { exists, _ := engine.IsTableExist("t_123123" ) fmt.Println(exists) }
创建表自定义表名 type User struct { ID int `xorm:"serial primary key 'id'"` Name string `xorm:"text not null 'name'"` Type string `xorm:"text not null 'type'"` } func (u *User) TableName () string { return "users" } db, err := xorm.NewEngine("postgres" , "postgres://db_admin:db_admin@db/sample_db?sslmode=disable" ) db.CreateTables(&User{})