[TOC]
一、Python 中操作 MySQL 步骤
1.1 引入模块
- 在py文件中引入pymysql模块
from pymysql import *
1.2 Connection 对象
- 用于建立与数据库的连接
- 创建对象:调用connect()方法
conn=connect(参数列表)
- 参数host:连接的mysql主机,如果本机是'localhost'
- 参数port:连接的mysql主机的端口,默认是3306
- 参数database:数据库的名称
- 参数user:连接的用户名
- 参数password:连接的密码
- 参数charset:通信采用的编码方式,推荐使用utf8
1.2.1 对象的方法
- close()关闭连接
- commit()提交
- cursor()返回Cursor对象,用于执行sql语句并获得结果
1.3 Cursor对象
- 用于执行sql语句,使用频度最高的语句为select、insert、update、delete
- 获取Cursor对象:调用Connection对象的cursor()方法
cs1=conn.cursor()
1.3.1 对象的方法
- close()关闭
- execute(operation [, parameters ])执行语句,返回受影响的行数,主要用于执行insert、update、delete语句,也可以执行create、alter、drop等语句
- fetchone()执行查询语句时,获取查询结果集的第一个行数据,返回一个元组
- fetchall()执行查询时,获取结果集的所有行,一行构成一个元组,再将这些元组装入一个元组返回
cs1 = conn.cursor()
cs1.execute("select * from goods") # 返回行数
# (1, 'r510vc 15.6英寸笔记本', '笔记本', '华硕', Decimal('3399.000'), b'\x01', b'\x00')
# 一条一条取,返回值为元组
cs1.fetchone()
# 根据参数取值,参数为3,取3行数据
cs1.fetchmany(3)
# 取所有行
cs1.fetchall()
1.3.2 对象的属性
- rowcount只读属性,表示最近一次execute()执行后受影响的行数
- connection获得当前连接对象
二、增删改查
2.1 增删改
记得提交:conn.commit()
如果增删改查错误:回滚conn.rollback()
from pymysql import *
def main():
# 创建Connection连接
conn = connect(host='localhost',port=3306,database='jing_dong',user='root',password='mysql',charset='utf8')
# 获得Cursor对象
cs1 = conn.cursor()
# 执行insert语句,并返回受影响的行数:添加一条数据
# 增加
count = cs1.execute('insert into goods_cates(name) values("硬盘")')
#打印受影响的行数
print(count)
count = cs1.execute('insert into goods_cates(name) values("光盘")')
print(count)
# # 更新
# count = cs1.execute('update goods_cates set name="机械硬盘" where name="硬盘"')
# # 删除
# count = cs1.execute('delete from goods_cates where id=6')
# 提交之前的操作,如果之前已经之执行过多次的execute,那么就都进行提交
conn.commit()
# 关闭Cursor对象
cs1.close()
# 关闭Connection对象
conn.close()
if __name__ == '__main__':
main()
2.2 查询一行数据
from pymysql import *
def main():
# 创建Connection连接,localhost=127.0.0.1
conn = connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset='utf8')
# 获得Cursor对象
cs1 = conn.cursor()
# 执行select语句,并返回受影响的行数:查询一条数据
count = cs1.execute('select id,name from goods where id>=4')
# 打印受影响的行数
print("查询到%d条数据:" % count)
for i in range(count):
# 获取查询的结果
result = cs1.fetchone()
# 打印查询的结果
print(result)
# 获取查询的结果
# 关闭Cursor对象
cs1.close()
conn.close()
if __name__ == '__main__':
main()
2.3 查询多行数据
from pymysql import *
def main():
# 创建Connection连接
conn = connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset='utf8')
# 获得Cursor对象
cs1 = conn.cursor()
# 执行select语句,并返回受影响的行数:查询一条数据
count = cs1.execute('select id,name from goods where id>=4')
# 打印受影响的行数
print("查询到%d条数据:" % count)
# for i in range(count):
# # 获取查询的结果
# result = cs1.fetchone()
# # 打印查询的结果
# print(result)
# # 获取查询的结果
result = cs1.fetchall()
print(result)
# 关闭Cursor对象
cs1.close()
conn.close()
if __name__ == '__main__':
main()
2.4 案例
from pymysql import connect
class JD(object):
def __init__(self):
# 创建Connection连接
self.conn = connect(host='localhost', port=3306, user='root', password='mysql', database='jing_dong', charset='utf8')
# 获得Cursor对象
self.cursor = self.conn.cursor()
def __del__(self):
# 关闭Cursor对象
self.cursor.close()
self.conn.close()
def execute_sql(self, sql):
self.cursor.execute(sql)
for temp in self.cursor.fetchall():
print(temp) # 每行的元组
def show_all_items(self):
"""显示所有的商品"""
sql = "select * from goods;"
self.execute_sql(sql)
def show_cates(self):
"""显示商品分类"""
sql = "select name from goods_cates;"
self.execute_sql(sql)
def show_brands(self):
"""显示商品分类"""
sql = "select name from goods_brands;"
self.execute_sql(sql)
@staticmethod
def print_menu():
print("....京东....")
print("1:所有的商品")
print("2:所有的商品分类")
print("3:所有的商品品牌分类")
num = input("请输入功能对应的序号:")
return num
def run(self):
while True:
num = self.print_menu()
if num == "1": # input输入的都是字符串
# 查询所有商品
self.show_all_items()
elif num == "2":
# 查询分类
self.show_cates()
elif num == "3":
# 查询品牌分类
self.show_brands()
else:
print("输入有误,请重新输入...")
def main():
# 1.创建一个京东商城对象
jd = JD()
# 2.调用这个对象的润run方法,让其运行
jd.run()
if __name__ == "__main__":
main()
三、参数化(防止sql注入)
- sql语句的参数化,可以有效防止sql注入。
- 注意:此处不同于python的字符串格式化,全部使用%s占位。
- sql注入:用户输入的字符串和你数据库设定的偏偏能配对。
from pymysql import *
def main():
find_name = input("请输入物品名称:")
# 创建Connection连接
conn = connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset='utf8')
# 获得Cursor对象
cs1 = conn.cursor()
# # 非安全的方式
# # 输入 " or 1=1 or " (双引号也要输入)
# sql = 'select * from goods where name="%s"' % find_name
# print("""===>%s<====""" % sql)
# # 执行select语句,并返回受影响的行数:查询所有数据
# count = cs1.execute(sql)
# 安全的方式
# 构造参数列表
params = [find_name]
# 执行select语句,并返回受影响的行数:查询所有数据
count = cs1.execute('select * from goods where name=%s', params)
# 注意:
# 如果要是有多个参数,需要进行参数化
# 那么params = [数值1, 数值2....],此时sql语句中有多个%s即可
# 打印受影响的行数
print(count)
# 获取查询的结果
# result = cs1.fetchone()
result = cs1.fetchall()
# 打印查询的结果
print(result)
# 关闭Cursor对象
cs1.close()
# 关闭Connection对象
conn.close()
if __name__ == '__main__':
main()
3.1 sql注入
from pymysql import connect
class JD(object):
def __init__(self):
# 创建Connection连接
self.conn = connect(host='localhost', port=3306, user='root', password='mysql', database='jing_dong',charset='utf8')
# 获得Cursor对象
self.cursor = self.conn.cursor()
def __del__(self):
# 关闭Cursor对象
self.cursor.close()
self.conn.close()
def execute_sql(self, sql):
self.cursor.execute(sql)
for temp in self.cursor.fetchall():
print(temp) # 每行的元组
def show_all_items(self):
"""显示所有的商品"""
sql = "select * from goods;"
self.execute_sql(sql)
def show_cates(self):
"""显示商品分类"""
sql = "select name from goods_cates;"
self.execute_sql(sql)
def show_brands(self):
"""显示商品分类"""
sql = "select name from goods_brands;"
self.execute_sql(sql)
def get_info_by_name(self):
find_name = input("请输入要查询的商品的名字:")
sql = """" select * from goods where name = '%s'; """ % find_name
print("------>%s<------" % sql)
self.execute_sql(sql)
@staticmethod
def print_menu():
print("....京东....")
print("1:所有的商品")
print("2:所有的商品分类")
print("3:所有的商品品牌分类")
print("4:根据名字查询一个商品")
num = input("请输入功能对应的序号:")
return num
def run(self):
while True:
num = self.print_menu()
if num == "1": # input输入的都是字符串
# 查询所有商品
self.show_all_items()
elif num == "2":
# 查询分类
self.show_cates()
elif num == "3":
# 查询品牌分类
self.show_brands()
elif num == "4":
# 根据名字查询商品
self.get_info_by_name()
else:
print("输入有误,请重新输入...")
def main():
# 1.创建一个京东商城对象
jd = JD()
# 2.调用这个对象的润run方法,让其运行
jd.run()
if __name__ == "__main__":
main()
3.2 防止sql注入
from pymysql import connect
class JD(object):
def __init__(self):
# 创建Connection连接
self.conn = connect(host='localhost', port=3306, user='root', password='mysql', database='jing_dong',charset='utf8')
# 获得Cursor对象
self.cursor = self.conn.cursor()
def __del__(self):
# 关闭Cursor对象
self.cursor.close()
self.conn.close()
def execute_sql(self, sql):
self.cursor.execute(sql)
for temp in self.cursor.fetchall():
print(temp) # 每行的元组
def show_all_items(self):
"""显示所有的商品"""
sql = "select * from goods;"
self.execute_sql(sql)
def show_cates(self):
"""显示商品分类"""
sql = "select name from goods_cates;"
self.execute_sql(sql)
def show_brands(self):
"""显示商品分类"""
sql = "select name from goods_brands;"
self.execute_sql(sql)
def get_info_by_name(self):
find_name = input("请输入要查询的商品的名字:")
sql = "select * from goods name = %s"
self.cursor.execute(sql, [find_name])
print(self.cursor.fetchall())
@staticmethod
def print_menu():
print("....京东....")
print("1:所有的商品")
print("2:所有的商品分类")
print("3:所有的商品品牌分类")
print("4:根据名字查询一个商品")
num = input("请输入功能对应的序号:")
return num
def run(self):
while True:
num = self.print_menu()
if num == "1": # input输入的都是字符串
# 查询所有商品
self.show_all_items()
elif num == "2":
# 查询分类
self.show_cates()
elif num == "3":
# 查询品牌分类
self.show_brands()
elif num == "4":
# 根据名字查询商品
self.get_info_by_name()
else:
print("输入有误,请重新输入...")
def main():
# 1.创建一个京东商城对象
jd = JD()
# 2.调用这个对象的润run方法,让其运行
jd.run()
if __name__ == "__main__":
main()