问题描述
- 假如我需要查询一个东西,就把这个东西当成球吧,一个球有不同的分类,所以有一个分类id叫做category_id。然后这个球又有不同的品牌,所以还有一个brand_id。当然,除了这两个之外还有别的一些属性。
class Ball{
private int category_id;
private int brand_id;
//xxx 其他属性
}
- 就大概是这么个结构,所以category_id与brand_id确定唯一的一条数据,并且也会只根据category_id查询所有同一个分类的球,也会根据brand_id查询同一个品牌的球。category_id与brand_id在数据库中都有可能为0。
- 综上可以得出会有这么几种查询:
- 根据categroy_id与brand_id查唯一的球
- 查询同一个categroy_id的所有球,查询同一个brand_id的所有球
- 无条件查询所有值
我的奇葩操作
当时我是这么想的,正常来说前端不填写category_id与brand_id的话这两个值就是0,所以如果当这两个值为0的时候查询唯一值与无条件查询就冲突了。
然后我竟然盯上了前端一定会传过来的另外两个参数:offset、limit。这两个参数用于分页嘛,那我查询唯一值的时候是不是这两个参数可以算用不上,本着绿色环保、节约内存的原则,就不需要加别的字段了。
这个逻辑就被我魔改为当offset、limit都为-1的时候,就是精准查询,当category_id为-1的时候就是查询所有的品牌,当brand_id为-1的时候就是查询所有的分类。当这四个参数都不等于-1就是无条件查询。
现在回忆自己当时的想法都觉得恶心,一个接口被搞得使用条件与限制这么多,用起来真的不知道多恶心。但是这个接口一直没有接界面,我觉得当时让我写这个接口的crud也就是让我熟悉开发流程而已。毕竟写了也没人调。。。
然后这个问题就在接完界面之后发生了,首先是界面不是我和前端沟通设计的,所以传-1这种行为是不可能的,并且offset、limit也不可能传-1,因为不管是精准查询还是查询所有,走的都是同一个查询接口,前端不可能给我判断好是精准查询还是查询所有值。所以除了这个接口就只能查出所有值,其他查询功能都不能用了。
也就是我发现问题的那天,需求变了,需要加一个month字段,并且通过category_id、brand_id、month来确定唯一值,这三个都需要分别的查询。我听完直接痛苦面具。三个字段难道我要控制另外两个为-1?
然后我也不知道犯了什么毛病继续把这个接口改成了需要传category_id、brand_id、month都为-1是无条件查询。。。这个接口身边一个同事(算我的小领导吧)问了我一句,你这个接口不加条件能查出全部数据吧。我很不好意思的说,需要把category_id、brand_id、month都传-1。说到一半我自己都笑了。
解决办法
- 说实话当时也确实想不出什么好办法来优化这个查询接口,然后小领导就给我教了我一个办法。他说:你想不到什么好办法的时候就可以去看看别人怎么写的,然后他顺手打开了头条的一个查询文档,指给我看人家查询用的是数组。他继续说:数组的话是不是完美解决了这个参数会为0的情况。
- 仔细一想,还真是!如果不传值的话这个数组长度就会为0或者是一个空值(go语言的话空值也可以判断长度),有值的话就取下表为0就好了。
- 所以只需要判断数组长度大于0,如果有值就把值加到where语句后面就完全可以支持各种查询。非常丝滑的解决了这个查询问题,真的是爱了爱了~