成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

可能這就是做開源項目的意義吧!

開源
使用了with模型關聯,核心思路是:根據傳入參數區分查詢對應的關聯模型,不做無效查詢。

本文重點

  1. 使用goframe v2最新版的最佳實踐
  2. 列表取值slice容量初始化,避免scan動態擴容
  3. slice的延遲初始化
  4. 更新操作注意的問題

老規則:我把詳細步驟已經整理好,大家可以參考這個步驟進行開發,更歡迎提優化建議。

取值列表優化

下方代碼示例是項目之前的列表取值寫法,和官方示例focus-single寫法一樣,思路如下:

  1. 獲得*gdb.Model對象,方便后續調用
  2. 實例化返回結構體
  3. 分頁查詢
  4. 執行查詢和賦值(只是為了查詢有無數據,并沒有賦值到響應結構體中)
  5. 無數據判斷
  6. 再查詢count,獲得數據個數
  7. 把查詢到的結果賦值到響應結構體中

每段代碼都寫清楚了注釋,這么寫能實現功能,但是性能不夠好,還有優化空間:

// GetList 查詢內容列表
func (s *sAdmin) GetList(ctx context.Context, in model.AdminGetListInput) (out *model.AdminGetListOutput, err error) {
//1.獲得*gdb.Model對象,方便后續調用
var (
m = dao.AdminInfo.Ctx(ctx)
)
//2. 實例化返回結構體
out = &model.AdminGetListOutput{
Page: in.Page,
Size: in.Size,
}
//3. 分頁查詢
listModel := m.Page(in.Page, in.Size)
//4. 執行查詢和賦值(只是為了查詢有無數據,并沒有賦值到響應結構體中)
var list []*entity.AdminInfo
if err := listModel.Scan(&list); err != nil {
return out, err
}
//5.無數據判斷
if len(list) == 0 {
return out, nil
}
//6. 再查詢count,獲得數據個數
out.Total, err = m.Count()
if err != nil {
return out, err
}
//7. 把查詢到的結果賦值到響應結構體中
if err := listModel.Scan(&out.List); err != nil {
return out, err
}
return
}

整理一下上面代碼的問題:

  1. 步驟4沒有必要,可以直接查詢count,如果count為0直接返回;否則再執行查詢賦值操作
  2. 上述這種寫法有個問題:當沒有查詢到數據時,list值為null,但是我們期望的返回值為空數組[]

圖片

  1. 還有就是slice的容量初始化下會更好,scan期間不會有擴容行為
  2. 再者就是延遲slice的初始化,如果前面出錯,就沒有必要實例化列表了

我們優化一下代碼,優化后的代碼如下,也寫了詳細的注釋:

  1. 獲得*gdb.Model對象,方便后續調用
  2. 實例化響應結構體
  3. 分頁查詢
  4. 再查詢count,判斷有無數據
  5. 延遲初始化list切片 確定有數據,再按期望大小初始化切片容量
  6. 把查詢到的結果賦值到響應結構體中
// GetList 查詢內容列表
func (s *sAdmin) GetList(ctx context.Context, in model.AdminGetListInput) (out *model.AdminGetListOutput, err error) {
//1. 獲得*gdb.Model對象,方便后續調用
m := dao.AdminInfo.Ctx(ctx)
//2. 實例化響應結構體
out = &model.AdminGetListOutput{
Page: in.Page,
Size: in.Size,
}
//3. 分頁查詢
listModel := m.Page(in.Page, in.Size)
//4. 再查詢count,判斷有無數據
out.Total, err = m.Count()
if err != nil || out.Total == 0 {
//解決空數據返回[] 而不是返回nil的問題
out.List = make([]model.AdminGetListOutputItem, 0, 0)
return out, err
}
//5. 延遲初始化list切片 確定有數據,再按期望大小初始化切片容量
out.List = make([]model.AdminGetListOutputItem, 0, in.Size)
//6. 把查詢到的結果賦值到響應結構體中
if err := listModel.Scan(&out.List); err != nil {
return out, err
}
return
}

優化代碼之后,無數據的list返回格式和預期一樣為[]:

圖片

這是有數據的返回結果示例:

圖片

以上優化記錄已經同步到GitHub,歡迎查看、復刻經驗:

??https://github.com/wangzhongyang007/goframe-shop-v2/commit/ee020ea96616c30cb5bce5f7ab24417ad56e1a67??

上面的例子很簡單,就是普通的查詢數據,也沒有搜索條件,也不涉及到模型關聯。

關聯查詢取值

咱們再舉一個復雜點的例子,帶大家進階一下,我就直接安排優化后的代碼了:

  1. 定義全局通用的查詢語句
  2. 實例化響應結構體
  3. 翻頁查詢
  4. 優先查詢count,報錯或者無數據則直接返回
  5. 延遲初始化list 確定有數據再按期望大小,實例化切片的容量
  6. 進一步優化:根據傳入參數區分查詢對應的關聯模型
