1.1. 前言
对于之前那种每一个功能都要将SQL语句分成简单语句,取出数据再拼凑。这种方法肯定不是我们想要的结构。这样对任何人都没有好处。而且如果有增加了需求,比如需要查询某个用户在某个店铺下了什么订单。这是我们又要写一遍简单的获取用的信息和订单信息的SQL。这样做显然会让我们的程序边的冗长。
1.2. 改进思路
这时候我们已经把SQL的粒度降低到了最小,说明的每个SQL的复用性将会很高。这时候我们就需要想到分装了。
1.3. 我对分装的理解
复用性高,使用平凡的功能,创建一个方法将它包装起来,提供给其他人调用。
1.4. 需要分装什么
很明显我们需要将每个拆分的SQL进行分装变成一个方法。为了我们更加方便的使用。这样我们在获取数据的时候就不需要关心SQL是如何编写的了。
1.5. 程序实现
该程序我将拆分的SQL分表分装在4个方法中。如下表所示:
分装的方法 | 方法功能 |
get_user_info | 通过用户ID获得“用户”信息 |
get_order_info | 通过用户ID获得“订单”信息 |
get_order_good_info | 通过订单ID获得“订单商品”信息 |
get_coupon_info | 通过订单ID获得“订单使用的券”信息 |
其中有一个业务方法(get_order_detail)实现了用户订单相关信息的获取:完整代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import
pandas
as
pd
import
mysql
.
connector
import
sys
reload
(
sys
)
sys
.
setdefaultencoding
(
'utf-8'
)
def
get_user_info
(
user_ids
,
conn
=
None
)
:
''
'
通过user_id获得用户信息
'
''
user_sql
=
''
'
SELECT user_id, name FROM user WHERE user_id IN({user_id});
'
''
.
format
(
user_id
=
','
.
join
(
user_ids
)
)
user_info
=
pd
.
read_sql
(
user_sql
,
conn
)
return
user_info
def
get_order_info
(
user_ids
,
conn
=
None
)
:
''
'
通过 用户ID 获得订单信息
'
''
order_sql
=
''
'
SELECT user_id, order_id, num FROM orders WHERE user_id IN({user_id});
'
''
.
format
(
user_id
=
','
.
join
(
user_ids
)
)
order_info
=
pd
.
read_sql
(
order_sql
,
conn
)
return
order_info
def
get_order_good_info
(
order_ids
,
conn
=
None
)
:
''
'
通过上面获得的 订单ID 获得订单商品信息。
'
''
order_good_sql
=
''
'
SELECT order_id, good_name FROM order_good WHERE order_id IN ({ids});
'
''
.
format
(
ids
=
','
.
join
(
order_ids
)
)
order_good_info
=
pd
.
read_sql
(
order_good_sql
,
conn
)
return
order_good_info
def
get_coupon_info
(
order_ids
,
conn
=
None
)
:
''
'
通过 订单ID 获得券信息
'
''
coupon_sql
=
''
'
SELECT order_id, name FROM coupon WHERE order_id IN({ids});
'
''
.
format
(
ids
=
','
.
join
(
order_ids
)
)
coupon_info
=
pd
.
read_sql
(
coupon_sql
,
conn
)
return
coupon_info
def
get_order_detail
(
user_id
,
conn
=
None
)
:
''
'
拼凑订单信息
'
''
user_ids
=
[
str
(
user_id
)
]
# 获得用户信息
user_info
=
get_user_info
(
user_ids
,
conn
=
conn
)
# 获得订单信息
order_info
=
get_order_info
(
user_ids
,
conn
=
conn
)
# 获得订单ID
order_ids
=
order_info
[
'order_id'
]
.
astype
(
str
)
# 获得订单商品信息
order_good_info
=
get_order_good_info
(
order_ids
,
conn
=
conn
)
# 获得券
coupon_info
=
get_coupon_info
(
order_ids
,
conn
=
conn
)
# 用户信息 + 订单信息
new_data_1
=
user_info
.
merge
(
order_info
,
left_on
=
'user_id'
,
right_on
=
'user_id'
,
how
=
'left'
)
# new_data_1 + 订单商品信息
new_data_2
=
new_data_1
.
merge
(
order_good_info
,
left_on
=
'order_id'
,
right_on
=
'order_id'
,
how
=
'left'
)
# new_data_2 + 券信息
new_data_3
=
new_data_2
.
merge
(
coupon_info
,
left_on
=
'order_id'
,
right_on
=
'order_id'
,
how
=
'left'
)
return
new_data_3
if
__name__
==
'__main__'
:
conf
=
{
'host'
:
'127.0.0.1'
,
'port'
:
'3306'
,
'database'
:
'test'
,
'user'
:
'root'
,
'password'
:
'root'
}
conn
=
mysql
.
connector
.
connect
(
*
*
conf
)
print
get_order_detail
(
10
,
conn
=
conn
)
conn
.
close
(
)
|
最后输出的结果:
1
2
3
4
5
6
7
8
9
10
11
|
user_id
name_x
order_id
num
good_name
name
_y
0
10
HH
1
11111
order_good_1
coupon
_1
1
10
HH
1
11111
order_good_2
coupon
_1
2
10
HH
2
22222
order_good_3
NaN
3
10
HH
2
22222
order_good_4
NaN
4
10
HH
3
33333
order_good_5
coupon
_3
5
10
HH
3
33333
order_good_6
coupon
_3
6
10
HH
4
44444
order_good_7
NaN
7
10
HH
4
44444
order_good_8
NaN
8
10
HH
5
55555
order_good_9
coupon
_5
9
10
HH
5
55555
order_good_10
coupon_5
|
源代码:no_join_2
上的代码显然让人一看,有一种想自杀的心都有了,不是说会变的简单么怎么,看上去代码还是那么多,而且还引入了分装,这到底是什么鬼!!!此时此刻的我只能“额......”。
麻烦大家先抛开代码还是很多的缺点,我们再来分析一下,如果现在的需求变了,说前台不用显示券的信息。这时候我们是不是只需要将get_order_detail方法中有关券的东西给注释掉就好了,而不需要去看之前的SQL是如何写的。如果,需求有变了说,需要显示每个订单是属于哪个门店的(假设我们这里有门店表,并且订单中有“门店ID”)。是不是只需要分装一个类似的get_store_info方法来回去门店信息(这个方法里面还是简单的SQL)。并只要在业务方法get_order_detail中调用get_store_info方法并将结果和之前的结果进行拼凑就好。这时候是不是连之前的SQL都不需要看只需要知道之前的输出是什么。
(提示:需求变更的时候,需要修改代码时,发现要看很长的SQL的时候,往往是很痛苦的。并且如果是修改自己编写的SQL还好,如果是交给其他人来修改。我只能说:“兄弟辛苦你了,为了你的不吃亏。你也写复杂SQL让给别人改吧。这样你的心情应该会好”)
如果大家文章看到这里,觉得要使用拆分SQL能很好的应付业务的变更这一点没有打动你。你的问题关注在我要代码少。那就请你往下看了。
昵称:HH
QQ:275258836
ttlsa群交流沟通(QQ群②:6690706 QQ群③:168085569 QQ群④:415230207(新) 微信公众号:ttlsacom)
感觉本文内容不错,读后有收获?
逛逛衣服店,鼓励作者写出更好文章。
转载请注明:成长的对话 » 会用JOIN,却不懂编程的“程序员”(3)