摘要:文章來源框架的數(shù)據(jù)庫操作由包提供支持,包經(jīng)過非常精心優(yōu)雅的設(shè)計,提供了非常強(qiáng)大的配置管理方法操作鏈?zhǔn)讲僮魇聞?wù)操作等功能。其他鏈?zhǔn)讲僮髡垍⒖忌鲜鲦準(zhǔn)讲僮髡鹿?jié)。
文章來源:http://gf.johng.cn/494380
gf框架的數(shù)據(jù)庫ORM操作由gdb包提供支持,gdb包經(jīng)過非常精心優(yōu)雅的設(shè)計,提供了非常強(qiáng)大的配置管理、方法操作、鏈?zhǔn)讲僮鳌⑹聞?wù)操作等功能。gdb包具體API說明文檔詳見:godoc 。本章節(jié)對gdb包的使用進(jìn)行基本的介紹,包括:gdb包基本功能介紹,配置管理功能說明,常見用法及常用操作示例。
使用方式:
import "gitee.com/johng/gf/g/database/gdb"數(shù)據(jù)庫配置
gdb數(shù)據(jù)結(jié)構(gòu):
type List []Map // 數(shù)據(jù)記錄列表 type Map map[string]interface{} // 數(shù)據(jù)記錄 type Config map[string]ConfigGroup // 數(shù)據(jù)庫配置對象 type ConfigGroup []ConfigNode // 數(shù)據(jù)庫分組配置 // 數(shù)據(jù)庫配置項(一個分組配置對應(yīng)多個配置項) type ConfigNode struct { Host string // 地址 Port string // 端口 User string // 賬號 Pass string // 密碼 Name string // 數(shù)據(jù)庫名稱 Type string // 數(shù)據(jù)庫類型:mysql, sqlite, mssql, pgsql, oracle(目前僅支持mysql,pgsql) Role string // (可選,默認(rèn)為master)數(shù)據(jù)庫的角色,用于主從操作分離,至少需要有一個master,參數(shù)值:master, slave Charset string // (可選,默認(rèn)為 utf-8)編碼,默認(rèn)為 utf-8 Priority int // (可選)用于負(fù)載均衡的權(quán)重計算,當(dāng)集群中只有一個節(jié)點時,權(quán)重沒有任何意義 Linkinfo string // (可選)自定義鏈接信息,當(dāng)該字段被設(shè)置值時,以上鏈接字段(Host,Port,User,Pass,Name)將失效(該字段是一個擴(kuò)展功能,參考sql.Open參數(shù)) }
其中,Map和List用于數(shù)據(jù)表記錄操作,分別對應(yīng)一條數(shù)據(jù)表記錄和數(shù)據(jù)表記錄列表;Config、ConfigGroup及ConfigNode用于數(shù)據(jù)庫配置管理,ConfigNode用于存儲一個數(shù)據(jù)庫節(jié)點信息,ConfigGroup用于管理多個數(shù)據(jù)庫節(jié)點組成的配置分組(一般一個分組對應(yīng)一個業(yè)務(wù)數(shù)據(jù)庫集群),Config用于管理多個ConfigGroup配置分組。
gdb主要特點:
支持多節(jié)點數(shù)據(jù)庫集群管理,采用單例模式管理數(shù)據(jù)庫實例化對象;
支持對數(shù)據(jù)庫集群分組管理,按照分組名稱獲取實例化的數(shù)據(jù)庫操作對象;
支持多種關(guān)系型數(shù)據(jù)庫管理,可通過ConfigNode.Type屬性進(jìn)行配置(目前僅支持mysql和pgsql數(shù)據(jù)庫);
支持Master-Slave讀寫分離,可通過ConfigNode.Role屬性進(jìn)行配置;
支持客戶端的負(fù)載均衡管理,可通過ConfigNode.Priority屬性進(jìn)行配置,值越大,優(yōu)先級越高;
特別說明,gdb的配置管理最大的特點是,(同一進(jìn)程中)所有的數(shù)據(jù)庫集群信息都使用同一個配置管理模塊進(jìn)行統(tǒng)一維護(hù),不同業(yè)務(wù)的數(shù)據(jù)庫集群配置使用不同的分組名稱進(jìn)行配置和獲取。
配置方法數(shù)據(jù)庫配置管理方法列表:
// 添加一個數(shù)據(jù)庫節(jié)點到指定的分組中 func AddConfigNode(group string, node ConfigNode) // 添加一個配置分組到數(shù)據(jù)庫配置管理中(同名覆蓋) func AddConfigGroup(group string, nodes ConfigGroup) // 添加一個數(shù)據(jù)庫節(jié)點到默認(rèn)的分組中(默認(rèn)為default,可修改) func AddDefaultConfigNode(node ConfigNode) // 添加一個配置分組到數(shù)據(jù)庫配置管理中(默認(rèn)分組為default,可修改) func AddDefaultConfigGroup(nodes ConfigGroup) // 設(shè)置數(shù)據(jù)庫配置為定義的配置信息 func SetConfig(c Config) // 設(shè)置默認(rèn)的分組名稱 func SetDefaultGroup(groupName string)
默認(rèn)分組表示,如果獲取數(shù)據(jù)庫對象時不指定配置分組名稱,那么gdb默認(rèn)讀取的配置分組。例如:gdb.Instance()可獲取一個默認(rèn)分組的數(shù)據(jù)庫單例對象。
簡單的做法,我們可以通過gdb包的SetConfig配置管理方法進(jìn)行自定義的數(shù)據(jù)庫全局配置,例如:
gdb.SetConfig(gdb.Config { "default" : gdb.ConfigGroup { gdb.ConfigNode { Host : "127.0.0.1", Port : "3306", User : "root", Pass : "123456", Name : "test", Type : "mysql", Role : "master", Priority : 100, }, gdb.ConfigNode { Host : "127.0.0.2", Port : "3306", User : "root", Pass : "123456", Name : "test", Type : "mysql", Role : "master", Priority : 100, }, }, })配置文件
當(dāng)然,gdb支持配置文件進(jìn)行配置,這樣也便于項目的配置管理,具體請參見【ORM高級用法】章節(jié)。
數(shù)據(jù)庫操作gdb數(shù)據(jù)庫操作的方法比較多,具體詳見godoc,以下僅對一些常用的方法進(jìn)行介紹。
方法操作// SQL操作方法,返回原生的標(biāo)準(zhǔn)庫sql對象 Query(query string, args ...interface{}) (*sql.Rows, error) Exec(query string, args ...interface{}) (sql.Result, error) Prepare(query string) (*sql.Stmt, error) // 數(shù)據(jù)表記錄查詢: // 查詢單條記錄、查詢多條記錄、查詢單個字段值(鏈?zhǔn)讲僮魍? GetAll(query string, args ...interface{}) (List, error) GetOne(query string, args ...interface{}) (Map, error) GetValue(query string, args ...interface{}) (interface{}, error) // 開啟事務(wù)操作 Begin() (*Tx, error) // 數(shù)據(jù)單條操作 Insert(table string, data Map) (sql.Result, error) Replace(table string, data Map) (sql.Result, error) Save(table string, data Map) (sql.Result, error) // 數(shù)據(jù)批量操作 BatchInsert(table string, list List, batch int) (sql.Result, error) BatchReplace(table string, list List, batch int) (sql.Result, error) BatchSave(table string, list List, batch int) (sql.Result, error) // 數(shù)據(jù)修改/刪除 Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) Delete(table string, condition interface{}, args ...interface{}) (sql.Result, error) // 創(chuàng)建鏈?zhǔn)讲僮鲗ο?Table為From的別名) Table(tables string) (*DbOp) From(tables string) (*DbOp) // 關(guān)閉數(shù)據(jù)庫 Close() error
需要說明一下Insert/Replace/Save三者的區(qū)別(BatchInsert/BatchReplace/BatchSave同理):
Insert:使用insert into語句進(jìn)行數(shù)據(jù)庫寫入,如果寫入的數(shù)據(jù)中存在Primary Key或者Unique Key的情況,返回失敗,否則寫入一條新數(shù)據(jù);
Replace:使用replace into語句進(jìn)行數(shù)據(jù)庫寫入,如果寫入的數(shù)據(jù)中存在Primary Key或者Unique Key的情況,刪除原有記錄,按照給定數(shù)據(jù)新寫入一條新記錄,否則寫入一條新數(shù)據(jù);
Save:使用insert into語句進(jìn)行數(shù)據(jù)庫寫入,如果寫入的數(shù)據(jù)中存在Primary Key或者Unique Key的情況,更新原有數(shù)據(jù),否則寫入一條新數(shù)據(jù);
鏈?zhǔn)讲僮?/b>gdb提供簡便靈活的鏈?zhǔn)讲僮鹘涌?,通過數(shù)據(jù)庫對象的db.Table/db.From方法或者事務(wù)對象的tx.Table/tx.From方法基于指定的數(shù)據(jù)表返回一個鏈?zhǔn)讲僮鲗ο驞bOp,該對象可以執(zhí)行以下方法(具體方法說明請參考API文檔)。
func LeftJoin(joinTable string, on string) (*DbOp) func RightJoin(joinTable string, on string) (*DbOp) func InnerJoin(joinTable string, on string) (*DbOp) func Fields(fields string) (*DbOp) func Limit(start int, limit int) (*DbOp) func Data(data interface{}) (*DbOp) func Batch(batch int) *DbOp func Where(where string, args...interface{}) (*DbOp) func GroupBy(groupby string) (*DbOp) func OrderBy(orderby string) (*DbOp) func Insert() (sql.Result, error) func Replace() (sql.Result, error) func Save() (sql.Result, error) func Update() (sql.Result, error) func Delete() (sql.Result, error) func Select() (List, error) func All() (List, error) func One() (Map, error) func Value() (interface{}, error)數(shù)據(jù)庫示例
https://gitee.com/johng/gf/bl...
方法操作
獲取ORM單例對象
// 獲取默認(rèn)配置的數(shù)據(jù)庫對象(配置名稱為"default") db, err := gdb.Instance() // 獲取配置分組名稱為"user-center"的數(shù)據(jù)庫對象 db, err := gdb.Instance("user-center")
數(shù)據(jù)寫入
r, err := db.Insert("user", gdb.Map { "name": "john", })
數(shù)據(jù)查詢(列表)
list, err := db.GetAll("select * from user limit 2")
數(shù)據(jù)查詢(單條)
one, err := db.GetOne("select * from user limit 2") // 或者 one, err := db.GetOne("select * from user where uid=1000")
數(shù)據(jù)保存
r, err := db.Save("user", gdb.Map { "uid" : 1, "name" : "john", })
批量操作
// BatchInsert/BatchReplace/BatchSave 同理 _, err := db.BatchInsert("user", gdb.List { {"name": "john_1"}, {"name": "john_2"}, {"name": "john_3"}, {"name": "john_4"}, }, 10)
數(shù)據(jù)更新/刪除
// db.Update/db.Delete 同理 r, err := db.Update("user", gdb.Map {"name": "john"}, "uid=?", 10000) r, err := db.Update("user", "name="john"", "uid=10000") r, err := db.Update("user", "name=?", "uid=?", "john", 10000)
注意,參數(shù)域支持并建議使用預(yù)處理模式進(jìn)行輸入,避免SQL注入風(fēng)險。
鏈?zhǔn)讲僮?/b>
鏈?zhǔn)讲樵?/strong>
// 查詢多條記錄并使用Limit分頁 r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*, ud.site").Where("u.uid > ?", 1).Limit(0, 10).Select() // 查詢符合條件的單條記錄(第一條) r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.site").Where("u.uid=?", 1).One() // 查詢字段值 r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("ud.site").Where("u.uid=?", 1).Value() // 分組及排序 r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.city").GroupBy("city").OrderBy("register_time asc").Select()
鏈?zhǔn)礁?刪除
// 更新 r, err := db.Table("user").Data(gdb.Map{"name" : "john2"}).Where("name=?", "john").Update() r, err := db.Table("user").Data("name="john3"").Where("name=?", "john2").Update() // 刪除 r, err := db.Table("user").Where("uid=?", 10).Delete()
鏈?zhǔn)綄懭?保存
r, err := db.Table("user").Data(gdb.Map{"name": "john"}).Insert() r, err := db.Table("user").Data(gdb.Map{"uid": 10000, "name": "john"}).Replace() r, err := db.Table("user").Data(gdb.Map{"uid": 10001, "name": "john"}).Save()
鏈?zhǔn)脚繉懭?/strong>
r, err := db.Table("user").Data(gdb.List{ {"name": "john_1"}, {"name": "john_2"}, {"name": "john_3"}, {"name": "john_4"}, }).Insert()
可以指定批量操作中分批寫入數(shù)據(jù)庫的每批次寫入條數(shù)數(shù)量:
r, err := db.Table("user").Data(gdb.List{ {"name": "john_1"}, {"name": "john_2"}, {"name": "john_3"}, {"name": "john_4"}, }).Batch(2).Insert()
鏈?zhǔn)脚勘4?/strong>
r, err := db.Table("user").Data(gdb.List{ {"uid":10000, "name": "john_1"}, {"uid":10001, "name": "john_2"}, {"uid":10002, "name": "john_3"}, {"uid":10003, "name": "john_4"}, }).Save()事務(wù)操作
開啟事務(wù)操作可以通過執(zhí)行db.Begin方法,該方法返回事務(wù)的操作對象,類型為*gdb.Tx,通過該對象執(zhí)行后續(xù)的數(shù)據(jù)庫操作,并可通過tx.Commit提交修改,或者通過tx.Rollback回滾修改。
開啟事務(wù)操作
if tx, err := db.Begin(); err == nil { fmt.Println("開啟事務(wù)操作") }
事務(wù)操作對象可以執(zhí)行所有db對象的方法,具體請參考API文檔。
事務(wù)回滾操作
if tx, err := db.Begin(); err == nil { r, err := tx.Save("user", gdb.Map{ "uid" : 1, "name" : "john", }) tx.Rollback() fmt.Println(r, err) }
事務(wù)提交操作
if tx, err := db.Begin(); err == nil { r, err := tx.Save("user", gdb.Map{ "uid" : 1, "name" : "john", }) tx.Commit() fmt.Println(r, err) }
事務(wù)鏈?zhǔn)讲僮?/strong>
事務(wù)操作對象仍然可以通過tx.Table或者tx.From方法返回一個鏈?zhǔn)讲僮鞯膶ο螅搶ο笈cdb.Table或者db.From方法返回值相同,只不過數(shù)據(jù)庫操作在事務(wù)上執(zhí)行,可提交或回滾。
if tx, err := db.Begin(); err == nil { r, err := tx.Table("user").Data(gdb.Map{"uid":1, "name": "john_1"}).Save() tx.Commit() fmt.Println(r, err) }
其他鏈?zhǔn)讲僮髡垍⒖忌鲜鲦準(zhǔn)讲僮髡鹿?jié)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/38979.html
摘要:中文介紹是一個輕量級框架,基于,可以看成的精簡版。官方網(wǎng)站項目地址開始使用下載或者安裝依賴包修改數(shù)據(jù)庫配置文件,將導(dǎo)入數(shù)據(jù)庫。一行代碼即可發(fā)送郵件。協(xié)議采用協(xié)議分發(fā),衍生項目除了必須采用協(xié)議之外無任何限制。 TinyLara showImg(http://lvwenhan.com/content/uploadfile/201410/dcd81414652600.png); __...
閱讀 2595·2021-09-23 11:21
閱讀 1891·2021-09-22 15:15
閱讀 982·2021-09-10 11:27
閱讀 3449·2019-08-30 15:54
閱讀 661·2019-08-30 15:52
閱讀 1342·2019-08-30 15:44
閱讀 2356·2019-08-29 15:06
閱讀 2981·2019-08-28 18:21