两个星期的数据库课程设计,做了这样一个简单的小应用,给出github地址。这里做个简单的记录。
主要内容
安卓应用市场管理系统,本系统面向用户,管理员,开发者三方
1.用户:实现用户注册和登录;实现app的详情查看,下载,评分,反馈
2.管理员:审核app的上架,下架;控制开发者或用户的账号注销,规范开发者的开发行为,查看系统的整体情况
3.开发者:实现开发者注册和登录;提交app(给管理员审核),更新app,查看开发app的评分反馈
工具&&环境
编辑器:visual studio code1.35.1
数据库:mysql Ver 14.14 Distrib 5.7.21, for Linux (x86_64)
编程语言:python3.6.5
系统框架:使用python内置tkinter GUI模块,第三方pymysql模块
硬件系统:Linux deepin 15.9.10
图形界面设计
各种语言都有自己的GUI库,Python本身就有不止一个GUI库。而其中tkinter是最简单的,较容易上手。因为之前并没有接触过GUI编程,所以选择了简单的tkinter模块。
控件函数绑定
主要使用tkinter中的button ,label entry,menubar组件来实现基本的GUI要求。通过将GUI控件和相关的函数通过bind函数command选项绑定,来实现具体的功能。
这种绑定存在一个问题,就是command中的函数不能带参数。这意味着无法为具体的应用设计相应的GUI控件。查了很多资料,后来知道,这里需要使用lambda语句。1
2
3
4
5
6
7
8for i in t:
print(i,i[0],type(i[0]))
# Button(self,text='下载\更新',command = self.Download).grid(row = x+2,column=4)
# Button(self,text='下载\更新',command = self.Rating).grid(row = x+2,column=4)
Button(self,text='评价',command = lambda:self.Download(i[0])).grid(row = x+2,column=6)
Button(self,text='评价',command = lambda:self.Rating(i[0])).grid(row = x+2,column=5)
# Button(self,text='评论').grid(row = x+2,column=6)
x=x+1
以上面的代码为例,理想情况是每一个应用有各自的评价按钮,而不是使用全局按钮,然后再输入应用名字,最后输入评论。
为了达到以上的目标,故使用lambda表达式来接收参数。
布局管理器
tkinter提供了多种布局管理器。我主要使用grid()方法;对于简单的界面,使用pack()。通过定义参数,确定控件的样式和位置。1
2
3
4
5
6#grid()布局管理器
Label(self,text='{0}'.format(i[0])).grid(row=x+2,column=0)
Label(self,text='{0}'.format(i[1])).grid(row=x+2,column=1)
#pack()布局管理器
self.queryPage.pack()
self.aboutPage.pack_forget() #忽略页面
交互界面设计
tkinter提供了一些很方便的控件来进行程序的交互界面设计。
showinfo()
1
showinfo(title='无记录', message='找不到该应用信息!')
askinteger()
1
self.developerid =simpledialog.askinteger(title="提示",prompt="请确定您的个人信息,输入您的开发者ID")
askyesno()
1
signal=askyesno(title="提示",message="您是否确定提交评论")
数据库设计
数据库中的设计元素很大部分是为了使用这个元素而设计的,有点刻意。比如视图,触发器,索引等等。但这些尝试让我对数据库理解的更加深刻,还是简单记录一下。
触发器设计
当删除一个开发者时,将删除其开发的应用和涉及到这些应用的评论。
第一个触发器1
2
3
4
5
6
7
8
9
10mysql> delimiter $
->create trigger dev_delete
->before delete on
->developer
->for each row
->begin
->delete from insideapp where old.developerid=insideapp.developerid;
->end$
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
第二个触发器1
2
3
4
5
6
7
8
9
10mysql> delimiter $
->create trigger insideapp_delete
->before delete on
->commenttable
->for each row
->begin
->delete from commenttable where old.insideappid=commenttable.appid;
->end$
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
数据库存储过程设计
为了给管理员提供动态的了解系统情况的接口,我想设计一个接口,而不是每次都从表中读取。
本来用视图尝试了很多办法,最后也没折腾出来。快要放弃的时候发现存储过程有处理这个问题的能力。1
2
3
4
5
6
7
8
9
10DROP procedure IF EXISTS `return_sum`;
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `return_sum`(out sum1 int,out sum2 int,out sum3 int,out sum4 int)
BEGIN
select COUNT(*) into sum1 from insideapp;
select count(*) into sum2 from outsideapp;
select count(*) into sum3 from developer;
select count(*) into sum4 from user;
END$$
DELIMITER ;
使用pymysql模块的对应代码如下(代码给出注释)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='2333',
database="appmarket",
charset='utf8'
)#连接本地MySQL数据库,获得的conn是一个连接对象
cur = conn.cursor()#由conn获取cursor对象
# cur.execute('call return_sum')
t = [1,2,3,4]
row = cur.callproc("return_sum",(1,2,3,4))#调用return_sum的存储过程
effect_row = cur.execute('select @_return_sum_0,@_return_sum_1,@_return_sum_2,@_return_sum_3')#执行sql命令
result = cur.fetchone()#上步命令返回多个值,以数组存储起来
print(result)
好了,完
END ~