Mysql数据库与python的关联--简单应用实例:音乐播放器的设计

安装模块; pip install PyMySQL

Connection对象:

用于建立和数据库的连接
创建对象:调用connect()方法
con = connect(参数列表)
参数host :远程连接mysql主机的ip,若为本机,则是‘localhost’
参数port:连接的主机的端口,默认为3306
参数bd :连接的数据库名称
参数 user: 连接的用户名
参数 password : 连接的密码
参数charset : 通信采用的编码,默认是gb2312,要求与数据库创建时指定的编码一致,否则出现乱码。

对象的方法:
close() 关闭连接
commit() 事物
rollback() 事物
cursor() 返回一个cursor 对象,用于执行sql语句并获得结果

cursor对象

执行sql 语句
创建对象:调用Connection对象的cursor()方法
cursorl = con.cursor()
对象的方法:
close() 关闭对象
execute(operation [ ,paramenters])执行语句,返回手影响的函数
fetchone() 执行查询语句,获取查新结果集的第一行数据,返回一个元组
next()执行查询语句时,获取当前行的下一行
fetchall()执行查询语句时,获取结果集的所有行,一行为一个元组,再将元组装入一个元组中返回

创建一个简单的音乐播放器实例

创建了三个对象来完成整个功能,要修改connect连接的数据库密码。

  1. MyDatabaseConnect
    里面封装了连接自己的本地数据库的一些步骤,对外的接口只需要选择自己的数据库即可
  2. Service
    该对象负责和数据库进行工作,完成对数据库的增删改查。
  3. MainWindow
    这里面是对整个播放器的界面以及事件的反应,对于每一个按钮,对应去调Service对象的方法来完成相应功能。
    整个页面只是一个数据库简单的实现,还有很多还没有优化,一个插入重复音乐的功能可能会报错,有空再来修改。
    部分数据库操作的逻辑如图:

在这里插入图片描述
整体的代码:

from tkinter import *
from tkinter.filedialog import askopenfilenames
import tkinter.messagebox
import pygame
import pymysql


# <Button-1>:鼠标左击事件,1,2,3代表鼠标左,中,右键
# <ButtonRelease-1>鼠标左键施释放事件
# <Double-Button-1>鼠标左键双击


# 创建一个数据库连接的类

class MyDatabasesConnect(object):
    # 传参选择固定的数据库
    def __init__(self, database):
        self.database = database
        self.cursor = None
        self.connection = None

    # 创建一个connection对象和数据库进行连接,创建一个cursor对象进行数据库的操作
    def connect(self):
        try:
            # 创建一个数据库连接
            # 输入connect的主要参数,主机地址,用户,密码,数据库
            self.connection = pymysql.connect('localhost', 'root', '你数据库的密码', self.database)

            # 创建cursor对象
            self.cursor = self.connection.cursor()
        except Exception as ex:
            print(ex)

    # 执行sql语句并根据选项进行返回数据,fetch_option=1/2,返回一行/多行数据
    def get_message(self, fetch_option, sql, *args):
        try:
            self.connect()
            self.cursor.execute(sql, args)
            if fetch_option == 1:
                return self.cursor.fetchone()
            elif fetch_option == 2:
                return self.cursor.fetchall()
            else:
                print('你输入的fetch_option有误,请输入1/2以返回一/多行数据结果')
        except Exception as ex:
            print(ex)
        # 执行完之后关闭连接
        finally:
            self.close()

    # 由于connect创建出的对象,会自动创建事务机制,因此在执行修改的语句的时候必须提交commit
    def execute_DML(self, sql, *args):
        try:
            self.connect()
            self.cursor.execute(sql, args)
            self.connection.commit()
        except Exception as ex:
            self.connection.rollback()
            print(ex)
        finally:
            self.close()

    # 当cursor,connection创建的时候要关闭
    def close(self):
        if self.cursor:
            self.cursor.close()
        if self.connection:
            self.connection.close()

# 创建一个和数据库进行交互的类

