目的:实现app列表筛选。

一、思路

原本是Java项目做的,感觉有些复杂,相反,Python代码较为简洁,改用Python实现。

要想实现筛选,就要想办法如何动态根据请求的条件写sql语句,第一步要考虑的是如何更好的封装请求到后台,以便于根据条件动态的拼接sql语句。

二、条件封装

首先将要所有要筛选的条件封装成json数据在请求里,形如:

{"MainCategories": "0","strategy": "0",
 "ManagementScale": "0","MaximumDrawdown":"0",
 "BusinessCity": "0","NumOfFund": "0",
 "NumberOfEmployees": "0","EstablishedTime": "0",
 "ContributedCapital": "0","PositiveRatio": "0"}

解释一下:"MainCategories": "0","MainCategories"代表单个条件(这只是我用到的,更具自己实际情况更换),"0"代表默认/不限,这是一个默认的情况。想要"MainCategories"的多个限制,可以传:"MainCategories": "1,2,3...:,这里1,2,3代表相应的限制,比如MainCategories这个条件是主要类型包含“不限”、“会员”、“非会员”、“高级会员”,那么0代表限制里的“不限”,1代表“会员”,2代表“非会员”,3代表“高级会员”,这样就可以完美的把想要的条件传到后台。其他条件原理一样。

三、条件处理

然后重点来了,再看一下如何获取json封装的条件并且处理。

我用的龙卷风框架(tornado),直接获取:

content = self.get_argument("content")//注:我请求的json数据的名字叫content。

此处封装一个方法,ReadJson(content):将json数据传过去。

方法内初始化sql条件:

sb = "" //注意,不是骂人,仿照java里的StringBuilder的缩写。

然后方法内首先要判断所传条件是否为空:

#若为空,直接返回空字符串,不做条件限制,直接查询全部。
if content == None or content =="":
   return sb

#若json条件不为空,python解析json转化为字典:

jsonObject = json.loads(client)//这里jsonObject是一个字典。包含key,value,这就好处理了。

//下班回家了,未完待续。。。

11.1

接下来的得到了包含我们传的条件的字典jsonObject,进行判断具体的条件,下面以第一个条件为例:

#判断“MainCategories”这个条件的值是否为空
if jsonObject is not None and jsonObject.get("MainCategories") is not None:
    #此时封装一个方法sqlPackage1()用来组装单个条件的sql
    #详细见:四、单条件内部判断、拼接
    mcSql = sqlPackage1(jsonObject.get("MainCategories"))
    #若MainCategories这个条件不是传的0,则代表不是不限,需要拼接单个条件的sql。
    if not operator.eq(jsonObject.get("MainCategories"),"0"):
        #再次封装一个方法,负责所有条件的处理(让所有条件作为sql语句无缝连接)
        #详细见:五、处理多个条件拼接的桥梁方法
        sb1 = ConnectComponents(sb, mcSql)
#这里sb1是第一个条件的sql语句

//下班回家了,未完待续。。。

四、单条件内部判断、拼接

以下是组装单个条件的sql方法:

#机构类型
def sqlPackage1(str):
    #定义一个集合组装载单个条件的sql
    mainCategoriesSQL=[]
    #获取所传条件
    mainCategories = str.split(",")
    for item in mainCategories:
        #若条件有0直接break结束循环,条件都是不限了,还组装个毛毛。。
        if item == "0":
            break
        #其他情况,根据需求封装,like模糊,=精准,between值范围。。。等等等
        elif item == "1":
            mainCategoriesSQL.append("c.MainCategories LIKE '%%证券%%'")
        elif item == "2":
            mainCategoriesSQL.append("c.MainCategories LIKE '%%股权、创业%%'")
        elif item == "3":
            mainCategoriesSQL.append("c.MainCategories LIKE '%%其他%%'")

    return mainCategoriesSQL
#假如第一个条件是:MainCategories:“1,2,3”,那么返回的sql字符串应该是:
    c.MainCategories LIKE '%%证券%%',c.MainCategories LIKE '%%股权、创业%%',c.MainCategories LIKE '%%其他%%'
#不要急,下面标题五里会对这个字符串进行处理的。

五、处理多个条件拼接的桥梁方法

见以下代码:

#连接各条件sql
#这里sb只是个空字符串而已,和上面的总sql没关系,这里的sql是标题四代码里返回的字符串
def ConnectComponents(sb,sql):
    拼接and条件
    sb+=" AND "
    #加入括号
    sb+="("
    #遍历字符串sql
    for str in sql:
        #拼接单个条件多情况OR语句
        sb=sb+str+" OR "
    
    #拼接右边
    sb+=") "
    #去OR除尾部多余的 OR 和“ )”
    sb_ = sb.rstrip(" OR ) ")
    #最后加上结尾的括号
    sbb = sb_+") "
    
    return sbb
#若是条件一,此时输出的语句应该是:
 AND (c.MainCategories LIKE '%%证券%%' OR c.MainCategories LIKE '%%股权、创业%%' OR c.MainCategories LIKE '%%其他%%') 
 #后面条件同理

最后,各个条件同理,组装在一起返回即可:

sb = sb1+sb2+sb3+sb4+sb5+sb6+sb7+sb8+sb9+sb10

return sb

未完待续。。。

12.10

以上仅仅是sql语句where后面的条件.

六、完整sql语句最终拼接

一个完整的sql要有头有尾,仅仅有条件自然是不行的,详见以下代码(含注释):

#首先保证sql有"头":select * from company c where 1=1,要给一个条件恒等式,防止后面封装的条件没有,我们都知道不推荐select * 查询,这里先这么写,方便查看完整sql
    basicsq = "select * from company c where 1=1"
    #这个addsql(名字瞎起的)就是我们根据所传条件要封装的条件语句了,ReadCompanyJson(content, client)这是个方法,就是前文封装条件的方法
    addsql = ReadCompanyJson(content, client)
    #这句就是保证sql有"尾"咯,可以根据实际需要,加上排序条件
    endsql1 = " order by c.IsId desc "
    #最后这是给sql加上分页条件,这个一般推荐使用,因为数据量太大分页还是很有必要的
    endsql2 = " limit  %s,%s" % (page * pageSize, pageSize)
    #全部语句相加,最终sql就完成了~
    sql = basicsq + addsql + endsql1 + str(endsql2)
    #将最终sql传入执行查询的方法,接下来详细贴代码
    company = screenCompany(sql)
    #最后返回结果,完事了~
    return company

七、执行sql的方法详情

#自己定义的方法
def screenCompany(sql):
    #mysql引擎,也是自己封装的,可以直接调用
    mysql=MysqlHelper("机构产品")
    #参数,这个就不用传了
    params=[]
    #根据sql执行方法查询,得到结果,返回就好了
    result = mysql.get_all(sql, params)

大功告成~