PyMySQL介绍
PyMySQL是在 Python3.x 版本中用于连接 MySQL 服务器的一个客户端库。
PyMySQL安装:
pip install pymysql
执行过程如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f1pNcLFJ-1670082096208)(images\7_4_1.png)]
检查是否安装成功:
方法一:在python交互模式运行 import pymysql,如果不报错,说明PyMySQL模块已安装成功,如下图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QgUieFro-1670082096210)(images\7_4_2.png)]
方法二:在命令行输入pip list,可以查看已安装的工具包,如下图,可以看到列表里有PyMySQL,说明我们已经安装了PyMySQL
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SKcoZu8O-1670082096211)(F:\python最新就业班\资料编写\第七阶段\images\7_4_11.png)]
方法三:在命令行输入pip show pymysql,如果显示了PyMySQL的信息,说明已经安装了PyMySQL
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KysDYMnU-1670082096213)(images\7_4_12.png)]
在pymysql中提供了Connection和Cursor对象来管理操作MySQL。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6l5wrB2p-1670082096213)(images\7_4_3.png)]
在.py文件中引入pymysql模块
from pymysql import *
代表一个与MySQL Server的socket连接,使用connect方法来创建一个连接实例。
创建对象,调用connect()方法:
conn = connect(参数列表)
参数host:连接的mysql主机,如果本机是’localhost’
参数port:连接的mysql主机的端口,默认是3306
参数database(db):数据库的名称
参数user:连接的用户名
参数password(passwd):连接的密码
参数charset:通信采用的编码方式,推荐使用utf8
Connection对象常用的API:
API | 说明 |
---|---|
connect() | 创建一个数据库连接实例 |
close() | 发送一个退出消息,并关闭连接 |
commit() | 提交修改至数据库 |
cursor() | 创建一个cursor(游标)实例 |
ping() | 检测服务器是否在运行 |
rollback() | 回滚当前事务 |
select_db(db) | 设置当前db |
show_warnings() | 显示警告信息 |
代表一个与MySQL数据库交互对象,使用Connection.Cursor()在当前socket连接上的交互对象。
游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次一行或者多行前进或向后浏览数据的能力。可以把游标当作一个指针,它可以指定结果中的任何位置,然后允许用户对指定位置的数据进行处理
通俗来说就是,操作数据和获取数据库结果都要通过游标来操作。
Cursor对象常用API:·
API | 说明 |
---|---|
close() | 关闭当前cursor |
execute() | 执行一个sql语句 |
executemany() | 执行批量sql语句 |
fetchall() | 取所有数据 |
fetchmany() | 取多条数据,指定取数据条数 |
fetchone() | 取一条数据 |
#1 导入pymysql库
from pymysql import *
#2 创建数据库连接
conn = Connect(host='localhost',port=3306,user='root',password='root',db='mytestdb',charset='utf8')
print(conn)
#3 创建游标
cur = conn.cursor()
#4 执行sql语句和数据处理
pass
#5 关闭游标
cur.close()
#6 关闭连接
conn.close()
执行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i7sTtCVS-1670082096215)(images\7_4_4.png)]
看到以上运行结果,说明Connection对象创建成功,数据库已经连接成功!
什么是sql注入
用户提交带有恶意的数据与SQL语句进行字符串方式的拼接,从而影响了SQL语句的语义,最终产生数据泄露或数据的篡改的现象。
如何防止sql注入-sql语句参数化
参数化查询是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,这个方法目前已被视为最有效可预防SQL注入攻击的防御方式。
#1 导入pymysql包
from pymysql import *
#2 创建数据连接
conn = connect(host='localhost',port=3306,user='root',password='root',db='mytestdb',charset='utf8')
#3 打开游标
cur = conn.cursor()
#4 执行sql语句和数据处理
sname = input('请输入用户名:')
passwd = input('请输入密码:')
#有sql注入漏洞的sql语句
#sql = "select * from t_student where sname='%s' and passwd='%s'"%(sname,passwd)
#print(sql)
#select * from t_student where sname='test' or 1=1 #' and passwd='dsafdsa'
#为防止sql注入,我们对sql语句进行参数化
sql = "select * from t_student where sname=%s and passwd=%s"
params = (sname,passwd)
rowcount = cur.execute(sql,params)
if rowcount != 0:
print("登录成功!")
else:
print("登录失败!")
#5 关闭游标
cur.close()
#6 关闭连接
conn.close()
#1 导入pymsql包
from pymysql import *
#2 创建数据库连接
conn = connect(host='localhost',port=3306,user='root',password='root',db='mytestdb',charset='utf8')
#3 打开游标
cur = conn.cursor()
#4 执行 sql语句
#编写sql语句
try:
sql = "insert into t_student values (%s,%s,%s,%s,%s,%s,%s,%s)"
params = (7,"肖小军","123456",'男',21,"2020-07-15","大数据班","[email protected]")
#执行sql语句
cur.execute(sql,params)
conn.commit()
except:
conn.rollback()
print("数据增加成功!")
#5 关闭游标
cur.close()
#6 关闭连接
conn.close()
运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p9Mr0vqE-1670082096216)(images\7_4_5.png)]
# 教育机构:马士兵教育
# 讲 师:张祖春
#1 导入pymsql包
from pymysql import *
#2 创建数据库连接
conn = connect(host='localhost',port=3306,user='root',password='root',db='mytestdb',charset='utf8')
#3 打开游标
cur = conn.cursor()
#4 执行 sql语句
#编写sql语句
try:
sql = "insert into t_student values (%s,%s,%s,%s,%s,%s,%s,%s)"
params = [(7,"王辉1","123456",'男',24,"2020-09-15","Python全栈班","[email protected]"),
(7, "王辉2", "123456", '男', 24, "2020-09-15", "Python全栈班", "[email protected]"),
(7, "王辉3", "123456", '男', 24, "2020-09-15", "Python全栈班", "[email protected]")
]
#执行sql语句
cur.executemany(sql,params)
conn.commit()
except:
conn.rollback()
print("数据增加成功!")
#5 关闭游标
cur.close()
#6 关闭连接
conn.close()
运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-av7euMus-1670082096217)(images\7_4_10.png)]
#1 导入pymsql包
from pymysql import *
#2 创建数据库连接
conn = connect(host='localhost',port=3306,user='root',password='root',db='mytestdb',charset='utf8')
print(conn)
#3 打开游标
cur = conn.cursor()
#4 执行 sql语句
#编写sql语句
try:
sql = "delete from t_student where sno=%s"
params = (7)
#执行sql语句
rowcount = cur.execute(sql,params)
conn.commit()
except:
conn.rollback()
print("已删除"+str(rowcount)+"条数据!")
#5 关闭游标
cur.close()
#6 关闭连接
conn.close()
执行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GcEpctsx-1670082096218)(images\7_4_6.png)]
#1 导入pymsql包
from pymysql import *
#2 创建数据库连接
conn = connect(host='localhost',port=3306,user='root',password='root',db='mytestdb',charset='utf8')
print(conn)
#3 打开游标
cur = conn.cursor()
#4 执行 sql语句
#编写sql语句
try:
# 删除和修改操作一定要限定条件,不然将影响其他数据,甚至误删或修改整个数据库
sql = "update t_student set sname=%s where sno=%s"
params = ('李敏',8)
#执行sql语句
rowcount = cur.execute(sql,params)
conn.commit()
except:
conn.rollback()
print("已修改"+str(rowcount)+"条数据!")
#5 关闭游标
cur.close()
#6 关闭连接
conn.close()
执行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CAHFWkKO-1670082096219)(images\7_4_7.png)]
#1 导入pymsql包
from pymysql import *
#2 创建数据库连接
conn = connect(host='localhost',port=3306,user='root',password='root',db='mytestdb',charset='utf8')
#3 打开游标
cur = conn.cursor()
#4 执行 sql语句
#编写sql语句
# 查询数据时,为了节约内存,不要用*,而应该指定具体要取的字段,另外要指定查询条件
sql = "select sno,sname,sex,age,classname from t_student where age>%s"
params = (20)
#执行sql语句
cur.execute(sql,params)
# result=cur.fetchone() #取一条数据
# print(result)
#result=cur.fetchmany(3) #取指定多条数据
result=cur.fetchall() #取所有数据
#打印输出执行结果
for row in result:
print(row)
#5 关闭游标
cur.close()
#6 关闭连接
conn.close()
观察前面的文件发现,除了sql语句及参数不同,其它语句都是一样的
这样造成了很多重复代码,我们可以把数据库常用操作封装为一个类,以便代码可以重复使用
创建MysqlHelper.py文件,定义类
from pymysql import *
class MysqlHelper(object):
#数据库连接参数,可以定义多个,比如conn_params1,conn_params2,用于连接多个数据库,在类实例化时指定
conn_params1 = {'host': 'localhost', 'port': 3306, 'user': 'root', 'passwd': 'root', 'db': 'mytestdb',
'charset': 'utf8'}
#类的构造函数,主要用于类的初始化
def __init__(self, conn_params):
self.__host = conn_params['host']
self.__port = conn_params['port']
self.__db = conn_params['db']
self.__user = conn_params['user']
self.__passwd = conn_params['passwd']
self.__charset = conn_params['charset']
#建立数据库连接和打开游标
def __connect(self):
self.__conn = connect(host=self.__host, port=self.__port, db=self.__db, user=self.__user, passwd=self.__passwd,
charset=self.__charset)
self.__cursor = self.__conn.cursor()
#关闭游标和关闭连接
def __close(self):
self.__cursor.close()
self.__conn.close()
#取一条数据
def get_one(self, sql, params):
result = None
try:
self.__connect()
self.__cursor.execute(sql, params)
result = self.__cursor.fetchone()
self.__close()
except Exception as e:
print(e)
return result
#取所有数据
def get_all(self, sql, params):
lst = ()
try:
self.__connect()
self.__cursor.execute(sql, params)
lst = self.__cursor.fetchall()
self.__close()
except Exception as e:
print(e)
return lst
#增加数据
def insert(self, sql, params):
return self.__edit(sql, params)
#修改数据
def update(self, sql, params):
return self.__edit(sql, params)
#删除数据
def delete(self, sql, params):
return self.__edit(sql, params)
#写数据操作具体实现,增删改操作都是调用这个方法来实现,这是个私有方法,不允许类外部调用
def __edit(self, sql, params):
count = 0
try:
self.__connect()
count = self.__cursor.execute(sql, params)
self.__conn.commit()
self.__close()
except Exception as e:
print(e)
return count
MysqlHelper类的调用
from MysqlHelper import *
# 数据库查询
'''
mysqlhelper = MysqlHelper(MysqlHelper.conn_params1)
sql = "select sno,sname,sex,age,classname from t_student where age>%s"
params = (20)
result = mysqlhelper.get_all(sql, params)
# 打印输出执行结果
for row in result:
print(row)'''
#增加数据
'''
mysqlhelper = MysqlHelper(MysqlHelper.conn_params1)
sql = "insert into t_student values (%s,%s,%s,%s,%s,%s,%s,%s)"
params = (11,"王五","123456",'男',24,"2020-09-15","python全栈班","[email protected]")
rowcount = mysqlhelper.insert(sql, params)
print("已增加"+str(rowcount)+"条数据")'''
#删除数据
'''
mysqlhelper = MysqlHelper(MysqlHelper.conn_params1)
sql = "delete from t_student where sno=%s"
params = (11)
rowcount = mysqlhelper.delete(sql, params)
print("已删除"+str(rowcount)+"条数据")'''
#修改数据
'''
mysqlhelper = MysqlHelper(MysqlHelper.conn_params1)
sql = "update t_student set classname=%s where sno=%s"
params = ('大数据班',9)
rowcount = mysqlhelper.update(sql, params)
print("已修改"+str(rowcount)+"条数据")'''