Golang实践录:xorm使用记录

xorm使用记录。主要针对 mysql,也会涉及其它的。

技术总结

提供通用接口,适用于多种数据库,隐藏细节。但需要手动添加数据库驱动(Golang 本身亦如是)。
可以用 Sync2 创建数据表,多次创建只提示警告,不会出错。要自行判断,或者额外创建好表,后续不再创建。
需要预先创建数据库,否则即使 Sync2 成功,也不会有数据表。
引入 xorm 包,再使用 sql 驱动,但使用下划线,表示只引入不使用包内函数。
xorm 的结构体成员要大写。

安装

1
2
3
4
5
6
7
8
9
10
go get github.com/go-xorm/xorm
go get github.com/go-xorm/core
go get github.com/go-xorm/cmd/xorm
// 似乎还有一个xorm.io,待写

驱动:
go get github.com/go-sql-driver/mysql // mysql
go get github.com/mattn/go-sqlite3 //SQLite
go get github.com/denisenkom/go-mssqldb // sqlserver
go get github.com/lunny/godbc // sqlserver

结构体与字段映射

常用方式:
SnakeMapper: 默认方式,驼峰命名,如 UserInfo -> user_info
SameMapper: 相同。UserInfo -> UserInfo
GonicMapper:在SnakeMapper的基础上增加了特例,ID -> id
PrefixMapper:前缀。
SuffixMapper:后续。

设置xorm的字段名称和数据库中的一样(包括表名、字段表)
engine.SetMapper(core.SameMapper{})

不建议做太复杂,选择一两种常用的即可。

示例1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
结构体:
type User struct {
Id int64 `xorm:"int(20) pk not null autoincr 'id'"`
Email string `xorm:"varchar(255) default null"`
First_name string `xorm:"varchar(255) default null"`
Last_name string `xorm:"varchar(255) default null"`
Username string `xorm:"varchar(255) default null"`
}
对应数据表:
mysql> desc user;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(20) | NO | PRI | NULL | auto_increment |
| email | varchar(255) | YES | | NULL | |
| first_name | varchar(255) | YES | | NULL | |
| last_name | varchar(255) | YES | | NULL | |
| username | varchar(255) | YES | | NULL | |
+------------+------------
注:结构体名即为表名,表名为小写,字段按驼峰命名,变量加下划线,保留。


// 自定义部分字段,即所有字段小写,无下划线
type User2 struct {
Id int64 `xorm:"int(20) pk not null autoincr"`
Email string `xorm:"varchar(255) default null"`
First_name string `xorm:"varchar(255) default null 'firstname'"`
Last_name string `xorm:"varchar(255) default null 'lastname'"`
Username string `xorm:"varchar(255) default null 'username'"`
}
mysql> desc user2;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(20) | NO | PRI | NULL | auto_increment |
| email | varchar(255) | YES | | NULL | |
| firstname | varchar(255) | YES | | NULL | |
| lastname | varchar(255) | YES | | NULL | |
| username | varchar(255) | YES | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
注:接上,但在变量中设置了字段名称,变量有下划线,但字段没有。


// 保存完全一致
type User3 struct {
Id int64 `xorm:"int(20) pk not null autoincr"`
Email string `xorm:"varchar(255) default null"`
First_name string `xorm:"varchar(255) default null"`
Last_name string `xorm:"varchar(255) default null"`
Username string `xorm:"varchar(255) default null"`
}
代码:engine.SetMapper(core.SameMapper{})
mysql> desc User3;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| Id | int(20) | NO | PRI | NULL | auto_increment |
| Email | varchar(255) | YES | | NULL | |
| First_name | varchar(255) | YES | | NULL | |
| Last_name | varchar(255) | YES | | NULL | |
| Username | varchar(255) | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+

注:表名和字段名完全一致。

反向导出结构体

1
go get github.com/go-xorm/cmd/xorm

会自动安装到 Golang 的 bin 目录,在命令行直接输入 xorm 即可。

1
2
3
4
xorm reverse mysql name:password@(ip:port)/xxx?charset=utf8 ./templates/goxorm/
windows 示例:
xorm reverse mysql root:root@\(172.18.18.18:3305\)/mydb?charset=utf8 ./templates/goxorm/
注:templates是指$GOPATH/src/github.com/go-xorm/cmd/xorm/templates

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE TABLE `userc` (
`信息id` bigint(20) NOT NULL AUTO_INCREMENT,
`邮箱地址` varchar(255) DEFAULT NULL,
`名` varchar(255) DEFAULT NULL,
`姓` varchar(255) DEFAULT NULL,
`姓名` varchar(255) DEFAULT NULL,
PRIMARY KEY (`信息id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

转换后:
type Userc struct {
true信息id int64 `xorm:"not null pk autoincr BIGINT(20)"`
true邮箱地址 string `xorm:"VARCHAR(255)"`
true名 string `xorm:"VARCHAR(255)"`
true姓 string `xorm:"VARCHAR(255)"`
true姓名 string `xorm:"VARCHAR(255)"`
}

数据库的中文

测试中文

1
2
3
4
5
6
7
8
9
type 学生信息表 struct {
true信息id int64 `xorm:"not null pk autoincr BIGINT(20)"`
true邮箱地址 string `xorm:"VARCHAR(255)"`
true名 string `xorm:"VARCHAR(255)"`
true姓 string `xorm:"VARCHAR(255)"`
true姓名 string `xorm:"VARCHAR(255)"`
}
engine.SetMapper(core.SameMapper{})
engine.Sync2(new(学生信息表))

结论:可以使用中文变量,但查询数据,会出错,故还是按英文进行

所遇问题

,如果有小写,会提示:

1
panic: reflect.Value.Interface: cannot return value obtained from unexported field or method

可以用单引号指定特定名称。

遇到空值:

1
Scan failed: sql: Scan error on column index 26, name "姓名": converting driver.Value type string ("NULL") to a float32: invalid syntax