xorm/README.md

419 lines
11 KiB
Markdown
Raw Normal View History

2013-05-06 08:01:17 +00:00
# xorm
2013-05-03 07:26:51 +00:00
2013-05-12 05:43:09 +00:00
[中文](https://github.com/lunny/xorm/blob/master/README_CN.md)
2013-05-03 07:26:51 +00:00
2013-08-16 04:22:34 +00:00
xorm is a simple and powerful ORM for Go. It makes dabatabse operating simple.
2013-10-09 07:08:52 +00:00
[![Build Status](https://drone.io/github.com/lunny/xorm/status.png)](https://drone.io/github.com/lunny/xorm/latest) [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/lunny/xorm) [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lunny/xorm/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
2013-09-11 08:30:17 +00:00
2013-09-29 14:39:59 +00:00
## Discuss
Message me on [G+](https://plus.google.com/u/0/106406879480103142585)
2013-08-16 04:22:34 +00:00
2013-06-08 04:47:28 +00:00
2013-05-11 10:38:43 +00:00
## Drivers Support
2013-08-16 04:22:34 +00:00
2013-05-11 10:38:43 +00:00
Drivers for Go's sql package which currently support database/sql includes:
2013-05-03 07:26:51 +00:00
2013-05-11 10:38:43 +00:00
* Mysql: [github.com/Go-SQL-Driver/MySQL](https://github.com/Go-SQL-Driver/MySQL)
2013-05-03 07:26:51 +00:00
2013-08-16 04:22:34 +00:00
* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv)
* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
2013-08-16 04:23:36 +00:00
* Postgres: [github.com/bylevel/pq](https://github.com/bylevel/pq)
2013-08-16 04:22:34 +00:00
## Changelog
2013-08-16 04:22:34 +00:00
2013-09-29 08:53:01 +00:00
* **v0.2.0** : Added Cache supported, select is speeder up 3~5x; Added SameMapper for same name between struct and table; Added Sync method for auto added tables, columns, indexes;
2013-08-16 04:22:34 +00:00
* **v0.1.9** : Added postgres and mymysql supported; Added ` and ? supported on Raw SQL even if postgres; Added Cols, StoreEngine, Charset function, Added many column data type supported, please see [Mapping Rules](#mapping).
* **v0.1.8** : Added union index and union unique supported, please see [Mapping Rules](#mapping).
* **v0.1.7** : Added IConnectPool interface and NoneConnectPool, SysConnectPool, SimpleConnectPool the three implements. You can choose one of them and the default is SysConnectPool. You can customrize your own connection pool. struct Engine added Close method, It should be invoked before system exit.
* **v0.1.6** : Added conversion interface support; added struct derive support; added single mapping support
* **v0.1.5** : Added multi threads support; added Sql() function for struct query; Get function changed return inteface; MakeSession and Create are instead with NewSession and NewEngine.
* **v0.1.4** : Added simple cascade load support; added more data type supports.
* **v0.1.3** : Find function now supports both slice and map; Add Table function for multi tables and temperory tables support
* **v0.1.2** : Insert function now supports both struct and slice pointer parameters, batch inserting and auto transaction
* **v0.1.1** : Add Id, In functions and improved README
* **v0.1.0** : Inital release.
## Features
* Struct<->Table Mapping Supports, both name mapping and filed tags mapping
* Database Transaction Support
* Both ORM and SQL Operation Support
* Simply usage
* Support Id, In, Where, Limit, Join, Having, Sql functions and sturct as query conditions
* Support simple cascade load just like Hibernate for Java
2013-05-03 07:26:51 +00:00
2013-08-16 04:22:34 +00:00
## Installing xorm
2013-05-06 08:01:17 +00:00
go get github.com/lunny/xorm
2013-05-03 07:26:51 +00:00
2013-05-06 08:01:17 +00:00
## Quick Start
2013-05-03 07:26:51 +00:00
2013-08-16 04:22:34 +00:00
1.Create a database engine just like sql.Open, commonly you just need create once. Please notice, Create function will be deprecated, use NewEngine instead.
```Go
import (
_ "github.com/Go-SQL-Driver/MySQL"
"github.com/lunny/xorm"
2013-05-11 13:27:36 +00:00
)
2013-08-16 04:22:34 +00:00
engine, err := xorm.NewEngine("mysql", "root:123@/test?charset=utf8")
2013-07-03 04:46:56 +00:00
defer engine.Close()
2013-05-11 10:38:43 +00:00
```
2013-08-16 04:22:34 +00:00
or
```Go
import (
_ "github.com/mattn/go-sqlite3"
"github.com/lunny/xorm"
)
engine, err = xorm.NewEngine("sqlite3", "./test.db")
defer engine.Close()
```
1.1.If you want to show all generated SQL
```Go
engine.ShowSQL = true
```
1.2 If you want to use your own connection pool
```Go
err = engine.SetPool(NewSimpleConnectPool())
```
2013-05-03 07:26:51 +00:00
2013-05-11 10:38:43 +00:00
2.Define a struct
2013-08-16 04:22:34 +00:00
```Go
2013-08-16 04:22:34 +00:00
type User struct {
2013-05-11 13:27:36 +00:00
Id int
Name string
Age int `xorm:"-"`
2013-08-16 04:22:34 +00:00
}
```
2013-05-12 06:25:36 +00:00
2.1.More mapping rules, please see [Mapping Rules](#mapping)
2013-05-03 07:26:51 +00:00
2013-05-11 10:38:43 +00:00
3.When you set up your program, you can use CreateTables to create database tables.
2013-05-06 08:01:17 +00:00
```Go
2013-08-16 04:22:34 +00:00
err := engine.CreateTables(&User{})
// or err := engine.Map(&User{}, &Article{})
// err = engine.CreateAll()
2013-05-11 13:27:36 +00:00
```
2013-05-06 08:01:17 +00:00
2013-08-16 04:22:34 +00:00
4.then, insert a struct to table, if success, User.Id will be set to id
2013-05-06 08:01:17 +00:00
```Go
2013-08-16 04:22:34 +00:00
id, err := engine.Insert(&User{Name:"lunny"})
2013-05-11 13:27:36 +00:00
```
2013-05-03 07:26:51 +00:00
2013-05-11 10:38:43 +00:00
or if you want to update records
2013-08-16 04:22:34 +00:00
```Go
2013-05-11 13:27:36 +00:00
user := User{Name:"xlw"}
2013-08-16 04:22:34 +00:00
rows, err := engine.Update(&user, &User{Id:1})
// or rows, err := engine.Where("id = ?", 1).Update(&user)
// or rows, err := engine.Id(1).Update(&user)
2013-05-11 13:27:36 +00:00
```
2013-05-03 07:26:51 +00:00
2013-05-11 10:38:43 +00:00
5.Fetch a single object by user
2013-08-16 04:22:34 +00:00
```Go
2013-05-11 13:27:36 +00:00
var user = User{Id:27}
2013-08-16 04:22:34 +00:00
has, err := engine.Get(&user)
// or has, err := engine.Id(27).Get(&user)
2013-05-03 07:26:51 +00:00
2013-05-11 13:27:36 +00:00
var user = User{Name:"xlw"}
2013-08-16 04:22:34 +00:00
has, err := engine.Get(&user)
```
6.Fetch multipe objects into a slice or a map, use Find
```Go
2013-05-11 13:27:36 +00:00
var everyone []Userinfo
2013-08-16 04:22:34 +00:00
err := engine.Find(&everyone)
users := make(map[int64]Userinfo)
err := engine.Find(&users)
```
6.1 also you can use Where, Limit
```Go
2013-05-11 13:27:36 +00:00
var allusers []Userinfo
err := engine.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
2013-08-16 04:22:34 +00:00
```
6.2 or you can use a struct query
```Go
2013-05-11 13:27:36 +00:00
var tenusers []Userinfo
err := engine.Limit(10).Find(&tenusers, &Userinfo{Name:"xlw"}) //Get All Name="xlw" limit 10 offset 0
2013-08-16 04:22:34 +00:00
```
6.3 or In function
2013-05-08 13:42:22 +00:00
2013-08-16 04:22:34 +00:00
```Go
2013-05-11 13:27:36 +00:00
var tenusers []Userinfo
2013-08-16 04:22:34 +00:00
err := engine.In("id", 1, 3, 5).Find(&tenusers) //Get All id in (1, 3, 5)
```
6.4 The default will query all columns of a table. Use Cols function if you want to select some columns
```Go
var tenusers []Userinfo
2013-08-16 04:22:34 +00:00
err := engine.Cols("id", "name").Find(&tenusers) //Find only id and name
```
7.Delete
```Go
err := engine.Delete(&User{Id:1})
// or err := engine.Id(1).Delete(&User{})
```
8.Count
```Go
2013-05-11 13:27:36 +00:00
total, err := engine.Count(&User{Name:"xlw"})
2013-08-16 04:22:34 +00:00
```
9.Cache
```Go
cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), 1000)
engine.SetDefaultCacher(cacher)
```
2013-08-16 04:22:34 +00:00
## Execute SQL
Of course, SQL execution is also provided.
1.if select then use Query
```Go
sql := "select * from userinfo"
results, err := engine.Query(sql)
```
2.if insert, update or delete then use Exec
```Go
sql = "update userinfo set username=? where id=?"
2013-05-11 13:27:36 +00:00
res, err := engine.Exec(sql, "xiaolun", 1)
2013-08-16 04:22:34 +00:00
```
## Advanced Usage
2013-05-06 08:01:17 +00:00
2013-06-22 01:02:01 +00:00
for deep usage, you should create a session, this func will create a database connection immediatelly.Please notice, MakeSession will be deprecated last, use NewSession instead
2013-08-16 04:22:34 +00:00
```Go
2013-06-22 01:02:01 +00:00
session := engine.NewSession()
2013-05-11 13:27:36 +00:00
defer session.Close()
2013-06-22 01:02:01 +00:00
2013-05-11 13:27:36 +00:00
```
2013-05-03 07:26:51 +00:00
2013-05-03 07:41:50 +00:00
1.Fetch a single object by where
2013-08-16 04:22:34 +00:00
```Go
2013-05-11 13:27:36 +00:00
var user Userinfo
session.Where("id=?", 27).Get(&user)
2013-05-03 07:41:50 +00:00
2013-07-12 02:14:44 +00:00
var userJohn Userinfo
session.Where("name = ?", "john").Get(&userJohn) // more complex query
2013-05-03 07:26:51 +00:00
2013-07-12 02:14:44 +00:00
var userOldJohn Userinfo
session.Where("name = ? and age > ?", "john", 88).Get(&userOldJohn) // even more complex
2013-05-11 13:27:36 +00:00
```
2013-05-03 07:26:51 +00:00
2013-05-03 07:41:50 +00:00
2.Fetch multiple objects
2013-08-16 04:22:34 +00:00
```Go
2013-05-11 13:27:36 +00:00
var allusers []Userinfo
err := session.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
2013-05-03 07:26:51 +00:00
2013-05-11 13:27:36 +00:00
var tenusers []Userinfo
err := session.Limit(10).Find(&tenusers, &Userinfo{Name:"xlw"}) //Get All Name="xlw" limit 10 if omit offset the default is 0
2013-05-06 08:01:17 +00:00
2013-05-11 13:27:36 +00:00
var everyone []Userinfo
2013-08-16 04:22:34 +00:00
err := session.Find(&everyone)
```
3.Transaction
```Go
// add Begin() before any action
err := session.Begin()
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
_, err = session.Insert(&user1)
if err != nil {
session.Rollback()
return
}
user2 := Userinfo{Username: "yyy"}
_, err = session.Where("id = ?", 2).Update(&user2)
if err != nil {
session.Rollback()
return
}
_, err = session.Delete(&user2)
if err != nil {
session.Rollback()
return
}
// add Commit() after all actions
err = session.Commit()
if err != nil {
return
}
```
4.Mixed Transaction
```Go
// add Begin() before any action
err := session.Begin()
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
_, err = session.Insert(&user1)
if err != nil {
session.Rollback()
return
}
user2 := Userinfo{Username: "yyy"}
_, err = session.Where("id = ?", 2).Update(&user2)
if err != nil {
session.Rollback()
return
}
_, err = session.Exec("delete from userinfo where username = ?", user2.Username)
if err != nil {
session.Rollback()
return
}
// add Commit() after all actions
err = session.Commit()
if err != nil {
return
2013-05-11 13:27:36 +00:00
}
2013-08-16 04:22:34 +00:00
```
5.Derive mapping
Please see derive.go in examples folder.
2013-05-03 07:26:51 +00:00
2013-08-16 04:22:34 +00:00
## Mapping Rules
2013-05-12 06:25:36 +00:00
<a name="mapping" id="mapping"></a>
2013-05-11 10:38:43 +00:00
1.Struct and struct's fields name should be Pascal style, and the table and column's name default is SQL style.
2013-08-16 04:22:34 +00:00
For example:
2013-05-03 07:26:51 +00:00
2013-05-11 10:38:43 +00:00
The struct's Name 'UserInfo' will turn into the table name 'user_info', the same as the keyname. If the keyname is 'UserName' will turn into the select colum 'user_name'
2013-05-03 07:26:51 +00:00
2013-05-11 10:38:43 +00:00
2.If You want change the mapping rules, you have two methods. One is to implement your own Map struct interface according IMapper, you can find the interface in mapper.go and set it to engine.Mapper
2013-08-16 04:22:34 +00:00
Another is use field tag, field tag support the below keywords which split with space:
<table>
<tr>
<td>name</td><td>column name, if no this name, the name is auto generated according field name and mapper rule.</td>
</tr>
<tr>
<td>pk</td><td>the field is a primary key</td>
</tr>
<tr>
<td>more than 30 column type supported, please see [Column Type](https://github.com/lunny/xorm/blob/master/docs/COLUMNTYPE.md)</td><td>column type</td>
2013-08-16 04:22:34 +00:00
</tr>
<tr>
<td>autoincr</td><td>auto incrment</td>
</tr>
<tr>
<td>[not ]null</td><td>if column can be null value</td>
</tr>
<tr>
<td>unique or unique(uniquename)</td><td>unique or union unique as uniquename</td>
</tr>
<tr>
<td>index or index(indexname)</td><td>index or union index as indexname</td>
</tr>
<tr>
<td>extends</td><td>used in anonymous struct means mapping this struct's fields to table</td>
</tr>
<tr>
<td>-</td><td>this field is not map as a table column</td>
2013-09-27 02:30:34 +00:00
</tr>
<tr>
<td>-></td><td>this field only write to db and not read from db</td>
</tr>
<tr>
<td>&lt;-</td><td>this field only read from db and not write to db</td>
</tr>
<tr>
<td>created</td><td>this field will auto fill current time when insert</td>
</tr>
<tr>
<td>updated</td><td>this field will auto fill current time when update</td>
</tr>
<tr>
<td>default 0 or default 'abc'</td><td>default value, use single quote for string</td>
2013-08-16 04:22:34 +00:00
</tr>
</table>
For Example
```Go
type Userinfo struct {
Uid int `xorm:"id pk not null autoincr"`
Username string `xorm:"unique"`
Departname string
Alias string `xorm:"-"`
Created time.Time
}
```
3.For customize table name, use Table() function, for example:
```Go
// batch create tables
for i := 0; i < 10; i++ {
engine.Table(fmt.Sprintf("user_%v", i)).CreateTable(&Userinfo{})
}
// insert into table according id
user := Userinfo{Uid: 25, Username:"sslfs"}
engine.Table(fmt.Sprintf("user_%v", user.Uid % 10)).Insert(&user)
```
## Documents
Please visit [GoWalker](http://gowalker.org/github.com/lunny/xorm)
## FAQ
1.How the xorm tag use both with json?
Use space.
```Go
type User struct {
Name string `json:"name" xorm:"name"`
}
```
2013-05-03 07:26:51 +00:00
## LICENSE
BSD License
[http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/)