在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ GO/ 5.5 使用beedb庫進(jìn)行ORM開發(fā)
7 文本處理
3 Web基礎(chǔ)
14 擴(kuò)展Web框架
10.4 小結(jié)
2.2 Go基礎(chǔ)
2.8 總結(jié)
6.1 session和cookie
5.5 使用beedb庫進(jìn)行ORM開發(fā)
8.3 REST
13.6 小結(jié)
5.4 使用PostgreSQL數(shù)據(jù)庫
14.6 pprof支持
14.1 靜態(tài)文件支持
11.2 使用GDB調(diào)試
7.7 小結(jié)
1 GO環(huán)境配置
14.5 多語言支持
7.1 XML處理
1.5 總結(jié)
13 如何設(shè)計(jì)一個(gè)Web框架
14.3 表單及驗(yàn)證支持
12 部署與維護(hù)
10 國際化和本地化
1.1 Go 安裝
6.2 Go如何使用session
5.6 NOSQL數(shù)據(jù)庫操作
6.5 小結(jié)
9.4 避免SQL注入
12.1 應(yīng)用日志
4.2 驗(yàn)證表單的輸入
10.1 設(shè)置默認(rèn)地區(qū)
1.3 Go 命令
9.6 加密和解密數(shù)據(jù)
4.1 處理表單的輸入
4.4 防止多次遞交表單
11.3 Go怎么寫測試用例
8 Web服務(wù)
12.3 應(yīng)用部署
5.7 小結(jié)
12.5 小結(jié)
11 錯(cuò)誤處理,調(diào)試和測試
9.2 確保輸入過濾
14.2 Session支持
6.4 預(yù)防session劫持
12.4 備份和恢復(fù)
8.1 Socket編程
13.1 項(xiàng)目規(guī)劃
13.4 日志和配置設(shè)計(jì)
7.6 字符串處理
13.2 自定義路由器設(shè)計(jì)
6.3 session存儲
3.4 Go的http包詳解
8.2 WebSocket
10.3 國際化站點(diǎn)
7.5 文件操作
7.4 模板處理
9.1 預(yù)防CSRF攻擊
13.3 controller設(shè)計(jì)
2.6 interface
14.4 用戶認(rèn)證
2.3 流程和函數(shù)
附錄A 參考資料
11.1 錯(cuò)誤處理
9.5 存儲密碼
9.3 避免XSS攻擊
12.2 網(wǎng)站錯(cuò)誤處理
6 session和數(shù)據(jù)存儲
2.4 struct類型
3.3 Go如何使得Web工作
2.5 面向?qū)ο?/span>
3.1 Web工作方式
1.2 GOPATH與工作空間
2.1 你好,Go
9.7 小結(jié)
13.5 實(shí)現(xiàn)博客的增刪改
7.2 JSON處理
10.2 本地化資源
7.3 正則處理
2 Go語言基礎(chǔ)
5.1 database/sql接口
4.5 處理文件上傳
8.5 小結(jié)
4.3 預(yù)防跨站腳本
5.3 使用SQLite數(shù)據(jù)庫
14.7 小結(jié)
3.2 Go搭建一個(gè)Web服務(wù)器
2.7 并發(fā)
5 訪問數(shù)據(jù)庫
4 表單
3.5 小結(jié)
1.4 Go開發(fā)工具
11.4 小結(jié)
9 安全與加密
5.2 使用MySQL數(shù)據(jù)庫
4.6 小結(jié)
8.4 RPC

5.5 使用beedb庫進(jìn)行ORM開發(fā)

beedb是我開發(fā)的一個(gè)Go進(jìn)行ORM操作的庫,它采用了Go style方式對數(shù)據(jù)庫進(jìn)行操作,實(shí)現(xiàn)了struct到數(shù)據(jù)表記錄的映射。beedb是一個(gè)十分輕量級的Go ORM框架,開發(fā)這個(gè)庫的本意降低復(fù)雜的ORM學(xué)習(xí)曲線,盡可能在ORM的運(yùn)行效率和功能之間尋求一個(gè)平衡,beedb是目前開源的Go ORM框架中實(shí)現(xiàn)比較完整的一個(gè)庫,而且運(yùn)行效率相當(dāng)不錯(cuò),功能也基本能滿足需求。但是目前還不支持關(guān)系關(guān)聯(lián),這個(gè)是接下來版本升級的重點(diǎn)。

