GoFrame代碼優(yōu)化gconv類型轉(zhuǎn)換避免重復定義map
前言
最近一直在研究 GoFrame 框架,經(jīng)過一段時間的使用、總結、思考,發(fā)現(xiàn)確實不失為一款非常值得使用的企業(yè)級開發(fā)框架。
在我初識GoFrame教程后,曾整理過一篇文章: 非常適合PHP同學學習的GO框架:GoFrame,有興趣的同學可以閱讀一下。
今天重點講一下我使用GoFrame的代碼優(yōu)化之旅。
核心重點
GoFrame幾乎封裝了所有能封裝的東西,而我們需要做的就是在框架的基礎上約定好自己項目的開發(fā)規(guī)范。
一定要遵守統(tǒng)一的規(guī)范!
一定要遵守統(tǒng)一的規(guī)范!
一定要遵守統(tǒng)一的規(guī)范!
類型轉(zhuǎn)換:GoFrame框架提供了非常強大易用的類型轉(zhuǎn)換包gconv,可以實現(xiàn)將常用數(shù)據(jù)類型轉(zhuǎn)換為指定的數(shù)據(jù)類型,對常用基本數(shù)據(jù)類型之間的無縫轉(zhuǎn)換,同時也支持任意類型到struct對象的轉(zhuǎn)換。由于gconv模塊內(nèi)部大量優(yōu)先使用了斷言而非反射,因此執(zhí)行的效率非常高。
數(shù)據(jù)庫ORM:通過Scan方法自動識別Map/Struct接收查詢結果,自動化查詢結果初始化、結構體類型轉(zhuǎn)換; 完美支持GoFrame框架層面的DAO設計,全自動化Model/DAO代碼生成,極大提高開發(fā)效率。
以上兩個部分是重中之重,建議大家好好研究。
類型轉(zhuǎn)換 和 數(shù)據(jù)庫ORM 也是我下面優(yōu)化代碼的重要參考。
優(yōu)化前
//獲取商品類目接口
func (s *goMeGoodsService) GetCategory(pid ...interface{}) {
ctx := context.Background()
res, err := gome.Category.Get(ctx, pid)
if err != nil {
checkErr(err, "GetCategory AddCategory")
}
data := res.Data
for _, v := range data {
if v.Code != "" && v.Name != "" {
_, err = s.AddCategory(v.Level, v.Code, v.Name, v.ParentCode)
checkErr(err, "GetCategory AddCategory")
}
}
}
//添加分類
func (s *goMeGoodsService) AddCategory(level int, code, name, parent_code string) (id int64, err error) {
categoryMapping := map[string]interface{}{
"level": level,
"code": code,
"name": name,
"parent_code": parent_code,
}
sqlRes, err := dao.GomeCategory.Data(categoryMapping).Insert()
if err != nil {
return
}
id, err = sqlRes.RowsAffected()
if err != nil {
return
}
return
}
這種重復定義讓我很難受:
categoryMapping := map[string]interface{}{
"level": level,
"code": code,
"name": name,
"parent_code": parent_code,
}
優(yōu)化后:
去掉定義map:
//獲取商品類目接口
func (s *goMeGoodsService) GetCategory(pid ...interface{}) {
ctx := context.Background()
res, err := gome.Category.Get(ctx, pid)
if err != nil {
checkErr(err, "GetCategory AddCategory")
}
//循環(huán)單條插入
for _, v := range res.Data {
_, err := dao.GomeCategory.Data(v).Insert()
if err != nil {
checkErrGome(err, "db添加分類失敗")
}
}
}
可以這么寫的原因
func (categoryGome) Get(ctx context.Context, pid ...interface{}) (res *CategoryRes, err error) {
method := "alemein.basic.get.category"
req := g.Map{}
if len(pid) > 0 {
req["parentCode"] = pid[0]
}
result, err := server.requestApi(ctx, method, req)
if err != nil {
return
}
_ = gjson.New(result).Scan(&res)
return
}
gome.Category.Get(ctx, pid) 返回的是 CategoryRes結構體:
type CategoryRes struct {
*CommonRes
Data []struct {
Code string `json:"code"`
Level int `json:"level"`
ParentCode string `json:"parentCode"`
Name string `json:"name"`
} `json:"data"`
}
進一步優(yōu)化 批量寫入
CategoryRes.Data 就是需要入庫的數(shù)組,我們直接使用Data()函數(shù)賦值,進行批量插入就行了。(默認每次插入10條數(shù)據(jù),可以通過batch(x)指定每次插入的數(shù)據(jù)條數(shù))
dao.GomeCategory.Data(res.Data).Insert()
更優(yōu)雅的寫法如下
//獲取商品類目接口
func (s *goMeGoodsService) GetCategory() {
ctx := context.Background()
//一級類名
res, err := gome.Category.Get(ctx)
if err != nil {
checkErr(err, "GetCategory AddCategory")
}
//批量插入 優(yōu)雅
_, batchErr := dao.GomeCategory.Data(res.Data).Insert()
if batchErr != nil {
checkErr(batchErr, "批量更新一級目錄失敗")
}
}
可以向上滑,看看優(yōu)化前的代碼是怎么寫的。
優(yōu)化后的代碼完全實現(xiàn)了優(yōu)化代碼前的功能,且性能更好,因為使用了批量插入。
總結
避免這種重復定義map的代碼, 合理使用gconv對map、結構體、結構體數(shù)組進行轉(zhuǎn)換。
不要像下面這樣寫代碼!NO!
//添加分類
func (s *goMeGoodsService) AddCategory(level int, code, name, parent_code string) (id int64, err error) {
categoryMapping := map[string]interface{}{
"level": level,
"code": code,
"name": name,
"parent_code": parent_code,
}
sqlRes, err := dao.GomeCategory.Data(categoryMapping).Insert()
if err != nil {
return
}
id, err = sqlRes.RowsAffected()
if err != nil {
return
}
return
}
要有這種優(yōu)化代碼的意識,當我們意識到重復定義時,就一定有辦法優(yōu)化。
當我們意識到邏輯混亂時,就一定有辦法優(yōu)化結構,混亂的邏輯往往是設計的不合理導致的。
以上就是GoFrame代碼優(yōu)化gconv類型轉(zhuǎn)換避免重復定義map的詳細內(nèi)容,更多關于GoFrame gconv類型轉(zhuǎn)換的資料請關注腳本之家其它相關文章!

