some improvements
This commit is contained in:
@@ -34,6 +34,8 @@ func main() { | ||||
| ||||
一般情况下如果只操作一个数据库,只需要创建一个Engine即可。Engine是GoRutine安全的。 | ||||
| ||||
创建完成`engine`之后,并没有立即连接数据库,此时可以通过`engine.Ping()`来进行数据库的连接测试是否可以连接到数据库。另外对于某些数据库有连接超时设置的,可以通过起一个定期Ping的Go程来保持连接鲜活。 | ||||
| ||||
对于有大量数据并且需要分区的应用,也可以根据规则来创建多个Engine,比如: | ||||
| ||||
```Go | ||||
@@ -72,6 +74,7 @@ f, err := os.Create("sql.log") | ||||
println(err.Error()) | ||||
return | ||||
} | ||||
defer f.Close() | ||||
engine.Logger = xorm.NewSimpleLogger(f) | ||||
``` | ||||
| ||||
| ||||
@@ -1,6 +1,6 @@ | ||||
### 名称映射规则 | ||||
| ||||
名称映射规则主要负责结构体名称到表名和结构体field到表字段的名称映射。由xorm.IMapper接口的实现者来管理,xorm内置了两种IMapper实现:`SnakeMapper` 和 `SameMapper`。SnakeMapper支持struct为驼峰式命名,表结构为下划线命名之间的转换;SameMapper支持结构体名称和对应的表名称以及结构体field名称与对应的表字段名称相同的命名。 | ||||
名称映射规则主要负责结构体名称到表名和结构体field到表字段的名称映射。由core.IMapper接口的实现者来管理,xorm内置了两种IMapper实现:`SnakeMapper` 和 `SameMapper`。SnakeMapper支持struct为驼峰式命名,表结构为下划线命名之间的转换;SameMapper支持结构体名称和对应的表名称以及结构体field名称与对应的表字段名称相同的命名。 | ||||
| ||||
当前SnakeMapper为默认值,如果需要改变时,在engine创建完成后使用 | ||||
| ||||
| ||||
@@ -1,16 +1,16 @@ | ||||
### 前缀映射,后缀映射和缓存映射 | ||||
| ||||
* 通过 `engine.NewPrefixMapper(SnakeMapper{}, "prefix")` 可以创建一个在SnakeMapper的基础上在命名中添加统一的前缀,当然也可以把SnakeMapper{}换成SameMapper或者你自定义的Mapper。 | ||||
* 通过 `core.NewPrefixMapper(core.SnakeMapper{}, "prefix")` 可以创建一个在SnakeMapper的基础上在命名中添加统一的前缀,当然也可以把SnakeMapper{}换成SameMapper或者你自定义的Mapper。 | ||||
| ||||
* 通过 `engine.NewSufffixMapper(SnakeMapper{}, "suffix")` 可以创建一个在SnakeMapper的基础上在命名中添加统一的后缀,当然也可以把SnakeMapper换成SameMapper或者你自定义的Mapper。 | ||||
* 通过 `core.NewSufffixMapper(core.SnakeMapper{}, "suffix")` 可以创建一个在SnakeMapper的基础上在命名中添加统一的后缀,当然也可以把SnakeMapper换成SameMapper或者你自定义的Mapper。 | ||||
| ||||
* 通过 `engine.NewCacheMapper(SnakeMapper{})` 可以创建一个组合了其它的映射规则,起到在内存中缓存曾经映射过的命名映射。 | ||||
* 通过 `core.NewCacheMapper(core.SnakeMapper{})` 可以创建一个组合了其它的映射规则,起到在内存中缓存曾经映射过的命名映射。 | ||||
| ||||
例如,如果希望所有的表名都在结构体自动命名的基础上加一个前缀而字段名不加前缀,则可以在engine创建完成后执行以下语句: | ||||
| ||||
```Go | ||||
tbMapper := engine.NewPrefixMapper(SnakeMapper{}, "prefix") | ||||
tbMapper := core.NewPrefixMapper(core.SnakeMapper{}, "prefix") | ||||
engine.SetTableMapper(tbMapper) | ||||
``` | ||||
| ||||
执行之后,结构体 `type User struct` 默认对应的表名就变成了 `prefix_user` 了,而默认是 `user` | ||||
执行之后,结构体 `type User struct` 默认对应的表名就变成了 `prefix_user` 了,而之前默认的是 `user` | ||||
@@ -1,12 +1,12 @@ | ||||
### 使用Table和Tag改变名称映射 | ||||
| ||||
如果所有的命名都是按照IMapper的映射来操作的,那当然是最理想的。但是如果碰到某个表名或者某个字段名跟映射规则不匹配时,我们就需要别的机制来改变。 | ||||
如果所有的命名都是按照IMapper的映射来操作的,那当然是最理想的。但是如果碰到某个表名或者某个字段名跟映射规则不匹配时,我们就需要别的机制来改变。xorm提供了如下几种方式来进行: | ||||
| ||||
* 如果结构体拥有`TableName() string`的成员方法,那么此方法的返回值即是该结构体对应的数据库表名。 | ||||
| ||||
* 通过`engine.Table()`方法可以改变struct对应的数据库表的名称,通过sturct中field对应的Tag中使用`xorm:"'column_name'"`可以使该field对应的Column名称为指定名称。这里使用两个单引号将Column名称括起来是为了防止名称冲突,因为我们在Tag中还可以对这个Column进行更多的定义。如果名称不冲突的情况,单引号也可以不使用。 | ||||
| ||||
到此名称映射的所有方法都给出了,一共三种方式,那么这三种是有优先级顺序的。 | ||||
到此名称映射的所有方法都给出了,一共三种方式,这三种是有优先级顺序的。 | ||||
| ||||
* 表名的优先级顺序如下: | ||||
| ||||
| ||||
@@ -4,7 +4,7 @@ | ||||
``` | ||||
type User struct { | ||||
Id int64 | ||||
Name string `xorm:"varchar(25) not null unique 'usr_name'"` | ||||
Name string `xorm:"varchar(25) notnull unique 'usr_name'"` | ||||
} | ||||
``` | ||||
| ||||
@@ -35,7 +35,7 @@ type User struct { | ||||
<td>index或index(indexname)</td><td>是否是索引,如不加括号则该字段自身为索引,如加上括号,则括号中为联合索引的名字,此时如果有另外一个或多个字段和本index的indexname相同,则这些indexname相同的字段组成联合索引</td> | ||||
</tr> | ||||
<tr> | ||||
<td>extends</td><td>应用于一个匿名结构体之上,表示此匿名结构体的成员也映射到数据库中</td> | ||||
<td>extends</td><td>应用于一个匿名成员结构体或者非匿名成员结构体之上,表示此结构体的所有成员也映射到数据库中,不过extends只加载一级深度</td> | ||||
</tr> | ||||
<tr> | ||||
<td>-</td><td>这个Field将不进行字段映射</td> | ||||
@@ -51,6 +51,9 @@ type User struct { | ||||
</tr> | ||||
<tr> | ||||
<td>updated</td><td>这个Field将在Insert或Update时自动赋值为当前时间</td> | ||||
</tr> | ||||
<tr> | ||||
<td>deleted</td><td>这个Field将在Delete时设置为当前时间,并且当前记录不删除</td> | ||||
</tr> | ||||
<tr> | ||||
<td>version</td><td>这个Field将会在insert时默认为1,每次更新自动加1</td> | ||||
@@ -64,9 +67,9 @@ type User struct { | ||||
| ||||
- 1.如果field名称为`Id`而且类型为`int64`并且没有定义tag,则会被xorm视为主键,并且拥有自增属性。如果想用`Id`以外的名字或非int64类型做为主键名,必须在对应的Tag上加上`xorm:"pk"`来定义主键,加上`xorm:"autoincr"`作为自增。这里需要注意的是,有些数据库并不允许非主键的自增属性。 | ||||
| ||||
- 2.string类型默认映射为varchar(255),如果需要不同的定义,可以在tag中自定义 | ||||
- 2.string类型默认映射为`varchar(255)`,如果需要不同的定义,可以在tag中自定义,如:`varchar(1024)` | ||||
| ||||
- 3.支持`type MyString string`等自定义的field,支持Slice, Map等field成员,这些成员默认存储为Text类型,并且默认将使用Json格式来序列化和反序列化。也支持数据库字段类型为Blob类型,如果是Blob类型,则先使用Json格式序列化再转成[]byte格式。当然[]byte或者[]uint8默认为Blob类型并且都以二进制方式存储。具体参见 [Go与字段类型对应表](chapter-02/5.types.md) | ||||
- 3.支持`type MyString string`等自定义的field,支持Slice, Map等field成员,这些成员默认存储为Text类型,并且默认将使用Json格式来序列化和反序列化。也支持数据库字段类型为Blob类型。如果是Blob类型,则先使用Json格式序列化再转成[]byte格式。如果是[]byte或者[]uint8,则不做转换二十直接以二进制方式存储。具体参见 [Go与字段类型对应表](chapter-02/5.types.md) | ||||
| ||||
- 4.实现了Conversion接口的类型或者结构体,将根据接口的转换方式在类型和数据库记录之间进行相互转换,这个接口的优先级是最高的。 | ||||
```Go | ||||
@@ -78,6 +81,7 @@ type Conversion interface { | ||||
| ||||
- 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类型和各个数据库类型的对应表: | ||||
| ||||
<table> | ||||
<tr> | ||||
| ||||
@@ -2,9 +2,6 @@ | ||||
| ||||
如果不使用tag来定义field对应的数据库字段类型,那么系统会自动给出一个默认的字段类型,对应表如下: | ||||
| ||||
| ||||
When a struct auto mapping to a database's table, the below table describes how they change to each other: | ||||
| ||||
<table> | ||||
<tr> | ||||
<td>go type's kind | ||||
| ||||
@@ -4,6 +4,8 @@ | ||||
| ||||
* Sync | ||||
| ||||
Sync将进行如下的同步操作: | ||||
| ||||
* 自动检测和创建表,这个检测是根据表的名字 | ||||
* 自动检测和新增表中的字段,这个检测是根据字段名 | ||||
* 自动检测和创建索引和唯一索引,这个检测是根据索引的一个或多个字段名,而不根据索引名称 | ||||
@@ -11,21 +13,25 @@ | ||||
调用方法如下: | ||||
| ||||
```Go | ||||
err := engine.Sync(new(User)) | ||||
err := engine.Sync(new(User), new(Group)) | ||||
``` | ||||
| ||||
* Sync2对Sync进行了改进,目前推荐使用Sync2。 | ||||
* Sync2 | ||||
| ||||
Sync2对Sync进行了改进,目前推荐使用Sync2。Sync2函数将进行如下的同步操作: | ||||
| ||||
* 自动检测和创建表,这个检测是根据表的名字 | ||||
* 自动检测和新增表中的字段,这个检测是根据字段名,同时对表中多余的字段给出警告信息 | ||||
* 自动检测,创建,和删除索引和唯一索引,这个检测是根据索引的一个或多个字段名,而不根据索引名称 | ||||
* 自动转换varchar字段类型到text字段类型,自动警告其它类型不一致的情况。 | ||||
* 自动检测,创建和删除索引和唯一索引,这个检测是根据索引的一个或多个字段名,而不根据索引名称。因此这里需要注意,如果在一个有大量数据的表中引入新的索引,数据库可能需要一定的时间来建立索引。 | ||||
* 自动转换varchar字段类型到text字段类型,自动警告其它字段类型在模型和数据库之间不一致的情况。 | ||||
* 自动警告字段的默认值,是否为空信息在模型和数据库之间不匹配的情况 | ||||
| ||||
以上这些警告信息需要将`engine.ShowWarn` 设置为 `true`。调用方法和Sync一样: | ||||
以上这些警告信息需要将`engine.ShowWarn` 设置为 `true` 才会显示。 | ||||
| ||||
调用方法和Sync一样: | ||||
| ||||
```Go | ||||
err := engine.Sync2(new(User)) | ||||
err := engine.Sync2(new(User), new(Group)) | ||||
``` | ||||
| ||||
| ||||
| ||||
@@ -18,4 +18,6 @@ DumpAll方法接收一个io.Writer接口来保存Dump出的数据库结构和数 | ||||
| ||||
和 | ||||
| ||||
`engine.ImportFile(fpath string)` | ||||
`engine.ImportFile(fpath string)` | ||||
| ||||
同样,这里需要对应的数据库的SQL语法支持。 | ||||
@@ -1,3 +1,5 @@ | ||||
## 表结构操作 | ||||
| ||||
xorm提供了一些动态获取和修改表结构的方法,通过这些方法可以动态同步数据库结构,导出数据库结构,导入数据库结构。如果您只是需要一个工具,可以直接使用`go install github.com/go-xorm/cmd/xorm`来安装xorm命令。 | ||||
xorm提供了一些动态获取和修改表结构的方法,通过这些方法可以动态同步数据库结构,导出数据库结构,导入数据库结构。 | ||||
| ||||
如果您只是需要一个工具,可以直接使用`go get github.com/go-xorm/cmd/xorm`来安装xorm命令行工具。 | ||||
@@ -80,5 +80,5 @@ affected, err := engine.Insert(user, &questions) | ||||
``` | ||||
| ||||
这里需要注意以下几点: | ||||
* 这里虽然支持同时插入,但这些插入并没有事务关系。因此有可能在中间插入出错后,后面的插入将不会继续。 | ||||
* 这里虽然支持同时插入,但这些插入并没有事务关系。因此有可能在中间插入出错后,后面的插入将不会继续。此时前面的插入已经成功,如果需要回滚,请开启事物。 | ||||
* 批量插入会自动生成`Insert into table values (),(),()`的语句,因此各个数据库对SQL语句有长度限制,因此这样的语句有一个最大的记录数,根据经验测算在150条左右。大于150条后,生成的sql语句将太长可能导致执行失败。因此在插入大量数据时,目前需要自行分割成每150条插入一次。 | ||||
@@ -3,8 +3,9 @@ | ||||
查询和统计主要使用`Get`, `Find`, `Count`, `Rows`, `Iterate`这几个方法。在进行查询时可以使用多个方法来形成查询条件,条件函数如下: | ||||
| ||||
* Id(interface{}) | ||||
传入一个PK字段的值,作为查询条件,如 | ||||
传入一个主键字段的值,作为查询条件,如 | ||||
```Go | ||||
var user User | ||||
engine.Id(1).Get(&user) | ||||
// SELECT * FROM user Where id = 1 | ||||
``` | ||||
| ||||
Reference in New Issue
Block a user