// GetList 查詢內容列表
func (*sCollection) GetList(ctx context.Context, in model.CollectionListInput) (out *model.CollectionListOutput, err error) {
//1. 定義全局通用的查詢語句
userId := gconv.Uint(ctx.Value(consts.CtxUserId))
m := dao.CollectionInfo.Ctx(ctx).Where(dao.CollectionInfo.Columns().Type, in.Type).
Where(dao.CollectionInfo.Columns().UserId, userId)
//2. 實例化響應結構體
out = &model.CollectionListOutput{
Page: in.Page,
Size: in.Size,
}
//3. 翻頁查詢
listModel := m.Page(in.Page, in.Size)
//4. 優先查詢count,報錯或者無數據則直接返回
out.Total, err = listModel.Count()
if err != nil || out.Total == 0 {
out.List = make([]model.CollectionListOutputItem, 0, 0)
return out, err
}
//5. 延遲初始化list 確定有數據再按期望大小,實例化切片的容量
out.List = make([]model.CollectionListOutputItem, 0, in.Size)
//6. 進一步優化:根據傳入參數區分查詢對應的關聯模型
if in.Type == consts.CollectionTypeGoods {
if err := listModel.With(model.GoodsItem{}).Scan(&out.List); err != nil {
return out, err
}
} else if in.Type == consts.CollectionTypeArticle {
if err := listModel.With(model.ArticleItem{}).Scan(&out.List); err != nil {
return out, err
}
} else {
if err := listModel.WithAll().Scan(&out.List); err != nil {
return out, err
}
}
return
}

上面的示例使用了with模型關聯,核心思路是:根據傳入參數區分查詢對應的關聯模型,不做無效查詢。

更新操作

使用OmitEmpty,更新操作過濾空值,比如:

func (*sAddress) Update(ctx context.Context, in model.UpdateAddressInput) (err error) {
if _, err = dao.AddressInfo.Ctx(ctx).Data(in).OmitEmpty().Where(dao.AddressInfo.Columns().Id, in.Id).Update(); err != nil {
return err
}
return nil
}

我開發過程中原本沒有使用OmitEmpty(),忽略了這個問題,感謝這位朋友提的建議。

開源項目地址:

做開源項目這件事,從沒想過一蹴而就,想得一直是越來越好,投入長期精力:??https://github.com/wangzhongyang007/goframe-shop-v2??

本文轉載自微信公眾號「 程序員升級打怪之旅」,作者「王中陽Go」,可以通過以下二維碼關注。

轉載本文請聯系「 程序員升級打怪之旅」公眾號。

責任編輯:武曉燕 來源: 程序員升職加薪之旅
相關推薦

2015-08-26 17:02:45

2018-11-08 15:30:04

JavaScriptES6異步

2015-07-21 10:24:02

Windows RT升級

2014-01-02 14:04:42

2014-04-14 09:58:18

開源項目

2019-01-02 04:40:19

物聯網企業IOT

2021-09-03 10:44:42

ThreadLocalObject 數組

2020-02-17 15:55:22

Office 365

2024-12-13 16:37:56

SpringBootJava

2016-01-12 17:01:45

Bootstrap原因

2015-07-27 10:56:02

2014-03-19 10:26:03

持續更新軟件開發

2024-04-24 09:47:36

2015-01-09 10:10:00

Linux

2018-11-01 13:38:51

Java中斷停止

2020-07-17 19:31:19

PythonR編程

2013-08-14 14:36:07

開源項目

2012-03-06 09:17:11

開源項目運作

2022-07-27 14:47:01

開源項目

2021-02-20 17:36:30

Google開源項目漏洞
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费国产黄网站在线观看视频 | 九九国产| 中文字幕亚洲一区二区三区 | 成人二区 | 91精品久久久久久综合五月天 | 日韩在线精品 | 99色综合| 精品一区二区视频 | 伊人99| 日韩一区二区福利 | 99久久免费精品国产免费高清 | 久久国产精品免费视频 | 国精久久| 久久久久国产一区二区三区 | 一区二区电影 | 亚洲第一在线 | 日本精品视频在线 | 精品一区二区三区在线播放 | 欧美日在线 | 中文字幕高清一区 | 精品国产一区二区三区性色av | 国产精品揄拍一区二区久久国内亚洲精 | a久久久久久 | 日本一区二区影视 | 亚洲色欧美另类 | 日韩一区二区三区在线播放 | 99精品网 | 亚洲免费视频在线观看 | 欧美aaa级 | 精品欧美激情在线观看 | 久久综合狠狠综合久久综合88 | 视频一区在线观看 | 99成人免费视频 | av电影一区二区 | 久久免费精品 | 国内精品成人 | 色吊丝2288sds中文字幕 | 在线色网| 久一精品| 黄免费观看 | 亚洲第一天堂无码专区 |