目的:实现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)
大功告成~