beedb是支持database/sql標(biāo)準(zhǔn)接口的ORM庫,所以理論上來說,只要數(shù)據(jù)庫驅(qū)動支持database/sql接口就可以無縫的接入beedb。目前我測試過的驅(qū)動包括下面幾個(gè):

Mysql:github.com/ziutek/mymysql/godrv[*]

Mysql:code.google.com/p/go-mysql-driver[*]

PostgreSQL:github.com/bmizerany/pq[*]

SQLite:github.com/mattn/go-sqlite3[*]

MS ADODB: github.com/mattn/go-adodb[*]

ODBC: bitbucket.org/miquella/mgodbc[*]

安裝

beedb支持go get方式安裝,是完全按照Go Style的方式來實(shí)現(xiàn)的。

go get github.com/astaxie/beedb

如何初始化

首先你需要import相應(yīng)的數(shù)據(jù)庫驅(qū)動包、database/sql標(biāo)準(zhǔn)接口包以及beedb包,如下所示:

import (
    "database/sql"
    "github.com/astaxie/beedb"
    _ "github.com/ziutek/mymysql/godrv"
)

導(dǎo)入必須的package之后,我們需要打開到數(shù)據(jù)庫的鏈接,然后創(chuàng)建一個(gè)beedb對象(以MySQL為例),如下所示

db, err := sql.Open("mymysql", "test/xiemengjun/123456")
if err != nil {
    panic(err)
}
orm := beedb.New(db)

beedb的New函數(shù)實(shí)際上應(yīng)該有兩個(gè)參數(shù),第一個(gè)參數(shù)標(biāo)準(zhǔn)接口的db,第二個(gè)參數(shù)是使用的數(shù)據(jù)庫引擎,如果你使用的數(shù)據(jù)庫引擎是MySQL/Sqlite,那么第二個(gè)參數(shù)都可以省略。

如果你使用的數(shù)據(jù)庫是SQLServer,那么初始化需要:

orm = beedb.New(db, "mssql")

如果你使用了PostgreSQL,那么初始化需要:

orm = beedb.New(db, "pg")

目前beedb支持打印調(diào)試,你可以通過如下的代碼實(shí)現(xiàn)調(diào)試

beedb.OnDebug=true

接下來我們的例子采用前面的數(shù)據(jù)庫表Userinfo,現(xiàn)在我們建立相應(yīng)的struct

type Userinfo struct {
    Uid     int `PK` //如果表的主鍵不是id,那么需要加上pk注釋,顯式的說這個(gè)字段是主鍵
    Username    string
    Departname  string
    Created     time.Time
}

注意一點(diǎn),beedb針對駝峰命名會自動幫你轉(zhuǎn)化成下劃線字段,例如你定義了Struct名字為UserInfo,那么轉(zhuǎn)化成底層實(shí)現(xiàn)的時(shí)候是user_info,字段命名也遵循該規(guī)則。

插入數(shù)據(jù)

下面的代碼演示了如何插入一條記錄,可以看到我們操作的是struct對象,而不是原生的sql語句,最后通過調(diào)用Save接口將數(shù)據(jù)保存到數(shù)據(jù)庫。

var saveone Userinfo
saveone.Username = "Test Add User"
saveone.Departname = "Test Add Departname"
saveone.Created = time.Now()
orm.Save(&saveone)

我們看到插入之后saveone.Uid就是插入成功之后的自增ID。Save接口會自動幫你存進(jìn)去。

beedb接口提供了另外一種插入的方式,map數(shù)據(jù)插入。