class Service(object):
    # 初始化就进行连接数据库,初始化pygame的音乐播放模块
    def __init__(self):
        self.connect = MyDatabasesConnect('my_db')
        self.user = None
        pygame.mixer.init()

    # 定义一个用户登录的方法,将用户输入的姓名和密码与数据库进行比对
    def login(self, username, password):
        self.user = self.connect.get_message(1,
                                             'select id ,user_name,u_password from muser where user_name = %s and u_password = %s',
                                             username, password)
        if self.user:
            print('%s登录成功' % self.user[1])
            return True
        else:
            print('登录失败!')
            return False

    # 定义一个加载本地音乐到数据库的方法,完成插入到music和play_list两张表中,传入参数为文件的路径
    def load_mp3(self, files):
        if files:
            for file in files:
                start = file.rfind('/')
                end = file.rfind('.mp3')
                song_name = file[start + 1:end]
                self.connect.execute_DML('insert into music values (%s,%s,%s)', 0, song_name, file)
                music_id = self.connect.get_message(1, 'select id from music where name = %s', song_name)
                self.connect.execute_DML('insert into play_list (user_id,music_id) values (%s,%s)', self.user[0],
                                         music_id[0])
        else:
            print('用户没有选择文件!')

    # 定义一个查找指定用户的播放列表的方法
    def find_user_playlist(self):
        sql = 'select music.name from music join play_list on music.id = play_list.music_id where play_list.user_id = %s'
        return self.connect.get_message(2, sql, self.user[0])

    # 播放音乐,注意返回的参数的类型是一个元组
    def play_mp3(self, mp3_name):
        file_path = self.connect.get_message(1, 'select path from music where name =%s', mp3_name)
        if file_path and file_path[0]:
            pygame.mixer.music.load(r'%s' % file_path[0])
            pygame.mixer.music.play()

    def stop(self):
        pygame.mixer.music.stop()
    def pause(self):
        pygame.mixer.music.pause()

    # 删除用户的播放列表中的某首歌
    def delete_music(self, mp3_name):
        music_id = self.connect.get_message(1, 'select id from music where name =%s', mp3_name)
        if music_id:
            self.connect.execute_DML('delete from play_list where user_id =%s and music_id=%s', self.user[0], music_id)

class MainWindow():
    # 播放音乐的方法
    def play(self, event):
        # 获取用户所选的歌曲的下标
        num = self.t1.curselection()
        # 获取MP3的名字
        mp3_name = self.t1.get(num)
        # 调用与服务器交互播放音乐的方法
        service.play_mp3(mp3_name)

    # 删除用户的播放列表的某首歌
    def delete_music(self, event):
        # 获取用户所选的歌曲的下标
        num = self.t1.curselection()
        # 获取MP3的名字
        mp3_name = self.t1.get(num)
        # 调用删除数据库的信息
        service.delete_music(mp3_name)
        # 调用查找用户播放列表
        list = service.find_user_playlist()
        # 清空当前播放列表
        self.t1.delete(0, END)
        # 将调用的播放列表的数据显示到列表中
        for i in list:
            self.t1.insert(END, i[0])
    def stop(self,event):
        service.stop()
    def pause(self,event):
        service.pause()

    def button_listener3(selfs, event):
        tkinter.messagebox.showinfo('messagebox', 'this is button1')

    # 加载本地音乐
    def load_mp3(self, event):
        # 打开一个本地的文件窗口,获取文件的路径及名字信息,文件类型指定为.mp3
        files = askopenfilenames(filetypes=(('Mp3 file', '*.mp3*'),))
        # 将获取的信息传入数据库操作中,进行存贮
        service.load_mp3(files)
        # 查找数据库对应的播放列表并返回信息
        list = service.find_user_playlist()
        self.t1.delete(0, END)
        for i in list:
            self.t1.insert(END, i[0])

    def select_text(self, event):
        # tkinter.messagebox.showinfo('messagebox','this is a message')
        #  item = self.t1.curselection()
        #  print(self.t1.get(item))
        pass

    def __init__(self):
        # 创建主体窗口
        self.frame = Tk()
        pygame.mixer.init()
        # 创建按钮
        self.button1 = Button(self.frame, text='播放')
        self.button2 = Button(self.frame, text='暂停')
        self.button3 = Button(self.frame, text='停止')
        self.button4 = Button(self.frame, text='导入歌曲')
        self.button5 = Button(self.frame, text='删除歌曲')
        self.button6 = Button(self.frame, text='增加音量')
        # 创建列表
        self.t1 = Listbox(self.frame, {'selectmode': SINGLE})
        # 放置的位置
        self.button1.grid(row=0, column=0, padx=5, pady=5)
        self.button2.grid(row=0, column=1, padx=5, pady=5)
        self.button3.grid(row=0, column=2, padx=5, pady=5)
        self.button4.grid(row=0, column=3, padx=5, pady=5)
        self.button5.grid(row=0, column=4, padx=5, pady=5)
        self.button6.grid(row=0, column=5, padx=5, pady=5)

        self.t1.grid(row=1, column=0, padx=5, pady=5, columnspan=6)
        # 显示播放列表
        list = service.find_user_playlist()
        self.t1.delete(0, END)
        for i in list:
            self.t1.insert(END, i[0])
        # 为按钮绑定相关的事件对应的函数
        self.t1.bind('<ButtonRelease-1>', self.select_text)
        self.button1.bind('<ButtonRelease-1>', self.play)
        self.button2.bind('<ButtonRelease-1>', self.pause)
        self.button3.bind('<ButtonRelease-1>', self.stop)
        self.button5.bind('<ButtonRelease-1>', self.delete_music)
        self.button4.bind('<ButtonRelease-1>', self.load_mp3)
        # 进行事件的实时监测
        self.frame.mainloop()

if __name__ == '__main__':
    # 进行打开播放器的操作,输入账号密码
    name = input('请输入登录账号:')
    password = input('请输入登录密码:')
    # 创建一个与数据库交互的对象
    service = Service()
    if service.login(name, password):
        window = MainWindow()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值