go使用beedb库进行ORM开发
beedb是我開發的一個Go進行ORM操作的庫,它采用了Go style方式對數據庫進行操作,實現了struct到數據表記錄的映射。beedb是一個十分輕量級的Go ORM框架,開發這個庫的本意降低復雜的ORM學習曲線,盡可能在ORM的運行效率和功能之間尋求一個平衡,beedb是目前開源的Go ORM框架中實現比較完整的一個庫,而且運行效率相當不錯,功能也基本能滿足需求。但是目前還不支持關系關聯,這個是接下來版本升級的重點。
beedb是支持database/sql標準接口的ORM庫,所以理論上來說,只要數據庫驅動支持database/sql接口就可以無縫的接入beedb。目前我測試過的驅動包括下面幾個:
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的方式來實現的。
go get github.com/astaxie/beedb如何初始化
首先你需要import相應的數據庫驅動包、database/sql標準接口包以及beedb包,如下所示:
import ("database/sql""github.com/astaxie/beedb"_ "github.com/ziutek/mymysql/godrv" )導入必須的package之后,我們需要打開到數據庫的鏈接,然后創建一個beedb對象(以MySQL為例),如下所示
db, err := sql.Open("mymysql", "test/xiemengjun/123456") if err != nil {panic(err) } orm := beedb.New(db)beedb的New函數實際上應該有兩個參數,第一個參數標準接口的db,第二個參數是使用的數據庫引擎,如果你使用的數據庫引擎是MySQL/Sqlite,那么第二個參數都可以省略。
如果你使用的數據庫是SQLServer,那么初始化需要:
orm = beedb.New(db, "mssql")如果你使用了PostgreSQL,那么初始化需要:
orm = beedb.New(db, "pg")目前beedb支持打印調試,你可以通過如下的代碼實現調試
beedb.OnDebug=true接下來我們的例子采用前面的數據庫表Userinfo,現在我們建立相應的struct
type Userinfo struct {Uid int `PK` //如果表的主鍵不是id,那么需要加上pk注釋,顯式的說這個字段是主鍵Username stringDepartname stringCreated time.Time }注意一點,beedb針對駝峰命名會自動幫你轉化成下劃線字段,例如你定義了Struct名字為UserInfo,那么轉化成底層實現的時候是user_info,字段命名也遵循該規則。
插入數據
下面的代碼演示了如何插入一條記錄,可以看到我們操作的是struct對象,而不是原生的sql語句,最后通過調用Save接口將數據保存到數據庫。
var saveone Userinfo saveone.Username = "Test Add User" saveone.Departname = "Test Add Departname" saveone.Created = time.Now() orm.Save(&saveone)我們看到插入之后saveone.Uid就是插入成功之后的自增ID。Save接口會自動幫你存進去。
beedb接口提供了另外一種插入的方式,map數據插入。
add := make(map[string]interface{}) add["username"] = "astaxie" add["departname"] = "cloud develop" add["created"] = "2012-12-02" orm.SetTable("userinfo").Insert(add)插入多條數據
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)上面的操作方式有點類似鏈式查詢,熟悉jquery的同學應該會覺得很親切,每次調用的method都會返回原orm對象,以便可以繼續調用該對象上的其他method。
上面我們調用的SetTable函數是顯式的告訴ORM,我要執行的這個map對應的數據庫表是userinfo。
更新數據
繼續上面的例子來演示更新操作,現在saveone的主鍵已經有值了,此時調用save接口,beedb內部會自動調用update以進行數據的更新而非插入操作。
saveone.Username = "Update Username" saveone.Departname = "Update Departname" saveone.Created = time.Now() orm.Save(&saveone) //現在saveone有了主鍵值,就執行更新操作更新數據也支持直接使用map操作
t := make(map[string]interface{}) t["username"] = "astaxie" orm.SetTable("userinfo").SetPK("uid").Where(2).Update(t)這里我們調用了幾個beedb的函數
SetPK:顯式的告訴ORM,數據庫表userinfo的主鍵是uid。
Where:用來設置條件,支持多個參數,第一個參數如果為整數,相當于調用了Where("主鍵=?",值)。 Updata函數接收map類型的數據,執行更新數據。
查詢數據
beedb的查詢接口比較靈活,具體使用請看下面的例子
例子1,根據主鍵獲取數據:
var user Userinfo //Where接受兩個參數,支持整形參數 orm.Where("uid=?", 27).Find(&user)例子2:
var user2 Userinfo orm.Where(3).Find(&user2) // 這是上面版本的縮寫版,可以省略主鍵例子3,不是主鍵類型的的條件:
var user3 Userinfo //Where接受兩個參數,支持字符型的參數 orm.Where("name = ?", "john").Find(&user3)例子4,更加復雜的條件:
var user4 Userinfo //Where支持三個參數 orm.Where("name = ? and age < ?", "john", 88).Find(&user4)可以通過如下接口獲取多條數據,請看示例
例子1,根據條件id>3,獲取20位置開始的10條數據的數據
var allusers []Userinfo err := orm.Where("id > ?", "3").Limit(10,20).FindAll(&allusers)例子2,省略limit第二個參數,默認從0開始,獲取10條數據
var tenusers []Userinfo err := orm.Where("id > ?", "3").Limit(10).FindAll(&tenusers)例子3,獲取全部數據
var everyone []Userinfo err := orm.OrderBy("uid desc,username asc").FindAll(&everyone)上面這些里面里面我們看到一個函數Limit,他是用來控制查詢結構條數的。
Limit:支持兩個參數,第一個參數表示查詢的條數,第二個參數表示讀取數據的起始位置,默認為0。
OrderBy:這個函數用來進行查詢排序,參數是需要排序的條件。
上面這些例子都是將獲取的的數據直接映射成struct對象,如果我們只是想獲取一些數據到map,以下方式可以實現:
a, _ := orm.SetTable("userinfo").SetPK("uid").Where(2).Select("uid,username").FindMap()上面和這個例子里面又出現了一個新的接口函數Select,這個函數用來指定需要查詢多少個字段。默認為全部字段*。
FindMap()函數返回的是[]map[string][]byte類型,所以你需要自己作類型轉換。
刪除數據
beedb提供了豐富的刪除數據接口,請看下面的例子
例子1,刪除單條數據
//saveone就是上面示例中的那個saveone orm.Delete(&saveone)例子2,刪除多條數據
//alluser就是上面定義的獲取多條數據的slice orm.DeleteAll(&alluser)例子3,根據sql刪除數據
orm.SetTable("userinfo").Where("uid>?", 3).DeleteRow()關聯查詢
目前beedb還不支持struct的關聯關系,但是有些應用卻需要用到連接查詢,所以現在beedb提供了一個簡陋的實現方案:
a, _ := orm.SetTable("userinfo").Join("LEFT", "userdeatail", "userinfo.uid=userdeatail.uid").Where("userinfo.uid=?", 1).Select("userinfo.uid,userinfo.username,userdeatail.profile").FindMap()上面代碼中我們看到了一個新的接口Join函數,這個函數帶有三個參數
- 第一個參數可以是:INNER, LEFT, OUTER, CROSS等
- 第二個參數表示連接的表
- 第三個參數表示連接的條件
Group By和Having
針對有些應用需要用到group by和having的功能,beedb也提供了一個簡陋的實現
a, _ := orm.SetTable("userinfo").GroupBy("username").Having("username='astaxie'").FindMap()上面的代碼中出現了兩個新接口函數
GroupBy:用來指定進行groupby的字段
Having:用來指定having執行的時候的條件
進一步的發展
目前beedb已經獲得了很多來自國內外用戶的反饋,我目前也正在考慮重構,接下來會在幾個方面進行改進
-
實現interface設計,類似databse/sql/driver的設計,設計beedb的接口,然后去實現相應數據庫的CRUD操作
-
實現關聯數據庫設計,支持一對一,一對多,多對多的實現,示例代碼如下:
type Profile struct{ Nickname string Mobile string }
type Userinfo struct { Uid int?PK?Username string Departname string Created time.Time Profile?HasOne?}
-
自動建庫建表建索引
-
實現連接池的實現,采用goroutine
總結
以上是生活随笔為你收集整理的go使用beedb库进行ORM开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: go使用PostgreSQL数据库
- 下一篇: go中NOSQL数据库操作