add := make(map[string]interface{})
add["username"] = "astaxie"
add["departname"] = "cloud develop"
add["created"] = "2012-12-02"
orm.SetTable("userinfo").Insert(add)

插入多條數(shù)據(jù)

addslice := make([]map[string]interface{}, 0)
add:=make(map[string]interface{})
add2:=make(map[string]interface{})
add["username"] = "astaxie"
add["departname"] = "cloud develop"
add["created"] = "2012-12-02"
add2["username"] = "astaxie2"
add2["departname"] = "cloud develop2"
add2["created"] = "2012-12-02"
addslice =append(addslice, add, add2)
orm.SetTable("userinfo").InsertBatch(addslice)

上面的操作方式有點(diǎn)類似鏈?zhǔn)讲樵儯煜query的同學(xué)應(yīng)該會覺得很親切,每次調(diào)用的method都會返回原orm對象,以便可以繼續(xù)調(diào)用該對象上的其他method。

上面我們調(diào)用的SetTable函數(shù)是顯式的告訴ORM,我要執(zhí)行的這個(gè)map對應(yīng)的數(shù)據(jù)庫表是userinfo。

更新數(shù)據(jù)

繼續(xù)上面的例子來演示更新操作,現(xiàn)在saveone的主鍵已經(jīng)有值了,此時(shí)調(diào)用save接口,beedb內(nèi)部會自動調(diào)用update以進(jìn)行數(shù)據(jù)的更新而非插入操作。

saveone.Username = "Update Username"
saveone.Departname = "Update Departname"
saveone.Created = time.Now()
orm.Save(&saveone)  //現(xiàn)在saveone有了主鍵值,就執(zhí)行更新操作

更新數(shù)據(jù)也支持直接使用map操作

t := make(map[string]interface{})
t["username"] = "astaxie"
orm.SetTable("userinfo").SetPK("uid").Where(2).Update(t)

這里我們調(diào)用了幾個(gè)beedb的函數(shù)

SetPK:顯式的告訴ORM,數(shù)據(jù)庫表userinfo的主鍵是uid。

Where:用來設(shè)置條件,支持多個(gè)參數(shù),第一個(gè)參數(shù)如果為整數(shù),相當(dāng)于調(diào)用了Where("主鍵=?",值)。 Updata函數(shù)接收map類型的數(shù)據(jù),執(zhí)行更新數(shù)據(jù)。

查詢數(shù)據(jù)

beedb的查詢接口比較靈活,具體使用請看下面的例子

例子1,根據(jù)主鍵獲取數(shù)據(jù):

var user Userinfo
//Where接受兩個(gè)參數(shù),支持整形參數(shù)
orm.Where("uid=?", 27).Find(&user)

例子2:

var user2 Userinfo
orm.Where(3).Find(&user2) // 這是上面版本的縮寫版,可以省略主鍵

例子3,不是主鍵類型的的條件:

var user3 Userinfo
//Where接受兩個(gè)參數(shù),支持字符型的參數(shù)
orm.Where("name  = ?", "john").Find(&user3)

例子4,更加復(fù)雜的條件:

var user4 Userinfo
//Where支持三個(gè)參數(shù)
orm.Where("name = ? and age < ?", "john", 88).Find(&user4)

可以通過如下接口獲取多條數(shù)據(jù),請看示例

例子1,根據(jù)條件id>3,獲取20位置開始的10條數(shù)據(jù)的數(shù)據(jù)

var allusers []Userinfo
err := orm.Where("id > ?", "3").Limit(10,20).FindAll(&allusers)

例子2,省略limit第二個(gè)參數(shù),默認(rèn)從0開始,獲取10條數(shù)據(jù)

var tenusers []Userinfo
err := orm.Where("id > ?", "3").Limit(10).FindAll(&tenusers)

例子3,獲取全部數(shù)據(jù)

var everyone []Userinfo
err := orm.OrderBy("uid desc,username asc").FindAll(&everyone)

上面這些里面里面我們看到一個(gè)函數(shù)Limit,他是用來控制查詢結(jié)構(gòu)條數(shù)的。

