Add en/0.5.x.md syntax highlighting
This commit is contained in:
16
en/05.3.md
16
en/05.3.md
@@ -15,16 +15,16 @@ The first driver is the only one that supports the `database/sql` interface stan
|
||||
## Samples
|
||||
|
||||
We create the following SQL:
|
||||
|
||||
```sql
|
||||
CREATE TABLE `userinfo` (
|
||||
`uid` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`username` VARCHAR(64) NULL,
|
||||
`departname` VARCHAR(64) NULL,
|
||||
`created` DATE NULL
|
||||
);
|
||||
|
||||
```
|
||||
An example:
|
||||
|
||||
```Go
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -101,11 +101,11 @@ An example:
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
You may have noticed that the code is almost the same as in the previous section, and that we only changed the name of the registered driver and called `sql.Open` to connect to SQLite in a different way.
|
||||
|
||||
Note that sometimes you can't use the `for` statement because you don't have more than one row, then you can use the `if` statement
|
||||
|
||||
```Go
|
||||
if rows.Next() {
|
||||
err = rows.Scan(&uid, &username, &department, &created)
|
||||
checkErr(err)
|
||||
@@ -114,14 +114,14 @@ Note that sometimes you can't use the `for` statement because you don't have mor
|
||||
fmt.Println(department)
|
||||
fmt.Println(created)
|
||||
}
|
||||
|
||||
```
|
||||
Also you have to do a `rows.Next()`, without using that you can't fetch data in the `Scan` function.
|
||||
|
||||
Transactions
|
||||
===============
|
||||
|
||||
The above example shows how you fetch data from the database, but when you want to write a web application then it will not only be necessary to fetch data from the db but it will also be required to write data into it. For that purpose, you should use transactions because for various reasons, such as having multiple go routines which access the database, the database might get locked. This is undesirable in your web application and the use of transactions is effective in ensuring your database activities either pass or fail completely depending on circumstances. It is clear that using transactions can prevent a lot of things from going wrong with the web app.
|
||||
|
||||
```Go
|
||||
trashSQL, err := database.Prepare("update task set is_deleted='Y',last_modified_at=datetime() where id=?")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -137,7 +137,7 @@ The above example shows how you fetch data from the database, but when you want
|
||||
} else {
|
||||
tx.Commit()
|
||||
}
|
||||
|
||||
```
|
||||
As it is clear from the above block of code, you first prepare a statement, after which you execute it, depending on the output of that execution then you either roll it back or commit it.
|
||||
|
||||
|
||||
|
||||
16
en/05.4.md
16
en/05.4.md
@@ -15,7 +15,7 @@ I will use the first one in the examples that follow.
|
||||
## Samples
|
||||
|
||||
We create the following SQL:
|
||||
|
||||
```sql
|
||||
CREATE TABLE userinfo
|
||||
(
|
||||
uid serial NOT NULL,
|
||||
@@ -25,9 +25,9 @@ We create the following SQL:
|
||||
CONSTRAINT userinfo_pkey PRIMARY KEY (uid)
|
||||
)
|
||||
WITH (OIDS=FALSE);
|
||||
|
||||
```
|
||||
An example:
|
||||
|
||||
```Go
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -102,20 +102,20 @@ An example:
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
Note that PostgreSQL uses the `$1, $2` format instead of the `?` that MySQL uses, and it has a different DSN format in `sql.Open`.
|
||||
Another thing is that the PostgreSQL driver does not support `sql.Result.LastInsertId()`.
|
||||
So instead of this,
|
||||
|
||||
```Go
|
||||
stmt, err := db.Prepare("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3);")
|
||||
res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
|
||||
fmt.Println(res.LastInsertId())
|
||||
|
||||
```
|
||||
use `db.QueryRow()` and `.Scan()` to get the value for the last inserted id.
|
||||
|
||||
```Go
|
||||
err = db.QueryRow("INSERT INTO TABLE_NAME values($1) returning uid;", VALUE1").Scan(&lastInsertId)
|
||||
fmt.Println(lastInsertId)
|
||||
|
||||
```
|
||||
## Links
|
||||
|
||||
- [Directory](preface.md)
|
||||
|
||||
101
en/05.5.md
101
en/05.5.md
@@ -32,69 +32,69 @@ You can use `go get` to install beedb locally.
|
||||
## Initialization
|
||||
|
||||
First, you have to import all the necessary packages:
|
||||
|
||||
```Go
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/astaxie/beedb"
|
||||
_ "github.com/ziutek/mymysql/godrv"
|
||||
)
|
||||
|
||||
```
|
||||
Then you need to open a database connection and create a beedb object (MySQL in this example):
|
||||
|
||||
```Go
|
||||
db, err := sql.Open("mymysql", "test/xiemengjun/123456")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
orm := beedb.New(db)
|
||||
|
||||
```
|
||||
`beedb.New()` actually has two arguments. The first is the database object, and the second is for indicating which database engine you're using. If you're using MySQL/SQLite, you can just skip the second argument.
|
||||
|
||||
Otherwise, this argument must be supplied. For instance, in the case of SQLServer:
|
||||
|
||||
```Go
|
||||
orm = beedb.New(db, "mssql")
|
||||
|
||||
```
|
||||
PostgreSQL:
|
||||
|
||||
```Go
|
||||
orm = beedb.New(db, "pg")
|
||||
|
||||
```
|
||||
beedb supports debugging. Use the following code to enable it:
|
||||
|
||||
```Go
|
||||
beedb.OnDebug=true
|
||||
|
||||
```
|
||||
Next, we have a struct for the `Userinfo` database table that we used in previous sections.
|
||||
|
||||
```Go
|
||||
type Userinfo struct {
|
||||
Uid int `PK` // if the primary key is not id, you need to add tag `PK` for your customized primary key.
|
||||
Username string
|
||||
Departname string
|
||||
Created time.Time
|
||||
}
|
||||
|
||||
```
|
||||
Be aware that beedb auto-converts camelcase names to lower snake case. For example, if we have `UserInfo` as the struct name, beedb will convert it to `user_info` in the database. The same rule applies to struct field names.
|
||||
|
||||
|
||||
## Insert data
|
||||
|
||||
The following example shows you how to use beedb to save a struct, instead of using raw SQL commands. We use the beedb Save method to apply the change.
|
||||
|
||||
```Go
|
||||
var saveone Userinfo
|
||||
saveone.Username = "Test Add User"
|
||||
saveone.Departname = "Test Add Departname"
|
||||
saveone.Created = time.Now()
|
||||
orm.Save(&saveone)
|
||||
|
||||
```
|
||||
You can check `saveone.Uid` after the record is inserted; its value is a self-incremented ID, which the Save method takes care of for you.
|
||||
|
||||
beedb provides another way of inserting data; this is via Go's map type.
|
||||
|
||||
```Go
|
||||
add := make(map[string]interface{})
|
||||
add["username"] = "astaxie"
|
||||
add["departname"] = "cloud develop"
|
||||
add["created"] = "2012-12-02"
|
||||
orm.SetTable("userinfo").Insert(add)
|
||||
|
||||
```
|
||||
Insert multiple data:
|
||||
|
||||
```Go
|
||||
addslice := make([]map[string]interface{}, 10)
|
||||
add:=make(map[string]interface{})
|
||||
add2:=make(map[string]interface{})
|
||||
@@ -106,7 +106,7 @@ Insert multiple data:
|
||||
add2["created"] = "2012-12-02"
|
||||
addslice = append(addslice, add, add2)
|
||||
orm.SetTable("userinfo").InsertBatch(addslice)
|
||||
|
||||
```
|
||||
The method shown above is similar to a chained query, which you should be familiar with if you've ever used jquery. It returns the original ORM object after calls, then continues doing other jobs.
|
||||
|
||||
The method `SetTable` tells the ORM we want to insert our data into the `userinfo` table.
|
||||
@@ -114,18 +114,18 @@ The method `SetTable` tells the ORM we want to insert our data into the `userinf
|
||||
## Update data
|
||||
|
||||
Let's continue working with the above example to see how to update data. Now that we have the primary key of saveone(Uid), beedb executes an update operation instead of inserting a new record.
|
||||
|
||||
```Go
|
||||
saveone.Username = "Update Username"
|
||||
saveone.Departname = "Update Departname"
|
||||
saveone.Created = time.Now()
|
||||
orm.Save(&saveone) // update
|
||||
|
||||
```
|
||||
Like before, you can also use map for updating data:
|
||||
|
||||
```Go
|
||||
t := make(map[string]interface{})
|
||||
t["username"] = "astaxie"
|
||||
orm.SetTable("userinfo").SetPK("uid").Where(2).Update(t)
|
||||
|
||||
```
|
||||
Let me explain some of the methods used above:
|
||||
|
||||
- `.SetPK()` tells the ORM that `uid` is the primary key records in the `userinfo` table.
|
||||
@@ -137,54 +137,54 @@ Let me explain some of the methods used above:
|
||||
The beedb query interface is very flexible. Let's see some examples:
|
||||
|
||||
Example 1, query by primary key:
|
||||
|
||||
```Go
|
||||
var user Userinfo
|
||||
// Where accepts two arguments, supports integers
|
||||
orm.Where("uid=?", 27).Find(&user)
|
||||
|
||||
```
|
||||
Example 2:
|
||||
|
||||
```Go
|
||||
var user2 Userinfo
|
||||
orm.Where(3).Find(&user2) // short form that omits primary key
|
||||
|
||||
```
|
||||
Example 3, other query conditions:
|
||||
|
||||
```Go
|
||||
var user3 Userinfo
|
||||
// Where two arguments are accepted, with support for char type.
|
||||
orm.Where("name = ?", "john").Find(&user3)
|
||||
|
||||
```
|
||||
Example 4, more complex conditions:
|
||||
|
||||
```Go
|
||||
var user4 Userinfo
|
||||
// Where three arguments are accepted
|
||||
orm.Where("name = ? and age < ?", "john", 88).Find(&user4)
|
||||
|
||||
```
|
||||
Examples to get multiple records:
|
||||
|
||||
Example 1, gets 10 records with `id>3` that starts with position 20:
|
||||
|
||||
```Go
|
||||
var allusers []Userinfo
|
||||
err := orm.Where("id > ?", "3").Limit(10,20).FindAll(&allusers)
|
||||
|
||||
```
|
||||
Example 2, omits the second argument of limit, so it starts with 0 and gets 10 records:
|
||||
|
||||
```Go
|
||||
var tenusers []Userinfo
|
||||
err := orm.Where("id > ?", "3").Limit(10).FindAll(&tenusers)
|
||||
|
||||
```
|
||||
Example 3, gets all records:
|
||||
|
||||
```Go
|
||||
var everyone []Userinfo
|
||||
err := orm.OrderBy("uid desc,username asc").FindAll(&everyone)
|
||||
|
||||
```
|
||||
As you can see, the Limit method is for limiting the number of results.
|
||||
|
||||
- `.Limit()` supports two arguments: the number of results and the starting position. 0 is the default value of the starting position.
|
||||
- `.OrderBy()` is for ordering results. The argument is the order condition.
|
||||
|
||||
All the examples here are simply mapping records to structs. You can also just put the data into a map as follows:
|
||||
|
||||
```Go
|
||||
a, _ := orm.SetTable("userinfo").SetPK("uid").Where(2).Select("uid,username").FindMap()
|
||||
|
||||
```
|
||||
- `.Select()` tells beedb how many fields you want to get from the database table. If unspecified, all fields are returned by default.
|
||||
- `.FindMap()` returns the `[]map[string][]byte` type, so you need to convert to other types yourself.
|
||||
|
||||
@@ -193,27 +193,27 @@ All the examples here are simply mapping records to structs. You can also just p
|
||||
beedb provides rich methods to delete data.
|
||||
|
||||
Example 1, delete a single record:
|
||||
|
||||
```Go
|
||||
// saveone is the one in above example.
|
||||
orm.Delete(&saveone)
|
||||
|
||||
```
|
||||
Example 2, delete multiple records:
|
||||
|
||||
```Go
|
||||
// alluser is the slice which gets multiple records.
|
||||
orm.DeleteAll(&alluser)
|
||||
|
||||
```
|
||||
Example 3, delete records by SQL:
|
||||
|
||||
```Go
|
||||
orm.SetTable("userinfo").Where("uid>?", 3).DeleteRow()
|
||||
|
||||
```
|
||||
## Association queries
|
||||
|
||||
beedb doesn't support joining between structs.
|
||||
However, since some applications need this feature, here is an implementation:
|
||||
|
||||
```Go
|
||||
a, _ := orm.SetTable("userinfo").Join("LEFT", "userdetail", "userinfo.uid=userdetail.uid")
|
||||
.Where("userinfo.uid=?", 1).Select("userinfo.uid,userinfo.username,userdetail.profile").FindMap()
|
||||
|
||||
```
|
||||
We see a new method called `.Join()` that has three arguments:
|
||||
|
||||
- The first argument: Type of Join; INNER, LEFT, OUTER, CROSS, etc.
|
||||
@@ -223,9 +223,9 @@ We see a new method called `.Join()` that has three arguments:
|
||||
## Group By and Having
|
||||
|
||||
beedb also has an implementation of `group by` and `having`.
|
||||
|
||||
```Go
|
||||
a, _ := orm.SetTable("userinfo").GroupBy("username").Having("username='astaxie'").FindMap()
|
||||
|
||||
```
|
||||
- `.GroupBy()` indicates the field that is for group by.
|
||||
- `.Having()` indicates conditions of having.
|
||||
|
||||
@@ -235,11 +235,12 @@ I have received a lot of feedback on beedb from many people all around the world
|
||||
|
||||
- Implement an interface design similar to `database/sql/driver` in order to facilitate CRUD operations.
|
||||
- Implement relational database associations like one to one, one to many and many to many. Here's a sample:
|
||||
|
||||
```Go
|
||||
type Profile struct {
|
||||
Nickname string
|
||||
Mobile string
|
||||
}
|
||||
|
||||
type Userinfo struct {
|
||||
Uid int
|
||||
PK_Username string
|
||||
@@ -247,7 +248,7 @@ I have received a lot of feedback on beedb from many people all around the world
|
||||
Created time.Time
|
||||
Profile HasOne
|
||||
}
|
||||
|
||||
```
|
||||
- Auto-create tables and indexes.
|
||||
- Implement a connection pool using goroutines.
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ I forked the last of these packages, fixed some bugs, and used it in my short UR
|
||||
- [https://github.com/astaxie/goredis](https://github.com/astaxie/goredis)
|
||||
|
||||
Let's see how to use the driver that I forked to operate on a database:
|
||||
|
||||
```Go
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -129,7 +129,7 @@ Let's see how to use the driver that I forked to operate on a database:
|
||||
}
|
||||
client.Del("l")
|
||||
}
|
||||
|
||||
```
|
||||
We can see that it is quite easy to operate redis in Go, and it has high performance. It's client commands are almost the same as redis' built-in commands.
|
||||
|
||||
## mongoDB
|
||||
|
||||
Reference in New Issue
Block a user