xorm/docs/en-US/intro/quick_start.md

676 lines
18 KiB
Markdown
Raw Normal View History

2014-09-11 10:03:03 +00:00
---
name: Quick Start
sort: 2
---
2014-04-17 09:08:21 +00:00
Quick Start
2013-09-11 08:23:10 +00:00
=====
2014-04-17 09:08:21 +00:00
* [1.Create ORM Engine](#10)
* [2.Define a struct](#20)
* [2.1.Name mapping rule](#21)
* [2.2.Use Table or Tag to change table or column name](#22)
* [2.3.Column define](#23)
* [3. database schema operation](#30)
* [3.1.Retrieve database schema infomation](#31)
* [3.2.Table Operation](#32)
* [3.3.Create indexes and uniques](#33)
* [3.4.Sync database schema](#34)
* [4.Insert records](#40)
* [5.Query and Count records](#60)
* [5.1.Query condition methods](#61)
* [5.2.Temporory methods](#62)
* [5.3.Get](#63)
* [5.4.Find](#64)
* [5.5.Iterate](#65)
* [5.6.Count](#66)
* [6.Update records](#70)
* [6.1.Optimistic Locking](#71)
* [7.Delete records](#80)
* [8.Execute SQL command](#90)
* [9.Execute SQL query](#100)
* [10.Transaction](#110)
* [11.Cache](#120)
* [13.Examples](#140)
2013-09-11 08:23:10 +00:00
<a name="10" id="10"></a>
2014-04-17 09:08:21 +00:00
## 1.Create ORM Engine
2013-09-11 08:23:10 +00:00
2014-04-17 09:08:21 +00:00
When using xorm, you can create multiple orm engines, an engine means a databse. So you can
2013-09-11 08:23:10 +00:00
```Go
2013-09-11 09:00:36 +00:00
import (
2013-10-21 14:23:45 +00:00
_ "github.com/go-sql-driver/mysql"
2014-04-11 09:16:43 +00:00
"github.com/go-xorm/xorm"
2014-03-12 15:23:01 +00:00
)
2013-09-11 09:00:36 +00:00
engine, err := xorm.NewEngine("mysql", "root:123@/test?charset=utf8")
defer engine.Close()
```
or
```Go
import (
_ "github.com/mattn/go-sqlite3"
2014-04-11 09:16:43 +00:00
"github.com/go-xorm/xorm"
2013-09-11 09:00:36 +00:00
)
2014-09-11 10:03:03 +00:00
engine, err = xorm.NewEngine("sqlite3", "./test.db")
2014-03-12 15:23:01 +00:00
defer engine.Close()
2013-09-11 08:23:10 +00:00
```
2014-05-02 00:48:51 +00:00
You can create many engines for different databases.Generally, you just need create only one engine. Engine supports run on go routines.
2013-09-11 08:23:10 +00:00
2014-04-17 09:08:21 +00:00
xorm supports four drivers now:
2013-09-11 08:23:10 +00:00
2014-03-12 15:23:01 +00:00
* Mysql: [github.com/Go-SQL-Driver/MySQL](https://github.com/Go-SQL-Driver/MySQL)
2014-09-11 14:39:28 +00:00
* MyMysql: [github.com/ziutek/mymysql](https://github.com/ziutek/mymysql)
2013-09-11 08:23:10 +00:00
* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
2014-03-12 15:23:01 +00:00
* Postgres: [github.com/lib/pq](https://github.com/lib/pq)
2013-12-31 05:02:35 +00:00
* MsSql: [github.com/lunny/godbc](https://githubcom/lunny/godbc)
2013-11-06 07:43:30 +00:00
2014-04-17 09:08:21 +00:00
NewEngine's parameters are the same as `sql.Open`. So you should read the drivers' document for parameters' usage.
2013-11-06 07:43:30 +00:00
2014-04-17 09:08:21 +00:00
After engine created, you can do some settings.
2013-09-11 08:23:10 +00:00
2014-04-17 09:08:21 +00:00
1.Logs
2013-09-11 09:00:36 +00:00
2014-04-17 09:08:21 +00:00
* `engine.ShowSQL = true`, Show SQL statement on standard output;
* `engine.ShowDebug = true`, Show debug infomation on standard output;
* `engine.ShowError = true`, Show error infomation on standard output;
* `engine.ShowWarn = true`, Show warnning information on standard output;
2014-04-17 09:08:21 +00:00
2.If want to record infomation with another method: use `engine.Logger` as `io.Writer`:
2013-09-11 08:23:10 +00:00
```Go
f, err := os.Create("sql.log")
if err != nil {
println(err.Error())
return
}
2014-07-04 06:16:03 +00:00
engine.Logger = xorm.NewSimpleLogger(f)
2013-09-11 08:23:10 +00:00
```
2014-04-17 13:28:26 +00:00
3.Engine provide DB connection pool settings.
2014-04-18 08:46:58 +00:00
* Use `engine.SetMaxIdleConns()` to set idle connections.
* Use `engine.SetMaxOpenConns()` to set Max connections. This methods support only Go 1.2+.
2013-09-11 08:23:10 +00:00
<a name="20" id="20"></a>
2014-04-17 09:08:21 +00:00
## 2.Define struct
2013-09-11 08:23:10 +00:00
xorm maps a struct to a database table, the rule is below.
2013-09-11 08:23:10 +00:00
2013-09-11 09:00:36 +00:00
<a name="21" id="21"></a>
2014-04-17 09:08:21 +00:00
### 2.1.name mapping rule
2013-09-11 08:23:10 +00:00
2014-04-17 09:08:21 +00:00
use xorm.IMapper interface to implement. There are two IMapper implemented: `SnakeMapper` and `SameMapper`. SnakeMapper means struct name is word by word and table name or column name as 下划线. SameMapper means same name between struct and table.
2014-04-17 09:08:21 +00:00
SnakeMapper is the default.
2013-09-11 08:23:10 +00:00
```Go
2013-12-31 05:02:35 +00:00
engine.SetMapper(SameMapper{})
2013-09-11 08:23:10 +00:00
```
And you should notice:
2013-12-31 05:02:35 +00:00
* If you want to use other mapping rule, implement IMapper
* Tables's mapping rule could be different from Columns':
2014-03-12 15:23:01 +00:00
2013-12-31 05:02:35 +00:00
```Go
engine.SetTableMapper(SameMapper{})
engine.SetColumnMapper(SnakeMapper{})
```
2013-09-11 08:23:10 +00:00
2013-09-11 09:00:36 +00:00
<a name="22" id="22"></a>
### 2.2.Prefix mapping, Suffix Mapping and Cache Mapping
2013-12-31 05:02:35 +00:00
2014-05-07 15:23:31 +00:00
* `engine.NewPrefixMapper(SnakeMapper{}, "prefix")` can add prefix string when naming based on SnakeMapper or SameMapper, or you custom Mapper.
* `engine.NewPrefixMapper(SnakeMapper{}, "suffix")` can add suffix string when naming based on SnakeMapper or SameMapper, or you custom Mapper.
* `engine.NewCacheMapper(SnakeMapper{})` add naming Mapper for memory cache.
2013-12-31 05:02:35 +00:00
2014-05-07 15:23:31 +00:00
Of course, you can implement IMapper to make custom naming strategy.
2014-04-17 09:08:21 +00:00
<a name="22" id="22"></a>
### 2.3.Tag mapping
2013-09-11 08:23:10 +00:00
2014-05-07 15:23:31 +00:00
It's idealized of using IMapper for all naming. But if table or column is not in rule, we need new method to archive.
2013-09-11 08:23:10 +00:00
2014-05-08 12:11:43 +00:00
* If struct or pointer of struct has `TableName() string` method, the return value will be the struct's table name.
* `engine.Table()` can change the database table name for struct. The struct tag `xorm:"'table_name'"` can set column name for struct field. Use a pair of single quotes to prevent confusion for column's definition in struct tag. If not in confusion, ignore single quotes.
2013-09-11 08:23:10 +00:00
2013-09-11 09:00:36 +00:00
<a name="23" id="23"></a>
2014-05-07 15:23:31 +00:00
### 2.4.Column definition
2014-05-07 15:23:31 +00:00
Struct tag defines something for column as basic sql concepts, such as :
2013-09-11 08:23:10 +00:00
```
type User struct {
Id int64
Name string `xorm:"varchar(25) not null unique 'usr_name'"`
}
```
2014-05-07 15:23:31 +00:00
Data types are different in different DBMS. So xorm makes own data types definition to keep compatible. Details is in document [Column Types](https://github.com/go-xorm/xorm/blob/master/docs/COLUMNTYPE.md).
2013-09-11 08:23:10 +00:00
2014-05-07 15:23:31 +00:00
The following table is field mapping rules, the keyword is not case sensitive except column name
2013-09-11 08:23:10 +00:00
<table>
<tr>
<td>name or 'name'</td><td>Column Name, optional</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
<td>pk</td><td>If column is Primary Key</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
2014-05-07 15:23:31 +00:00
<td>support over 30 kinds of column types, details in [Column Types](https://github.com/go-xorm/xorm/blob/master/docs/COLUMNTYPE.md)</td><td>column type</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
<td>autoincr</td><td>If autoincrement column</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
<td>[not ]null | notnull</td><td>if column could be blank</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
2014-05-07 15:23:31 +00:00
<td>unique/unique(uniquename)</td><td>column is Unique index; if add (uniquename), the column is used for combined unique index with the field that defining same uniquename.</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
2014-05-07 15:23:31 +00:00
<td>index/index(indexname)</td><td>column is index. if add (indexname), the column is used for combined index with the field that defining same indexname.</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
2014-05-07 15:23:31 +00:00
<td>extends</td><td>use for anonymous field, map the struct in anonymous field to database</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
<td>-</td><td>This field will not be mapping</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
2014-05-07 15:23:31 +00:00
<td>-></td><td>only write into database</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
2014-05-07 15:23:31 +00:00
<td>&lt;-</td><td>only read from database</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
2014-04-17 09:08:21 +00:00
<td>created</td><td>This field will be filled in current time on insert</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
2014-04-17 09:08:21 +00:00
<td>updated</td><td>This field will be filled in current time on insert or update</td>
</tr>
2014-04-17 09:08:21 +00:00
<tr>
<td>version</td><td>This field will be filled 1 on insert and autoincrement on update</td>
2013-09-11 08:23:10 +00:00
</tr>
<tr>
<td>default 0 | default 'name'</td><td>column default value</td>
2013-09-11 08:23:10 +00:00
</tr>
</table>
2014-05-07 15:23:31 +00:00
Some default mapping rules
2013-09-11 08:23:10 +00:00
2014-05-07 15:23:31 +00:00
- 1. If field is name of `Id` and type of `int64`, xorm makes it as auto increment primary key. If another field, use struct tag `xorm:"pk"`.
2013-09-11 08:23:10 +00:00
2014-05-07 15:23:31 +00:00
- 2. String is corresponding to varchar(255).
2013-09-11 08:23:10 +00:00
2014-05-07 15:23:31 +00:00
- 3. Support custom type as `type MyString string`slice, map as field type. They are saving as Text column type and json-encode string. Support Blob column type with field type []byte or []uint8.
2013-09-11 08:23:10 +00:00
2014-05-07 15:23:31 +00:00
- 4. You can implement Conversion interface to define your custom mapping rule between field and database data.
```
2013-09-24 17:31:25 +00:00
type Conversion interface {
FromDB([]byte) error
ToDB() ([]byte, error)
}
```
- 5. If one struct has a Conversion field, so we need set an implementation to the field before get data from database. We can implement `BeforeSet(name string, cell xorm.Cell)` on struct to do this. For example: [testConversion](https://github.com/go-xorm/tests/blob/master/base.go#L1826)
2013-09-11 08:23:10 +00:00
<a name="30" id="30"></a>
2014-05-07 15:23:31 +00:00
## 3. database meta information
2014-05-07 15:23:31 +00:00
xorm provides methods to getting and setting table schema. For less schema changing production, `engine.Sync()` is enough.
<a name="31" id="31"></a>
## 3.1 retrieve database meta info
2013-09-11 08:23:10 +00:00
* DBMetas()
2014-05-07 15:23:31 +00:00
`engine.DBMetas()` returns all tables schema information.
<a name="31" id="31"></a>
## 3.2.directly table operation
* CreateTables()
2014-05-07 15:23:31 +00:00
`engine.CreateTables(struct)` creates table with struct or struct pointer.
`engine.Charset()` and `engine.StoreEngine()` can change charset or storage engine for **mysql** database.
* IsTableEmpty()
2014-05-07 15:23:31 +00:00
check table is empty or not.
* IsTableExist()
2014-05-07 15:23:31 +00:00
check table is existed or not.
* DropTables()
2014-05-07 15:23:31 +00:00
`engine.DropTables(struct)` drops table and indexes with struct or struct pointer. `engine.DropTables(string)` only drops table except indexes.
<a name="32" id="32"></a>
## 3.3.create indexes and uniques
* CreateIndexes
2014-05-07 15:23:31 +00:00
create indexes with struct.
* CreateUniques
2014-05-07 15:23:31 +00:00
create unique indexes with struct.
<a name="34" id="34"></a>
2014-05-07 15:23:31 +00:00
## 3.4.Synchronize database schema
2014-05-07 15:23:31 +00:00
xorm watches tables and indexes and sync schema:
1) use table name to create or drop table
2) use column name to alter column
3) use the indexes definition in struct field tag to create or drop indexes.
```Go
err := engine.Sync(new(User))
```
2013-09-11 08:23:10 +00:00
<a name="50" id="50"></a>
2014-05-07 15:23:31 +00:00
## 4.Insert data
2013-09-11 09:00:36 +00:00
2014-04-17 09:08:21 +00:00
Inserting records use Insert method.
2014-01-15 02:31:14 +00:00
2014-04-17 09:08:21 +00:00
* Insert one record
2013-09-11 08:23:10 +00:00
```Go
user := new(User)
user.Name = "myname"
affected, err := engine.Insert(user)
2013-09-11 08:23:10 +00:00
```
2014-04-17 09:08:21 +00:00
After inseted, `user.Id` will be filled with primary key column value.
2013-09-11 08:23:10 +00:00
```Go
fmt.Println(user.Id)
```
2014-04-17 09:08:21 +00:00
* Insert multiple records by Slice on one table
```Go
users := make([]User, 0)
users[0].Name = "name0"
...
affected, err := engine.Insert(&users)
```
2014-04-17 09:08:21 +00:00
* Insert multiple records by Slice of pointer on one table
2013-11-23 03:12:22 +00:00
```Go
users := make([]*User, 0)
users[0] = new(User)
users[0].Name = "name0"
...
affected, err := engine.Insert(&users)
```
2014-04-17 09:08:21 +00:00
* Insert one record on two table.
```Go
user := new(User)
user.Name = "myname"
question := new(Question)
question.Content = "whywhywhwy?"
affected, err := engine.Insert(user, question)
```
2014-04-17 09:08:21 +00:00
* Insert multiple records on multiple tables.
```Go
users := make([]User, 0)
users[0].Name = "name0"
...
questions := make([]Question, 0)
questions[0].Content = "whywhywhwy?"
affected, err := engine.Insert(&users, &questions)
```
2014-04-17 09:08:21 +00:00
* Insert one or multple records on multiple tables.
```Go
user := new(User)
user.Name = "myname"
...
questions := make([]Question, 0)
questions[0].Content = "whywhywhwy?"
affected, err := engine.Insert(user, &questions)
```
2014-04-17 09:08:21 +00:00
Notice: If you want to use transaction on inserting, you should use session.Begin() before calling Insert.
2013-09-11 08:23:10 +00:00
<a name="60" id="60"></a>
2014-05-05 09:46:09 +00:00
## 5. Chainable APIs
2013-09-11 09:00:36 +00:00
<a name="61" id="61"></a>
2014-05-05 09:46:09 +00:00
### 5.1. Chainable APIs for Queries, Execusions and Aggregations
2013-09-11 08:23:10 +00:00
2014-05-05 09:46:09 +00:00
Queries and Aggregations is basically formed by using `Get`, `Find`, `Count` methods, with conjunction of following chainable APIs to form conditions, grouping and ordering:
2014-09-11 10:03:03 +00:00
查询和统计主要使用`Get`, `Find`, `Count`三个方法。在进行查询时可以使用多个方法来形成查询条件,条件函数如下:
2013-09-11 08:23:10 +00:00
2014-05-05 09:46:09 +00:00
* Id([]interface{})
Primary Key lookup
2013-09-11 08:23:10 +00:00
* Where(string, …interface{})
2014-05-05 09:46:09 +00:00
As SQL conditional WHERE clause
2013-09-11 08:23:10 +00:00
* And(string, …interface{})
2014-05-05 09:46:09 +00:00
Conditional AND
2013-09-11 08:23:10 +00:00
* Or(string, …interface{})
2014-05-05 09:46:09 +00:00
Conditional OR
2013-09-11 08:23:10 +00:00
* Sql(string, …interface{})
2014-05-07 05:11:21 +00:00
Custom SQL query
2013-09-11 08:23:10 +00:00
* Asc(…string)
2014-05-05 09:46:09 +00:00
Ascending ordering on 1 or more fields
2013-09-11 08:23:10 +00:00
* Desc(…string)
2014-05-05 09:46:09 +00:00
Descending ordering on 1 or more fields
2013-09-11 08:23:10 +00:00
* OrderBy(string)
2014-05-07 05:11:21 +00:00
As SQL ORDER BY
2013-09-11 08:23:10 +00:00
* In(string, …interface{})
2014-05-07 05:11:21 +00:00
As SQL Conditional IN
2013-09-11 08:23:10 +00:00
* Cols(…string)
2014-05-05 09:46:09 +00:00
Explicity specify query or update columns. e.g.,:
```Go
engine.Cols("age", "name").Find(&users)
// SELECT age, name FROM user
engine.Cols("age", "name").Update(&user)
// UPDATE user SET age=? AND name=?
```
* Omit(...string)
2014-05-05 09:46:09 +00:00
Inverse function to Cols, to exclude specify query or update columns. Warning: Don't use with Cols()
```Go
2014-04-23 06:57:40 +00:00
engine.Omit("age").Update(&user)
// UPDATE user SET name = ? AND department = ?
```
* Distinct(…string)
2014-05-07 05:11:21 +00:00
As SQL DISTINCT
```Go
engine.Distinct("age", "department").Find(&users)
// SELECT DISTINCT age, department FROM user
```
2014-05-07 05:11:21 +00:00
Caution: this method will not lookup from caching store
2013-09-11 08:23:10 +00:00
* Table(nameOrStructPtr interface{})
2014-05-07 05:11:21 +00:00
Specify table name, or if struct pointer is passed into the name is extract from struct type name by IMapper conversion policy
2013-09-11 08:23:10 +00:00
* Limit(int, …int)
2014-05-07 05:11:21 +00:00
As SQL LIMIT with optional second param for OFFSET
2013-09-11 08:23:10 +00:00
* Top(int)
2014-05-07 05:11:21 +00:00
As SQL LIMIT
2014-05-07 05:11:21 +00:00
* Join(type, tableName, criteria string)
As SQL JOIN, support
type: either of these values [INNER, LEFT OUTER, CROSS] are supported now
tableName: joining table name
criteria: join criteria
2013-09-11 08:23:10 +00:00
* GroupBy(string)
2014-05-07 05:11:21 +00:00
As SQL GROUP BY
2013-09-11 08:23:10 +00:00
* Having(string)
2014-05-07 05:11:21 +00:00
As SQL HAVING
2013-09-11 08:23:10 +00:00
<a name="62" id="62"></a>
2014-05-07 05:11:21 +00:00
### 5.2. Override default behavior APIs
* NoAutoTime()
2014-05-07 05:11:21 +00:00
No auto timestamp for Created and Updated fields for INSERT and UPDATE
* NoCache()
2014-05-07 05:11:21 +00:00
Disable cache lookup
* UseBool(...string)
2014-05-07 05:11:21 +00:00
xorm's default behavior is fields with 0, "", nil, false, will not be used during query or update, use this method to explicit specify bool type fields for query or update
2014-04-17 09:08:21 +00:00
* Cascade(bool)
2014-05-07 05:11:21 +00:00
Do cascade lookup for associations
2013-09-11 08:23:10 +00:00
2014-04-17 09:08:21 +00:00
<a name="50" id="50"></a>
### 5.3.Get one record
Fetch a single object by user
2014-01-15 02:31:14 +00:00
2013-09-11 08:23:10 +00:00
```Go
2014-04-17 09:08:21 +00:00
var user = User{Id:27}
has, err := engine.Get(&user)
// or has, err := engine.Id(27).Get(&user)
2014-01-15 02:31:14 +00:00
2014-04-17 09:08:21 +00:00
var user = User{Name:"xlw"}
has, err := engine.Get(&user)
```
2014-01-15 02:31:14 +00:00
2014-04-17 09:08:21 +00:00
<a name="60" id="60"></a>
### 5.4.Find
Fetch multipe objects into a slice or a map, use Find
2014-01-15 02:31:14 +00:00
```Go
2014-04-17 09:08:21 +00:00
var everyone []Userinfo
err := engine.Find(&everyone)
users := make(map[int64]Userinfo)
err := engine.Find(&users)
```
2014-01-15 02:31:14 +00:00
2014-04-17 09:08:21 +00:00
* also you can use Where, Limit
2013-09-11 08:23:10 +00:00
```Go
2014-04-17 09:08:21 +00:00
var allusers []Userinfo
err := engine.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
```
2014-04-17 09:08:21 +00:00
* or you can use a struct query
2014-01-15 02:31:14 +00:00
2013-09-11 08:23:10 +00:00
```Go
2014-04-17 09:08:21 +00:00
var tenusers []Userinfo
err := engine.Limit(10).Find(&tenusers, &Userinfo{Name:"xlw"}) //Get All Name="xlw" limit 10 offset 0
```
2013-11-23 02:53:45 +00:00
2014-04-17 09:08:21 +00:00
* or In function
2014-01-15 02:31:14 +00:00
```Go
2014-04-17 09:08:21 +00:00
var tenusers []Userinfo
err := engine.In("id", 1, 3, 5).Find(&tenusers) //Get All id in (1, 3, 5)
2013-09-11 08:23:10 +00:00
```
2014-04-17 09:08:21 +00:00
* The default will query all columns of a table. Use Cols function if you want to select some columns
2014-01-15 02:31:14 +00:00
```Go
2014-04-17 09:08:21 +00:00
var tenusers []Userinfo
err := engine.Cols("id", "name").Find(&tenusers) //Find only id and name
```
2014-04-17 09:08:21 +00:00
<a name="70" id="70"></a>
### 5.5.Iterate records
Iterate, like find, but handle records one by one
2014-01-15 02:31:14 +00:00
2013-10-17 05:15:29 +00:00
```Go
err := engine.Where("age > ? or name=?)", 30, "xlw").Iterate(new(Userinfo), func(i int, bean interface{})error{
user := bean.(*Userinfo)
//do somthing use i and user
})
```
<a name="66" id="66"></a>
2014-05-07 05:11:21 +00:00
### 5.6.Count method usage
2013-09-11 09:00:36 +00:00
2014-05-07 05:11:21 +00:00
An ORM pointer struct is required for Count method in order to determine which table to retrieve from.
2013-09-11 08:23:10 +00:00
```Go
user := new(User)
total, err := engine.Where("id >?", 1).Count(user)
```
<a name="70" id="70"></a>
## 6.Update
2013-09-11 09:00:36 +00:00
更新数据使用`Update`方法Update方法的第一个参数为需要更新的内容可以为一个结构体指针或者一个Map[string]interface{}类型。当传入的为结构体指针时只有非空和0的field才会被作为更新的字段。当传入的为Map类型时key为数据库Column的名字value为要更新的内容。
2013-09-11 08:23:10 +00:00
```Go
user := new(User)
user.Name = "myname"
2013-11-18 15:07:18 +00:00
affected, err := engine.Id(id).Update(user)
2013-09-11 08:23:10 +00:00
```
2013-10-31 15:58:14 +00:00
这里需要注意Update会自动从user结构体中提取非0和非nil得值作为需要更新的内容因此如果需要更新一个值为0则此种方法将无法实现因此有两种选择
1. 通过添加Cols函数指定需要更新结构体中的哪些值未指定的将不更新指定了的即使为0也会更新。
```Go
affected, err := engine.Id(id).Cols("age").Update(&user)
```
2. 通过传入map[string]interface{}来进行更新但这时需要额外指定更新到哪个表因为通过map是无法自动检测更新哪个表的。
```Go
affected, err := engine.Table(new(User)).Id(id).Update(map[string]interface{}{"age":0})
```
2014-04-17 09:08:21 +00:00
2014-08-28 16:06:15 +00:00
### 6.1.Optimistic Lock
2014-08-28 16:06:15 +00:00
To enable object optimistic lock, add 'version' tag value:
2014-09-11 10:03:03 +00:00
```Go
type User struct {
Id int64
Name string
Version int `xorm:"version"`
}
2014-09-11 10:03:03 +00:00
```
2014-08-28 16:06:15 +00:00
The version starts with 1 when inserted to DB. For updating make sure originated version value is used for optimistic lock check.
```Go
var user User
engine.Id(1).Get(&user)
// SELECT * FROM user WHERE id = ?
engine.Id(1).Update(&user)
// UPDATE user SET ..., version = version + 1 WHERE id = ? AND version = ?
```
2014-04-17 09:08:21 +00:00
2013-09-11 08:23:10 +00:00
<a name="80" id="80"></a>
2014-04-17 09:08:21 +00:00
## 7.Delete one or more records
Delete one or more records
2013-09-11 09:00:36 +00:00
2014-04-17 09:08:21 +00:00
* delete by id
2014-01-15 02:31:14 +00:00
2013-09-11 08:23:10 +00:00
```Go
2014-04-17 09:08:21 +00:00
err := engine.Id(1).Delete(&User{})
2013-09-11 08:23:10 +00:00
```
2014-04-17 09:08:21 +00:00
* delete by other conditions
2014-04-17 09:08:21 +00:00
```Go
err := engine.Delete(&User{Name:"xlw"})
```
2013-09-11 08:23:10 +00:00
<a name="90" id="90"></a>
2014-04-17 09:08:21 +00:00
## 8.Execute SQL query
2013-09-11 09:00:36 +00:00
2014-04-17 09:08:21 +00:00
Of course, SQL execution is also provided.
If select then use Query
2013-12-31 05:02:35 +00:00
2013-09-11 08:23:10 +00:00
```Go
2013-09-11 09:00:36 +00:00
sql := "select * from userinfo"
results, err := engine.Query(sql)
2013-09-11 08:23:10 +00:00
```
<a name="100" id="100"></a>
2014-04-17 09:08:21 +00:00
## 9.Execute SQL command
If insert, update or delete then use Exec
2013-12-31 05:02:35 +00:00
2013-09-11 08:23:10 +00:00
```Go
2014-04-17 09:08:21 +00:00
sql = "update userinfo set username=? where id=?"
2014-03-12 15:23:01 +00:00
res, err := engine.Exec(sql, "xiaolun", 1)
2013-09-11 08:23:10 +00:00
```
<a name="110" id="110"></a>
2014-04-17 09:08:21 +00:00
## 10.Transaction
2013-09-11 08:23:10 +00:00
```Go
session := engine.NewSession()
2013-12-12 07:42:44 +00:00
defer session.Close()
2014-04-17 09:08:21 +00:00
2013-09-11 08:23:10 +00:00
// add Begin() before any action
2014-04-17 09:08:21 +00:00
err := session.Begin()
2013-09-11 08:23:10 +00:00
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
2014-03-12 15:23:01 +00:00
}
2013-09-11 08:23:10 +00:00
```
2013-09-11 09:00:36 +00:00
<a name="120" id="120"></a>
2014-05-07 05:11:21 +00:00
## 11.Built-in LRU memory cache provider
2014-04-17 09:08:21 +00:00
1. Global Cache
Xorm implements cache support. Defaultly, it's disabled. If enable it, use below code.
```Go
cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), 1000)
engine.SetDefaultCacher(cacher)
```
2014-01-15 02:31:14 +00:00
2014-04-17 09:08:21 +00:00
If disable some tables' cache, then:
2014-01-15 02:31:14 +00:00
```Go
2014-04-17 09:08:21 +00:00
engine.MapCacher(&user, nil)
```
2014-04-17 09:08:21 +00:00
2. Table's Cache
If only some tables need cache, then:
2014-01-15 02:31:14 +00:00
```Go
2014-04-17 09:08:21 +00:00
cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), 1000)
engine.MapCacher(&user, cacher)
```
2014-04-17 09:08:21 +00:00
Caution:
2014-04-17 09:08:21 +00:00
1. When use Cols methods on cache enabled, the system still return all the columns.
2014-04-17 09:08:21 +00:00
2. When using Exec method, you should clear cache
2014-01-15 02:31:14 +00:00
```Go
engine.Exec("update user set name = ? where id = ?", "xlw", 1)
engine.ClearCache(new(User))
```
2014-04-17 09:08:21 +00:00
Cache implement theory below:
2014-04-11 09:16:43 +00:00
![cache design](https://raw.github.com/go-xorm/xorm/master/docs/cache_design.png)
2013-10-17 05:15:29 +00:00
<a name="140" id="140"></a>
2014-04-17 09:08:21 +00:00
## 13.Examples
2013-11-22 08:11:32 +00:00
2014-05-07 05:11:21 +00:00
Please visit [https://github.com/go-xorm/xorm/tree/master/examples](https://github.com/go-xorm/xorm/tree/master/examples)
2013-11-22 08:11:32 +00:00