go日常使用总结

3 篇文章 0 订阅

前言

不知不觉入职也有1个月了,逐渐习惯了使用go语言开发,也在使用中遇到一些问题,就当作是月度总结好了。

总结

1. sql相关

sql单引号拼接问题

尽量不要直接用%s、%d、%v之类的拼值,先拼?,?,?,?,然后直接传值,走sql包的赋值,会自动过滤sql注入,用可变参数的…展开参数。即使用2个切片,一个string类型切片,用来存储(?,?,?),一个空接口接收任意类型的切片,用来存储传给占位符?的参数,通过strings.Join()方法,将多个(?,?,?,?)传入%s,参数使用可变的空接口类型切片。

//eg.
_update = ‘UPDATE resource SET state=? WHERE group_id IN (%s)’
var(
	sqls []string
	args []interface{}
)
Args = append(args, model.ApplyNoAssignment)
for _, id := range ids {
	sals = append(sals, “?”)
	args = append(args, id)
}
res, err := tx.Exec(fmt.Sprintf(_update, strings.Join(sals, “,”)), args…)

批量insert问题

在批量插入时,使用批量insert语句而非多条insert语句

# 批量INSERT INTO语句,这是正确的语法示例

INSERT INTO tb(col1,col2) VALUES(value1,values2),(value3,values4),(value5,values6);

rowStrings := make([]string, 0, len(wids))
rowArgs := make([]interface{}, 0)
ctime := time.Now()
for _, v := range wids {
	rowStrings = append(rowStrings, "(?,?,?,?,?,?,?,?)")
	rowArgs = append(rowArgs, item.Sid, v, item.Mid, item.Type, item.State, item.StickTop, ctime, ctime)
}
tx := d.DB.Begin()
if err = tx.Model(&model.Like{}).Exec(fmt.Sprintf(_likeBatchSQL, strings.Join(rowStrings, ",")), rowArgs...).Error; err != nil {
	err = errors.Wrapf(err, " d.DB.Model(&model.Like{}).Exec(%s)", _likeBatchSQL)
	tx.Rollback()
	return
}

SQL的ErrNoRows问题

Query不会返回ErrNoRows错误,因此不需要这个判断。只有QueryRow才会返回该错误

where可能存在重复的问题:

db:=d.DB.Model(&show.EntranceSave{}).Where(“state!=2”)
If state != _allList {
	db = db.Where(“state=?”,state)
}
Db.Count(&res.Pager.Total)
//重复where条件,因写成如下形式:
db := d.DB.Model(&show.EntranceSave{})
	if state != _allList {
		db = db.Where("state=?", state)
	} else {
        db = db.Where("state!=2")
    }

2. 对象初始化问题

写法一:

If err = d.mc.Get(c,key).Scan(attrsCache) 

这种写法,传递的是对象本体,并且对象本地是个指针,因此必须对对象本体进行指针地址的初始化,方式如下:

//方式一:
attrsCache = new(model.EdgeAttrsCache)
//方式二:
attrsCache = &model.EdgeAttrsCache{}

写法二:

If err = d.mc.Get(c,key).Scan(&attrsCache)

这种写法传递的是对象本体的地址,在取对象地址时,就已经对对象本体初始化了,可以不再对对象本体进行额外初始化。

3. 空值判断

在公司mc生成器生成的代码中,一般对于查询成功但无记录现象置err为nil,因此在上层逻辑中就需要判断err==nil且res!=nil缓存命中才成功。db中当err不是nil时,直接返回

对于http接口获取的对象,需要进行空指针判断,防止对方接口对结构体或结构体中某个对象传递了nil,此时调用方将会panic

4.异步消费

当业务逻辑为read cache -> cache miss -> 回源 -> add cache,这是一个完全同步的过程,其中add cache可以塞到chan,给一个goroutine异步消费,最好不要同步add cache的逻辑。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值