代码获取
本篇文章的代码放在了Github上,可以免费获取。
https://github.com/zhangdapeng520/zdpgo_gin_examples
概述
在查询用户信息的时候,由于密码这个字段比较敏感,需要进行处理,不要返回给前端。
我一开始的解决方案是直接查询数据以后做一次转换,但是这种方案效率比较低,所以我就在思考有没有更快的方案?
比如说,能不能直接选择特定字段进行查询。
结果是令人满意的,gorm提供了Select这个方法,可以让我们选择特点的字段。
官方文档
https://gorm.io/zh_CN/docs/query.html
Select allows you to specify the fields that you want to retrieve from database. Otherwise, GORM will select all fields by default.
db.Select("name", "age").Find(&users)
// SELECT name, age FROM users;db.Select([]string{"name", "age"}).Find(&users)
// SELECT name, age FROM users;db.Table("users").Select("COALESCE(age,?)", 42).Rows()
// SELECT COALESCE(age,'42') FROM users;
Also check out Smart Select Fields
刚开始的解决方案
func userGetAll(c *gin.Context) {var users []model.Userg.GDB.Find(&users)// 转换var data []userResponsefor _, user := range users {data = append(data, userResponse{Id: user.Id,Username: user.Username,Money: user.Money,})}c.JSON(200, data)
}
通过postman进行测试。
经过实测,这种方案确实是能够查询到想要的东西的。
然后我检查了日志:
消耗的时间是1.0227ms。
该方案缺点
1、代码量比较多,需要定义额外的结构体,需要编写解析的代码。
2、时间复杂多明显增加,因为遍历操作是O(n),所以时间复杂度会增加O(n)
后来的解决方案
func userGetAll(c *gin.Context) {var users []model.Userg.GDB.Select([]string{"id", "username", "money"}).Find(&users)c.JSON(200, &users)
}
通过postman进行测试。
经过实测,也是能够出来的。
然后我观察了一下控制台的日志。
消耗的时间是,518.8us,之前的方案是 1.0227ms。
1ms = 1000us,所以通过Python可以计算。
新方案的时间是之前方案的1.97倍,也就是将近2倍的时间。
这个是在数据量只有1条的情况下,如果数据量变得非常多,新方案的收益是非常可观。
新方案的缺点
主要是在回显给前端的时候,有password的这个字段,虽然这个字段是空的。
解决方案
给结构体的json解析tag增加标签,增加omitempty这个标识符。表示如果该字段是空值,就不要解析了。
type User struct {Id int `json:"id"`Username string `json:"username"`Password string `json:"password,omitempty"`Money float64 `json:"money"`
}
经过 postman 实测,效果达到了。
经过多次请求的测试,发现接口性能有一定的提升。
总结
本篇文章主要讲解了gorm如果实现指定字段查询,然后还提供了go语言json解析时如果字段是空值如何不让其回显给前端的方案。
人生苦短,我用pygo,我是您身边的Python私教。
如果你想学编程,做项目,或者提升自己的技术,都欢迎您联系我。