Limit:支持兩個(gè)參數(shù),第一個(gè)參數(shù)表示查詢的條數(shù),第二個(gè)參數(shù)表示讀取數(shù)據(jù)的起始位置,默認(rèn)為0。

OrderBy:這個(gè)函數(shù)用來進(jìn)行查詢排序,參數(shù)是需要排序的條件。

上面這些例子都是將獲取的的數(shù)據(jù)直接映射成struct對象,如果我們只是想獲取一些數(shù)據(jù)到map,以下方式可以實(shí)現(xiàn):

a, _ := orm.SetTable("userinfo").SetPK("uid").Where(2).Select("uid,username").FindMap()

上面和這個(gè)例子里面又出現(xiàn)了一個(gè)新的接口函數(shù)Select,這個(gè)函數(shù)用來指定需要查詢多少個(gè)字段。默認(rèn)為全部字段*。

FindMap()函數(shù)返回的是[]map[string][]byte類型,所以你需要自己作類型轉(zhuǎn)換。

刪除數(shù)據(jù)

beedb提供了豐富的刪除數(shù)據(jù)接口,請看下面的例子

例子1,刪除單條數(shù)據(jù)

//saveone就是上面示例中的那個(gè)saveone
orm.Delete(&saveone)

例子2,刪除多條數(shù)據(jù)

//alluser就是上面定義的獲取多條數(shù)據(jù)的slice
orm.DeleteAll(&alluser)

例子3,根據(jù)sql刪除數(shù)據(jù)

orm.SetTable("userinfo").Where("uid>?", 3).DeleteRow()

關(guān)聯(lián)查詢

目前beedb還不支持struct的關(guān)聯(lián)關(guān)系,但是有些應(yīng)用卻需要用到連接查詢,所以現(xiàn)在beedb提供了一個(gè)簡陋的實(shí)現(xiàn)方案:

a, _ := orm.SetTable("userinfo").Join("LEFT", "userdeatail", "userinfo.uid=userdeatail.uid").Where("userinfo.uid=?", 1).Select("userinfo.uid,userinfo.username,userdeatail.profile").FindMap()

上面代碼中我們看到了一個(gè)新的接口Join函數(shù),這個(gè)函數(shù)帶有三個(gè)參數(shù)

  • 第一個(gè)參數(shù)可以是:INNER, LEFT, OUTER, CROSS等
  • 第二個(gè)參數(shù)表示連接的表
  • 第三個(gè)參數(shù)表示連接的條件

Group By和Having

針對有些應(yīng)用需要用到group by和having的功能,beedb也提供了一個(gè)簡陋的實(shí)現(xiàn)

a, _ := orm.SetTable("userinfo").GroupBy("username").Having("username='astaxie'").FindMap()

上面的代碼中出現(xiàn)了兩個(gè)新接口函數(shù)

GroupBy:用來指定進(jìn)行g(shù)roupby的字段

Having:用來指定having執(zhí)行的時(shí)候的條件

進(jìn)一步的發(fā)展

目前beedb已經(jīng)獲得了很多來自國內(nèi)外用戶的反饋,我目前也正在考慮重構(gòu),接下來會在幾個(gè)方面進(jìn)行改進(jìn)

  • 實(shí)現(xiàn)interface設(shè)計(jì),類似databse/sql/driver的設(shè)計(jì),設(shè)計(jì)beedb的接口,然后去實(shí)現(xiàn)相應(yīng)數(shù)據(jù)庫的CRUD操作
  • 實(shí)現(xiàn)關(guān)聯(lián)數(shù)據(jù)庫設(shè)計(jì),支持一對一,一對多,多對多的實(shí)現(xiàn),示例代碼如下:

    type Profile struct{ Nickname string Mobile string }

    type Userinfo struct { Uid int PK Username string Departname string Created time.Time Profile HasOne }

  • 自動建庫建表建索引
  • 實(shí)現(xiàn)連接池的實(shí)現(xiàn),采用goroutine