號稱go語言版本的laravel's eloquent, 發布了久違了2.0版本, 新版本做了很大的改進和升級, 下面我們一起來看一下新版本的特性.
架構調整
gorose 2.0版本做了徹底的重構, 擁有全新的架構. 架構如圖:
image
gorose 2.0 采用模塊化架構, 通過interface的api通信,嚴格的上層依賴下層.每一個模塊都可以拆卸, 甚至可以自定義為自己喜歡的樣子.
- 主模塊
- engin
gorose 初始化配置模塊, 可以全局保存并復用 - session
真正操作數據庫底層模塊, 所有的操作, 最終都會走到這里來獲取或修改數據 - orm
對象關系映射模塊, 所有的orm操作, 都在這里完成 - builder
構建終極執行的sql模塊, 可以構建任何數據庫的sql, 但要符合database/sql
包的接口
- engin
- 子模塊
- driver
數據庫驅動模塊, 被engin和builder依賴, 根據驅動來搞事情 - binder
結果集綁定模塊, 所有的返回結果集都在這里
- driver
其他語言入手姿勢
- php: 使用過
laravel
的orm就可以快速上手使用 - python: 使用過
orator orm
的用戶,可以快速上手 - ruby: 使用過
rails
的orm就可以快速上手
支持驅動
mysql : https://github.com/go-sql-driver/mysql
sqlite3 : https://github.com/mattn/go-sqlite3
postgres : https://github.com/lib/pq
oracle : https://github.com/mattn/go-oci8
mssql : https://github.com/denisenkom/go-mssqldb
clickhouse : https://github.com/kshvakov/clickhouse
特色
- 連接池
- 鏈式調用
- 支持傳入struct,map或字符串表名
- 讀寫分離集群支持
- 海量數據自動分塊處理
- 一鍵開啟事務,自動回滾和提交
- 模塊化架構,自由擴展
官方文檔
api預覽
db.Table().Fields().Where().GroupBy().Having().OrderBy.Limit().Select()
db.Table().Data().Insert()
db.Table().Data().Where().Update()
db.Table().Where().Delete()
最佳實踐
sql
DROP TABLE IF EXISTS "users";
CREATE TABLE "users" (
"uid" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT NOT NULL,
"age" integer NOT NULL
);
INSERT INTO "users" VALUES (1, 'gorose', 18);
INSERT INTO "users" VALUES (2, 'goroom', 18);
INSERT INTO "users" VALUES (3, 'fizzday', 18);
實戰代碼
package main
import (
"fmt"
"github.com/gohouse/gorose"
_ "github.com/mattn/go-sqlite3"
)
type Users struct {
Uid int64 `gorose:"uid"`
Name string `gorose:"name"`
Age int64 `gorose:"age"`
Xxx interface{} `gorose:"ignore"` // 這個字段在orm中會忽略
}
func (u *Users) TableName() string {
return "users"
}
var err error
var engin *gorose.Engin
func init() {
// 全局初始化數據庫,并復用
// 這里的engin需要全局保存,可以用全局變量,也可以用單例
// 配置&gorose.Config{}是單一數據庫配置
// 如果配置讀寫分離集群,則使用&gorose.ConfigCluster{}
engin, err = gorose.Open(&gorose.Config{Driver: "sqlite3", Dsn: "./db.sqlite"})
}
func DB() gorose.IOrm {
return engin.NewOrm()
}
func main() {
// 這里定義一個變量db, 是為了復用db對象, 可以在最后使用 db.LastSql() 獲取最后執行的sql
// 如果不復用 db, 而是直接使用 DB(), 則會新建一個orm對象, 每一次都是全新的對象
// 所以復用 db, 一定要在當前會話周期內
db := DB()
// 這里的對象是map, 所以需要初始化(var u = user{}), 不能像struct那樣, 可以直接 `var u Users`
var u = Users{}
var count int64
// 統計數據
count,err = db.Table(&u).Fields("uid,name,age").Where("age",">",0).OrderBy("uid desc").Limit(10).Offset(1).Count()
if err!=nil {
fmt.Println(err)
}
// 查詢數據并綁定到 user{} 上, 這里復用了 db 及上下文條件參數
// 如果不想復用,則可以使用DB()就會開啟全新會話,或者使用db.Reset()
// db.Reset()只會清除上下文參數干擾,不回更換鏈接,DB()則會更換鏈接
err = db.Select()
fmt.Println(count)
fmt.Println(u, u.Name.String())
fmt.Println(db.LastSql())
}